summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/infra-dashboard/README.md3
-rw-r--r--tools/infra-dashboard/css/bootstrap.min.css5488
-rw-r--r--tools/infra-dashboard/css/dataTables.bootstrap.min.css1
-rw-r--r--tools/infra-dashboard/css/font-awesome.css1801
-rw-r--r--tools/infra-dashboard/css/fullcalendar.css1260
-rw-r--r--tools/infra-dashboard/css/fullcalendar.print.css208
-rw-r--r--tools/infra-dashboard/css/highslide.min.css793
-rw-r--r--tools/infra-dashboard/css/opnfv.css2479
-rw-r--r--tools/infra-dashboard/css/source-sans-pro.css96
-rw-r--r--tools/infra-dashboard/css/template.css802
-rw-r--r--tools/infra-dashboard/css/theme.css387
-rw-r--r--tools/infra-dashboard/fonts/SourceSansPro-Bold.ttfbin118604 -> 0 bytes
-rw-r--r--tools/infra-dashboard/fonts/SourceSansPro-ExtraLight.ttfbin119324 -> 0 bytes
-rw-r--r--tools/infra-dashboard/fonts/SourceSansPro-Regular.ttfbin119080 -> 0 bytes
-rw-r--r--tools/infra-dashboard/fonts/fontawesome-webfont.ttfbin142072 -> 0 bytes
-rw-r--r--tools/infra-dashboard/fonts/fontawesome-webfont.woffbin83588 -> 0 bytes
-rw-r--r--tools/infra-dashboard/fonts/fontawesome-webfont.woff2bin66624 -> 0 bytes
-rw-r--r--tools/infra-dashboard/fonts/source-sans-pro.black.ttfbin118004 -> 0 bytes
-rw-r--r--tools/infra-dashboard/index.php355
-rw-r--r--tools/infra-dashboard/js/bootstrap.js2118
-rw-r--r--tools/infra-dashboard/js/fullcalendar.js12670
-rw-r--r--tools/infra-dashboard/js/fullcalendar.min.js9
-rw-r--r--tools/infra-dashboard/js/highslide-full.min.js3315
-rw-r--r--tools/infra-dashboard/js/highslide.config.min.js1
-rw-r--r--tools/infra-dashboard/js/jquery-1.7.2.js9404
-rw-r--r--tools/infra-dashboard/js/jquery.min.js5
-rw-r--r--tools/infra-dashboard/js/modernizr.js4
-rw-r--r--tools/infra-dashboard/js/moment.min.js7
-rw-r--r--tools/infra-dashboard/js/script.js27
-rw-r--r--tools/infra-dashboard/js/test_graph.js108
-rw-r--r--tools/infra-dashboard/media/ajax-loader.gifbin3208 -> 0 bytes
-rw-r--r--tools/infra-dashboard/media/collaborative-projects-logo.pngbin3625 -> 0 bytes
-rw-r--r--tools/infra-dashboard/media/diagonal-white.pngbin82 -> 0 bytes
-rw-r--r--tools/infra-dashboard/media/favicon_400x400.jpgbin10235 -> 0 bytes
-rw-r--r--tools/infra-dashboard/media/loader.white.gifbin673 -> 0 bytes
-rw-r--r--tools/infra-dashboard/media/opnfvlogo.JPGbin12297 -> 0 bytes
-rw-r--r--tools/infra-dashboard/pages/ci_pods.php91
-rw-r--r--tools/infra-dashboard/pages/dev_pods.php342
-rw-r--r--tools/infra-dashboard/pages/slaves.php58
-rw-r--r--tools/infra-dashboard/populateDB.txt203
-rw-r--r--tools/infra-dashboard/utils/book.php82
-rw-r--r--tools/infra-dashboard/utils/database.php20
-rw-r--r--tools/infra-dashboard/utils/jenkinsAdapter.php204
-rw-r--r--tools/infra-dashboard/utils/login.php56
44 files changed, 0 insertions, 42397 deletions
diff --git a/tools/infra-dashboard/README.md b/tools/infra-dashboard/README.md
deleted file mode 100644
index b43afd66..00000000
--- a/tools/infra-dashboard/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# OPNFV Infrastructure Dashboard
-This is the dashboard proposal for OPNFV Pharos and CI resources reservation.
-Creator and maintainer: jose.lausuch@ericsson.com
diff --git a/tools/infra-dashboard/css/bootstrap.min.css b/tools/infra-dashboard/css/bootstrap.min.css
deleted file mode 100644
index 1d23653c..00000000
--- a/tools/infra-dashboard/css/bootstrap.min.css
+++ /dev/null
@@ -1,5488 +0,0 @@
-/*!
- * Bootstrap v3.2.0 (http://getbootstrap.com)
- * Copyright 2011-2014 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- */
-/*!
- * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=e82eeb1f3b04b506268e)
- * Config saved to config.json and https://gist.github.com/e82eeb1f3b04b506268e
- */
-/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
-
-.sr-only,
-svg:not(:root) {
- overflow: hidden
-}
-hr,
-img {
- border: 0
-}
-body,
-figure {
- margin: 0
-}
-.img-thumbnail,
-.thumbnail {
- -webkit-transition: all .2s ease-in-out
-}
-.btn-group>.btn-group,
-.btn-toolbar .btn-group,
-.btn-toolbar .input-group,
-.col-xs-1,
-.col-xs-10,
-.col-xs-11,
-.col-xs-12,
-.col-xs-2,
-.col-xs-3,
-.col-xs-4,
-.col-xs-5,
-.col-xs-6,
-.col-xs-7,
-.col-xs-8,
-.col-xs-9,
-.dropdown-menu {
- float: left
-}
-.navbar-fixed-bottom .navbar-collapse,
-.navbar-fixed-top .navbar-collapse,
-.pre-scrollable {
- max-height: 340px
-}
-html {
- font-family: sans-serif;
- -ms-text-size-adjust: 100%;
- -webkit-text-size-adjust: 100%;
- font-size: 10px;
- -webkit-tap-highlight-color: transparent
-}
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-main,
-nav,
-section,
-summary {
- display: block
-}
-audio,
-canvas,
-progress,
-video {
- display: inline-block;
- vertical-align: baseline
-}
-audio:not([controls]) {
- display: none;
- height: 0
-}
-[hidden],
-template {
- display: none
-}
-a {
- background: 0 0
-}
-a:active,
-a:hover {
- outline: 0
-}
-b,
-optgroup,
-strong {
- font-weight: 700
-}
-dfn {
- font-style: italic
-}
-h1 {
- margin: .67em 0
-}
-mark {
- background: #ff0;
- color: #000
-}
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline
-}
-sup {
- top: -.5em
-}
-sub {
- bottom: -.25em
-}
-img {
- vertical-align: middle
-}
-hr {
- -moz-box-sizing: content-box;
- box-sizing: content-box;
- height: 0
-}
-pre,
-textarea {
- overflow: auto
-}
-code,
-kbd,
-pre,
-samp {
- font-size: 1em
-}
-button,
-input,
-optgroup,
-select,
-textarea {
- color: inherit;
- font: inherit;
- margin: 0
-}
-button {
- overflow: visible
-}
-button,
-select {
- text-transform: none
-}
-button,
-html input[type=button],
-input[type=reset],
-input[type=submit] {
- -webkit-appearance: button;
- cursor: pointer
-}
-button[disabled],
-html input[disabled] {
- cursor: default
-}
-button::-moz-focus-inner,
-input::-moz-focus-inner {
- border: 0;
- padding: 0
-}
-input[type=checkbox],
-input[type=radio] {
- box-sizing: border-box;
- padding: 0
-}
-input[type=number]::-webkit-inner-spin-button,
-input[type=number]::-webkit-outer-spin-button {
- height: auto
-}
-input[type=search]::-webkit-search-cancel-button,
-input[type=search]::-webkit-search-decoration {
- -webkit-appearance: none
-}
-table {
- border-collapse: collapse;
- border-spacing: 0
-}
-td,
-th {
- padding: 0
-}
-@media print {
- blockquote,
- img,
- pre,
- tr {
- page-break-inside: avoid
- }
- * {
- text-shadow: none!important;
- color: #000!important;
- background: 0 0!important;
- box-shadow: none!important
- }
- a,
- a:visited {
- text-decoration: underline
- }
- a[href]:after {
- content: " (" attr(href) ")"
- }
- abbr[title]:after {
- content: " (" attr(title) ")"
- }
- a[href^="#"]:after,
- a[href^="javascript:"]:after {
- content: ""
- }
- blockquote,
- pre {
- border: 1px solid #999
- }
- thead {
- display: table-header-group
- }
- img {
- max-width: 100%!important
- }
- h2,
- h3,
- p {
- orphans: 3;
- widows: 3
- }
- h2,
- h3 {
- page-break-after: avoid
- }
- select {
- background: #fff!important
- }
- .navbar {
- display: none
- }
- .table td,
- .table th {
- background-color: #fff!important
- }
- .btn>.caret,
- .dropup>.btn>.caret {
- border-top-color: #000!important
- }
- .label {
- border: 1px solid #000
- }
- .table {
- border-collapse: collapse!important
- }
- .table-bordered td,
- .table-bordered th {
- border: 1px solid #ddd!important
- }
-}
-.btn,
-.btn-danger.active,
-.btn-danger:active,
-.btn-default.active,
-.btn-default:active,
-.btn-info.active,
-.btn-info:active,
-.btn-primary.active,
-.btn-primary:active,
-.btn-warning.active,
-.btn-warning:active,
-.btn.active,
-.btn:active,
-.dropdown-menu>.disabled>a:focus,
-.dropdown-menu>.disabled>a:hover,
-.form-control,
-.navbar-toggle,
-.open>.dropdown-toggle.btn-danger,
-.open>.dropdown-toggle.btn-default,
-.open>.dropdown-toggle.btn-info,
-.open>.dropdown-toggle.btn-primary,
-.open>.dropdown-toggle.btn-warning {
- background-image: none
-}
-.img-thumbnail,
-body {
- background-color: #fff
-}
-*,
-:after,
-:before {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box
-}
-body {
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
- font-size: 14px;
- line-height: 1.42857143;
- color: #333
-}
-button,
-input,
-select,
-textarea {
- font-family: inherit;
- font-size: inherit;
- line-height: inherit
-}
-a {
- color: #428bca;
- text-decoration: none
-}
-a:focus,
-a:hover {
- color: #2a6496;
- text-decoration: underline
-}
-a:focus {
- outline: dotted thin;
- outline: -webkit-focus-ring-color auto 5px;
- outline-offset: -2px
-}
-.carousel-inner>.item>a>img,
-.carousel-inner>.item>img,
-.img-responsive,
-.thumbnail a>img,
-.thumbnail>img {
- display: block;
- width: 100%\9;
- max-width: 100%;
- height: auto
-}
-.img-rounded {
- border-radius: 6px
-}
-.img-thumbnail {
- padding: 4px;
- line-height: 1.42857143;
- border: 1px solid #ddd;
- border-radius: 4px;
- -o-transition: all .2s ease-in-out;
- transition: all .2s ease-in-out;
- display: inline-block;
- width: 100%\9;
- max-width: 100%;
- height: auto
-}
-.img-circle {
- border-radius: 50%
-}
-hr {
- margin-top: 20px;
- margin-bottom: 20px;
- border-top: 1px solid #eee
-}
-.sr-only {
- position: absolute;
- width: 1px;
- height: 1px;
- margin: -1px;
- padding: 0;
- clip: rect(0, 0, 0, 0);
- border: 0
-}
-.sr-only-focusable:active,
-.sr-only-focusable:focus {
- position: static;
- width: auto;
- height: auto;
- margin: 0;
- overflow: visible;
- clip: auto
-}
-.h1,
-.h2,
-.h3,
-.h4,
-.h5,
-.h6,
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
- font-family: inherit;
- font-weight: 500;
- line-height: 1.1;
- color: inherit
-}
-.h1 .small,
-.h1 small,
-.h2 .small,
-.h2 small,
-.h3 .small,
-.h3 small,
-.h4 .small,
-.h4 small,
-.h5 .small,
-.h5 small,
-.h6 .small,
-.h6 small,
-h1 .small,
-h1 small,
-h2 .small,
-h2 small,
-h3 .small,
-h3 small,
-h4 .small,
-h4 small,
-h5 .small,
-h5 small,
-h6 .small,
-h6 small {
- font-weight: 400;
- line-height: 1;
- color: #777
-}
-.h1,
-.h2,
-.h3,
-h1,
-h2,
-h3 {
- margin-top: 20px;
- margin-bottom: 10px
-}
-.h1 .small,
-.h1 small,
-.h2 .small,
-.h2 small,
-.h3 .small,
-.h3 small,
-h1 .small,
-h1 small,
-h2 .small,
-h2 small,
-h3 .small,
-h3 small {
- font-size: 65%
-}
-.h4,
-.h5,
-.h6,
-h4,
-h5,
-h6 {
- margin-top: 10px;
- margin-bottom: 10px
-}
-.h4 .small,
-.h4 small,
-.h5 .small,
-.h5 small,
-.h6 .small,
-.h6 small,
-h4 .small,
-h4 small,
-h5 .small,
-h5 small,
-h6 .small,
-h6 small {
- font-size: 75%
-}
-.h1,
-h1 {
- font-size: 36px
-}
-.h2,
-h2 {
- font-size: 30px
-}
-.h3,
-h3 {
- font-size: 24px
-}
-.h4,
-h4 {
- font-size: 18px
-}
-.h5,
-h5 {
- font-size: 14px
-}
-.h6,
-h6 {
- font-size: 9pt
-}
-p {
- margin: 0 0 10px
-}
-.lead {
- margin-bottom: 20px;
- font-size: 1pc;
- font-weight: 300;
- line-height: 1.4
-}
-dt,
-label {
- font-weight: 700
-}
-address,
-blockquote .small,
-blockquote footer,
-blockquote small,
-dd,
-dt,
-pre {
- line-height: 1.42857143
-}
-@media (min-width: 768px) {
- .lead {
- font-size: 21px
- }
-}
-.small,
-small {
- font-size: 85%
-}
-cite {
- font-style: normal
-}
-.mark,
-mark {
- background-color: #fcf8e3;
- padding: .2em
-}
-.list-inline,
-.list-unstyled {
- padding-left: 0;
- list-style: none
-}
-.text-left {
- text-align: left
-}
-.text-right {
- text-align: right
-}
-.text-center {
- text-align: center
-}
-.text-justify {
- text-align: justify
-}
-.text-nowrap {
- white-space: nowrap
-}
-.text-lowercase {
- text-transform: lowercase
-}
-.text-uppercase {
- text-transform: uppercase
-}
-.text-capitalize {
- text-transform: capitalize
-}
-.text-muted {
- color: #777
-}
-.text-primary {
- color: #428bca
-}
-a.text-primary:hover {
- color: #3071a9
-}
-.text-success {
- color: #3c763d
-}
-a.text-success:hover {
- color: #2b542c
-}
-.text-info {
- color: #31708f
-}
-a.text-info:hover {
- color: #245269
-}
-.text-warning {
- color: #8a6d3b
-}
-a.text-warning:hover {
- color: #66512c
-}
-.text-danger {
- color: #a94442
-}
-a.text-danger:hover {
- color: #843534
-}
-.bg-primary {
- color: #fff;
- background-color: #428bca
-}
-a.bg-primary:hover {
- background-color: #3071a9
-}
-.bg-success {
- background-color: #dff0d8
-}
-a.bg-success:hover {
- background-color: #c1e2b3
-}
-.bg-info {
- background-color: #d9edf7
-}
-a.bg-info:hover {
- background-color: #afd9ee
-}
-.bg-warning {
- background-color: #fcf8e3
-}
-a.bg-warning:hover {
- background-color: #f7ecb5
-}
-.bg-danger {
- background-color: #f2dede
-}
-a.bg-danger:hover {
- background-color: #e4b9b9
-}
-pre code,
-table {
- background-color: transparent
-}
-.page-header {
- padding-bottom: 9px;
- margin: 40px 0 20px;
- border-bottom: 1px solid #eee
-}
-dl,
-ol,
-ul {
- margin-top: 0
-}
-blockquote ol:last-child,
-blockquote p:last-child,
-blockquote ul:last-child,
-ol ol,
-ol ul,
-ul ol,
-ul ul {
- margin-bottom: 0
-}
-address,
-dl {
- margin-bottom: 20px
-}
-ol,
-ul {
- margin-bottom: 10px
-}
-.list-inline {
- margin-left: -5px
-}
-.list-inline>li {
- display: inline-block;
- padding-left: 5px;
- padding-right: 5px
-}
-dd {
- margin-left: 0
-}
-@media (min-width: 768px) {
- .dl-horizontal dt {
- float: left;
- width: 10pc;
- clear: left;
- text-align: right;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap
- }
- .dl-horizontal dd {
- margin-left: 180px
- }
- .container {
- width: 750px
- }
-}
-abbr[data-original-title],
-abbr[title] {
- cursor: help;
- border-bottom: 1px dotted #777
-}
-.initialism {
- font-size: 90%;
- text-transform: uppercase
-}
-blockquote {
- padding: 10px 20px;
- margin: 0 0 20px;
- font-size: 17.5px;
- border-left: 5px solid #eee
-}
-blockquote .small,
-blockquote footer,
-blockquote small {
- display: block;
- font-size: 80%;
- color: #777
-}
-legend,
-pre {
- display: block;
- color: #333
-}
-blockquote .small:before,
-blockquote footer:before,
-blockquote small:before {
- content: '\2014 \00A0'
-}
-.blockquote-reverse,
-blockquote.pull-right {
- padding-right: 15px;
- padding-left: 0;
- border-right: 5px solid #eee;
- border-left: 0;
- text-align: right
-}
-code,
-kbd {
- padding: 2px 4px;
- font-size: 90%
-}
-.blockquote-reverse .small:before,
-.blockquote-reverse footer:before,
-.blockquote-reverse small:before,
-blockquote.pull-right .small:before,
-blockquote.pull-right footer:before,
-blockquote.pull-right small:before {
- content: ''
-}
-.blockquote-reverse .small:after,
-.blockquote-reverse footer:after,
-.blockquote-reverse small:after,
-blockquote.pull-right .small:after,
-blockquote.pull-right footer:after,
-blockquote.pull-right small:after {
- content: '\00A0 \2014'
-}
-.popover>.arrow:after,
-blockquote:after,
-blockquote:before {
- content: ""
-}
-address {
- font-style: normal
-}
-code,
-kbd,
-pre,
-samp {
- font-family: Menlo, Monaco, Consolas, "Courier New", monospace
-}
-code {
- color: #c7254e;
- background-color: #f9f2f4;
- border-radius: 4px
-}
-kbd {
- color: #fff;
- background-color: #333;
- border-radius: 3px;
- box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25)
-}
-kbd kbd {
- padding: 0;
- font-size: 100%;
- box-shadow: none
-}
-pre {
- padding: 9.5px;
- margin: 0 0 10px;
- font-size: 13px;
- word-break: break-all;
- word-wrap: break-word;
- background-color: #f5f5f5;
- border: 1px solid #ccc;
- border-radius: 4px
-}
-.container,
-.container-fluid {
- margin-right: auto;
- margin-left: auto
-}
-pre code {
- padding: 0;
- font-size: inherit;
- color: inherit;
- white-space: pre-wrap;
- border-radius: 0
-}
-.container,
-.container-fluid {
- padding-left: 15px;
- padding-right: 15px
-}
-.pre-scrollable {
- overflow-y: scroll
-}
-@media (min-width: 992px) {
- .container {
- width: 970px
- }
-}
-@media (min-width: 1200px) {
- .container {
- width: 1170px
- }
-}
-.row {
- margin-left: -15px;
- margin-right: -15px
-}
-.col-lg-1,
-.col-lg-10,
-.col-lg-11,
-.col-lg-12,
-.col-lg-2,
-.col-lg-3,
-.col-lg-4,
-.col-lg-5,
-.col-lg-6,
-.col-lg-7,
-.col-lg-8,
-.col-lg-9,
-.col-md-1,
-.col-md-10,
-.col-md-11,
-.col-md-12,
-.col-md-2,
-.col-md-3,
-.col-md-4,
-.col-md-5,
-.col-md-6,
-.col-md-7,
-.col-md-8,
-.col-md-9,
-.col-sm-1,
-.col-sm-10,
-.col-sm-11,
-.col-sm-12,
-.col-sm-2,
-.col-sm-3,
-.col-sm-4,
-.col-sm-5,
-.col-sm-6,
-.col-sm-7,
-.col-sm-8,
-.col-sm-9,
-.col-xs-1,
-.col-xs-10,
-.col-xs-11,
-.col-xs-12,
-.col-xs-2,
-.col-xs-3,
-.col-xs-4,
-.col-xs-5,
-.col-xs-6,
-.col-xs-7,
-.col-xs-8,
-.col-xs-9 {
- position: relative;
- min-height: 1px;
- padding-left: 15px;
- padding-right: 15px
-}
-.col-xs-12 {
- width: 100%
-}
-.col-xs-11 {
- width: 91.66666667%
-}
-.col-xs-10 {
- width: 83.33333333%
-}
-.col-xs-9 {
- width: 75%
-}
-.col-xs-8 {
- width: 66.66666667%
-}
-.col-xs-7 {
- width: 58.33333333%
-}
-.col-xs-6 {
- width: 50%
-}
-.col-xs-5 {
- width: 41.66666667%
-}
-.col-xs-4 {
- width: 33.33333333%
-}
-.col-xs-3 {
- width: 25%
-}
-.col-xs-2 {
- width: 16.66666667%
-}
-.col-xs-1 {
- width: 8.33333333%
-}
-.col-xs-pull-12 {
- right: 100%
-}
-.col-xs-pull-11 {
- right: 91.66666667%
-}
-.col-xs-pull-10 {
- right: 83.33333333%
-}
-.col-xs-pull-9 {
- right: 75%
-}
-.col-xs-pull-8 {
- right: 66.66666667%
-}
-.col-xs-pull-7 {
- right: 58.33333333%
-}
-.col-xs-pull-6 {
- right: 50%
-}
-.col-xs-pull-5 {
- right: 41.66666667%
-}
-.col-xs-pull-4 {
- right: 33.33333333%
-}
-.col-xs-pull-3 {
- right: 25%
-}
-.col-xs-pull-2 {
- right: 16.66666667%
-}
-.col-xs-pull-1 {
- right: 8.33333333%
-}
-.col-xs-pull-0 {
- right: auto
-}
-.col-xs-push-12 {
- left: 100%
-}
-.col-xs-push-11 {
- left: 91.66666667%
-}
-.col-xs-push-10 {
- left: 83.33333333%
-}
-.col-xs-push-9 {
- left: 75%
-}
-.col-xs-push-8 {
- left: 66.66666667%
-}
-.col-xs-push-7 {
- left: 58.33333333%
-}
-.col-xs-push-6 {
- left: 50%
-}
-.col-xs-push-5 {
- left: 41.66666667%
-}
-.col-xs-push-4 {
- left: 33.33333333%
-}
-.col-xs-push-3 {
- left: 25%
-}
-.col-xs-push-2 {
- left: 16.66666667%
-}
-.col-xs-push-1 {
- left: 8.33333333%
-}
-.col-xs-push-0 {
- left: auto
-}
-.col-xs-offset-12 {
- margin-left: 100%
-}
-.col-xs-offset-11 {
- margin-left: 91.66666667%
-}
-.col-xs-offset-10 {
- margin-left: 83.33333333%
-}
-.col-xs-offset-9 {
- margin-left: 75%
-}
-.col-xs-offset-8 {
- margin-left: 66.66666667%
-}
-.col-xs-offset-7 {
- margin-left: 58.33333333%
-}
-.col-xs-offset-6 {
- margin-left: 50%
-}
-.col-xs-offset-5 {
- margin-left: 41.66666667%
-}
-.col-xs-offset-4 {
- margin-left: 33.33333333%
-}
-.col-xs-offset-3 {
- margin-left: 25%
-}
-.col-xs-offset-2 {
- margin-left: 16.66666667%
-}
-.col-xs-offset-1 {
- margin-left: 8.33333333%
-}
-.col-xs-offset-0 {
- margin-left: 0
-}
-@media (min-width: 768px) {
- .col-sm-1,
- .col-sm-10,
- .col-sm-11,
- .col-sm-12,
- .col-sm-2,
- .col-sm-3,
- .col-sm-4,
- .col-sm-5,
- .col-sm-6,
- .col-sm-7,
- .col-sm-8,
- .col-sm-9 {
- float: left
- }
- .col-sm-12 {
- width: 100%
- }
- .col-sm-11 {
- width: 91.66666667%
- }
- .col-sm-10 {
- width: 83.33333333%
- }
- .col-sm-9 {
- width: 75%
- }
- .col-sm-8 {
- width: 66.66666667%
- }
- .col-sm-7 {
- width: 58.33333333%
- }
- .col-sm-6 {
- width: 50%
- }
- .col-sm-5 {
- width: 41.66666667%
- }
- .col-sm-4 {
- width: 33.33333333%
- }
- .col-sm-3 {
- width: 25%
- }
- .col-sm-2 {
- width: 16.66666667%
- }
- .col-sm-1 {
- width: 8.33333333%
- }
- .col-sm-pull-12 {
- right: 100%
- }
- .col-sm-pull-11 {
- right: 91.66666667%
- }
- .col-sm-pull-10 {
- right: 83.33333333%
- }
- .col-sm-pull-9 {
- right: 75%
- }
- .col-sm-pull-8 {
- right: 66.66666667%
- }
- .col-sm-pull-7 {
- right: 58.33333333%
- }
- .col-sm-pull-6 {
- right: 50%
- }
- .col-sm-pull-5 {
- right: 41.66666667%
- }
- .col-sm-pull-4 {
- right: 33.33333333%
- }
- .col-sm-pull-3 {
- right: 25%
- }
- .col-sm-pull-2 {
- right: 16.66666667%
- }
- .col-sm-pull-1 {
- right: 8.33333333%
- }
- .col-sm-pull-0 {
- right: auto
- }
- .col-sm-push-12 {
- left: 100%
- }
- .col-sm-push-11 {
- left: 91.66666667%
- }
- .col-sm-push-10 {
- left: 83.33333333%
- }
- .col-sm-push-9 {
- left: 75%
- }
- .col-sm-push-8 {
- left: 66.66666667%
- }
- .col-sm-push-7 {
- left: 58.33333333%
- }
- .col-sm-push-6 {
- left: 50%
- }
- .col-sm-push-5 {
- left: 41.66666667%
- }
- .col-sm-push-4 {
- left: 33.33333333%
- }
- .col-sm-push-3 {
- left: 25%
- }
- .col-sm-push-2 {
- left: 16.66666667%
- }
- .col-sm-push-1 {
- left: 8.33333333%
- }
- .col-sm-push-0 {
- left: auto
- }
- .col-sm-offset-12 {
- margin-left: 100%
- }
- .col-sm-offset-11 {
- margin-left: 91.66666667%
- }
- .col-sm-offset-10 {
- margin-left: 83.33333333%
- }
- .col-sm-offset-9 {
- margin-left: 75%
- }
- .col-sm-offset-8 {
- margin-left: 66.66666667%
- }
- .col-sm-offset-7 {
- margin-left: 58.33333333%
- }
- .col-sm-offset-6 {
- margin-left: 50%
- }
- .col-sm-offset-5 {
- margin-left: 41.66666667%
- }
- .col-sm-offset-4 {
- margin-left: 33.33333333%
- }
- .col-sm-offset-3 {
- margin-left: 25%
- }
- .col-sm-offset-2 {
- margin-left: 16.66666667%
- }
- .col-sm-offset-1 {
- margin-left: 8.33333333%
- }
- .col-sm-offset-0 {
- margin-left: 0
- }
-}
-@media (min-width: 992px) {
- .col-md-1,
- .col-md-10,
- .col-md-11,
- .col-md-12,
- .col-md-2,
- .col-md-3,
- .col-md-4,
- .col-md-5,
- .col-md-6,
- .col-md-7,
- .col-md-8,
- .col-md-9 {
- float: left
- }
- .col-md-12 {
- width: 100%
- }
- .col-md-11 {
- width: 91.66666667%
- }
- .col-md-10 {
- width: 83.33333333%
- }
- .col-md-9 {
- width: 75%
- }
- .col-md-8 {
- width: 66.66666667%
- }
- .col-md-7 {
- width: 58.33333333%
- }
- .col-md-6 {
- width: 50%
- }
- .col-md-5 {
- width: 41.66666667%
- }
- .col-md-4 {
- width: 33.33333333%
- }
- .col-md-3 {
- width: 25%
- }
- .col-md-2 {
- width: 16.66666667%
- }
- .col-md-1 {
- width: 8.33333333%
- }
- .col-md-pull-12 {
- right: 100%
- }
- .col-md-pull-11 {
- right: 91.66666667%
- }
- .col-md-pull-10 {
- right: 83.33333333%
- }
- .col-md-pull-9 {
- right: 75%
- }
- .col-md-pull-8 {
- right: 66.66666667%
- }
- .col-md-pull-7 {
- right: 58.33333333%
- }
- .col-md-pull-6 {
- right: 50%
- }
- .col-md-pull-5 {
- right: 41.66666667%
- }
- .col-md-pull-4 {
- right: 33.33333333%
- }
- .col-md-pull-3 {
- right: 25%
- }
- .col-md-pull-2 {
- right: 16.66666667%
- }
- .col-md-pull-1 {
- right: 8.33333333%
- }
- .col-md-pull-0 {
- right: auto
- }
- .col-md-push-12 {
- left: 100%
- }
- .col-md-push-11 {
- left: 91.66666667%
- }
- .col-md-push-10 {
- left: 83.33333333%
- }
- .col-md-push-9 {
- left: 75%
- }
- .col-md-push-8 {
- left: 66.66666667%
- }
- .col-md-push-7 {
- left: 58.33333333%
- }
- .col-md-push-6 {
- left: 50%
- }
- .col-md-push-5 {
- left: 41.66666667%
- }
- .col-md-push-4 {
- left: 33.33333333%
- }
- .col-md-push-3 {
- left: 25%
- }
- .col-md-push-2 {
- left: 16.66666667%
- }
- .col-md-push-1 {
- left: 8.33333333%
- }
- .col-md-push-0 {
- left: auto
- }
- .col-md-offset-12 {
- margin-left: 100%
- }
- .col-md-offset-11 {
- margin-left: 91.66666667%
- }
- .col-md-offset-10 {
- margin-left: 83.33333333%
- }
- .col-md-offset-9 {
- margin-left: 75%
- }
- .col-md-offset-8 {
- margin-left: 66.66666667%
- }
- .col-md-offset-7 {
- margin-left: 58.33333333%
- }
- .col-md-offset-6 {
- margin-left: 50%
- }
- .col-md-offset-5 {
- margin-left: 41.66666667%
- }
- .col-md-offset-4 {
- margin-left: 33.33333333%
- }
- .col-md-offset-3 {
- margin-left: 25%
- }
- .col-md-offset-2 {
- margin-left: 16.66666667%
- }
- .col-md-offset-1 {
- margin-left: 8.33333333%
- }
- .col-md-offset-0 {
- margin-left: 0
- }
-}
-@media (min-width: 1200px) {
- .col-lg-1,
- .col-lg-10,
- .col-lg-11,
- .col-lg-12,
- .col-lg-2,
- .col-lg-3,
- .col-lg-4,
- .col-lg-5,
- .col-lg-6,
- .col-lg-7,
- .col-lg-8,
- .col-lg-9 {
- float: left
- }
- .col-lg-12 {
- width: 100%
- }
- .col-lg-11 {
- width: 91.66666667%
- }
- .col-lg-10 {
- width: 83.33333333%
- }
- .col-lg-9 {
- width: 75%
- }
- .col-lg-8 {
- width: 66.66666667%
- }
- .col-lg-7 {
- width: 58.33333333%
- }
- .col-lg-6 {
- width: 50%
- }
- .col-lg-5 {
- width: 41.66666667%
- }
- .col-lg-4 {
- width: 33.33333333%
- }
- .col-lg-3 {
- width: 25%
- }
- .col-lg-2 {
- width: 16.66666667%
- }
- .col-lg-1 {
- width: 8.33333333%
- }
- .col-lg-pull-12 {
- right: 100%
- }
- .col-lg-pull-11 {
- right: 91.66666667%
- }
- .col-lg-pull-10 {
- right: 83.33333333%
- }
- .col-lg-pull-9 {
- right: 75%
- }
- .col-lg-pull-8 {
- right: 66.66666667%
- }
- .col-lg-pull-7 {
- right: 58.33333333%
- }
- .col-lg-pull-6 {
- right: 50%
- }
- .col-lg-pull-5 {
- right: 41.66666667%
- }
- .col-lg-pull-4 {
- right: 33.33333333%
- }
- .col-lg-pull-3 {
- right: 25%
- }
- .col-lg-pull-2 {
- right: 16.66666667%
- }
- .col-lg-pull-1 {
- right: 8.33333333%
- }
- .col-lg-pull-0 {
- right: auto
- }
- .col-lg-push-12 {
- left: 100%
- }
- .col-lg-push-11 {
- left: 91.66666667%
- }
- .col-lg-push-10 {
- left: 83.33333333%
- }
- .col-lg-push-9 {
- left: 75%
- }
- .col-lg-push-8 {
- left: 66.66666667%
- }
- .col-lg-push-7 {
- left: 58.33333333%
- }
- .col-lg-push-6 {
- left: 50%
- }
- .col-lg-push-5 {
- left: 41.66666667%
- }
- .col-lg-push-4 {
- left: 33.33333333%
- }
- .col-lg-push-3 {
- left: 25%
- }
- .col-lg-push-2 {
- left: 16.66666667%
- }
- .col-lg-push-1 {
- left: 8.33333333%
- }
- .col-lg-push-0 {
- left: auto
- }
- .col-lg-offset-12 {
- margin-left: 100%
- }
- .col-lg-offset-11 {
- margin-left: 91.66666667%
- }
- .col-lg-offset-10 {
- margin-left: 83.33333333%
- }
- .col-lg-offset-9 {
- margin-left: 75%
- }
- .col-lg-offset-8 {
- margin-left: 66.66666667%
- }
- .col-lg-offset-7 {
- margin-left: 58.33333333%
- }
- .col-lg-offset-6 {
- margin-left: 50%
- }
- .col-lg-offset-5 {
- margin-left: 41.66666667%
- }
- .col-lg-offset-4 {
- margin-left: 33.33333333%
- }
- .col-lg-offset-3 {
- margin-left: 25%
- }
- .col-lg-offset-2 {
- margin-left: 16.66666667%
- }
- .col-lg-offset-1 {
- margin-left: 8.33333333%
- }
- .col-lg-offset-0 {
- margin-left: 0
- }
-}
-th {
- text-align: left
-}
-.table {
- width: 100%;
- max-width: 100%;
- margin-bottom: 20px
-}
-.table>tbody>tr>td,
-.table>tbody>tr>th,
-.table>tfoot>tr>td,
-.table>tfoot>tr>th,
-.table>thead>tr>td,
-.table>thead>tr>th {
- padding: 8px;
- line-height: 1.42857143;
- vertical-align: top;
- border-top: 1px solid #ddd
-}
-.table>thead>tr>th {
- vertical-align: bottom;
- border-bottom: 2px solid #ddd
-}
-.table>caption+thead>tr:first-child>td,
-.table>caption+thead>tr:first-child>th,
-.table>colgroup+thead>tr:first-child>td,
-.table>colgroup+thead>tr:first-child>th,
-.table>thead:first-child>tr:first-child>td,
-.table>thead:first-child>tr:first-child>th {
- border-top: 0
-}
-.table>tbody+tbody {
- border-top: 2px solid #ddd
-}
-.table .table {
- background-color: #fff
-}
-.table-condensed>tbody>tr>td,
-.table-condensed>tbody>tr>th,
-.table-condensed>tfoot>tr>td,
-.table-condensed>tfoot>tr>th,
-.table-condensed>thead>tr>td,
-.table-condensed>thead>tr>th {
- padding: 5px
-}
-.table-bordered,
-.table-bordered>tbody>tr>td,
-.table-bordered>tbody>tr>th,
-.table-bordered>tfoot>tr>td,
-.table-bordered>tfoot>tr>th,
-.table-bordered>thead>tr>td,
-.table-bordered>thead>tr>th {
- border: 1px solid #ddd
-}
-.table-bordered>thead>tr>td,
-.table-bordered>thead>tr>th {
- border-bottom-width: 2px
-}
-.table-striped>tbody>tr:nth-child(odd)>td,
-.table-striped>tbody>tr:nth-child(odd)>th {
- background-color: #f9f9f9
-}
-.table-hover>tbody>tr:hover>td,
-.table-hover>tbody>tr:hover>th,
-.table>tbody>tr.active>td,
-.table>tbody>tr.active>th,
-.table>tbody>tr>td.active,
-.table>tbody>tr>th.active,
-.table>tfoot>tr.active>td,
-.table>tfoot>tr.active>th,
-.table>tfoot>tr>td.active,
-.table>tfoot>tr>th.active,
-.table>thead>tr.active>td,
-.table>thead>tr.active>th,
-.table>thead>tr>td.active,
-.table>thead>tr>th.active {
- background-color: #f5f5f5
-}
-table col[class*=col-] {
- position: static;
- float: none;
- display: table-column
-}
-table td[class*=col-],
-table th[class*=col-] {
- position: static;
- float: none;
- display: table-cell
-}
-.table-hover>tbody>tr.active:hover>td,
-.table-hover>tbody>tr.active:hover>th,
-.table-hover>tbody>tr:hover>.active,
-.table-hover>tbody>tr>td.active:hover,
-.table-hover>tbody>tr>th.active:hover {
- background-color: #e8e8e8
-}
-.table>tbody>tr.success>td,
-.table>tbody>tr.success>th,
-.table>tbody>tr>td.success,
-.table>tbody>tr>th.success,
-.table>tfoot>tr.success>td,
-.table>tfoot>tr.success>th,
-.table>tfoot>tr>td.success,
-.table>tfoot>tr>th.success,
-.table>thead>tr.success>td,
-.table>thead>tr.success>th,
-.table>thead>tr>td.success,
-.table>thead>tr>th.success {
- background-color: #dff0d8
-}
-.table-hover>tbody>tr.success:hover>td,
-.table-hover>tbody>tr.success:hover>th,
-.table-hover>tbody>tr:hover>.success,
-.table-hover>tbody>tr>td.success:hover,
-.table-hover>tbody>tr>th.success:hover {
- background-color: #d0e9c6
-}
-.table>tbody>tr.info>td,
-.table>tbody>tr.info>th,
-.table>tbody>tr>td.info,
-.table>tbody>tr>th.info,
-.table>tfoot>tr.info>td,
-.table>tfoot>tr.info>th,
-.table>tfoot>tr>td.info,
-.table>tfoot>tr>th.info,
-.table>thead>tr.info>td,
-.table>thead>tr.info>th,
-.table>thead>tr>td.info,
-.table>thead>tr>th.info {
- background-color: #d9edf7
-}
-.table-hover>tbody>tr.info:hover>td,
-.table-hover>tbody>tr.info:hover>th,
-.table-hover>tbody>tr:hover>.info,
-.table-hover>tbody>tr>td.info:hover,
-.table-hover>tbody>tr>th.info:hover {
- background-color: #c4e3f3
-}
-.table>tbody>tr.warning>td,
-.table>tbody>tr.warning>th,
-.table>tbody>tr>td.warning,
-.table>tbody>tr>th.warning,
-.table>tfoot>tr.warning>td,
-.table>tfoot>tr.warning>th,
-.table>tfoot>tr>td.warning,
-.table>tfoot>tr>th.warning,
-.table>thead>tr.warning>td,
-.table>thead>tr.warning>th,
-.table>thead>tr>td.warning,
-.table>thead>tr>th.warning {
- background-color: #fcf8e3
-}
-.table-hover>tbody>tr.warning:hover>td,
-.table-hover>tbody>tr.warning:hover>th,
-.table-hover>tbody>tr:hover>.warning,
-.table-hover>tbody>tr>td.warning:hover,
-.table-hover>tbody>tr>th.warning:hover {
- background-color: #faf2cc
-}
-.table>tbody>tr.danger>td,
-.table>tbody>tr.danger>th,
-.table>tbody>tr>td.danger,
-.table>tbody>tr>th.danger,
-.table>tfoot>tr.danger>td,
-.table>tfoot>tr.danger>th,
-.table>tfoot>tr>td.danger,
-.table>tfoot>tr>th.danger,
-.table>thead>tr.danger>td,
-.table>thead>tr.danger>th,
-.table>thead>tr>td.danger,
-.table>thead>tr>th.danger {
- background-color: #f2dede
-}
-.table-hover>tbody>tr.danger:hover>td,
-.table-hover>tbody>tr.danger:hover>th,
-.table-hover>tbody>tr:hover>.danger,
-.table-hover>tbody>tr>td.danger:hover,
-.table-hover>tbody>tr>th.danger:hover {
- background-color: #ebcccc
-}
-@media screen and (max-width: 767px) {
- .table-responsive {
- width: 100%;
- margin-bottom: 15px;
- overflow-y: hidden;
- overflow-x: auto;
- -ms-overflow-style: -ms-autohiding-scrollbar;
- border: 1px solid #ddd;
- -webkit-overflow-scrolling: touch
- }
- .table-responsive>.table {
- margin-bottom: 0
- }
- .table-responsive>.table>tbody>tr>td,
- .table-responsive>.table>tbody>tr>th,
- .table-responsive>.table>tfoot>tr>td,
- .table-responsive>.table>tfoot>tr>th,
- .table-responsive>.table>thead>tr>td,
- .table-responsive>.table>thead>tr>th {
- white-space: nowrap
- }
- .table-responsive>.table-bordered {
- border: 0
- }
- .table-responsive>.table-bordered>tbody>tr>td:first-child,
- .table-responsive>.table-bordered>tbody>tr>th:first-child,
- .table-responsive>.table-bordered>tfoot>tr>td:first-child,
- .table-responsive>.table-bordered>tfoot>tr>th:first-child,
- .table-responsive>.table-bordered>thead>tr>td:first-child,
- .table-responsive>.table-bordered>thead>tr>th:first-child {
- border-left: 0
- }
- .table-responsive>.table-bordered>tbody>tr>td:last-child,
- .table-responsive>.table-bordered>tbody>tr>th:last-child,
- .table-responsive>.table-bordered>tfoot>tr>td:last-child,
- .table-responsive>.table-bordered>tfoot>tr>th:last-child,
- .table-responsive>.table-bordered>thead>tr>td:last-child,
- .table-responsive>.table-bordered>thead>tr>th:last-child {
- border-right: 0
- }
- .table-responsive>.table-bordered>tbody>tr:last-child>td,
- .table-responsive>.table-bordered>tbody>tr:last-child>th,
- .table-responsive>.table-bordered>tfoot>tr:last-child>td,
- .table-responsive>.table-bordered>tfoot>tr:last-child>th {
- border-bottom: 0
- }
-}
-fieldset,
-legend {
- padding: 0;
- border: 0
-}
-fieldset {
- margin: 0;
- min-width: 0
-}
-legend {
- width: 100%;
- margin-bottom: 20px;
- font-size: 21px;
- line-height: inherit;
- border-bottom: 1px solid #e5e5e5
-}
-label {
- display: inline-block;
- max-width: 100%;
- margin-bottom: 5px
-}
-input[type=search] {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- -webkit-appearance: none
-}
-input[type=checkbox],
-input[type=radio] {
- margin: 4px 0 0;
- margin-top: 1px\9;
- line-height: normal
-}
-.form-control,
-output {
- font-size: 14px;
- line-height: 1.42857143;
- color: #555;
- display: block
-}
-input[type=file] {
- display: block
-}
-input[type=range] {
- display: block;
- width: 100%
-}
-select[multiple],
-select[size] {
- height: auto
-}
-input[type=file]:focus,
-input[type=checkbox]:focus,
-input[type=radio]:focus {
- outline: dotted thin;
- outline: -webkit-focus-ring-color auto 5px;
- outline-offset: -2px
-}
-output {
- padding-top: 7px
-}
-.form-control {
- width: 100%;
- height: 34px;
- padding: 6px 9pt;
- background-color: #fff;
- border: 1px solid #ccc;
- border-radius: 4px;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
- -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
- -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
- transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s
-}
-.form-control:focus {
- border-color: #66afe9;
- outline: 0;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6)
-}
-.form-control::-moz-placeholder {
- color: #777;
- opacity: 1
-}
-.form-control:-ms-input-placeholder {
- color: #777
-}
-.form-control::-webkit-input-placeholder {
- color: #777
-}
-.has-success .checkbox,
-.has-success .checkbox-inline,
-.has-success .control-label,
-.has-success .form-control-feedback,
-.has-success .help-block,
-.has-success .radio,
-.has-success .radio-inline {
- color: #3c763d
-}
-.form-control[disabled],
-.form-control[readonly],
-fieldset[disabled] .form-control {
- cursor: not-allowed;
- background-color: #eee;
- opacity: 1
-}
-textarea.form-control {
- height: auto
-}
-input[type=date],
-input[type=time],
-input[type=datetime-local],
-input[type=month] {
- line-height: 34px;
- line-height: 1.42857143\9
-}
-input[type=date].input-sm,
-input[type=time].input-sm,
-input[type=datetime-local].input-sm,
-input[type=month].input-sm {
- line-height: 30px
-}
-input[type=date].input-lg,
-input[type=time].input-lg,
-input[type=datetime-local].input-lg,
-input[type=month].input-lg {
- line-height: 46px
-}
-.form-group {
- margin-bottom: 15px
-}
-.checkbox,
-.radio {
- position: relative;
- display: block;
- min-height: 20px;
- margin-top: 10px;
- margin-bottom: 10px
-}
-.checkbox label,
-.radio label {
- padding-left: 20px;
- margin-bottom: 0;
- font-weight: 400;
- cursor: pointer
-}
-.checkbox input[type=checkbox],
-.checkbox-inline input[type=checkbox],
-.radio input[type=radio],
-.radio-inline input[type=radio] {
- position: absolute;
- margin-left: -20px;
- margin-top: 4px\9
-}
-.checkbox+.checkbox,
-.radio+.radio {
- margin-top: -5px
-}
-.checkbox-inline,
-.radio-inline {
- display: inline-block;
- padding-left: 20px;
- margin-bottom: 0;
- vertical-align: middle;
- font-weight: 400;
- cursor: pointer
-}
-.checkbox-inline+.checkbox-inline,
-.radio-inline+.radio-inline {
- margin-top: 0;
- margin-left: 10px
-}
-.checkbox-inline.disabled,
-.checkbox.disabled label,
-.radio-inline.disabled,
-.radio.disabled label,
-fieldset[disabled] .checkbox label,
-fieldset[disabled] .checkbox-inline,
-fieldset[disabled] .radio label,
-fieldset[disabled] .radio-inline,
-fieldset[disabled] input[type=checkbox],
-fieldset[disabled] input[type=radio],
-input[type=checkbox].disabled,
-input[type=checkbox][disabled],
-input[type=radio].disabled,
-input[type=radio][disabled] {
- cursor: not-allowed
-}
-.form-control-static {
- padding-top: 7px;
- padding-bottom: 7px;
- margin-bottom: 0
-}
-.form-control-static.input-lg,
-.form-control-static.input-sm {
- padding-left: 0;
- padding-right: 0
-}
-.form-horizontal .form-group-sm .form-control,
-.input-sm {
- height: 30px;
- padding: 5px 10px;
- font-size: 9pt;
- line-height: 1.5;
- border-radius: 3px
-}
-select.input-sm {
- height: 30px;
- line-height: 30px
-}
-select[multiple].input-sm,
-textarea.input-sm {
- height: auto
-}
-.form-horizontal .form-group-lg .form-control,
-.input-lg {
- height: 46px;
- padding: 10px 1pc;
- font-size: 18px;
- line-height: 1.33;
- border-radius: 6px
-}
-select.input-lg {
- height: 46px;
- line-height: 46px
-}
-select[multiple].input-lg,
-textarea.input-lg {
- height: auto
-}
-.has-feedback {
- position: relative
-}
-.has-feedback .form-control {
- padding-right: 42.5px
-}
-.form-control-feedback {
- position: absolute;
- top: 25px;
- right: 0;
- z-index: 2;
- display: block;
- width: 34px;
- height: 34px;
- line-height: 34px;
- text-align: center
-}
-.collapsing,
-.dropdown {
- position: relative
-}
-.input-lg+.form-control-feedback {
- width: 46px;
- height: 46px;
- line-height: 46px
-}
-.input-sm+.form-control-feedback {
- width: 30px;
- height: 30px;
- line-height: 30px
-}
-.has-success .form-control {
- border-color: #3c763d;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075)
-}
-.has-success .form-control:focus {
- border-color: #2b542c;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168
-}
-.has-success .input-group-addon {
- color: #3c763d;
- border-color: #3c763d;
- background-color: #dff0d8
-}
-.has-warning .checkbox,
-.has-warning .checkbox-inline,
-.has-warning .control-label,
-.has-warning .form-control-feedback,
-.has-warning .help-block,
-.has-warning .radio,
-.has-warning .radio-inline {
- color: #8a6d3b
-}
-.has-warning .form-control {
- border-color: #8a6d3b;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075)
-}
-.has-warning .form-control:focus {
- border-color: #66512c;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b
-}
-.has-warning .input-group-addon {
- color: #8a6d3b;
- border-color: #8a6d3b;
- background-color: #fcf8e3
-}
-.has-error .checkbox,
-.has-error .checkbox-inline,
-.has-error .control-label,
-.has-error .form-control-feedback,
-.has-error .help-block,
-.has-error .radio,
-.has-error .radio-inline {
- color: #a94442
-}
-.has-error .form-control {
- border-color: #a94442;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075)
-}
-.has-error .form-control:focus {
- border-color: #843534;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483
-}
-.has-error .input-group-addon {
- color: #a94442;
- border-color: #a94442;
- background-color: #f2dede
-}
-.has-feedback label.sr-only~.form-control-feedback {
- top: 0
-}
-.help-block {
- display: block;
- margin-top: 5px;
- margin-bottom: 10px;
- color: #737373
-}
-@media (min-width: 768px) {
- .form-inline .control-label,
- .form-inline .form-group {
- margin-bottom: 0;
- vertical-align: middle
- }
- .form-inline .form-group {
- display: inline-block
- }
- .form-inline .form-control {
- display: inline-block;
- width: auto;
- vertical-align: middle
- }
- .form-inline .input-group {
- display: inline-table;
- vertical-align: middle
- }
- .form-inline .input-group .form-control,
- .form-inline .input-group .input-group-addon,
- .form-inline .input-group .input-group-btn {
- width: auto
- }
- .form-inline .input-group>.form-control {
- width: 100%
- }
- .form-inline .checkbox,
- .form-inline .radio {
- display: inline-block;
- margin-top: 0;
- margin-bottom: 0;
- vertical-align: middle
- }
- .form-inline .checkbox label,
- .form-inline .radio label {
- padding-left: 0
- }
- .form-inline .checkbox input[type=checkbox],
- .form-inline .radio input[type=radio] {
- position: relative;
- margin-left: 0
- }
- .form-inline .has-feedback .form-control-feedback {
- top: 0
- }
- .form-horizontal .control-label {
- text-align: right;
- margin-bottom: 0;
- padding-top: 7px
- }
-}
-.form-horizontal .checkbox,
-.form-horizontal .checkbox-inline,
-.form-horizontal .radio,
-.form-horizontal .radio-inline {
- margin-top: 0;
- margin-bottom: 0;
- padding-top: 7px
-}
-.form-horizontal .checkbox,
-.form-horizontal .radio {
- min-height: 27px
-}
-.form-horizontal .form-group {
- margin-left: -15px;
- margin-right: -15px
-}
-.form-horizontal .has-feedback .form-control-feedback {
- top: 0;
- right: 15px
-}
-@media (min-width: 768px) {
- .form-horizontal .form-group-lg .control-label {
- padding-top: 14.3px
- }
- .form-horizontal .form-group-sm .control-label {
- padding-top: 6px
- }
-}
-.btn {
- display: inline-block;
- margin-bottom: 0;
- font-weight: 400;
- text-align: center;
- vertical-align: middle;
- cursor: pointer;
- border: 1px solid transparent;
- white-space: nowrap;
- padding: 6px 9pt;
- font-size: 14px;
- line-height: 1.42857143;
- border-radius: 4px;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none
-}
-.btn.active:focus,
-.btn:active:focus,
-.btn:focus {
- outline: dotted thin;
- outline: -webkit-focus-ring-color auto 5px;
- outline-offset: -2px
-}
-.btn:focus,
-.btn:hover {
- color: #333;
- text-decoration: none
-}
-.btn.active,
-.btn:active {
- outline: 0;
- -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
- box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125)
-}
-.btn.disabled,
-.btn[disabled],
-fieldset[disabled] .btn {
- cursor: not-allowed;
- pointer-events: none;
- opacity: .65;
- filter: alpha(opacity=65);
- -webkit-box-shadow: none;
- box-shadow: none
-}
-.btn-default {
- color: #333;
- background-color: #fff;
- border-color: #ccc
-}
-.btn-default.active,
-.btn-default:active,
-.btn-default:focus,
-.btn-default:hover,
-.open>.dropdown-toggle.btn-default {
- color: #333;
- background-color: #e6e6e6;
- border-color: #adadad
-}
-.btn-default.disabled,
-.btn-default.disabled.active,
-.btn-default.disabled:active,
-.btn-default.disabled:focus,
-.btn-default.disabled:hover,
-.btn-default[disabled],
-.btn-default[disabled].active,
-.btn-default[disabled]:active,
-.btn-default[disabled]:focus,
-.btn-default[disabled]:hover,
-fieldset[disabled] .btn-default,
-fieldset[disabled] .btn-default.active,
-fieldset[disabled] .btn-default:active,
-fieldset[disabled] .btn-default:focus,
-fieldset[disabled] .btn-default:hover {
- background-color: #fff;
- border-color: #ccc
-}
-.btn-default .badge {
- color: #fff;
- background-color: #333
-}
-.btn-primary {
- color: #fff;
- background-color: #428bca;
- border-color: #357ebd
-}
-.btn-primary.active,
-.btn-primary:active,
-.btn-primary:focus,
-.btn-primary:hover,
-.open>.dropdown-toggle.btn-primary {
- color: #fff;
- background-color: #3071a9;
- border-color: #285e8e
-}
-.btn-primary.disabled,
-.btn-primary.disabled.active,
-.btn-primary.disabled:active,
-.btn-primary.disabled:focus,
-.btn-primary.disabled:hover,
-.btn-primary[disabled],
-.btn-primary[disabled].active,
-.btn-primary[disabled]:active,
-.btn-primary[disabled]:focus,
-.btn-primary[disabled]:hover,
-fieldset[disabled] .btn-primary,
-fieldset[disabled] .btn-primary.active,
-fieldset[disabled] .btn-primary:active,
-fieldset[disabled] .btn-primary:focus,
-fieldset[disabled] .btn-primary:hover {
- background-color: #428bca;
- border-color: #357ebd
-}
-.btn-primary .badge {
- color: #428bca;
- background-color: #fff
-}
-.btn-success {
- color: #fff;
- background-color: #5cb85c;
- border-color: #4cae4c
-}
-.btn-success.active,
-.btn-success:active,
-.btn-success:focus,
-.btn-success:hover,
-.open>.dropdown-toggle.btn-success {
- color: #fff;
- background-color: #449d44;
- border-color: #398439
-}
-.btn-success.active,
-.btn-success:active,
-.open>.dropdown-toggle.btn-success {
- background-image: none
-}
-.btn-success.disabled,
-.btn-success.disabled.active,
-.btn-success.disabled:active,
-.btn-success.disabled:focus,
-.btn-success.disabled:hover,
-.btn-success[disabled],
-.btn-success[disabled].active,
-.btn-success[disabled]:active,
-.btn-success[disabled]:focus,
-.btn-success[disabled]:hover,
-fieldset[disabled] .btn-success,
-fieldset[disabled] .btn-success.active,
-fieldset[disabled] .btn-success:active,
-fieldset[disabled] .btn-success:focus,
-fieldset[disabled] .btn-success:hover {
- background-color: #5cb85c;
- border-color: #4cae4c
-}
-.btn-success .badge {
- color: #5cb85c;
- background-color: #fff
-}
-.btn-info {
- color: #fff;
- background-color: #5bc0de;
- border-color: #46b8da
-}
-.btn-info.active,
-.btn-info:active,
-.btn-info:focus,
-.btn-info:hover,
-.open>.dropdown-toggle.btn-info {
- color: #fff;
- background-color: #31b0d5;
- border-color: #269abc
-}
-.btn-info.disabled,
-.btn-info.disabled.active,
-.btn-info.disabled:active,
-.btn-info.disabled:focus,
-.btn-info.disabled:hover,
-.btn-info[disabled],
-.btn-info[disabled].active,
-.btn-info[disabled]:active,
-.btn-info[disabled]:focus,
-.btn-info[disabled]:hover,
-fieldset[disabled] .btn-info,
-fieldset[disabled] .btn-info.active,
-fieldset[disabled] .btn-info:active,
-fieldset[disabled] .btn-info:focus,
-fieldset[disabled] .btn-info:hover {
- background-color: #5bc0de;
- border-color: #46b8da
-}
-.btn-info .badge {
- color: #5bc0de;
- background-color: #fff
-}
-.btn-warning {
- color: #fff;
- background-color: #f0ad4e;
- border-color: #eea236
-}
-.btn-warning.active,
-.btn-warning:active,
-.btn-warning:focus,
-.btn-warning:hover,
-.open>.dropdown-toggle.btn-warning {
- color: #fff;
- background-color: #ec971f;
- border-color: #d58512
-}
-.btn-warning.disabled,
-.btn-warning.disabled.active,
-.btn-warning.disabled:active,
-.btn-warning.disabled:focus,
-.btn-warning.disabled:hover,
-.btn-warning[disabled],
-.btn-warning[disabled].active,
-.btn-warning[disabled]:active,
-.btn-warning[disabled]:focus,
-.btn-warning[disabled]:hover,
-fieldset[disabled] .btn-warning,
-fieldset[disabled] .btn-warning.active,
-fieldset[disabled] .btn-warning:active,
-fieldset[disabled] .btn-warning:focus,
-fieldset[disabled] .btn-warning:hover {
- background-color: #f0ad4e;
- border-color: #eea236
-}
-.btn-warning .badge {
- color: #f0ad4e;
- background-color: #fff
-}
-.btn-danger {
- color: #fff;
- background-color: #d9534f;
- border-color: #d43f3a
-}
-.btn-danger.active,
-.btn-danger:active,
-.btn-danger:focus,
-.btn-danger:hover,
-.open>.dropdown-toggle.btn-danger {
- color: #fff;
- background-color: #c9302c;
- border-color: #ac2925
-}
-.btn-danger.disabled,
-.btn-danger.disabled.active,
-.btn-danger.disabled:active,
-.btn-danger.disabled:focus,
-.btn-danger.disabled:hover,
-.btn-danger[disabled],
-.btn-danger[disabled].active,
-.btn-danger[disabled]:active,
-.btn-danger[disabled]:focus,
-.btn-danger[disabled]:hover,
-fieldset[disabled] .btn-danger,
-fieldset[disabled] .btn-danger.active,
-fieldset[disabled] .btn-danger:active,
-fieldset[disabled] .btn-danger:focus,
-fieldset[disabled] .btn-danger:hover {
- background-color: #d9534f;
- border-color: #d43f3a
-}
-.btn-danger .badge {
- color: #d9534f;
- background-color: #fff
-}
-.btn-link {
- color: #428bca;
- font-weight: 400;
- cursor: pointer;
- border-radius: 0
-}
-.btn-link,
-.btn-link:active,
-.btn-link[disabled],
-fieldset[disabled] .btn-link {
- background-color: transparent;
- -webkit-box-shadow: none;
- box-shadow: none
-}
-.btn-link,
-.btn-link:active,
-.btn-link:focus,
-.btn-link:hover {
- border-color: transparent
-}
-.btn-link:focus,
-.btn-link:hover {
- color: #2a6496;
- text-decoration: underline;
- background-color: transparent
-}
-.btn-link[disabled]:focus,
-.btn-link[disabled]:hover,
-fieldset[disabled] .btn-link:focus,
-fieldset[disabled] .btn-link:hover {
- color: #777;
- text-decoration: none
-}
-.btn-group-lg>.btn,
-.btn-lg {
- padding: 10px 1pc;
- font-size: 18px;
- line-height: 1.33;
- border-radius: 6px
-}
-.btn-group-sm>.btn,
-.btn-sm {
- padding: 5px 10px;
- font-size: 9pt;
- line-height: 1.5;
- border-radius: 3px
-}
-.btn-group-xs>.btn,
-.btn-xs {
- padding: 1px 5px;
- font-size: 9pt;
- line-height: 1.5;
- border-radius: 3px
-}
-.btn-block {
- display: block;
- width: 100%
-}
-.btn-block+.btn-block {
- margin-top: 5px
-}
-input[type=button].btn-block,
-input[type=reset].btn-block,
-input[type=submit].btn-block {
- width: 100%
-}
-.fade {
- opacity: 0;
- -webkit-transition: opacity .15s linear;
- -o-transition: opacity .15s linear;
- transition: opacity .15s linear
-}
-.fade.in {
- opacity: 1
-}
-.collapse {
- display: none
-}
-.collapse.in {
- display: block
-}
-tr.collapse.in {
- display: table-row
-}
-tbody.collapse.in {
- display: table-row-group
-}
-.collapsing {
- height: 0;
- overflow: hidden;
- -webkit-transition: height .35s ease;
- -o-transition: height .35s ease;
- transition: height .35s ease
-}
-.caret {
- display: inline-block;
- width: 0;
- height: 0;
- margin-left: 2px;
- vertical-align: middle;
- border-top: 4px solid;
- border-right: 4px solid transparent;
- border-left: 4px solid transparent
-}
-.dropdown-toggle:focus {
- outline: 0
-}
-.dropdown-menu {
- position: absolute;
- top: 100%;
- left: 0;
- z-index: 1000;
- display: none;
- min-width: 10pc;
- padding: 5px 0;
- margin: 2px 0 0;
- list-style: none;
- font-size: 14px;
- text-align: left;
- background-color: #fff;
- border: 1px solid #ccc;
- border: 1px solid rgba(0, 0, 0, .15);
- border-radius: 4px;
- -webkit-box-shadow: 0 6px 9pt rgba(0, 0, 0, .175);
- box-shadow: 0 6px 9pt rgba(0, 0, 0, .175);
- background-clip: padding-box
-}
-.dropdown-menu-right,
-.dropdown-menu.pull-right {
- left: auto;
- right: 0
-}
-.dropdown-header,
-.dropdown-menu>li>a {
- display: block;
- padding: 3px 20px;
- line-height: 1.42857143;
- white-space: nowrap
-}
-.btn-group-vertical>.btn:not(:first-child):not(:last-child),
-.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn,
-.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
- border-radius: 0
-}
-.dropdown-menu .divider {
- height: 1px;
- margin: 9px 0;
- overflow: hidden;
- background-color: #e5e5e5
-}
-.dropdown-menu>li>a {
- clear: both;
- font-weight: 400;
- color: #333
-}
-.dropdown-menu>li>a:focus,
-.dropdown-menu>li>a:hover {
- text-decoration: none;
- color: #262626;
- background-color: #f5f5f5
-}
-.dropdown-menu>.active>a,
-.dropdown-menu>.active>a:focus,
-.dropdown-menu>.active>a:hover {
- color: #fff;
- text-decoration: none;
- outline: 0;
- background-color: #428bca
-}
-.dropdown-menu>.disabled>a,
-.dropdown-menu>.disabled>a:focus,
-.dropdown-menu>.disabled>a:hover {
- color: #777
-}
-.dropdown-menu>.disabled>a:focus,
-.dropdown-menu>.disabled>a:hover {
- text-decoration: none;
- background-color: transparent;
- filter: progid: DXImageTransform.Microsoft.gradient(enabled=false);
- cursor: not-allowed
-}
-.open>.dropdown-menu {
- display: block
-}
-.open>a {
- outline: 0
-}
-.dropdown-menu-left {
- left: 0;
- right: auto
-}
-.dropdown-header {
- font-size: 9pt;
- color: #777
-}
-.dropdown-backdrop {
- position: fixed;
- left: 0;
- right: 0;
- bottom: 0;
- top: 0;
- z-index: 990
-}
-.nav-justified>.dropdown .dropdown-menu,
-.nav-tabs.nav-justified>.dropdown .dropdown-menu {
- top: auto;
- left: auto
-}
-.pull-right>.dropdown-menu {
- right: 0;
- left: auto
-}
-.dropup .caret,
-.navbar-fixed-bottom .dropdown .caret {
- border-top: 0;
- border-bottom: 4px solid;
- content: ""
-}
-.dropup .dropdown-menu,
-.navbar-fixed-bottom .dropdown .dropdown-menu {
- top: auto;
- bottom: 100%;
- margin-bottom: 1px
-}
-@media (min-width: 768px) {
- .navbar-right .dropdown-menu {
- left: auto;
- right: 0
- }
- .navbar-right .dropdown-menu-left {
- left: 0;
- right: auto
- }
-}
-.btn-group,
-.btn-group-vertical {
- position: relative;
- display: inline-block;
- vertical-align: middle
-}
-.btn-group-vertical>.btn,
-.btn-group>.btn {
- position: relative;
- float: left
-}
-.btn-group-vertical>.btn.active,
-.btn-group-vertical>.btn:active,
-.btn-group-vertical>.btn:focus,
-.btn-group-vertical>.btn:hover,
-.btn-group>.btn.active,
-.btn-group>.btn:active,
-.btn-group>.btn:focus,
-.btn-group>.btn:hover {
- z-index: 2
-}
-.btn-group-vertical>.btn:focus,
-.btn-group>.btn:focus {
- outline: 0
-}
-.btn-group .btn+.btn,
-.btn-group .btn+.btn-group,
-.btn-group .btn-group+.btn,
-.btn-group .btn-group+.btn-group {
- margin-left: -1px
-}
-.btn-toolbar {
- margin-left: -5px
-}
-.btn-toolbar>.btn,
-.btn-toolbar>.btn-group,
-.btn-toolbar>.input-group {
- margin-left: 5px
-}
-.btn .caret,
-.btn-group>.btn:first-child {
- margin-left: 0
-}
-.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle) {
- border-bottom-right-radius: 0;
- border-top-right-radius: 0
-}
-.btn-group>.btn:last-child:not(:first-child),
-.btn-group>.dropdown-toggle:not(:first-child) {
- border-bottom-left-radius: 0;
- border-top-left-radius: 0
-}
-.btn-group>.btn-group:first-child>.btn:last-child,
-.btn-group>.btn-group:first-child>.dropdown-toggle {
- border-bottom-right-radius: 0;
- border-top-right-radius: 0
-}
-.btn-group>.btn-group:last-child>.btn:first-child {
- border-bottom-left-radius: 0;
- border-top-left-radius: 0
-}
-.btn-group .dropdown-toggle:active,
-.btn-group.open .dropdown-toggle {
- outline: 0
-}
-.btn-group>.btn+.dropdown-toggle {
- padding-left: 8px;
- padding-right: 8px
-}
-.btn-group>.btn-lg+.dropdown-toggle {
- padding-left: 9pt;
- padding-right: 9pt
-}
-.btn-group.open .dropdown-toggle {
- -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
- box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125)
-}
-.btn-group.open .dropdown-toggle.btn-link {
- -webkit-box-shadow: none;
- box-shadow: none
-}
-.btn-lg .caret {
- border-width: 5px 5px 0
-}
-.dropup .btn-lg .caret {
- border-width: 0 5px 5px
-}
-.btn-group-vertical>.btn,
-.btn-group-vertical>.btn-group,
-.btn-group-vertical>.btn-group>.btn {
- display: block;
- float: none;
- width: 100%;
- max-width: 100%
-}
-.btn-group-vertical>.btn-group>.btn {
- float: none
-}
-.btn-group-vertical>.btn+.btn,
-.btn-group-vertical>.btn+.btn-group,
-.btn-group-vertical>.btn-group+.btn,
-.btn-group-vertical>.btn-group+.btn-group {
- margin-top: -1px;
- margin-left: 0
-}
-.input-group-btn:last-child>.btn,
-.input-group-btn:last-child>.btn-group,
-.input-group-btn>.btn+.btn {
- margin-left: -1px
-}
-.btn-group-vertical>.btn:first-child:not(:last-child) {
- border-top-right-radius: 4px;
- border-bottom-right-radius: 0;
- border-bottom-left-radius: 0
-}
-.btn-group-vertical>.btn:last-child:not(:first-child) {
- border-bottom-left-radius: 4px;
- border-top-right-radius: 0;
- border-top-left-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,
-.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle {
- border-bottom-right-radius: 0;
- border-bottom-left-radius: 0
-}
-.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child {
- border-top-right-radius: 0;
- border-top-left-radius: 0
-}
-.btn-group-justified {
- display: table;
- width: 100%;
- table-layout: fixed;
- border-collapse: separate
-}
-.btn-group-justified>.btn,
-.btn-group-justified>.btn-group {
- float: none;
- display: table-cell;
- width: 1%
-}
-.btn-group-justified>.btn-group .btn {
- width: 100%
-}
-.btn-group-justified>.btn-group .dropdown-menu {
- left: auto
-}
-[data-toggle=buttons]>.btn>input[type=checkbox],
-[data-toggle=buttons]>.btn>input[type=radio] {
- position: absolute;
- z-index: -1;
- opacity: 0;
- filter: alpha(opacity=0)
-}
-.input-group {
- position: relative;
- display: table;
- border-collapse: separate
-}
-.input-group[class*=col-] {
- float: none;
- padding-left: 0;
- padding-right: 0
-}
-.input-group .form-control {
- position: relative;
- z-index: 2;
- float: left;
- width: 100%;
- margin-bottom: 0
-}
-.input-group-lg>.form-control,
-.input-group-lg>.input-group-addon,
-.input-group-lg>.input-group-btn>.btn {
- height: 46px;
- padding: 10px 1pc;
- font-size: 18px;
- line-height: 1.33;
- border-radius: 6px
-}
-select.input-group-lg>.form-control,
-select.input-group-lg>.input-group-addon,
-select.input-group-lg>.input-group-btn>.btn {
- height: 46px;
- line-height: 46px
-}
-select[multiple].input-group-lg>.form-control,
-select[multiple].input-group-lg>.input-group-addon,
-select[multiple].input-group-lg>.input-group-btn>.btn,
-textarea.input-group-lg>.form-control,
-textarea.input-group-lg>.input-group-addon,
-textarea.input-group-lg>.input-group-btn>.btn {
- height: auto
-}
-.input-group-sm>.form-control,
-.input-group-sm>.input-group-addon,
-.input-group-sm>.input-group-btn>.btn {
- height: 30px;
- padding: 5px 10px;
- font-size: 9pt;
- line-height: 1.5;
- border-radius: 3px
-}
-select.input-group-sm>.form-control,
-select.input-group-sm>.input-group-addon,
-select.input-group-sm>.input-group-btn>.btn {
- height: 30px;
- line-height: 30px
-}
-select[multiple].input-group-sm>.form-control,
-select[multiple].input-group-sm>.input-group-addon,
-select[multiple].input-group-sm>.input-group-btn>.btn,
-textarea.input-group-sm>.form-control,
-textarea.input-group-sm>.input-group-addon,
-textarea.input-group-sm>.input-group-btn>.btn {
- height: auto
-}
-.input-group .form-control,
-.input-group-addon,
-.input-group-btn {
- display: table-cell
-}
-.nav>li,
-.nav>li>a {
- display: block;
- position: relative
-}
-.input-group .form-control:not(:first-child):not(:last-child),
-.input-group-addon:not(:first-child):not(:last-child),
-.input-group-btn:not(:first-child):not(:last-child) {
- border-radius: 0
-}
-.input-group-addon,
-.input-group-btn {
- width: 1%;
- white-space: nowrap;
- vertical-align: middle
-}
-.input-group-addon {
- padding: 6px 9pt;
- font-size: 14px;
- font-weight: 400;
- line-height: 1;
- color: #555;
- text-align: center;
- background-color: #eee;
- border: 1px solid #ccc;
- border-radius: 4px
-}
-.input-group-addon.input-sm {
- padding: 5px 10px;
- font-size: 9pt;
- border-radius: 3px
-}
-.input-group-addon.input-lg {
- padding: 10px 1pc;
- font-size: 18px;
- border-radius: 6px
-}
-.input-group-addon input[type=checkbox],
-.input-group-addon input[type=radio] {
- margin-top: 0
-}
-.input-group .form-control:first-child,
-.input-group-addon:first-child,
-.input-group-btn:first-child>.btn,
-.input-group-btn:first-child>.btn-group>.btn,
-.input-group-btn:first-child>.dropdown-toggle,
-.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,
-.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle) {
- border-bottom-right-radius: 0;
- border-top-right-radius: 0
-}
-.input-group-addon:first-child {
- border-right: 0
-}
-.input-group .form-control:last-child,
-.input-group-addon:last-child,
-.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,
-.input-group-btn:first-child>.btn:not(:first-child),
-.input-group-btn:last-child>.btn,
-.input-group-btn:last-child>.btn-group>.btn,
-.input-group-btn:last-child>.dropdown-toggle {
- border-bottom-left-radius: 0;
- border-top-left-radius: 0
-}
-.input-group-addon:last-child {
- border-left: 0
-}
-.input-group-btn {
- position: relative;
- font-size: 0;
- white-space: nowrap
-}
-.input-group-btn>.btn {
- position: relative
-}
-.input-group-btn>.btn:active,
-.input-group-btn>.btn:focus,
-.input-group-btn>.btn:hover {
- z-index: 2
-}
-.input-group-btn:first-child>.btn,
-.input-group-btn:first-child>.btn-group {
- margin-right: -1px
-}
-.nav {
- margin-bottom: 0;
- padding-left: 0;
- list-style: none
-}
-.nav>li>a {
- padding: 10px 15px
-}
-.nav>li>a:focus,
-.nav>li>a:hover {
- text-decoration: none;
- background-color: #eee
-}
-.nav>li.disabled>a {
- color: #777
-}
-.nav>li.disabled>a:focus,
-.nav>li.disabled>a:hover {
- color: #777;
- text-decoration: none;
- background-color: transparent;
- cursor: not-allowed
-}
-.nav .open>a,
-.nav .open>a:focus,
-.nav .open>a:hover {
- background-color: #eee;
- border-color: #428bca
-}
-.nav .nav-divider {
- height: 1px;
- margin: 9px 0;
- overflow: hidden;
- background-color: #e5e5e5
-}
-.nav>li>a>img {
- max-width: none
-}
-.nav-tabs {
- border-bottom: 1px solid #ddd
-}
-.nav-tabs>li {
- float: left;
- margin-bottom: -1px
-}
-.nav-tabs>li>a {
- margin-right: 2px;
- line-height: 1.42857143;
- border: 1px solid transparent;
- border-radius: 4px 4px 0 0
-}
-.nav-tabs>li>a:hover {
- border-color: #eee #eee #ddd
-}
-.nav-tabs>li.active>a,
-.nav-tabs>li.active>a:focus,
-.nav-tabs>li.active>a:hover {
- color: #555;
- background-color: #fff;
- border: 1px solid #ddd;
- border-bottom-color: transparent;
- cursor: default
-}
-.nav-tabs.nav-justified {
- width: 100%;
- border-bottom: 0
-}
-.nav-tabs.nav-justified>li {
- float: none
-}
-.nav-tabs.nav-justified>li>a {
- text-align: center;
- margin-bottom: 5px;
- margin-right: 0;
- border-radius: 4px
-}
-.nav-tabs.nav-justified>.active>a,
-.nav-tabs.nav-justified>.active>a:focus,
-.nav-tabs.nav-justified>.active>a:hover {
- border: 1px solid #ddd
-}
-@media (min-width: 768px) {
- .nav-tabs.nav-justified>li {
- display: table-cell;
- width: 1%
- }
- .nav-tabs.nav-justified>li>a {
- margin-bottom: 0;
- border-bottom: 1px solid #ddd;
- border-radius: 4px 4px 0 0
- }
- .nav-tabs.nav-justified>.active>a,
- .nav-tabs.nav-justified>.active>a:focus,
- .nav-tabs.nav-justified>.active>a:hover {
- border-bottom-color: #fff
- }
-}
-.nav-pills>li {
- float: left
-}
-.nav-justified>li,
-.nav-stacked>li {
- float: none
-}
-.nav-pills>li>a {
- border-radius: 4px
-}
-.nav-pills>li+li {
- margin-left: 2px
-}
-.nav-pills>li.active>a,
-.nav-pills>li.active>a:focus,
-.nav-pills>li.active>a:hover {
- color: #fff;
- background-color: #428bca
-}
-.nav-stacked>li+li {
- margin-top: 2px;
- margin-left: 0
-}
-.nav-justified {
- width: 100%
-}
-.nav-justified>li>a {
- text-align: center;
- margin-bottom: 5px
-}
-.nav-tabs-justified {
- border-bottom: 0
-}
-.nav-tabs-justified>li>a {
- margin-right: 0;
- border-radius: 4px
-}
-.nav-tabs-justified>.active>a,
-.nav-tabs-justified>.active>a:focus,
-.nav-tabs-justified>.active>a:hover {
- border: 1px solid #ddd
-}
-@media (min-width: 768px) {
- .nav-justified>li {
- display: table-cell;
- width: 1%
- }
- .nav-justified>li>a {
- margin-bottom: 0
- }
- .nav-tabs-justified>li>a {
- border-bottom: 1px solid #ddd;
- border-radius: 4px 4px 0 0
- }
- .nav-tabs-justified>.active>a,
- .nav-tabs-justified>.active>a:focus,
- .nav-tabs-justified>.active>a:hover {
- border-bottom-color: #fff
- }
-}
-.tab-content>.tab-pane {
- display: none
-}
-.tab-content>.active {
- display: block
-}
-.nav-tabs .dropdown-menu {
- margin-top: -1px;
- border-top-right-radius: 0;
- border-top-left-radius: 0
-}
-.navbar {
- position: relative;
- min-height: 50px;
- margin-bottom: 20px;
- border: 1px solid transparent
-}
-.navbar-collapse {
- overflow-x: visible;
- padding-right: 15px;
- padding-left: 15px;
- border-top: 1px solid transparent;
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
- -webkit-overflow-scrolling: touch
-}
-.navbar-collapse.in {
- overflow-y: auto
-}
-@media (min-width: 768px) {
- .navbar {
- border-radius: 4px
- }
- .navbar-header {
- float: left
- }
- .navbar-collapse {
- width: auto;
- border-top: 0;
- box-shadow: none
- }
- .navbar-collapse.collapse {
- display: block!important;
- height: auto!important;
- padding-bottom: 0;
- overflow: visible!important
- }
- .navbar-collapse.in {
- overflow-y: visible
- }
- .navbar-fixed-bottom .navbar-collapse,
- .navbar-fixed-top .navbar-collapse,
- .navbar-static-top .navbar-collapse {
- padding-left: 0;
- padding-right: 0
- }
-}
-.carousel-inner,
-.embed-responsive,
-.modal,
-.modal-open,
-.progress {
- overflow: hidden
-}
-@media (max-width: 480px) and (orientation: landscape) {
- .navbar-fixed-bottom .navbar-collapse,
- .navbar-fixed-top .navbar-collapse {
- max-height: 200px
- }
-}
-.container-fluid>.navbar-collapse,
-.container-fluid>.navbar-header,
-.container>.navbar-collapse,
-.container>.navbar-header {
- margin-right: -15px;
- margin-left: -15px
-}
-.navbar-static-top {
- z-index: 1000;
- border-width: 0 0 1px
-}
-.navbar-fixed-bottom,
-.navbar-fixed-top {
- position: fixed;
- right: 0;
- left: 0;
- z-index: 1030;
- -webkit-transform: translate3d(0, 0, 0);
- transform: translate3d(0, 0, 0)
-}
-.navbar-fixed-top {
- top: 0;
- border-width: 0 0 1px
-}
-.navbar-fixed-bottom {
- bottom: 0;
- margin-bottom: 0;
- border-width: 1px 0 0
-}
-.navbar-brand {
- float: left;
- padding: 15px;
- font-size: 18px;
- line-height: 20px;
- height: 50px
-}
-.navbar-brand:focus,
-.navbar-brand:hover {
- text-decoration: none
-}
-@media (min-width: 768px) {
- .container-fluid>.navbar-collapse,
- .container-fluid>.navbar-header,
- .container>.navbar-collapse,
- .container>.navbar-header {
- margin-right: 0;
- margin-left: 0
- }
- .navbar-fixed-bottom,
- .navbar-fixed-top,
- .navbar-static-top {
- border-radius: 0
- }
- .navbar>.container .navbar-brand,
- .navbar>.container-fluid .navbar-brand {
- margin-left: -15px
- }
-}
-.navbar-toggle {
- position: relative;
- float: right;
- margin-right: 15px;
- padding: 9px 10px;
- margin-top: 8px;
- margin-bottom: 8px;
- background-color: transparent;
- border: 1px solid transparent;
- border-radius: 4px
-}
-.navbar-toggle:focus {
- outline: 0
-}
-.navbar-toggle .icon-bar {
- display: block;
- width: 22px;
- height: 2px;
- border-radius: 1px
-}
-.navbar-toggle .icon-bar+.icon-bar {
- margin-top: 4px
-}
-.navbar-nav {
- margin: 7.5px -15px
-}
-.navbar-nav>li>a {
- padding-top: 10px;
- padding-bottom: 10px;
- line-height: 20px
-}
-@media (max-width: 767px) {
- .navbar-nav .open .dropdown-menu {
- position: static;
- float: none;
- width: auto;
- margin-top: 0;
- background-color: transparent;
- border: 0;
- box-shadow: none
- }
- .navbar-nav .open .dropdown-menu .dropdown-header,
- .navbar-nav .open .dropdown-menu>li>a {
- padding: 5px 15px 5px 25px
- }
- .navbar-nav .open .dropdown-menu>li>a {
- line-height: 20px
- }
- .navbar-nav .open .dropdown-menu>li>a:focus,
- .navbar-nav .open .dropdown-menu>li>a:hover {
- background-image: none
- }
-}
-.progress-bar-striped,
-.progress-striped .progress-bar,
-.progress-striped .progress-bar-success {
- background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
- background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent)
-}
-@media (min-width: 768px) {
- .navbar-toggle {
- display: none
- }
- .navbar-nav {
- float: left;
- margin: 0
- }
- .navbar-nav>li {
- float: left
- }
- .navbar-nav>li>a {
- padding-top: 15px;
- padding-bottom: 15px
- }
- .navbar-nav.navbar-right:last-child {
- margin-right: -15px
- }
- .navbar-left {
- float: left!important
- }
- .navbar-right {
- float: right!important
- }
-}
-.navbar-form {
- padding: 10px 15px;
- border-top: 1px solid transparent;
- border-bottom: 1px solid transparent;
- -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);
- margin: 8px -15px
-}
-@media (min-width: 768px) {
- .navbar-form .control-label,
- .navbar-form .form-group {
- margin-bottom: 0;
- vertical-align: middle
- }
- .navbar-form .form-group {
- display: inline-block
- }
- .navbar-form .form-control {
- display: inline-block;
- width: auto;
- vertical-align: middle
- }
- .navbar-form .input-group {
- display: inline-table;
- vertical-align: middle
- }
- .navbar-form .input-group .form-control,
- .navbar-form .input-group .input-group-addon,
- .navbar-form .input-group .input-group-btn {
- width: auto
- }
- .navbar-form .input-group>.form-control {
- width: 100%
- }
- .navbar-form .checkbox,
- .navbar-form .radio {
- display: inline-block;
- margin-top: 0;
- margin-bottom: 0;
- vertical-align: middle
- }
- .navbar-form .checkbox label,
- .navbar-form .radio label {
- padding-left: 0
- }
- .navbar-form .checkbox input[type=checkbox],
- .navbar-form .radio input[type=radio] {
- position: relative;
- margin-left: 0
- }
- .navbar-form .has-feedback .form-control-feedback {
- top: 0
- }
- .navbar-form {
- width: auto;
- border: 0;
- margin-left: 0;
- margin-right: 0;
- padding-top: 0;
- padding-bottom: 0;
- -webkit-box-shadow: none;
- box-shadow: none
- }
- .navbar-form.navbar-right:last-child {
- margin-right: -15px
- }
-}
-.breadcrumb>li,
-.pagination {
- display: inline-block
-}
-@media (max-width: 767px) {
- .navbar-form .form-group {
- margin-bottom: 5px
- }
-}
-.navbar-nav>li>.dropdown-menu {
- margin-top: 0;
- border-top-right-radius: 0;
- border-top-left-radius: 0
-}
-.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu {
- border-bottom-right-radius: 0;
- border-bottom-left-radius: 0
-}
-.navbar-btn {
- margin-top: 8px;
- margin-bottom: 8px
-}
-.navbar-btn.btn-sm {
- margin-top: 10px;
- margin-bottom: 10px
-}
-.navbar-btn.btn-xs {
- margin-top: 14px;
- margin-bottom: 14px
-}
-.navbar-text {
- margin-top: 15px;
- margin-bottom: 15px
-}
-@media (min-width: 768px) {
- .navbar-text {
- float: left;
- margin-left: 15px;
- margin-right: 15px
- }
- .navbar-text.navbar-right:last-child {
- margin-right: 0
- }
-}
-.navbar-default {
- background-color: #f8f8f8;
- border-color: #e7e7e7
-}
-.navbar-default .navbar-brand {
- color: #777
-}
-.navbar-default .navbar-brand:focus,
-.navbar-default .navbar-brand:hover {
- color: #5e5e5e;
- background-color: transparent
-}
-.navbar-default .navbar-nav>li>a,
-.navbar-default .navbar-text {
- color: #777
-}
-.navbar-default .navbar-nav>li>a:focus,
-.navbar-default .navbar-nav>li>a:hover {
- color: #333;
- background-color: transparent
-}
-.navbar-default .navbar-nav>.active>a,
-.navbar-default .navbar-nav>.active>a:focus,
-.navbar-default .navbar-nav>.active>a:hover {
- color: #555;
- background-color: #e7e7e7
-}
-.navbar-default .navbar-nav>.disabled>a,
-.navbar-default .navbar-nav>.disabled>a:focus,
-.navbar-default .navbar-nav>.disabled>a:hover {
- color: #ccc;
- background-color: transparent
-}
-.navbar-default .navbar-toggle {
- border-color: #ddd
-}
-.navbar-default .navbar-toggle:focus,
-.navbar-default .navbar-toggle:hover {
- background-color: #ddd
-}
-.navbar-default .navbar-toggle .icon-bar {
- background-color: #888
-}
-.navbar-default .navbar-collapse,
-.navbar-default .navbar-form {
- border-color: #e7e7e7
-}
-.navbar-default .navbar-nav>.open>a,
-.navbar-default .navbar-nav>.open>a:focus,
-.navbar-default .navbar-nav>.open>a:hover {
- background-color: #e7e7e7;
- color: #555
-}
-@media (max-width: 767px) {
- .navbar-default .navbar-nav .open .dropdown-menu>li>a {
- color: #777
- }
- .navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,
- .navbar-default .navbar-nav .open .dropdown-menu>li>a:hover {
- color: #333;
- background-color: transparent
- }
- .navbar-default .navbar-nav .open .dropdown-menu>.active>a,
- .navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,
- .navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover {
- color: #555;
- background-color: #e7e7e7
- }
- .navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,
- .navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,
- .navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover {
- color: #ccc;
- background-color: transparent
- }
-}
-.navbar-default .navbar-link {
- color: #777
-}
-.navbar-default .navbar-link:hover {
- color: #333
-}
-.navbar-default .btn-link {
- color: #777
-}
-.navbar-default .btn-link:focus,
-.navbar-default .btn-link:hover {
- color: #333
-}
-.navbar-default .btn-link[disabled]:focus,
-.navbar-default .btn-link[disabled]:hover,
-fieldset[disabled] .navbar-default .btn-link:focus,
-fieldset[disabled] .navbar-default .btn-link:hover {
- color: #ccc
-}
-.navbar-inverse {
- background-color: #222;
- border-color: #080808
-}
-.navbar-inverse .navbar-brand {
- color: #777
-}
-.navbar-inverse .navbar-brand:focus,
-.navbar-inverse .navbar-brand:hover {
- color: #fff;
- background-color: transparent
-}
-.navbar-inverse .navbar-nav>li>a,
-.navbar-inverse .navbar-text {
- color: #777
-}
-.navbar-inverse .navbar-nav>li>a:focus,
-.navbar-inverse .navbar-nav>li>a:hover {
- color: #fff;
- background-color: transparent
-}
-.navbar-inverse .navbar-nav>.active>a,
-.navbar-inverse .navbar-nav>.active>a:focus,
-.navbar-inverse .navbar-nav>.active>a:hover {
- color: #fff;
- background-color: #080808
-}
-.navbar-inverse .navbar-nav>.disabled>a,
-.navbar-inverse .navbar-nav>.disabled>a:focus,
-.navbar-inverse .navbar-nav>.disabled>a:hover {
- color: #444;
- background-color: transparent
-}
-.navbar-inverse .navbar-toggle {
- border-color: #333
-}
-.navbar-inverse .navbar-toggle:focus,
-.navbar-inverse .navbar-toggle:hover {
- background-color: #333
-}
-.navbar-inverse .navbar-toggle .icon-bar {
- background-color: #fff
-}
-.navbar-inverse .navbar-collapse,
-.navbar-inverse .navbar-form {
- border-color: #101010
-}
-.navbar-inverse .navbar-nav>.open>a,
-.navbar-inverse .navbar-nav>.open>a:focus,
-.navbar-inverse .navbar-nav>.open>a:hover {
- background-color: #080808;
- color: #fff
-}
-@media (max-width: 767px) {
- .navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header {
- border-color: #080808
- }
- .navbar-inverse .navbar-nav .open .dropdown-menu .divider {
- background-color: #080808
- }
- .navbar-inverse .navbar-nav .open .dropdown-menu>li>a {
- color: #777
- }
- .navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,
- .navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover {
- color: #fff;
- background-color: transparent
- }
- .navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,
- .navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,
- .navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover {
- color: #fff;
- background-color: #080808
- }
- .navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,
- .navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,
- .navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover {
- color: #444;
- background-color: transparent
- }
-}
-.navbar-inverse .navbar-link {
- color: #777
-}
-.navbar-inverse .navbar-link:hover {
- color: #fff
-}
-.navbar-inverse .btn-link {
- color: #777
-}
-.navbar-inverse .btn-link:focus,
-.navbar-inverse .btn-link:hover {
- color: #fff
-}
-.navbar-inverse .btn-link[disabled]:focus,
-.navbar-inverse .btn-link[disabled]:hover,
-fieldset[disabled] .navbar-inverse .btn-link:focus,
-fieldset[disabled] .navbar-inverse .btn-link:hover {
- color: #444
-}
-.breadcrumb {
- padding: 8px 15px;
- margin-bottom: 20px;
- list-style: none;
- background-color: #f5f5f5;
- border-radius: 4px
-}
-.breadcrumb>li+li:before {
- content: "/\00a0";
- padding: 0 5px;
- color: #ccc
-}
-.breadcrumb>.active {
- color: #777
-}
-.pagination {
- padding-left: 0;
- margin: 20px 0;
- border-radius: 4px
-}
-.pager li,
-.pagination>li {
- display: inline
-}
-.pagination>li>a,
-.pagination>li>span {
- position: relative;
- float: left;
- padding: 6px 9pt;
- line-height: 1.0;
- text-decoration: none;
- color: #428bca;
- background-color: #fff;
- border: 1px solid #ddd;
- margin-left: -1px
-}
-.badge,
-.label {
- font-weight: 700;
- line-height: 1;
- vertical-align: baseline;
- white-space: nowrap;
- text-align: center
-}
-.pagination>li:first-child>a,
-.pagination>li:first-child>span {
- margin-left: 0;
- border-bottom-left-radius: 4px;
- border-top-left-radius: 4px
-}
-.pagination>li:last-child>a,
-.pagination>li:last-child>span {
- border-bottom-right-radius: 4px;
- border-top-right-radius: 4px
-}
-.pagination>li>a:focus,
-.pagination>li>a:hover,
-.pagination>li>span:focus,
-.pagination>li>span:hover {
- color: #2a6496;
- background-color: #eee;
- border-color: #ddd
-}
-.pagination>.active>a,
-.pagination>.active>a:focus,
-.pagination>.active>a:hover,
-.pagination>.active>span,
-.pagination>.active>span:focus,
-.pagination>.active>span:hover {
- z-index: 2;
- color: #fff;
- background-color: #428bca;
- border-color: #428bca;
- cursor: default
-}
-.pagination>.disabled>a,
-.pagination>.disabled>a:focus,
-.pagination>.disabled>a:hover,
-.pagination>.disabled>span,
-.pagination>.disabled>span:focus,
-.pagination>.disabled>span:hover {
- color: #777;
- background-color: #fff;
- border-color: #ddd;
- cursor: not-allowed
-}
-.pagination-lg>li>a,
-.pagination-lg>li>span {
- padding: 10px 1pc;
- font-size: 18px
-}
-.pagination-lg>li:first-child>a,
-.pagination-lg>li:first-child>span {
- border-bottom-left-radius: 6px;
- border-top-left-radius: 6px
-}
-.pagination-lg>li:last-child>a,
-.pagination-lg>li:last-child>span {
- border-bottom-right-radius: 6px;
- border-top-right-radius: 6px
-}
-.pagination-sm>li>a,
-.pagination-sm>li>span {
- padding: 5px 10px;
- font-size: 9pt
-}
-.pagination-sm>li:first-child>a,
-.pagination-sm>li:first-child>span {
- border-bottom-left-radius: 3px;
- border-top-left-radius: 3px
-}
-.pagination-sm>li:last-child>a,
-.pagination-sm>li:last-child>span {
- border-bottom-right-radius: 3px;
- border-top-right-radius: 3px
-}
-.pager {
- padding-left: 0;
- margin: 20px 0;
- list-style: none;
- text-align: center
-}
-.pager li>a,
-.pager li>span {
- display: inline-block;
- padding: 5px 14px;
- background-color: #fff;
- border: 1px solid #ddd;
- border-radius: 15px
-}
-.pager li>a:focus,
-.pager li>a:hover {
- text-decoration: none;
- background-color: #eee
-}
-.pager .next>a,
-.pager .next>span {
- float: right
-}
-.pager .previous>a,
-.pager .previous>span {
- float: left
-}
-.pager .disabled>a,
-.pager .disabled>a:focus,
-.pager .disabled>a:hover,
-.pager .disabled>span {
- color: #777;
- background-color: #fff;
- cursor: not-allowed
-}
-.label {
- display: inline;
- padding: .2em .6em .3em;
- font-size: 75%;
- color: #fff;
- border-radius: .25em
-}
-a.label:focus,
-a.label:hover {
- color: #fff;
- text-decoration: none;
- cursor: pointer
-}
-.label:empty {
- display: none
-}
-.btn .label {
- position: relative;
- top: -1px
-}
-.label-default {
- background-color: #777
-}
-.label-default[href]:focus,
-.label-default[href]:hover {
- background-color: #5e5e5e
-}
-.label-primary {
- background-color: #428bca
-}
-.label-primary[href]:focus,
-.label-primary[href]:hover {
- background-color: #3071a9
-}
-.label-success {
- background-color: #5cb85c
-}
-.label-success[href]:focus,
-.label-success[href]:hover {
- background-color: #449d44
-}
-.label-info {
- background-color: #5bc0de
-}
-.label-info[href]:focus,
-.label-info[href]:hover {
- background-color: #31b0d5
-}
-.label-warning {
- background-color: #f0ad4e
-}
-.label-warning[href]:focus,
-.label-warning[href]:hover {
- background-color: #ec971f
-}
-.label-danger {
- background-color: #d9534f
-}
-.label-danger[href]:focus,
-.label-danger[href]:hover {
- background-color: #c9302c
-}
-.badge {
- display: inline-block;
- min-width: 10px;
- padding: 3px 7px;
- font-size: 9pt;
- color: #fff;
- background-color: #777;
- border-radius: 10px
-}
-.badge:empty {
- display: none
-}
-.list-group-item,
-.media-object,
-.thumbnail {
- display: block
-}
-.btn .badge {
- position: relative;
- top: -1px
-}
-.btn-xs .badge {
- top: 0;
- padding: 1px 5px
-}
-a.badge:focus,
-a.badge:hover {
- color: #fff;
- text-decoration: none;
- cursor: pointer
-}
-.nav-pills>.active>a>.badge,
-a.list-group-item.active>.badge {
- color: #428bca;
- background-color: #fff
-}
-.jumbotron,
-.jumbotron .h1,
-.jumbotron h1 {
- color: inherit
-}
-.nav-pills>li>a>.badge {
- margin-left: 3px
-}
-.jumbotron {
- padding: 30px;
- margin-bottom: 30px;
- background-color: #eee
-}
-.jumbotron p {
- margin-bottom: 15px;
- font-size: 21px;
- font-weight: 200
-}
-.alert,
-.thumbnail {
- margin-bottom: 20px
-}
-.alert .alert-link,
-.close {
- font-weight: 700
-}
-.jumbotron>hr {
- border-top-color: #d5d5d5
-}
-.container .jumbotron {
- border-radius: 6px
-}
-.jumbotron .container {
- max-width: 100%
-}
-@media screen and (min-width: 768px) {
- .jumbotron {
- padding-top: 3pc;
- padding-bottom: 3pc
- }
- .container .jumbotron {
- padding-left: 60px;
- padding-right: 60px
- }
- .jumbotron .h1,
- .jumbotron h1 {
- font-size: 63px
- }
-}
-.thumbnail {
- padding: 4px;
- line-height: 1.42857143;
- background-color: #fff;
- border: 1px solid #ddd;
- border-radius: 4px;
- -o-transition: all .2s ease-in-out;
- transition: all .2s ease-in-out
-}
-.thumbnail a>img,
-.thumbnail>img {
- margin-left: auto;
- margin-right: auto
-}
-a.thumbnail.active,
-a.thumbnail:focus,
-a.thumbnail:hover {
- border-color: #428bca
-}
-.thumbnail .caption {
- padding: 9px;
- color: #333
-}
-.alert {
- padding: 15px;
- border: 1px solid transparent;
- border-radius: 4px
-}
-.alert h4 {
- margin-top: 0;
- color: inherit
-}
-.alert>p,
-.alert>ul {
- margin-bottom: 0
-}
-.alert>p+p {
- margin-top: 5px
-}
-.alert-dismissable,
-.alert-dismissible {
- padding-right: 35px
-}
-.alert-dismissable .close,
-.alert-dismissible .close {
- position: relative;
- top: -2px;
- right: -21px;
- color: inherit
-}
-.modal,
-.modal-backdrop {
- top: 0;
- right: 0;
- bottom: 0;
- left: 0
-}
-.alert-success {
- background-color: #dff0d8;
- border-color: #d6e9c6;
- color: #3c763d
-}
-.alert-success hr {
- border-top-color: #c9e2b3
-}
-.alert-success .alert-link {
- color: #2b542c
-}
-.alert-info {
- background-color: #d9edf7;
- border-color: #bce8f1;
- color: #31708f
-}
-.alert-info hr {
- border-top-color: #a6e1ec
-}
-.alert-info .alert-link {
- color: #245269
-}
-.alert-warning {
- background-color: #fcf8e3;
- border-color: #faebcc;
- color: #8a6d3b
-}
-.alert-warning hr {
- border-top-color: #f7e1b5
-}
-.alert-warning .alert-link {
- color: #66512c
-}
-.alert-danger {
- background-color: #f2dede;
- border-color: #ebccd1;
- color: #a94442
-}
-.alert-danger hr {
- border-top-color: #e4b9c0
-}
-.alert-danger .alert-link {
- color: #843534
-}
-@-webkit-keyframes progress-bar-stripes {
- from {
- background-position: 40px 0
- }
- to {
- background-position: 0 0
- }
-}
-@keyframes progress-bar-stripes {
- from {
- background-position: 40px 0
- }
- to {
- background-position: 0 0
- }
-}
-.progress {
- height: 20px;
- margin-bottom: 20px;
- background-color: #f5f5f5;
- border-radius: 4px;
- -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);
- box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1)
-}
-.progress-bar {
- float: left;
- width: 0;
- height: 100%;
- font-size: 9pt;
- line-height: 20px;
- color: #fff;
- text-align: center;
- background-color: #428bca;
- -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
- box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);
- -webkit-transition: width .6s ease;
- -o-transition: width .6s ease;
- transition: width .6s ease
-}
-.close,
-.list-group-item>.badge {
- float: right
-}
-.progress-bar-striped,
-.progress-striped .progress-bar {
- background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
- background-size: 40px 40px
-}
-.progress-bar.active,
-.progress.active .progress-bar {
- -webkit-animation: progress-bar-stripes 2s linear infinite;
- -o-animation: progress-bar-stripes 2s linear infinite;
- animation: progress-bar-stripes 2s linear infinite
-}
-.progress-bar[aria-valuenow="1"],
-.progress-bar[aria-valuenow="2"] {
- min-width: 30px
-}
-.progress-bar[aria-valuenow="0"] {
- color: #777;
- min-width: 30px;
- background-color: transparent;
- background-image: none;
- box-shadow: none
-}
-.progress-bar-success {
- background-color: #5cb85c
-}
-.progress-striped .progress-bar-success {
- background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent)
-}
-.progress-striped .progress-bar-info,
-.progress-striped .progress-bar-warning {
- background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
- background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent)
-}
-.progress-bar-info {
- background-color: #5bc0de
-}
-.progress-striped .progress-bar-info {
- background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent)
-}
-.progress-bar-warning {
- background-color: #f0ad4e
-}
-.progress-striped .progress-bar-warning {
- background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent)
-}
-.progress-bar-danger {
- background-color: #d9534f
-}
-.progress-striped .progress-bar-danger {
- background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
- background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
- background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent)
-}
-.media,
-.media-body {
- overflow: hidden;
- zoom: 1
-}
-.media,
-.media .media {
- margin-top: 15px
-}
-.media:first-child {
- margin-top: 0
-}
-.media-heading {
- margin: 0 0 5px
-}
-.media>.pull-left {
- margin-right: 10px
-}
-.media>.pull-right {
- margin-left: 10px
-}
-.media-list {
- padding-left: 0;
- list-style: none
-}
-.list-group {
- margin-bottom: 20px;
- padding-left: 0
-}
-.list-group-item {
- position: relative;
- padding: 10px 15px;
- margin-bottom: -1px;
- background-color: #fff;
- border: 1px solid #ddd
-}
-.list-group-item:first-child {
- border-top-right-radius: 4px;
- border-top-left-radius: 4px
-}
-.list-group-item:last-child {
- margin-bottom: 0;
- border-bottom-right-radius: 4px;
- border-bottom-left-radius: 4px
-}
-.list-group-item>.badge+.badge {
- margin-right: 5px
-}
-a.list-group-item {
- color: #555
-}
-a.list-group-item .list-group-item-heading {
- color: #333
-}
-a.list-group-item:focus,
-a.list-group-item:hover {
- text-decoration: none;
- color: #555;
- background-color: #f5f5f5
-}
-.list-group-item.disabled,
-.list-group-item.disabled:focus,
-.list-group-item.disabled:hover {
- background-color: #eee;
- color: #777
-}
-.list-group-item.disabled .list-group-item-heading,
-.list-group-item.disabled:focus .list-group-item-heading,
-.list-group-item.disabled:hover .list-group-item-heading {
- color: inherit
-}
-.list-group-item.disabled .list-group-item-text,
-.list-group-item.disabled:focus .list-group-item-text,
-.list-group-item.disabled:hover .list-group-item-text {
- color: #777
-}
-.list-group-item.active,
-.list-group-item.active:focus,
-.list-group-item.active:hover {
- z-index: 2;
- color: #fff;
- background-color: #428bca;
- border-color: #428bca
-}
-.list-group-item.active .list-group-item-heading,
-.list-group-item.active .list-group-item-heading>.small,
-.list-group-item.active .list-group-item-heading>small,
-.list-group-item.active:focus .list-group-item-heading,
-.list-group-item.active:focus .list-group-item-heading>.small,
-.list-group-item.active:focus .list-group-item-heading>small,
-.list-group-item.active:hover .list-group-item-heading,
-.list-group-item.active:hover .list-group-item-heading>.small,
-.list-group-item.active:hover .list-group-item-heading>small {
- color: inherit
-}
-.list-group-item.active .list-group-item-text,
-.list-group-item.active:focus .list-group-item-text,
-.list-group-item.active:hover .list-group-item-text {
- color: #e1edf7
-}
-.list-group-item-success {
- color: #3c763d;
- background-color: #dff0d8
-}
-a.list-group-item-success {
- color: #3c763d
-}
-a.list-group-item-success .list-group-item-heading {
- color: inherit
-}
-a.list-group-item-success:focus,
-a.list-group-item-success:hover {
- color: #3c763d;
- background-color: #d0e9c6
-}
-a.list-group-item-success.active,
-a.list-group-item-success.active:focus,
-a.list-group-item-success.active:hover {
- color: #fff;
- background-color: #3c763d;
- border-color: #3c763d
-}
-.list-group-item-info {
- color: #31708f;
- background-color: #d9edf7
-}
-a.list-group-item-info {
- color: #31708f
-}
-a.list-group-item-info .list-group-item-heading {
- color: inherit
-}
-a.list-group-item-info:focus,
-a.list-group-item-info:hover {
- color: #31708f;
- background-color: #c4e3f3
-}
-a.list-group-item-info.active,
-a.list-group-item-info.active:focus,
-a.list-group-item-info.active:hover {
- color: #fff;
- background-color: #31708f;
- border-color: #31708f
-}
-.list-group-item-warning {
- color: #8a6d3b;
- background-color: #fcf8e3
-}
-a.list-group-item-warning {
- color: #8a6d3b
-}
-a.list-group-item-warning .list-group-item-heading {
- color: inherit
-}
-a.list-group-item-warning:focus,
-a.list-group-item-warning:hover {
- color: #8a6d3b;
- background-color: #faf2cc
-}
-a.list-group-item-warning.active,
-a.list-group-item-warning.active:focus,
-a.list-group-item-warning.active:hover {
- color: #fff;
- background-color: #8a6d3b;
- border-color: #8a6d3b
-}
-.list-group-item-danger {
- color: #a94442;
- background-color: #f2dede
-}
-a.list-group-item-danger {
- color: #a94442
-}
-a.list-group-item-danger .list-group-item-heading {
- color: inherit
-}
-a.list-group-item-danger:focus,
-a.list-group-item-danger:hover {
- color: #a94442;
- background-color: #ebcccc
-}
-a.list-group-item-danger.active,
-a.list-group-item-danger.active:focus,
-a.list-group-item-danger.active:hover {
- color: #fff;
- background-color: #a94442;
- border-color: #a94442
-}
-.panel-heading>.dropdown .dropdown-toggle,
-.panel-title,
-.panel-title>a {
- color: inherit
-}
-.list-group-item-heading {
- margin-top: 0;
- margin-bottom: 5px
-}
-.list-group-item-text {
- margin-bottom: 0;
- line-height: 1.3
-}
-.panel {
- margin-bottom: 20px;
- background-color: #fff;
- border: 1px solid transparent;
- border-radius: 4px;
- -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);
- box-shadow: 0 1px 1px rgba(0, 0, 0, .05)
-}
-.panel-title,
-.panel>.list-group,
-.panel>.panel-collapse>.table,
-.panel>.table,
-.panel>.table-responsive>.table {
- margin-bottom: 0
-}
-.panel-body {
- padding: 15px
-}
-.panel-heading {
- padding: 10px 15px;
- border-bottom: 1px solid transparent;
- border-top-right-radius: 3px;
- border-top-left-radius: 3px
-}
-.panel-group .panel-heading,
-.panel>.list-group:last-child .list-group-item:last-child,
-.panel>.table-bordered>tbody>tr:first-child>td,
-.panel>.table-bordered>tbody>tr:first-child>th,
-.panel>.table-bordered>tbody>tr:last-child>td,
-.panel>.table-bordered>tbody>tr:last-child>th,
-.panel>.table-bordered>tfoot>tr:last-child>td,
-.panel>.table-bordered>tfoot>tr:last-child>th,
-.panel>.table-bordered>thead>tr:first-child>td,
-.panel>.table-bordered>thead>tr:first-child>th,
-.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,
-.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,
-.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,
-.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,
-.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,
-.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th,
-.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,
-.panel>.table-responsive>.table-bordered>thead>tr:first-child>th {
- border-bottom: 0
-}
-.panel-title {
- margin-top: 0;
- font-size: 1pc
-}
-.panel-footer {
- padding: 10px 15px;
- background-color: #f5f5f5;
- border-top: 1px solid #ddd;
- border-bottom-right-radius: 3px;
- border-bottom-left-radius: 3px
-}
-.panel>.list-group .list-group-item {
- border-width: 1px 0;
- border-radius: 0
-}
-.panel>.list-group:last-child .list-group-item:last-child,
-.panel>.table-responsive:last-child>.table:last-child,
-.panel>.table:last-child {
- border-bottom-left-radius: 3px;
- border-bottom-right-radius: 3px
-}
-.panel>.list-group:first-child .list-group-item:first-child {
- border-top: 0;
- border-top-right-radius: 3px;
- border-top-left-radius: 3px
-}
-.list-group+.panel-footer,
-.panel-heading+.list-group .list-group-item:first-child {
- border-top-width: 0
-}
-.panel>.table-responsive:first-child>.table:first-child,
-.panel>.table:first-child {
- border-top-right-radius: 3px;
- border-top-left-radius: 3px
-}
-.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,
-.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,
-.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,
-.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,
-.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,
-.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,
-.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,
-.panel>.table:first-child>thead:first-child>tr:first-child th:first-child {
- border-top-left-radius: 3px
-}
-.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,
-.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,
-.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,
-.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,
-.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,
-.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,
-.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,
-.panel>.table:first-child>thead:first-child>tr:first-child th:last-child {
- border-top-right-radius: 3px
-}
-.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,
-.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,
-.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,
-.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,
-.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,
-.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,
-.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,
-.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child {
- border-bottom-left-radius: 3px
-}
-.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,
-.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,
-.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,
-.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,
-.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,
-.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,
-.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,
-.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child {
- border-bottom-right-radius: 3px
-}
-.panel>.panel-body+.table,
-.panel>.panel-body+.table-responsive {
- border-top: 1px solid #ddd
-}
-.panel>.table>tbody:first-child>tr:first-child td,
-.panel>.table>tbody:first-child>tr:first-child th {
- border-top: 0
-}
-.panel>.table-bordered,
-.panel>.table-responsive>.table-bordered {
- border: 0
-}
-.panel>.table-bordered>tbody>tr>td:first-child,
-.panel>.table-bordered>tbody>tr>th:first-child,
-.panel>.table-bordered>tfoot>tr>td:first-child,
-.panel>.table-bordered>tfoot>tr>th:first-child,
-.panel>.table-bordered>thead>tr>td:first-child,
-.panel>.table-bordered>thead>tr>th:first-child,
-.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,
-.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,
-.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,
-.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,
-.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,
-.panel>.table-responsive>.table-bordered>thead>tr>th:first-child {
- border-left: 0
-}
-.panel>.table-bordered>tbody>tr>td:last-child,
-.panel>.table-bordered>tbody>tr>th:last-child,
-.panel>.table-bordered>tfoot>tr>td:last-child,
-.panel>.table-bordered>tfoot>tr>th:last-child,
-.panel>.table-bordered>thead>tr>td:last-child,
-.panel>.table-bordered>thead>tr>th:last-child,
-.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,
-.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,
-.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,
-.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,
-.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,
-.panel>.table-responsive>.table-bordered>thead>tr>th:last-child {
- border-right: 0
-}
-.panel>.table-responsive {
- border: 0;
- margin-bottom: 0
-}
-.panel-group {
- margin-bottom: 20px
-}
-.panel-group .panel {
- margin-bottom: 0;
- border-radius: 4px
-}
-.panel-group .panel+.panel {
- margin-top: 5px
-}
-.panel-group .panel-heading+.panel-collapse>.panel-body {
- border-top: 1px solid #ddd
-}
-.panel-group .panel-footer {
- border-top: 0
-}
-.panel-group .panel-footer+.panel-collapse .panel-body {
- border-bottom: 1px solid #ddd
-}
-.panel-default {
- border-color: #ddd
-}
-.panel-default>.panel-heading {
- color: #333;
- background-color: #f5f5f5;
- border-color: #ddd
-}
-.panel-default>.panel-heading+.panel-collapse>.panel-body {
- border-top-color: #ddd
-}
-.panel-default>.panel-heading .badge {
- color: #f5f5f5;
- background-color: #333
-}
-.panel-default>.panel-footer+.panel-collapse>.panel-body {
- border-bottom-color: #ddd
-}
-.panel-primary {
- border-color: #428bca
-}
-.panel-primary>.panel-heading {
- color: #fff;
- background-color: #428bca;
- border-color: #428bca
-}
-.panel-primary>.panel-heading+.panel-collapse>.panel-body {
- border-top-color: #428bca
-}
-.panel-primary>.panel-heading .badge {
- color: #428bca;
- background-color: #fff
-}
-.panel-primary>.panel-footer+.panel-collapse>.panel-body {
- border-bottom-color: #428bca
-}
-.panel-success {
- border-color: #d6e9c6
-}
-.panel-success>.panel-heading {
- color: #3c763d;
- background-color: #dff0d8;
- border-color: #d6e9c6
-}
-.panel-success>.panel-heading+.panel-collapse>.panel-body {
- border-top-color: #d6e9c6
-}
-.panel-success>.panel-heading .badge {
- color: #dff0d8;
- background-color: #3c763d
-}
-.panel-success>.panel-footer+.panel-collapse>.panel-body {
- border-bottom-color: #d6e9c6
-}
-.panel-info {
- border-color: #bce8f1
-}
-.panel-info>.panel-heading {
- color: #31708f;
- background-color: #d9edf7;
- border-color: #bce8f1
-}
-.panel-info>.panel-heading+.panel-collapse>.panel-body {
- border-top-color: #bce8f1
-}
-.panel-info>.panel-heading .badge {
- color: #d9edf7;
- background-color: #31708f
-}
-.panel-info>.panel-footer+.panel-collapse>.panel-body {
- border-bottom-color: #bce8f1
-}
-.panel-warning {
- border-color: #faebcc
-}
-.panel-warning>.panel-heading {
- color: #8a6d3b;
- background-color: #fcf8e3;
- border-color: #faebcc
-}
-.panel-warning>.panel-heading+.panel-collapse>.panel-body {
- border-top-color: #faebcc
-}
-.panel-warning>.panel-heading .badge {
- color: #fcf8e3;
- background-color: #8a6d3b
-}
-.panel-warning>.panel-footer+.panel-collapse>.panel-body {
- border-bottom-color: #faebcc
-}
-.panel-danger {
- border-color: #ebccd1
-}
-.panel-danger>.panel-heading {
- color: #a94442;
- background-color: #f2dede;
- border-color: #ebccd1
-}
-.panel-danger>.panel-heading+.panel-collapse>.panel-body {
- border-top-color: #ebccd1
-}
-.panel-danger>.panel-heading .badge {
- color: #f2dede;
- background-color: #a94442
-}
-.panel-danger>.panel-footer+.panel-collapse>.panel-body {
- border-bottom-color: #ebccd1
-}
-.embed-responsive {
- position: relative;
- display: block;
- height: 0;
- padding: 0
-}
-.embed-responsive .embed-responsive-item,
-.embed-responsive embed,
-.embed-responsive iframe,
-.embed-responsive object {
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- height: 100%;
- width: 100%;
- border: 0
-}
-.embed-responsive.embed-responsive-16by9 {
- padding-bottom: 56.25%
-}
-.embed-responsive.embed-responsive-4by3 {
- padding-bottom: 75%
-}
-.well {
- min-height: 20px;
- padding: 19px;
- margin-bottom: 20px;
- background-color: #f5f5f5;
- border: 1px solid #e3e3e3;
- border-radius: 4px;
- -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);
- box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05)
-}
-.well blockquote {
- border-color: #ddd;
- border-color: rgba(0, 0, 0, .15)
-}
-.well-lg {
- padding: 24px;
- border-radius: 6px
-}
-.well-sm {
- padding: 9px;
- border-radius: 3px
-}
-.close {
- font-size: 21px;
- line-height: 1;
- color: #000;
- text-shadow: 0 1px 0 #fff;
- opacity: .2;
- filter: alpha(opacity=20)
-}
-.carousel-caption,
-.carousel-control {
- text-shadow: 0 1px 2px rgba(0, 0, 0, .6)
-}
-.close:focus,
-.close:hover {
- color: #000;
- text-decoration: none;
- cursor: pointer;
- opacity: .5;
- filter: alpha(opacity=50)
-}
-button.close {
- padding: 0;
- cursor: pointer;
- background: 0 0;
- border: 0;
- -webkit-appearance: none
-}
-.modal-content,
-.popover {
- background-clip: padding-box
-}
-.modal {
- display: none;
- position: fixed;
- z-index: 1050;
- -webkit-overflow-scrolling: touch;
- outline: 0
-}
-.modal.fade .modal-dialog {
- -webkit-transform: translate3d(0, -25%, 0);
- transform: translate3d(0, -25%, 0);
- -webkit-transition: -webkit-transform .3s ease-out;
- -moz-transition: -moz-transform .3s ease-out;
- -o-transition: -o-transform .3s ease-out;
- transition: transform .3s ease-out
-}
-.modal.in .modal-dialog {
- -webkit-transform: translate3d(0, 0, 0);
- transform: translate3d(0, 0, 0)
-}
-.modal-open .modal {
- overflow-x: hidden;
- overflow-y: auto
-}
-.modal-dialog {
- position: relative;
- width: auto;
- margin: 10px
-}
-.modal-content {
- position: relative;
- background-color: #fff;
- border: 1px solid #999;
- border: 1px solid rgba(0, 0, 0, .2);
- border-radius: 6px;
- -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
- box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
- outline: 0
-}
-.modal-backdrop {
- position: fixed;
- z-index: 1040;
- background-color: #000
-}
-.modal-backdrop.fade {
- opacity: 0;
- filter: alpha(opacity=0)
-}
-.modal-backdrop.in {
- opacity: .5;
- filter: alpha(opacity=50)
-}
-.modal-header {
- padding: 15px;
- border-bottom: 1px solid #e5e5e5;
- min-height: 16.43px
-}
-.modal-header .close {
- margin-top: -2px
-}
-.modal-title {
- margin: 0;
- line-height: 1.42857143
-}
-.modal-body {
- position: relative;
- padding: 15px
-}
-.modal-footer {
- padding: 15px;
- text-align: right;
- border-top: 1px solid #e5e5e5
-}
-.tooltip.top .tooltip-arrow,
-.tooltip.top-left .tooltip-arrow,
-.tooltip.top-right .tooltip-arrow {
- bottom: 0;
- border-width: 5px 5px 0;
- border-top-color: #000
-}
-.modal-footer .btn+.btn {
- margin-left: 5px;
- margin-bottom: 0
-}
-.modal-footer .btn-group .btn+.btn {
- margin-left: -1px
-}
-.modal-footer .btn-block+.btn-block {
- margin-left: 0
-}
-.modal-scrollbar-measure {
- position: absolute;
- top: -9999px;
- width: 50px;
- height: 50px;
- overflow: scroll
-}
-@media (min-width: 768px) {
- .modal-dialog {
- width: 600px;
- margin: 30px auto
- }
- .modal-content {
- -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
- box-shadow: 0 5px 15px rgba(0, 0, 0, .5)
- }
- .modal-sm {
- width: 300px
- }
-}
-@media (min-width: 992px) {
- .modal-lg {
- width: 900px
- }
-}
-.tooltip {
- position: absolute;
- z-index: 1070;
- display: block;
- visibility: visible;
- font-size: 9pt;
- line-height: 1.4;
- opacity: 0;
- filter: alpha(opacity=0)
-}
-.tooltip.in {
- opacity: .9;
- filter: alpha(opacity=90)
-}
-.tooltip.top {
- margin-top: -3px;
- padding: 5px 0
-}
-.tooltip.right {
- margin-left: 3px;
- padding: 0 5px
-}
-.tooltip.bottom {
- margin-top: 3px;
- padding: 5px 0
-}
-.tooltip.left {
- margin-left: -3px;
- padding: 0 5px
-}
-.tooltip-inner {
- max-width: 200px;
- padding: 3px 8px;
- color: #fff;
- text-align: center;
- text-decoration: none;
- background-color: #000;
- border-radius: 4px
-}
-.tooltip-arrow {
- position: absolute;
- width: 0;
- height: 0;
- border-color: transparent;
- border-style: solid
-}
-.tooltip.top .tooltip-arrow {
- left: 50%;
- margin-left: -5px
-}
-.tooltip.top-left .tooltip-arrow {
- left: 5px
-}
-.tooltip.top-right .tooltip-arrow {
- right: 5px
-}
-.tooltip.right .tooltip-arrow {
- top: 50%;
- left: 0;
- margin-top: -5px;
- border-width: 5px 5px 5px 0;
- border-right-color: #000
-}
-.tooltip.left .tooltip-arrow {
- top: 50%;
- right: 0;
- margin-top: -5px;
- border-width: 5px 0 5px 5px;
- border-left-color: #000
-}
-.tooltip.bottom .tooltip-arrow,
-.tooltip.bottom-left .tooltip-arrow,
-.tooltip.bottom-right .tooltip-arrow {
- border-width: 0 5px 5px;
- border-bottom-color: #000;
- top: 0
-}
-.tooltip.bottom .tooltip-arrow {
- left: 50%;
- margin-left: -5px
-}
-.tooltip.bottom-left .tooltip-arrow {
- left: 5px
-}
-.tooltip.bottom-right .tooltip-arrow {
- right: 5px
-}
-.popover {
- position: absolute;
- top: 0;
- left: 0;
- z-index: 1060;
- display: none;
- max-width: 276px;
- padding: 1px;
- text-align: left;
- background-color: #fff;
- border: 1px solid #ccc;
- border: 1px solid rgba(0, 0, 0, .2);
- border-radius: 6px;
- -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
- box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
- white-space: normal
-}
-.popover.top {
- margin-top: -10px
-}
-.popover.right {
- margin-left: 10px
-}
-.popover.bottom {
- margin-top: 10px
-}
-.popover.left {
- margin-left: -10px
-}
-.popover-title {
- margin: 0;
- padding: 8px 14px;
- font-size: 14px;
- font-weight: 400;
- line-height: 18px;
- background-color: #f7f7f7;
- border-bottom: 1px solid #ebebeb;
- border-radius: 5px 5px 0 0
-}
-.popover-content {
- padding: 9px 14px
-}
-.popover>.arrow,
-.popover>.arrow:after {
- position: absolute;
- display: block;
- width: 0;
- height: 0;
- border-color: transparent;
- border-style: solid
-}
-.carousel,
-.carousel-inner {
- position: relative
-}
-.popover>.arrow {
- border-width: 11px
-}
-.popover>.arrow:after {
- border-width: 10px
-}
-.popover.top>.arrow {
- left: 50%;
- margin-left: -11px;
- border-bottom-width: 0;
- border-top-color: #999;
- border-top-color: rgba(0, 0, 0, .25);
- bottom: -11px
-}
-.popover.top>.arrow:after {
- content: " ";
- bottom: 1px;
- margin-left: -10px;
- border-bottom-width: 0;
- border-top-color: #fff
-}
-.popover.left>.arrow:after,
-.popover.right>.arrow:after {
- content: " ";
- bottom: -10px
-}
-.popover.right>.arrow {
- top: 50%;
- left: -11px;
- margin-top: -11px;
- border-left-width: 0;
- border-right-color: #999;
- border-right-color: rgba(0, 0, 0, .25)
-}
-.popover.right>.arrow:after {
- left: 1px;
- border-left-width: 0;
- border-right-color: #fff
-}
-.popover.bottom>.arrow {
- left: 50%;
- margin-left: -11px;
- border-top-width: 0;
- border-bottom-color: #999;
- border-bottom-color: rgba(0, 0, 0, .25);
- top: -11px
-}
-.popover.bottom>.arrow:after {
- content: " ";
- top: 1px;
- margin-left: -10px;
- border-top-width: 0;
- border-bottom-color: #fff
-}
-.popover.left>.arrow {
- top: 50%;
- right: -11px;
- margin-top: -11px;
- border-right-width: 0;
- border-left-color: #999;
- border-left-color: rgba(0, 0, 0, .25)
-}
-.popover.left>.arrow:after {
- right: 1px;
- border-right-width: 0;
- border-left-color: #fff
-}
-.carousel-inner {
- width: 100%
-}
-.carousel-inner>.item {
- display: none;
- position: relative;
- -webkit-transition: .6s ease-in-out left;
- -o-transition: .6s ease-in-out left;
- transition: .6s ease-in-out left
-}
-.carousel-inner>.item>a>img,
-.carousel-inner>.item>img {
- line-height: 1
-}
-.carousel-inner>.active,
-.carousel-inner>.next,
-.carousel-inner>.prev {
- display: block
-}
-.carousel-inner>.active {
- left: 0
-}
-.carousel-inner>.next,
-.carousel-inner>.prev {
- position: absolute;
- top: 0;
- width: 100%
-}
-.carousel-inner>.next {
- left: 100%
-}
-.carousel-inner>.prev {
- left: -100%
-}
-.carousel-inner>.next.left,
-.carousel-inner>.prev.right {
- left: 0
-}
-.carousel-inner>.active.left {
- left: -100%
-}
-.carousel-inner>.active.right {
- left: 100%
-}
-.carousel-control {
- position: absolute;
- top: 0;
- left: 0;
- bottom: 0;
- width: 15%;
- opacity: .5;
- filter: alpha(opacity=50);
- font-size: 20px;
- color: #fff;
- text-align: center
-}
-.carousel-control.left {
- background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0, rgba(0, 0, 0, .0001) 100%);
- background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0, rgba(0, 0, 0, .0001) 100%);
- background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0, rgba(0, 0, 0, .0001) 100%);
- background-repeat: repeat-x;
- filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)
-}
-.carousel-control.right {
- left: auto;
- right: 0;
- background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0, rgba(0, 0, 0, .5) 100%);
- background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0, rgba(0, 0, 0, .5) 100%);
- background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0, rgba(0, 0, 0, .5) 100%);
- background-repeat: repeat-x;
- filter: progid: DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)
-}
-.carousel-control:focus,
-.carousel-control:hover {
- outline: 0;
- color: #fff;
- text-decoration: none;
- opacity: .9;
- filter: alpha(opacity=90)
-}
-.carousel-control .glyphicon-chevron-left,
-.carousel-control .glyphicon-chevron-right,
-.carousel-control .icon-next,
-.carousel-control .icon-prev {
- position: absolute;
- top: 50%;
- z-index: 5;
- display: inline-block
-}
-.carousel-control .glyphicon-chevron-left,
-.carousel-control .icon-prev {
- left: 50%;
- margin-left: -10px
-}
-.carousel-control .glyphicon-chevron-right,
-.carousel-control .icon-next {
- right: 50%;
- margin-right: -10px
-}
-.carousel-control .icon-next,
-.carousel-control .icon-prev {
- width: 20px;
- height: 20px;
- margin-top: -10px;
- font-family: serif
-}
-.carousel-control .icon-prev:before {
- content: '\2039'
-}
-.carousel-control .icon-next:before {
- content: '\203a'
-}
-.carousel-indicators {
- position: absolute;
- bottom: 10px;
- left: 50%;
- z-index: 15;
- width: 60%;
- margin-left: -30%;
- padding-left: 0;
- list-style: none;
- text-align: center
-}
-.carousel-indicators li {
- display: inline-block;
- width: 10px;
- height: 10px;
- margin: 1px;
- text-indent: -999px;
- border: 1px solid #fff;
- border-radius: 10px;
- cursor: pointer;
- background-color: #000\9;
- background-color: transparent
-}
-.carousel-indicators .active {
- margin: 0;
- width: 9pt;
- height: 9pt;
- background-color: #fff
-}
-.carousel-caption {
- position: absolute;
- left: 15%;
- right: 15%;
- bottom: 20px;
- z-index: 10;
- padding-top: 20px;
- padding-bottom: 20px;
- color: #fff;
- text-align: center
-}
-.carousel-caption .btn,
-.text-hide {
- text-shadow: none
-}
-@media screen and (min-width: 768px) {
- .carousel-control .glyphicon-chevron-left,
- .carousel-control .glyphicon-chevron-right,
- .carousel-control .icon-next,
- .carousel-control .icon-prev {
- width: 30px;
- height: 30px;
- margin-top: -15px;
- font-size: 30px
- }
- .carousel-control .glyphicon-chevron-left,
- .carousel-control .icon-prev {
- margin-left: -15px
- }
- .carousel-control .glyphicon-chevron-right,
- .carousel-control .icon-next {
- margin-right: -15px
- }
- .carousel-caption {
- left: 20%;
- right: 20%;
- padding-bottom: 30px
- }
- .carousel-indicators {
- bottom: 20px
- }
-}
-.btn-group-vertical>.btn-group:after,
-.btn-group-vertical>.btn-group:before,
-.btn-toolbar:after,
-.btn-toolbar:before,
-.clearfix:after,
-.clearfix:before,
-.container-fluid:after,
-.container-fluid:before,
-.container:after,
-.container:before,
-.dl-horizontal dd:after,
-.dl-horizontal dd:before,
-.form-horizontal .form-group:after,
-.form-horizontal .form-group:before,
-.modal-footer:after,
-.modal-footer:before,
-.nav:after,
-.nav:before,
-.navbar-collapse:after,
-.navbar-collapse:before,
-.navbar-header:after,
-.navbar-header:before,
-.navbar:after,
-.navbar:before,
-.pager:after,
-.pager:before,
-.panel-body:after,
-.panel-body:before,
-.row:after,
-.row:before {
- content: " ";
- display: table
-}
-.btn-group-vertical>.btn-group:after,
-.btn-toolbar:after,
-.clearfix:after,
-.container-fluid:after,
-.container:after,
-.dl-horizontal dd:after,
-.form-horizontal .form-group:after,
-.modal-footer:after,
-.nav:after,
-.navbar-collapse:after,
-.navbar-header:after,
-.navbar:after,
-.pager:after,
-.panel-body:after,
-.row:after {
- clear: both
-}
-.center-block {
- display: block;
- margin-left: auto;
- margin-right: auto
-}
-.pull-right {
- float: right!important
-}
-.pull-left {
- float: left!important
-}
-.hide {
- display: none!important
-}
-.show {
- display: block!important
-}
-.hidden,
-.visible-lg,
-.visible-lg-block,
-.visible-lg-inline,
-.visible-lg-inline-block,
-.visible-md,
-.visible-md-block,
-.visible-md-inline,
-.visible-md-inline-block,
-.visible-sm,
-.visible-sm-block,
-.visible-sm-inline,
-.visible-sm-inline-block,
-.visible-xs,
-.visible-xs-block,
-.visible-xs-inline,
-.visible-xs-inline-block {
- display: none!important
-}
-.invisible {
- visibility: hidden
-}
-.text-hide {
- font: 0/0 a;
- color: transparent;
- background-color: transparent;
- border: 0
-}
-.hidden {
- visibility: hidden!important
-}
-.affix {
- position: fixed;
- -webkit-transform: translate3d(0, 0, 0);
- transform: translate3d(0, 0, 0)
-}
-@-ms-viewport {
- width: device-width
-}
-@media (max-width: 767px) {
- .visible-xs {
- display: block!important
- }
- table.visible-xs {
- display: table
- }
- tr.visible-xs {
- display: table-row!important
- }
- td.visible-xs,
- th.visible-xs {
- display: table-cell!important
- }
- .visible-xs-block {
- display: block!important
- }
- .visible-xs-inline {
- display: inline!important
- }
- .visible-xs-inline-block {
- display: inline-block!important
- }
-}
-@media (min-width: 768px) and (max-width: 991px) {
- .visible-sm {
- display: block!important
- }
- table.visible-sm {
- display: table
- }
- tr.visible-sm {
- display: table-row!important
- }
- td.visible-sm,
- th.visible-sm {
- display: table-cell!important
- }
- .visible-sm-block {
- display: block!important
- }
- .visible-sm-inline {
- display: inline!important
- }
- .visible-sm-inline-block {
- display: inline-block!important
- }
-}
-@media (min-width: 992px) and (max-width: 1199px) {
- .visible-md {
- display: block!important
- }
- table.visible-md {
- display: table
- }
- tr.visible-md {
- display: table-row!important
- }
- td.visible-md,
- th.visible-md {
- display: table-cell!important
- }
- .visible-md-block {
- display: block!important
- }
- .visible-md-inline {
- display: inline!important
- }
- .visible-md-inline-block {
- display: inline-block!important
- }
-}
-@media (min-width: 1200px) {
- .visible-lg {
- display: block!important
- }
- table.visible-lg {
- display: table
- }
- tr.visible-lg {
- display: table-row!important
- }
- td.visible-lg,
- th.visible-lg {
- display: table-cell!important
- }
- .visible-lg-block {
- display: block!important
- }
- .visible-lg-inline {
- display: inline!important
- }
- .visible-lg-inline-block {
- display: inline-block!important
- }
- .hidden-lg {
- display: none!important
- }
-}
-@media (max-width: 767px) {
- .hidden-xs {
- display: none!important
- }
-}
-@media (min-width: 768px) and (max-width: 991px) {
- .hidden-sm {
- display: none!important
- }
-}
-@media (min-width: 992px) and (max-width: 1199px) {
- .hidden-md {
- display: none!important
- }
-}
-.visible-print {
- display: none!important
-}
-@media print {
- .visible-print {
- display: block!important
- }
- table.visible-print {
- display: table
- }
- tr.visible-print {
- display: table-row!important
- }
- td.visible-print,
- th.visible-print {
- display: table-cell!important
- }
-}
-.visible-print-block {
- display: none!important
-}
-@media print {
- .visible-print-block {
- display: block!important
- }
-}
-.visible-print-inline {
- display: none!important
-}
-@media print {
- .visible-print-inline {
- display: inline!important
- }
-}
-.visible-print-inline-block {
- display: none!important
-}
-@media print {
- .visible-print-inline-block {
- display: inline-block!important
- }
- .hidden-print {
- display: none!important
- }
-} \ No newline at end of file
diff --git a/tools/infra-dashboard/css/dataTables.bootstrap.min.css b/tools/infra-dashboard/css/dataTables.bootstrap.min.css
deleted file mode 100644
index 745f2996..00000000
--- a/tools/infra-dashboard/css/dataTables.bootstrap.min.css
+++ /dev/null
@@ -1 +0,0 @@
-table.dataTable{clear:both;margin-top:6px !important;margin-bottom:6px !important;max-width:none !important}table.dataTable td,table.dataTable th{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}table.dataTable td.dataTables_empty,table.dataTable th.dataTables_empty{text-align:center}table.dataTable.nowrap th,table.dataTable.nowrap td{white-space:nowrap}div.dataTables_wrapper div.dataTables_length label{font-weight:normal;text-align:left;white-space:nowrap}div.dataTables_wrapper div.dataTables_length select{width:75px;display:inline-block}div.dataTables_wrapper div.dataTables_filter{text-align:right}div.dataTables_wrapper div.dataTables_filter label{font-weight:normal;white-space:nowrap;text-align:left}div.dataTables_wrapper div.dataTables_filter input{margin-left:0.5em;display:inline-block;width:auto}div.dataTables_wrapper div.dataTables_info{padding-top:8px;white-space:nowrap}div.dataTables_wrapper div.dataTables_paginate{margin:0;white-space:nowrap;text-align:right}div.dataTables_wrapper div.dataTables_paginate ul.pagination{margin:2px 0;white-space:nowrap}div.dataTables_wrapper div.dataTables_processing{position:absolute;top:50%;left:50%;width:200px;margin-left:-100px;margin-top:-26px;text-align:center;padding:1em 0}table.dataTable thead>tr>th.sorting_asc,table.dataTable thead>tr>th.sorting_desc,table.dataTable thead>tr>th.sorting,table.dataTable thead>tr>td.sorting_asc,table.dataTable thead>tr>td.sorting_desc,table.dataTable thead>tr>td.sorting{padding-right:30px}table.dataTable thead>tr>th:active,table.dataTable thead>tr>td:active{outline:none}table.dataTable thead .sorting,table.dataTable thead .sorting_asc,table.dataTable thead .sorting_desc,table.dataTable thead .sorting_asc_disabled,table.dataTable thead .sorting_desc_disabled{cursor:pointer;position:relative}table.dataTable thead .sorting:after,table.dataTable thead .sorting_asc:after,table.dataTable thead .sorting_desc:after,table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{position:absolute;bottom:8px;right:8px;display:block;font-family:'Glyphicons Halflings';opacity:0.5}table.dataTable thead .sorting:after{opacity:0.2;content:"\e150"}table.dataTable thead .sorting_asc:after{content:"\e155"}table.dataTable thead .sorting_desc:after{content:"\e156"}table.dataTable thead .sorting_asc_disabled:after,table.dataTable thead .sorting_desc_disabled:after{color:#eee}div.dataTables_scrollHead table.dataTable{margin-bottom:0 !important}div.dataTables_scrollBody table{border-top:none;margin-top:0 !important;margin-bottom:0 !important}div.dataTables_scrollBody table thead .sorting:after,div.dataTables_scrollBody table thead .sorting_asc:after,div.dataTables_scrollBody table thead .sorting_desc:after{display:none}div.dataTables_scrollBody table tbody tr:first-child th,div.dataTables_scrollBody table tbody tr:first-child td{border-top:none}div.dataTables_scrollFoot table{margin-top:0 !important;border-top:none}@media screen and (max-width: 767px){div.dataTables_wrapper div.dataTables_length,div.dataTables_wrapper div.dataTables_filter,div.dataTables_wrapper div.dataTables_info,div.dataTables_wrapper div.dataTables_paginate{text-align:center}}table.dataTable.table-condensed>thead>tr>th{padding-right:20px}table.dataTable.table-condensed .sorting:after,table.dataTable.table-condensed .sorting_asc:after,table.dataTable.table-condensed .sorting_desc:after{top:6px;right:6px}table.table-bordered.dataTable{border-collapse:separate !important}table.table-bordered.dataTable th,table.table-bordered.dataTable td{border-left-width:0}table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable th:last-child,table.table-bordered.dataTable td:last-child,table.table-bordered.dataTable td:last-child{border-right-width:0}table.table-bordered.dataTable tbody th,table.table-bordered.dataTable tbody td{border-bottom-width:0}div.dataTables_scrollHead table.table-bordered{border-bottom-width:0}div.table-responsive>div.dataTables_wrapper>div.row{margin:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:first-child{padding-left:0}div.table-responsive>div.dataTables_wrapper>div.row>div[class^="col-"]:last-child{padding-right:0}
diff --git a/tools/infra-dashboard/css/font-awesome.css b/tools/infra-dashboard/css/font-awesome.css
deleted file mode 100644
index 2dcdc220..00000000
--- a/tools/infra-dashboard/css/font-awesome.css
+++ /dev/null
@@ -1,1801 +0,0 @@
-/*!
- * Font Awesome 4.3.0 by @davegandy - http://fontawesome.io - @fontawesome
- * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
- */
-/* FONT PATH
- * -------------------------- */
-@font-face {
- font-family: 'FontAwesome';
- src: url('../fonts/fontawesome-webfont.eot?v=4.3.0');
- src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.3.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.3.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.3.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.3.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.3.0#fontawesomeregular') format('svg');
- font-weight: normal;
- font-style: normal;
-}
-.fa {
- display: inline-block;
- font: normal normal normal 14px/1 FontAwesome;
- font-size: inherit;
- text-rendering: auto;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- transform: translate(0, 0);
-}
-/* makes the font 33% larger relative to the icon container */
-.fa-lg {
- font-size: 1.33333333em;
- line-height: 0.75em;
- vertical-align: -15%;
-}
-.fa-2x {
- font-size: 2em;
-}
-.fa-3x {
- font-size: 3em;
-}
-.fa-4x {
- font-size: 4em;
-}
-.fa-5x {
- font-size: 5em;
-}
-.fa-fw {
- width: 1.28571429em;
- text-align: center;
-}
-.fa-ul {
- padding-left: 0;
- margin-left: 2.14285714em;
- list-style-type: none;
-}
-.fa-ul > li {
- position: relative;
-}
-.fa-li {
- position: absolute;
- left: -2.14285714em;
- width: 2.14285714em;
- top: 0.14285714em;
- text-align: center;
-}
-.fa-li.fa-lg {
- left: -1.85714286em;
-}
-.fa-border {
- padding: .2em .25em .15em;
- border: solid 0.08em #eeeeee;
- border-radius: .1em;
-}
-.pull-right {
- float: right;
-}
-.pull-left {
- float: left;
-}
-.fa.pull-left {
- margin-right: .3em;
-}
-.fa.pull-right {
- margin-left: .3em;
-}
-.fa-spin {
- -webkit-animation: fa-spin 2s infinite linear;
- animation: fa-spin 2s infinite linear;
-}
-.fa-pulse {
- -webkit-animation: fa-spin 1s infinite steps(8);
- animation: fa-spin 1s infinite steps(8);
-}
-@-webkit-keyframes fa-spin {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(359deg);
- transform: rotate(359deg);
- }
-}
-@keyframes fa-spin {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(359deg);
- transform: rotate(359deg);
- }
-}
-.fa-rotate-90 {
- filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1);
- -webkit-transform: rotate(90deg);
- -ms-transform: rotate(90deg);
- transform: rotate(90deg);
-}
-.fa-rotate-180 {
- filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2);
- -webkit-transform: rotate(180deg);
- -ms-transform: rotate(180deg);
- transform: rotate(180deg);
-}
-.fa-rotate-270 {
- filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
- -webkit-transform: rotate(270deg);
- -ms-transform: rotate(270deg);
- transform: rotate(270deg);
-}
-.fa-flip-horizontal {
- filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);
- -webkit-transform: scale(-1, 1);
- -ms-transform: scale(-1, 1);
- transform: scale(-1, 1);
-}
-.fa-flip-vertical {
- filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);
- -webkit-transform: scale(1, -1);
- -ms-transform: scale(1, -1);
- transform: scale(1, -1);
-}
-:root .fa-rotate-90,
-:root .fa-rotate-180,
-:root .fa-rotate-270,
-:root .fa-flip-horizontal,
-:root .fa-flip-vertical {
- filter: none;
-}
-.fa-stack {
- position: relative;
- display: inline-block;
- width: 2em;
- height: 2em;
- line-height: 2em;
- vertical-align: middle;
-}
-.fa-stack-1x,
-.fa-stack-2x {
- position: absolute;
- left: 0;
- width: 100%;
- text-align: center;
-}
-.fa-stack-1x {
- line-height: inherit;
-}
-.fa-stack-2x {
- font-size: 2em;
-}
-.fa-inverse {
- color: #ffffff;
-}
-/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
- readers do not read off random characters that represent icons */
-.fa-glass:before {
- content: "\f000";
-}
-.fa-music:before {
- content: "\f001";
-}
-.fa-search:before {
- content: "\f002";
-}
-.fa-envelope-o:before {
- content: "\f003";
-}
-.fa-heart:before {
- content: "\f004";
-}
-.fa-star:before {
- content: "\f005";
-}
-.fa-star-o:before {
- content: "\f006";
-}
-.fa-user:before {
- content: "\f007";
-}
-.fa-film:before {
- content: "\f008";
-}
-.fa-th-large:before {
- content: "\f009";
-}
-.fa-th:before {
- content: "\f00a";
-}
-.fa-th-list:before {
- content: "\f00b";
-}
-.fa-check:before {
- content: "\f00c";
-}
-.fa-remove:before,
-.fa-close:before,
-.fa-times:before {
- content: "\f00d";
-}
-.fa-search-plus:before {
- content: "\f00e";
-}
-.fa-search-minus:before {
- content: "\f010";
-}
-.fa-power-off:before {
- content: "\f011";
-}
-.fa-signal:before {
- content: "\f012";
-}
-.fa-gear:before,
-.fa-cog:before {
- content: "\f013";
-}
-.fa-trash-o:before {
- content: "\f014";
-}
-.fa-home:before {
- content: "\f015";
-}
-.fa-file-o:before {
- content: "\f016";
-}
-.fa-clock-o:before {
- content: "\f017";
-}
-.fa-road:before {
- content: "\f018";
-}
-.fa-download:before {
- content: "\f019";
-}
-.fa-arrow-circle-o-down:before {
- content: "\f01a";
-}
-.fa-arrow-circle-o-up:before {
- content: "\f01b";
-}
-.fa-inbox:before {
- content: "\f01c";
-}
-.fa-play-circle-o:before {
- content: "\f01d";
-}
-.fa-rotate-right:before,
-.fa-repeat:before {
- content: "\f01e";
-}
-.fa-refresh:before {
- content: "\f021";
-}
-.fa-list-alt:before {
- content: "\f022";
-}
-.fa-lock:before {
- content: "\f023";
-}
-.fa-flag:before {
- content: "\f024";
-}
-.fa-headphones:before {
- content: "\f025";
-}
-.fa-volume-off:before {
- content: "\f026";
-}
-.fa-volume-down:before {
- content: "\f027";
-}
-.fa-volume-up:before {
- content: "\f028";
-}
-.fa-qrcode:before {
- content: "\f029";
-}
-.fa-barcode:before {
- content: "\f02a";
-}
-.fa-tag:before {
- content: "\f02b";
-}
-.fa-tags:before {
- content: "\f02c";
-}
-.fa-book:before {
- content: "\f02d";
-}
-.fa-bookmark:before {
- content: "\f02e";
-}
-.fa-print:before {
- content: "\f02f";
-}
-.fa-camera:before {
- content: "\f030";
-}
-.fa-font:before {
- content: "\f031";
-}
-.fa-bold:before {
- content: "\f032";
-}
-.fa-italic:before {
- content: "\f033";
-}
-.fa-text-height:before {
- content: "\f034";
-}
-.fa-text-width:before {
- content: "\f035";
-}
-.fa-align-left:before {
- content: "\f036";
-}
-.fa-align-center:before {
- content: "\f037";
-}
-.fa-align-right:before {
- content: "\f038";
-}
-.fa-align-justify:before {
- content: "\f039";
-}
-.fa-list:before {
- content: "\f03a";
-}
-.fa-dedent:before,
-.fa-outdent:before {
- content: "\f03b";
-}
-.fa-indent:before {
- content: "\f03c";
-}
-.fa-video-camera:before {
- content: "\f03d";
-}
-.fa-photo:before,
-.fa-image:before,
-.fa-picture-o:before {
- content: "\f03e";
-}
-.fa-pencil:before {
- content: "\f040";
-}
-.fa-map-marker:before {
- content: "\f041";
-}
-.fa-adjust:before {
- content: "\f042";
-}
-.fa-tint:before {
- content: "\f043";
-}
-.fa-edit:before,
-.fa-pencil-square-o:before {
- content: "\f044";
-}
-.fa-share-square-o:before {
- content: "\f045";
-}
-.fa-check-square-o:before {
- content: "\f046";
-}
-.fa-arrows:before {
- content: "\f047";
-}
-.fa-step-backward:before {
- content: "\f048";
-}
-.fa-fast-backward:before {
- content: "\f049";
-}
-.fa-backward:before {
- content: "\f04a";
-}
-.fa-play:before {
- content: "\f04b";
-}
-.fa-pause:before {
- content: "\f04c";
-}
-.fa-stop:before {
- content: "\f04d";
-}
-.fa-forward:before {
- content: "\f04e";
-}
-.fa-fast-forward:before {
- content: "\f050";
-}
-.fa-step-forward:before {
- content: "\f051";
-}
-.fa-eject:before {
- content: "\f052";
-}
-.fa-chevron-left:before {
- content: "\f053";
-}
-.fa-chevron-right:before {
- content: "\f054";
-}
-.fa-plus-circle:before {
- content: "\f055";
-}
-.fa-minus-circle:before {
- content: "\f056";
-}
-.fa-times-circle:before {
- content: "\f057";
-}
-.fa-check-circle:before {
- content: "\f058";
-}
-.fa-question-circle:before {
- content: "\f059";
-}
-.fa-info-circle:before {
- content: "\f05a";
-}
-.fa-crosshairs:before {
- content: "\f05b";
-}
-.fa-times-circle-o:before {
- content: "\f05c";
-}
-.fa-check-circle-o:before {
- content: "\f05d";
-}
-.fa-ban:before {
- content: "\f05e";
-}
-.fa-arrow-left:before {
- content: "\f060";
-}
-.fa-arrow-right:before {
- content: "\f061";
-}
-.fa-arrow-up:before {
- content: "\f062";
-}
-.fa-arrow-down:before {
- content: "\f063";
-}
-.fa-mail-forward:before,
-.fa-share:before {
- content: "\f064";
-}
-.fa-expand:before {
- content: "\f065";
-}
-.fa-compress:before {
- content: "\f066";
-}
-.fa-plus:before {
- content: "\f067";
-}
-.fa-minus:before {
- content: "\f068";
-}
-.fa-asterisk:before {
- content: "\f069";
-}
-.fa-exclamation-circle:before {
- content: "\f06a";
-}
-.fa-gift:before {
- content: "\f06b";
-}
-.fa-leaf:before {
- content: "\f06c";
-}
-.fa-fire:before {
- content: "\f06d";
-}
-.fa-eye:before {
- content: "\f06e";
-}
-.fa-eye-slash:before {
- content: "\f070";
-}
-.fa-warning:before,
-.fa-exclamation-triangle:before {
- content: "\f071";
-}
-.fa-plane:before {
- content: "\f072";
-}
-.fa-calendar:before {
- content: "\f073";
-}
-.fa-random:before {
- content: "\f074";
-}
-.fa-comment:before {
- content: "\f075";
-}
-.fa-magnet:before {
- content: "\f076";
-}
-.fa-chevron-up:before {
- content: "\f077";
-}
-.fa-chevron-down:before {
- content: "\f078";
-}
-.fa-retweet:before {
- content: "\f079";
-}
-.fa-shopping-cart:before {
- content: "\f07a";
-}
-.fa-folder:before {
- content: "\f07b";
-}
-.fa-folder-open:before {
- content: "\f07c";
-}
-.fa-arrows-v:before {
- content: "\f07d";
-}
-.fa-arrows-h:before {
- content: "\f07e";
-}
-.fa-bar-chart-o:before,
-.fa-bar-chart:before {
- content: "\f080";
-}
-.fa-twitter-square:before {
- content: "\f081";
-}
-.fa-facebook-square:before {
- content: "\f082";
-}
-.fa-camera-retro:before {
- content: "\f083";
-}
-.fa-key:before {
- content: "\f084";
-}
-.fa-gears:before,
-.fa-cogs:before {
- content: "\f085";
-}
-.fa-comments:before {
- content: "\f086";
-}
-.fa-thumbs-o-up:before {
- content: "\f087";
-}
-.fa-thumbs-o-down:before {
- content: "\f088";
-}
-.fa-star-half:before {
- content: "\f089";
-}
-.fa-heart-o:before {
- content: "\f08a";
-}
-.fa-sign-out:before {
- content: "\f08b";
-}
-.fa-linkedin-square:before {
- content: "\f08c";
-}
-.fa-thumb-tack:before {
- content: "\f08d";
-}
-.fa-external-link:before {
- content: "\f08e";
-}
-.fa-sign-in:before {
- content: "\f090";
-}
-.fa-trophy:before {
- content: "\f091";
-}
-.fa-github-square:before {
- content: "\f092";
-}
-.fa-upload:before {
- content: "\f093";
-}
-.fa-lemon-o:before {
- content: "\f094";
-}
-.fa-phone:before {
- content: "\f095";
-}
-.fa-square-o:before {
- content: "\f096";
-}
-.fa-bookmark-o:before {
- content: "\f097";
-}
-.fa-phone-square:before {
- content: "\f098";
-}
-.fa-twitter:before {
- content: "\f099";
-}
-.fa-facebook-f:before,
-.fa-facebook:before {
- content: "\f09a";
-}
-.fa-github:before {
- content: "\f09b";
-}
-.fa-unlock:before {
- content: "\f09c";
-}
-.fa-credit-card:before {
- content: "\f09d";
-}
-.fa-rss:before {
- content: "\f09e";
-}
-.fa-hdd-o:before {
- content: "\f0a0";
-}
-.fa-bullhorn:before {
- content: "\f0a1";
-}
-.fa-bell:before {
- content: "\f0f3";
-}
-.fa-certificate:before {
- content: "\f0a3";
-}
-.fa-hand-o-right:before {
- content: "\f0a4";
-}
-.fa-hand-o-left:before {
- content: "\f0a5";
-}
-.fa-hand-o-up:before {
- content: "\f0a6";
-}
-.fa-hand-o-down:before {
- content: "\f0a7";
-}
-.fa-arrow-circle-left:before {
- content: "\f0a8";
-}
-.fa-arrow-circle-right:before {
- content: "\f0a9";
-}
-.fa-arrow-circle-up:before {
- content: "\f0aa";
-}
-.fa-arrow-circle-down:before {
- content: "\f0ab";
-}
-.fa-globe:before {
- content: "\f0ac";
-}
-.fa-wrench:before {
- content: "\f0ad";
-}
-.fa-tasks:before {
- content: "\f0ae";
-}
-.fa-filter:before {
- content: "\f0b0";
-}
-.fa-briefcase:before {
- content: "\f0b1";
-}
-.fa-arrows-alt:before {
- content: "\f0b2";
-}
-.fa-group:before,
-.fa-users:before {
- content: "\f0c0";
-}
-.fa-chain:before,
-.fa-link:before {
- content: "\f0c1";
-}
-.fa-cloud:before {
- content: "\f0c2";
-}
-.fa-flask:before {
- content: "\f0c3";
-}
-.fa-cut:before,
-.fa-scissors:before {
- content: "\f0c4";
-}
-.fa-copy:before,
-.fa-files-o:before {
- content: "\f0c5";
-}
-.fa-paperclip:before {
- content: "\f0c6";
-}
-.fa-save:before,
-.fa-floppy-o:before {
- content: "\f0c7";
-}
-.fa-square:before {
- content: "\f0c8";
-}
-.fa-navicon:before,
-.fa-reorder:before,
-.fa-bars:before {
- content: "\f0c9";
-}
-.fa-list-ul:before {
- content: "\f0ca";
-}
-.fa-list-ol:before {
- content: "\f0cb";
-}
-.fa-strikethrough:before {
- content: "\f0cc";
-}
-.fa-underline:before {
- content: "\f0cd";
-}
-.fa-table:before {
- content: "\f0ce";
-}
-.fa-magic:before {
- content: "\f0d0";
-}
-.fa-truck:before {
- content: "\f0d1";
-}
-.fa-pinterest:before {
- content: "\f0d2";
-}
-.fa-pinterest-square:before {
- content: "\f0d3";
-}
-.fa-google-plus-square:before {
- content: "\f0d4";
-}
-.fa-google-plus:before {
- content: "\f0d5";
-}
-.fa-money:before {
- content: "\f0d6";
-}
-.fa-caret-down:before {
- content: "\f0d7";
-}
-.fa-caret-up:before {
- content: "\f0d8";
-}
-.fa-caret-left:before {
- content: "\f0d9";
-}
-.fa-caret-right:before {
- content: "\f0da";
-}
-.fa-columns:before {
- content: "\f0db";
-}
-.fa-unsorted:before,
-.fa-sort:before {
- content: "\f0dc";
-}
-.fa-sort-down:before,
-.fa-sort-desc:before {
- content: "\f0dd";
-}
-.fa-sort-up:before,
-.fa-sort-asc:before {
- content: "\f0de";
-}
-.fa-envelope:before {
- content: "\f0e0";
-}
-.fa-linkedin:before {
- content: "\f0e1";
-}
-.fa-rotate-left:before,
-.fa-undo:before {
- content: "\f0e2";
-}
-.fa-legal:before,
-.fa-gavel:before {
- content: "\f0e3";
-}
-.fa-dashboard:before,
-.fa-tachometer:before {
- content: "\f0e4";
-}
-.fa-comment-o:before {
- content: "\f0e5";
-}
-.fa-comments-o:before {
- content: "\f0e6";
-}
-.fa-flash:before,
-.fa-bolt:before {
- content: "\f0e7";
-}
-.fa-sitemap:before {
- content: "\f0e8";
-}
-.fa-umbrella:before {
- content: "\f0e9";
-}
-.fa-paste:before,
-.fa-clipboard:before {
- content: "\f0ea";
-}
-.fa-lightbulb-o:before {
- content: "\f0eb";
-}
-.fa-exchange:before {
- content: "\f0ec";
-}
-.fa-cloud-download:before {
- content: "\f0ed";
-}
-.fa-cloud-upload:before {
- content: "\f0ee";
-}
-.fa-user-md:before {
- content: "\f0f0";
-}
-.fa-stethoscope:before {
- content: "\f0f1";
-}
-.fa-suitcase:before {
- content: "\f0f2";
-}
-.fa-bell-o:before {
- content: "\f0a2";
-}
-.fa-coffee:before {
- content: "\f0f4";
-}
-.fa-cutlery:before {
- content: "\f0f5";
-}
-.fa-file-text-o:before {
- content: "\f0f6";
-}
-.fa-building-o:before {
- content: "\f0f7";
-}
-.fa-hospital-o:before {
- content: "\f0f8";
-}
-.fa-ambulance:before {
- content: "\f0f9";
-}
-.fa-medkit:before {
- content: "\f0fa";
-}
-.fa-fighter-jet:before {
- content: "\f0fb";
-}
-.fa-beer:before {
- content: "\f0fc";
-}
-.fa-h-square:before {
- content: "\f0fd";
-}
-.fa-plus-square:before {
- content: "\f0fe";
-}
-.fa-angle-double-left:before {
- content: "\f100";
-}
-.fa-angle-double-right:before {
- content: "\f101";
-}
-.fa-angle-double-up:before {
- content: "\f102";
-}
-.fa-angle-double-down:before {
- content: "\f103";
-}
-.fa-angle-left:before {
- content: "\f104";
-}
-.fa-angle-right:before {
- content: "\f105";
-}
-.fa-angle-up:before {
- content: "\f106";
-}
-.fa-angle-down:before {
- content: "\f107";
-}
-.fa-desktop:before {
- content: "\f108";
-}
-.fa-laptop:before {
- content: "\f109";
-}
-.fa-tablet:before {
- content: "\f10a";
-}
-.fa-mobile-phone:before,
-.fa-mobile:before {
- content: "\f10b";
-}
-.fa-circle-o:before {
- content: "\f10c";
-}
-.fa-quote-left:before {
- content: "\f10d";
-}
-.fa-quote-right:before {
- content: "\f10e";
-}
-.fa-spinner:before {
- content: "\f110";
-}
-.fa-circle:before {
- content: "\f111";
-}
-.fa-mail-reply:before,
-.fa-reply:before {
- content: "\f112";
-}
-.fa-github-alt:before {
- content: "\f113";
-}
-.fa-folder-o:before {
- content: "\f114";
-}
-.fa-folder-open-o:before {
- content: "\f115";
-}
-.fa-smile-o:before {
- content: "\f118";
-}
-.fa-frown-o:before {
- content: "\f119";
-}
-.fa-meh-o:before {
- content: "\f11a";
-}
-.fa-gamepad:before {
- content: "\f11b";
-}
-.fa-keyboard-o:before {
- content: "\f11c";
-}
-.fa-flag-o:before {
- content: "\f11d";
-}
-.fa-flag-checkered:before {
- content: "\f11e";
-}
-.fa-terminal:before {
- content: "\f120";
-}
-.fa-code:before {
- content: "\f121";
-}
-.fa-mail-reply-all:before,
-.fa-reply-all:before {
- content: "\f122";
-}
-.fa-star-half-empty:before,
-.fa-star-half-full:before,
-.fa-star-half-o:before {
- content: "\f123";
-}
-.fa-location-arrow:before {
- content: "\f124";
-}
-.fa-crop:before {
- content: "\f125";
-}
-.fa-code-fork:before {
- content: "\f126";
-}
-.fa-unlink:before,
-.fa-chain-broken:before {
- content: "\f127";
-}
-.fa-question:before {
- content: "\f128";
-}
-.fa-info:before {
- content: "\f129";
-}
-.fa-exclamation:before {
- content: "\f12a";
-}
-.fa-superscript:before {
- content: "\f12b";
-}
-.fa-subscript:before {
- content: "\f12c";
-}
-.fa-eraser:before {
- content: "\f12d";
-}
-.fa-puzzle-piece:before {
- content: "\f12e";
-}
-.fa-microphone:before {
- content: "\f130";
-}
-.fa-microphone-slash:before {
- content: "\f131";
-}
-.fa-shield:before {
- content: "\f132";
-}
-.fa-calendar-o:before {
- content: "\f133";
-}
-.fa-fire-extinguisher:before {
- content: "\f134";
-}
-.fa-rocket:before {
- content: "\f135";
-}
-.fa-maxcdn:before {
- content: "\f136";
-}
-.fa-chevron-circle-left:before {
- content: "\f137";
-}
-.fa-chevron-circle-right:before {
- content: "\f138";
-}
-.fa-chevron-circle-up:before {
- content: "\f139";
-}
-.fa-chevron-circle-down:before {
- content: "\f13a";
-}
-.fa-html5:before {
- content: "\f13b";
-}
-.fa-css3:before {
- content: "\f13c";
-}
-.fa-anchor:before {
- content: "\f13d";
-}
-.fa-unlock-alt:before {
- content: "\f13e";
-}
-.fa-bullseye:before {
- content: "\f140";
-}
-.fa-ellipsis-h:before {
- content: "\f141";
-}
-.fa-ellipsis-v:before {
- content: "\f142";
-}
-.fa-rss-square:before {
- content: "\f143";
-}
-.fa-play-circle:before {
- content: "\f144";
-}
-.fa-ticket:before {
- content: "\f145";
-}
-.fa-minus-square:before {
- content: "\f146";
-}
-.fa-minus-square-o:before {
- content: "\f147";
-}
-.fa-level-up:before {
- content: "\f148";
-}
-.fa-level-down:before {
- content: "\f149";
-}
-.fa-check-square:before {
- content: "\f14a";
-}
-.fa-pencil-square:before {
- content: "\f14b";
-}
-.fa-external-link-square:before {
- content: "\f14c";
-}
-.fa-share-square:before {
- content: "\f14d";
-}
-.fa-compass:before {
- content: "\f14e";
-}
-.fa-toggle-down:before,
-.fa-caret-square-o-down:before {
- content: "\f150";
-}
-.fa-toggle-up:before,
-.fa-caret-square-o-up:before {
- content: "\f151";
-}
-.fa-toggle-right:before,
-.fa-caret-square-o-right:before {
- content: "\f152";
-}
-.fa-euro:before,
-.fa-eur:before {
- content: "\f153";
-}
-.fa-gbp:before {
- content: "\f154";
-}
-.fa-dollar:before,
-.fa-usd:before {
- content: "\f155";
-}
-.fa-rupee:before,
-.fa-inr:before {
- content: "\f156";
-}
-.fa-cny:before,
-.fa-rmb:before,
-.fa-yen:before,
-.fa-jpy:before {
- content: "\f157";
-}
-.fa-ruble:before,
-.fa-rouble:before,
-.fa-rub:before {
- content: "\f158";
-}
-.fa-won:before,
-.fa-krw:before {
- content: "\f159";
-}
-.fa-bitcoin:before,
-.fa-btc:before {
- content: "\f15a";
-}
-.fa-file:before {
- content: "\f15b";
-}
-.fa-file-text:before {
- content: "\f15c";
-}
-.fa-sort-alpha-asc:before {
- content: "\f15d";
-}
-.fa-sort-alpha-desc:before {
- content: "\f15e";
-}
-.fa-sort-amount-asc:before {
- content: "\f160";
-}
-.fa-sort-amount-desc:before {
- content: "\f161";
-}
-.fa-sort-numeric-asc:before {
- content: "\f162";
-}
-.fa-sort-numeric-desc:before {
- content: "\f163";
-}
-.fa-thumbs-up:before {
- content: "\f164";
-}
-.fa-thumbs-down:before {
- content: "\f165";
-}
-.fa-youtube-square:before {
- content: "\f166";
-}
-.fa-youtube:before {
- content: "\f167";
-}
-.fa-xing:before {
- content: "\f168";
-}
-.fa-xing-square:before {
- content: "\f169";
-}
-.fa-youtube-play:before {
- content: "\f16a";
-}
-.fa-dropbox:before {
- content: "\f16b";
-}
-.fa-stack-overflow:before {
- content: "\f16c";
-}
-.fa-instagram:before {
- content: "\f16d";
-}
-.fa-flickr:before {
- content: "\f16e";
-}
-.fa-adn:before {
- content: "\f170";
-}
-.fa-bitbucket:before {
- content: "\f171";
-}
-.fa-bitbucket-square:before {
- content: "\f172";
-}
-.fa-tumblr:before {
- content: "\f173";
-}
-.fa-tumblr-square:before {
- content: "\f174";
-}
-.fa-long-arrow-down:before {
- content: "\f175";
-}
-.fa-long-arrow-up:before {
- content: "\f176";
-}
-.fa-long-arrow-left:before {
- content: "\f177";
-}
-.fa-long-arrow-right:before {
- content: "\f178";
-}
-.fa-apple:before {
- content: "\f179";
-}
-.fa-windows:before {
- content: "\f17a";
-}
-.fa-android:before {
- content: "\f17b";
-}
-.fa-linux:before {
- content: "\f17c";
-}
-.fa-dribbble:before {
- content: "\f17d";
-}
-.fa-skype:before {
- content: "\f17e";
-}
-.fa-foursquare:before {
- content: "\f180";
-}
-.fa-trello:before {
- content: "\f181";
-}
-.fa-female:before {
- content: "\f182";
-}
-.fa-male:before {
- content: "\f183";
-}
-.fa-gittip:before,
-.fa-gratipay:before {
- content: "\f184";
-}
-.fa-sun-o:before {
- content: "\f185";
-}
-.fa-moon-o:before {
- content: "\f186";
-}
-.fa-archive:before {
- content: "\f187";
-}
-.fa-bug:before {
- content: "\f188";
-}
-.fa-vk:before {
- content: "\f189";
-}
-.fa-weibo:before {
- content: "\f18a";
-}
-.fa-renren:before {
- content: "\f18b";
-}
-.fa-pagelines:before {
- content: "\f18c";
-}
-.fa-stack-exchange:before {
- content: "\f18d";
-}
-.fa-arrow-circle-o-right:before {
- content: "\f18e";
-}
-.fa-arrow-circle-o-left:before {
- content: "\f190";
-}
-.fa-toggle-left:before,
-.fa-caret-square-o-left:before {
- content: "\f191";
-}
-.fa-dot-circle-o:before {
- content: "\f192";
-}
-.fa-wheelchair:before {
- content: "\f193";
-}
-.fa-vimeo-square:before {
- content: "\f194";
-}
-.fa-turkish-lira:before,
-.fa-try:before {
- content: "\f195";
-}
-.fa-plus-square-o:before {
- content: "\f196";
-}
-.fa-space-shuttle:before {
- content: "\f197";
-}
-.fa-slack:before {
- content: "\f198";
-}
-.fa-envelope-square:before {
- content: "\f199";
-}
-.fa-wordpress:before {
- content: "\f19a";
-}
-.fa-openid:before {
- content: "\f19b";
-}
-.fa-institution:before,
-.fa-bank:before,
-.fa-university:before {
- content: "\f19c";
-}
-.fa-mortar-board:before,
-.fa-graduation-cap:before {
- content: "\f19d";
-}
-.fa-yahoo:before {
- content: "\f19e";
-}
-.fa-google:before {
- content: "\f1a0";
-}
-.fa-reddit:before {
- content: "\f1a1";
-}
-.fa-reddit-square:before {
- content: "\f1a2";
-}
-.fa-stumbleupon-circle:before {
- content: "\f1a3";
-}
-.fa-stumbleupon:before {
- content: "\f1a4";
-}
-.fa-delicious:before {
- content: "\f1a5";
-}
-.fa-digg:before {
- content: "\f1a6";
-}
-.fa-pied-piper:before {
- content: "\f1a7";
-}
-.fa-pied-piper-alt:before {
- content: "\f1a8";
-}
-.fa-drupal:before {
- content: "\f1a9";
-}
-.fa-joomla:before {
- content: "\f1aa";
-}
-.fa-language:before {
- content: "\f1ab";
-}
-.fa-fax:before {
- content: "\f1ac";
-}
-.fa-building:before {
- content: "\f1ad";
-}
-.fa-child:before {
- content: "\f1ae";
-}
-.fa-paw:before {
- content: "\f1b0";
-}
-.fa-spoon:before {
- content: "\f1b1";
-}
-.fa-cube:before {
- content: "\f1b2";
-}
-.fa-cubes:before {
- content: "\f1b3";
-}
-.fa-behance:before {
- content: "\f1b4";
-}
-.fa-behance-square:before {
- content: "\f1b5";
-}
-.fa-steam:before {
- content: "\f1b6";
-}
-.fa-steam-square:before {
- content: "\f1b7";
-}
-.fa-recycle:before {
- content: "\f1b8";
-}
-.fa-automobile:before,
-.fa-car:before {
- content: "\f1b9";
-}
-.fa-cab:before,
-.fa-taxi:before {
- content: "\f1ba";
-}
-.fa-tree:before {
- content: "\f1bb";
-}
-.fa-spotify:before {
- content: "\f1bc";
-}
-.fa-deviantart:before {
- content: "\f1bd";
-}
-.fa-soundcloud:before {
- content: "\f1be";
-}
-.fa-database:before {
- content: "\f1c0";
-}
-.fa-file-pdf-o:before {
- content: "\f1c1";
-}
-.fa-file-word-o:before {
- content: "\f1c2";
-}
-.fa-file-excel-o:before {
- content: "\f1c3";
-}
-.fa-file-powerpoint-o:before {
- content: "\f1c4";
-}
-.fa-file-photo-o:before,
-.fa-file-picture-o:before,
-.fa-file-image-o:before {
- content: "\f1c5";
-}
-.fa-file-zip-o:before,
-.fa-file-archive-o:before {
- content: "\f1c6";
-}
-.fa-file-sound-o:before,
-.fa-file-audio-o:before {
- content: "\f1c7";
-}
-.fa-file-movie-o:before,
-.fa-file-video-o:before {
- content: "\f1c8";
-}
-.fa-file-code-o:before {
- content: "\f1c9";
-}
-.fa-vine:before {
- content: "\f1ca";
-}
-.fa-codepen:before {
- content: "\f1cb";
-}
-.fa-jsfiddle:before {
- content: "\f1cc";
-}
-.fa-life-bouy:before,
-.fa-life-buoy:before,
-.fa-life-saver:before,
-.fa-support:before,
-.fa-life-ring:before {
- content: "\f1cd";
-}
-.fa-circle-o-notch:before {
- content: "\f1ce";
-}
-.fa-ra:before,
-.fa-rebel:before {
- content: "\f1d0";
-}
-.fa-ge:before,
-.fa-empire:before {
- content: "\f1d1";
-}
-.fa-git-square:before {
- content: "\f1d2";
-}
-.fa-git:before {
- content: "\f1d3";
-}
-.fa-hacker-news:before {
- content: "\f1d4";
-}
-.fa-tencent-weibo:before {
- content: "\f1d5";
-}
-.fa-qq:before {
- content: "\f1d6";
-}
-.fa-wechat:before,
-.fa-weixin:before {
- content: "\f1d7";
-}
-.fa-send:before,
-.fa-paper-plane:before {
- content: "\f1d8";
-}
-.fa-send-o:before,
-.fa-paper-plane-o:before {
- content: "\f1d9";
-}
-.fa-history:before {
- content: "\f1da";
-}
-.fa-genderless:before,
-.fa-circle-thin:before {
- content: "\f1db";
-}
-.fa-header:before {
- content: "\f1dc";
-}
-.fa-paragraph:before {
- content: "\f1dd";
-}
-.fa-sliders:before {
- content: "\f1de";
-}
-.fa-share-alt:before {
- content: "\f1e0";
-}
-.fa-share-alt-square:before {
- content: "\f1e1";
-}
-.fa-bomb:before {
- content: "\f1e2";
-}
-.fa-soccer-ball-o:before,
-.fa-futbol-o:before {
- content: "\f1e3";
-}
-.fa-tty:before {
- content: "\f1e4";
-}
-.fa-binoculars:before {
- content: "\f1e5";
-}
-.fa-plug:before {
- content: "\f1e6";
-}
-.fa-slideshare:before {
- content: "\f1e7";
-}
-.fa-twitch:before {
- content: "\f1e8";
-}
-.fa-yelp:before {
- content: "\f1e9";
-}
-.fa-newspaper-o:before {
- content: "\f1ea";
-}
-.fa-wifi:before {
- content: "\f1eb";
-}
-.fa-calculator:before {
- content: "\f1ec";
-}
-.fa-paypal:before {
- content: "\f1ed";
-}
-.fa-google-wallet:before {
- content: "\f1ee";
-}
-.fa-cc-visa:before {
- content: "\f1f0";
-}
-.fa-cc-mastercard:before {
- content: "\f1f1";
-}
-.fa-cc-discover:before {
- content: "\f1f2";
-}
-.fa-cc-amex:before {
- content: "\f1f3";
-}
-.fa-cc-paypal:before {
- content: "\f1f4";
-}
-.fa-cc-stripe:before {
- content: "\f1f5";
-}
-.fa-bell-slash:before {
- content: "\f1f6";
-}
-.fa-bell-slash-o:before {
- content: "\f1f7";
-}
-.fa-trash:before {
- content: "\f1f8";
-}
-.fa-copyright:before {
- content: "\f1f9";
-}
-.fa-at:before {
- content: "\f1fa";
-}
-.fa-eyedropper:before {
- content: "\f1fb";
-}
-.fa-paint-brush:before {
- content: "\f1fc";
-}
-.fa-birthday-cake:before {
- content: "\f1fd";
-}
-.fa-area-chart:before {
- content: "\f1fe";
-}
-.fa-pie-chart:before {
- content: "\f200";
-}
-.fa-line-chart:before {
- content: "\f201";
-}
-.fa-lastfm:before {
- content: "\f202";
-}
-.fa-lastfm-square:before {
- content: "\f203";
-}
-.fa-toggle-off:before {
- content: "\f204";
-}
-.fa-toggle-on:before {
- content: "\f205";
-}
-.fa-bicycle:before {
- content: "\f206";
-}
-.fa-bus:before {
- content: "\f207";
-}
-.fa-ioxhost:before {
- content: "\f208";
-}
-.fa-angellist:before {
- content: "\f209";
-}
-.fa-cc:before {
- content: "\f20a";
-}
-.fa-shekel:before,
-.fa-sheqel:before,
-.fa-ils:before {
- content: "\f20b";
-}
-.fa-meanpath:before {
- content: "\f20c";
-}
-.fa-buysellads:before {
- content: "\f20d";
-}
-.fa-connectdevelop:before {
- content: "\f20e";
-}
-.fa-dashcube:before {
- content: "\f210";
-}
-.fa-forumbee:before {
- content: "\f211";
-}
-.fa-leanpub:before {
- content: "\f212";
-}
-.fa-sellsy:before {
- content: "\f213";
-}
-.fa-shirtsinbulk:before {
- content: "\f214";
-}
-.fa-simplybuilt:before {
- content: "\f215";
-}
-.fa-skyatlas:before {
- content: "\f216";
-}
-.fa-cart-plus:before {
- content: "\f217";
-}
-.fa-cart-arrow-down:before {
- content: "\f218";
-}
-.fa-diamond:before {
- content: "\f219";
-}
-.fa-ship:before {
- content: "\f21a";
-}
-.fa-user-secret:before {
- content: "\f21b";
-}
-.fa-motorcycle:before {
- content: "\f21c";
-}
-.fa-street-view:before {
- content: "\f21d";
-}
-.fa-heartbeat:before {
- content: "\f21e";
-}
-.fa-venus:before {
- content: "\f221";
-}
-.fa-mars:before {
- content: "\f222";
-}
-.fa-mercury:before {
- content: "\f223";
-}
-.fa-transgender:before {
- content: "\f224";
-}
-.fa-transgender-alt:before {
- content: "\f225";
-}
-.fa-venus-double:before {
- content: "\f226";
-}
-.fa-mars-double:before {
- content: "\f227";
-}
-.fa-venus-mars:before {
- content: "\f228";
-}
-.fa-mars-stroke:before {
- content: "\f229";
-}
-.fa-mars-stroke-v:before {
- content: "\f22a";
-}
-.fa-mars-stroke-h:before {
- content: "\f22b";
-}
-.fa-neuter:before {
- content: "\f22c";
-}
-.fa-facebook-official:before {
- content: "\f230";
-}
-.fa-pinterest-p:before {
- content: "\f231";
-}
-.fa-whatsapp:before {
- content: "\f232";
-}
-.fa-server:before {
- content: "\f233";
-}
-.fa-user-plus:before {
- content: "\f234";
-}
-.fa-user-times:before {
- content: "\f235";
-}
-.fa-hotel:before,
-.fa-bed:before {
- content: "\f236";
-}
-.fa-viacoin:before {
- content: "\f237";
-}
-.fa-train:before {
- content: "\f238";
-}
-.fa-subway:before {
- content: "\f239";
-}
-.fa-medium:before {
- content: "\f23a";
-}
diff --git a/tools/infra-dashboard/css/fullcalendar.css b/tools/infra-dashboard/css/fullcalendar.css
deleted file mode 100644
index 89684cb3..00000000
--- a/tools/infra-dashboard/css/fullcalendar.css
+++ /dev/null
@@ -1,1260 +0,0 @@
-/*!
- * FullCalendar v2.7.2 Stylesheet
- * Docs & License: http://fullcalendar.io/
- * (c) 2016 Adam Shaw
- */
-
-
-.fc {
- direction: ltr;
- text-align: left;
-}
-
-.fc-rtl {
- text-align: right;
-}
-
-body .fc { /* extra precedence to overcome jqui */
- font-size: 1em;
-}
-
-
-/* Colors
---------------------------------------------------------------------------------------------------*/
-
-.fc-unthemed th,
-.fc-unthemed td,
-.fc-unthemed thead,
-.fc-unthemed tbody,
-.fc-unthemed .fc-divider,
-.fc-unthemed .fc-row,
-.fc-unthemed .fc-content, /* for gutter border */
-.fc-unthemed .fc-popover {
- border-color: #ddd;
-}
-
-.fc-unthemed .fc-popover {
- background-color: #fff;
-}
-
-.fc-unthemed .fc-divider,
-.fc-unthemed .fc-popover .fc-header {
- background: #eee;
-}
-
-.fc-unthemed .fc-popover .fc-header .fc-close {
- color: #666;
-}
-
-.fc-unthemed .fc-today {
- background: #fcf8e3;
-}
-
-.fc-highlight { /* when user is selecting cells */
- background: #bce8f1;
- opacity: .3;
- filter: alpha(opacity=30); /* for IE */
-}
-
-.fc-bgevent { /* default look for background events */
- background: rgb(143, 223, 130);
- opacity: .3;
- filter: alpha(opacity=30); /* for IE */
-}
-
-.fc-nonbusiness { /* default look for non-business-hours areas */
- /* will inherit .fc-bgevent's styles */
- background: #d7d7d7;
-}
-
-
-/* Icons (inline elements with styled text that mock arrow icons)
---------------------------------------------------------------------------------------------------*/
-
-.fc-icon {
- display: inline-block;
- height: 1em;
- line-height: 1em;
- font-size: 1em;
- text-align: center;
- overflow: hidden;
- font-family: "Courier New", Courier, monospace;
-
- /* don't allow browser text-selection */
- -webkit-touch-callout: none;
- -webkit-user-select: none;
- -khtml-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- }
-
-/*
-Acceptable font-family overrides for individual icons:
- "Arial", sans-serif
- "Times New Roman", serif
-
-NOTE: use percentage font sizes or else old IE chokes
-*/
-
-.fc-icon:after {
- position: relative;
-}
-
-.fc-icon-left-single-arrow:after {
- content: "\02039";
- font-weight: bold;
- font-size: 200%;
- top: -7%;
-}
-
-.fc-icon-right-single-arrow:after {
- content: "\0203A";
- font-weight: bold;
- font-size: 200%;
- top: -7%;
-}
-
-.fc-icon-left-double-arrow:after {
- content: "\000AB";
- font-size: 160%;
- top: -7%;
-}
-
-.fc-icon-right-double-arrow:after {
- content: "\000BB";
- font-size: 160%;
- top: -7%;
-}
-
-.fc-icon-left-triangle:after {
- content: "\25C4";
- font-size: 125%;
- top: 3%;
-}
-
-.fc-icon-right-triangle:after {
- content: "\25BA";
- font-size: 125%;
- top: 3%;
-}
-
-.fc-icon-down-triangle:after {
- content: "\25BC";
- font-size: 125%;
- top: 2%;
-}
-
-.fc-icon-x:after {
- content: "\000D7";
- font-size: 200%;
- top: 6%;
-}
-
-
-/* Buttons (styled <button> tags, normalized to work cross-browser)
---------------------------------------------------------------------------------------------------*/
-
-.fc button {
- /* force height to include the border and padding */
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- box-sizing: border-box;
-
- /* dimensions */
- margin: 0;
- height: 2.1em;
- padding: 0 .6em;
-
- /* text & cursor */
- font-size: 1em; /* normalize */
- white-space: nowrap;
- cursor: pointer;
-}
-
-/* Firefox has an annoying inner border */
-.fc button::-moz-focus-inner { margin: 0; padding: 0; }
-
-.fc-state-default { /* non-theme */
- border: 1px solid;
-}
-
-.fc-state-default.fc-corner-left { /* non-theme */
- border-top-left-radius: 4px;
- border-bottom-left-radius: 4px;
-}
-
-.fc-state-default.fc-corner-right { /* non-theme */
- border-top-right-radius: 4px;
- border-bottom-right-radius: 4px;
-}
-
-/* icons in buttons */
-
-.fc button .fc-icon { /* non-theme */
- position: relative;
- top: -0.05em; /* seems to be a good adjustment across browsers */
- margin: 0 .2em;
- vertical-align: middle;
-}
-
-/*
- button states
- borrowed from twitter bootstrap (http://twitter.github.com/bootstrap/)
-*/
-
-.fc-state-default {
- background-color: #f5f5f5;
- background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
- background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
- background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
- background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
- background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
- background-repeat: repeat-x;
- border-color: #e6e6e6 #e6e6e6 #bfbfbf;
- border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
- color: #333;
- text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
- box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
-}
-
-.fc-state-hover,
-.fc-state-down,
-.fc-state-active,
-.fc-state-disabled {
- color: #333333;
- background-color: #e6e6e6;
-}
-
-.fc-state-hover {
- color: #333333;
- text-decoration: none;
- background-position: 0 -15px;
- -webkit-transition: background-position 0.1s linear;
- -moz-transition: background-position 0.1s linear;
- -o-transition: background-position 0.1s linear;
- transition: background-position 0.1s linear;
-}
-
-.fc-state-down,
-.fc-state-active {
- background-color: #cccccc;
- background-image: none;
- box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
-}
-
-.fc-state-disabled {
- cursor: default;
- background-image: none;
- opacity: 0.65;
- filter: alpha(opacity=65);
- box-shadow: none;
-}
-
-
-/* Buttons Groups
---------------------------------------------------------------------------------------------------*/
-
-.fc-button-group {
- display: inline-block;
-}
-
-/*
-every button that is not first in a button group should scootch over one pixel and cover the
-previous button's border...
-*/
-
-.fc .fc-button-group > * { /* extra precedence b/c buttons have margin set to zero */
- float: left;
- margin: 0 0 0 -1px;
-}
-
-.fc .fc-button-group > :first-child { /* same */
- margin-left: 0;
-}
-
-
-/* Popover
---------------------------------------------------------------------------------------------------*/
-
-.fc-popover {
- position: absolute;
- box-shadow: 0 2px 6px rgba(0,0,0,.15);
-}
-
-.fc-popover .fc-header { /* TODO: be more consistent with fc-head/fc-body */
- padding: 2px 4px;
-}
-
-.fc-popover .fc-header .fc-title {
- margin: 0 2px;
-}
-
-.fc-popover .fc-header .fc-close {
- cursor: pointer;
-}
-
-.fc-ltr .fc-popover .fc-header .fc-title,
-.fc-rtl .fc-popover .fc-header .fc-close {
- float: left;
-}
-
-.fc-rtl .fc-popover .fc-header .fc-title,
-.fc-ltr .fc-popover .fc-header .fc-close {
- float: right;
-}
-
-/* unthemed */
-
-.fc-unthemed .fc-popover {
- border-width: 1px;
- border-style: solid;
-}
-
-.fc-unthemed .fc-popover .fc-header .fc-close {
- font-size: .9em;
- margin-top: 2px;
-}
-
-/* jqui themed */
-
-.fc-popover > .ui-widget-header + .ui-widget-content {
- border-top: 0; /* where they meet, let the header have the border */
-}
-
-
-/* Misc Reusable Components
---------------------------------------------------------------------------------------------------*/
-
-.fc-divider {
- border-style: solid;
- border-width: 1px;
-}
-
-hr.fc-divider {
- height: 0;
- margin: 0;
- padding: 0 0 2px; /* height is unreliable across browsers, so use padding */
- border-width: 1px 0;
-}
-
-.fc-clear {
- clear: both;
-}
-
-.fc-bg,
-.fc-bgevent-skeleton,
-.fc-highlight-skeleton,
-.fc-helper-skeleton {
- /* these element should always cling to top-left/right corners */
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
-}
-
-.fc-bg {
- bottom: 0; /* strech bg to bottom edge */
-}
-
-.fc-bg table {
- height: 100%; /* strech bg to bottom edge */
-}
-
-
-/* Tables
---------------------------------------------------------------------------------------------------*/
-
-.fc table {
- width: 100%;
- table-layout: fixed;
- border-collapse: collapse;
- border-spacing: 0;
- font-size: 1em; /* normalize cross-browser */
-}
-
-.fc th {
- text-align: center;
-}
-
-.fc th,
-.fc td {
- border-style: solid;
- border-width: 1px;
- padding: 0;
- vertical-align: top;
-}
-
-.fc td.fc-today {
- border-style: double; /* overcome neighboring borders */
-}
-
-
-/* Fake Table Rows
---------------------------------------------------------------------------------------------------*/
-
-.fc .fc-row { /* extra precedence to overcome themes w/ .ui-widget-content forcing a 1px border */
- /* no visible border by default. but make available if need be (scrollbar width compensation) */
- border-style: solid;
- border-width: 0;
-}
-
-.fc-row table {
- /* don't put left/right border on anything within a fake row.
- the outer tbody will worry about this */
- border-left: 0 hidden transparent;
- border-right: 0 hidden transparent;
-
- /* no bottom borders on rows */
- border-bottom: 0 hidden transparent;
-}
-
-.fc-row:first-child table {
- border-top: 0 hidden transparent; /* no top border on first row */
-}
-
-
-/* Day Row (used within the header and the DayGrid)
---------------------------------------------------------------------------------------------------*/
-
-.fc-row {
- position: relative;
-}
-
-.fc-row .fc-bg {
- z-index: 1;
-}
-
-/* highlighting cells & background event skeleton */
-
-.fc-row .fc-bgevent-skeleton,
-.fc-row .fc-highlight-skeleton {
- bottom: 0; /* stretch skeleton to bottom of row */
-}
-
-.fc-row .fc-bgevent-skeleton table,
-.fc-row .fc-highlight-skeleton table {
- height: 100%; /* stretch skeleton to bottom of row */
-}
-
-.fc-row .fc-highlight-skeleton td,
-.fc-row .fc-bgevent-skeleton td {
- border-color: transparent;
-}
-
-.fc-row .fc-bgevent-skeleton {
- z-index: 2;
-
-}
-
-.fc-row .fc-highlight-skeleton {
- z-index: 3;
-}
-
-/*
-row content (which contains day/week numbers and events) as well as "helper" (which contains
-temporary rendered events).
-*/
-
-.fc-row .fc-content-skeleton {
- position: relative;
- z-index: 4;
- padding-bottom: 2px; /* matches the space above the events */
-}
-
-.fc-row .fc-helper-skeleton {
- z-index: 5;
-}
-
-.fc-row .fc-content-skeleton td,
-.fc-row .fc-helper-skeleton td {
- /* see-through to the background below */
- background: none; /* in case <td>s are globally styled */
- border-color: transparent;
-
- /* don't put a border between events and/or the day number */
- border-bottom: 0;
-}
-
-.fc-row .fc-content-skeleton tbody td, /* cells with events inside (so NOT the day number cell) */
-.fc-row .fc-helper-skeleton tbody td {
- /* don't put a border between event cells */
- border-top: 0;
-}
-
-
-/* Scrolling Container
---------------------------------------------------------------------------------------------------*/
-
-.fc-scroller {
- -webkit-overflow-scrolling: touch;
-}
-
-/* TODO: move to agenda/basic */
-.fc-scroller > .fc-day-grid,
-.fc-scroller > .fc-time-grid {
- position: relative; /* re-scope all positions */
- width: 100%; /* hack to force re-sizing this inner element when scrollbars appear/disappear */
-}
-
-
-/* Global Event Styles
---------------------------------------------------------------------------------------------------*/
-
-.fc-event {
- position: relative; /* for resize handle and other inner positioning */
- display: block; /* make the <a> tag block */
- font-size: .85em;
- line-height: 1.3;
- border-radius: 3px;
- border: 1px solid #3a87ad; /* default BORDER color */
- background-color: #3a87ad; /* default BACKGROUND color */
- font-weight: normal; /* undo jqui's ui-widget-header bold */
-}
-
-/* overpower some of bootstrap's and jqui's styles on <a> tags */
-.fc-event,
-.fc-event:hover,
-.ui-widget .fc-event {
- color: #fff; /* default TEXT color */
- text-decoration: none; /* if <a> has an href */
-}
-
-.fc-event[href],
-.fc-event.fc-draggable {
- cursor: pointer; /* give events with links and draggable events a hand mouse pointer */
-}
-
-.fc-not-allowed, /* causes a "warning" cursor. applied on body */
-.fc-not-allowed .fc-event { /* to override an event's custom cursor */
- cursor: not-allowed;
-}
-
-.fc-event .fc-bg { /* the generic .fc-bg already does position */
- z-index: 1;
- background: #fff;
- opacity: .25;
- filter: alpha(opacity=25); /* for IE */
-}
-
-.fc-event .fc-content {
- position: relative;
- z-index: 2;
-}
-
-/* resizer (cursor AND touch devices) */
-
-.fc-event .fc-resizer {
- position: absolute;
- z-index: 4;
-}
-
-/* resizer (touch devices) */
-
-.fc-event .fc-resizer {
- display: none;
-}
-
-.fc-event.fc-allow-mouse-resize .fc-resizer,
-.fc-event.fc-selected .fc-resizer {
- /* only show when hovering or selected (with touch) */
- display: block;
-}
-
-/* hit area */
-
-.fc-event.fc-selected .fc-resizer:before {
- /* 40x40 touch area */
- content: "";
- position: absolute;
- z-index: 9999; /* user of this util can scope within a lower z-index */
- top: 50%;
- left: 50%;
- width: 40px;
- height: 40px;
- margin-left: -20px;
- margin-top: -20px;
-}
-
-
-/* Event Selection (only for touch devices)
---------------------------------------------------------------------------------------------------*/
-
-.fc-event.fc-selected {
- z-index: 9999 !important; /* overcomes inline z-index */
- box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
-}
-
-.fc-event.fc-selected.fc-dragging {
- box-shadow: 0 2px 7px rgba(0, 0, 0, 0.3);
-}
-
-
-/* Horizontal Events
---------------------------------------------------------------------------------------------------*/
-
-/* bigger touch area when selected */
-.fc-h-event.fc-selected:before {
- content: "";
- position: absolute;
- z-index: 3; /* below resizers */
- top: -10px;
- bottom: -10px;
- left: 0;
- right: 0;
-}
-
-/* events that are continuing to/from another week. kill rounded corners and butt up against edge */
-
-.fc-ltr .fc-h-event.fc-not-start,
-.fc-rtl .fc-h-event.fc-not-end {
- margin-left: 0;
- border-left-width: 0;
- padding-left: 1px; /* replace the border with padding */
- border-top-left-radius: 0;
- border-bottom-left-radius: 0;
-}
-
-.fc-ltr .fc-h-event.fc-not-end,
-.fc-rtl .fc-h-event.fc-not-start {
- margin-right: 0;
- border-right-width: 0;
- padding-right: 1px; /* replace the border with padding */
- border-top-right-radius: 0;
- border-bottom-right-radius: 0;
-}
-
-/* resizer (cursor AND touch devices) */
-
-/* left resizer */
-.fc-ltr .fc-h-event .fc-start-resizer,
-.fc-rtl .fc-h-event .fc-end-resizer {
- cursor: w-resize;
- left: -1px; /* overcome border */
-}
-
-/* right resizer */
-.fc-ltr .fc-h-event .fc-end-resizer,
-.fc-rtl .fc-h-event .fc-start-resizer {
- cursor: e-resize;
- right: -1px; /* overcome border */
-}
-
-/* resizer (mouse devices) */
-
-.fc-h-event.fc-allow-mouse-resize .fc-resizer {
- width: 7px;
- top: -1px; /* overcome top border */
- bottom: -1px; /* overcome bottom border */
-}
-
-/* resizer (touch devices) */
-
-.fc-h-event.fc-selected .fc-resizer {
- /* 8x8 little dot */
- border-radius: 4px;
- border-width: 1px;
- width: 6px;
- height: 6px;
- border-style: solid;
- border-color: inherit;
- background: #fff;
- /* vertically center */
- top: 50%;
- margin-top: -4px;
-}
-
-/* left resizer */
-.fc-ltr .fc-h-event.fc-selected .fc-start-resizer,
-.fc-rtl .fc-h-event.fc-selected .fc-end-resizer {
- margin-left: -4px; /* centers the 8x8 dot on the left edge */
-}
-
-/* right resizer */
-.fc-ltr .fc-h-event.fc-selected .fc-end-resizer,
-.fc-rtl .fc-h-event.fc-selected .fc-start-resizer {
- margin-right: -4px; /* centers the 8x8 dot on the right edge */
-}
-
-
-/* DayGrid events
-----------------------------------------------------------------------------------------------------
-We use the full "fc-day-grid-event" class instead of using descendants because the event won't
-be a descendant of the grid when it is being dragged.
-*/
-
-.fc-day-grid-event {
- margin: 1px 2px 0; /* spacing between events and edges */
- padding: 0 1px;
-}
-
-.fc-day-grid-event.fc-selected:after {
- content: "";
- position: absolute;
- z-index: 1; /* same z-index as fc-bg, behind text */
- /* overcome the borders */
- top: -1px;
- right: -1px;
- bottom: -1px;
- left: -1px;
- /* darkening effect */
- background: #000;
- opacity: .25;
- filter: alpha(opacity=25); /* for IE */
-}
-
-.fc-day-grid-event .fc-content { /* force events to be one-line tall */
- white-space: nowrap;
- overflow: hidden;
-}
-
-.fc-day-grid-event .fc-time {
- font-weight: bold;
-}
-
-/* resizer (cursor devices) */
-
-/* left resizer */
-.fc-ltr .fc-day-grid-event.fc-allow-mouse-resize .fc-start-resizer,
-.fc-rtl .fc-day-grid-event.fc-allow-mouse-resize .fc-end-resizer {
- margin-left: -2px; /* to the day cell's edge */
-}
-
-/* right resizer */
-.fc-ltr .fc-day-grid-event.fc-allow-mouse-resize .fc-end-resizer,
-.fc-rtl .fc-day-grid-event.fc-allow-mouse-resize .fc-start-resizer {
- margin-right: -2px; /* to the day cell's edge */
-}
-
-
-/* Event Limiting
---------------------------------------------------------------------------------------------------*/
-
-/* "more" link that represents hidden events */
-
-a.fc-more {
- margin: 1px 3px;
- font-size: .85em;
- cursor: pointer;
- text-decoration: none;
-}
-
-a.fc-more:hover {
- text-decoration: underline;
-}
-
-.fc-limited { /* rows and cells that are hidden because of a "more" link */
- display: none;
-}
-
-/* popover that appears when "more" link is clicked */
-
-.fc-day-grid .fc-row {
- z-index: 1; /* make the "more" popover one higher than this */
-}
-
-.fc-more-popover {
- z-index: 2;
- width: 220px;
-}
-
-.fc-more-popover .fc-event-container {
- padding: 10px;
-}
-
-
-/* Now Indicator
---------------------------------------------------------------------------------------------------*/
-
-.fc-now-indicator {
- position: absolute;
- border: 0 solid red;
-}
-
-
-/* Utilities
---------------------------------------------------------------------------------------------------*/
-
-.fc-unselectable {
- -webkit-user-select: none;
- -khtml-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- -webkit-touch-callout: none;
- -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-}
-
-/* Toolbar
---------------------------------------------------------------------------------------------------*/
-
-.fc-toolbar {
- text-align: center;
- margin-bottom: 1em;
-}
-
-.fc-toolbar .fc-left {
- float: left;
-}
-
-.fc-toolbar .fc-right {
- float: right;
-}
-
-.fc-toolbar .fc-center {
- display: inline-block;
-}
-
-/* the things within each left/right/center section */
-.fc .fc-toolbar > * > * { /* extra precedence to override button border margins */
- float: left;
- margin-left: .75em;
-}
-
-/* the first thing within each left/center/right section */
-.fc .fc-toolbar > * > :first-child { /* extra precedence to override button border margins */
- margin-left: 0;
-}
-
-/* title text */
-
-.fc-toolbar h2 {
- margin: 0;
-}
-
-/* button layering (for border precedence) */
-
-.fc-toolbar button {
- position: relative;
-}
-
-.fc-toolbar .fc-state-hover,
-.fc-toolbar .ui-state-hover {
- z-index: 2;
-}
-
-.fc-toolbar .fc-state-down {
- z-index: 3;
-}
-
-.fc-toolbar .fc-state-active,
-.fc-toolbar .ui-state-active {
- z-index: 4;
-}
-
-.fc-toolbar button:focus {
- z-index: 5;
-}
-
-
-/* View Structure
---------------------------------------------------------------------------------------------------*/
-
-/* undo twitter bootstrap's box-sizing rules. normalizes positioning techniques */
-/* don't do this for the toolbar because we'll want bootstrap to style those buttons as some pt */
-.fc-view-container *,
-.fc-view-container *:before,
-.fc-view-container *:after {
- -webkit-box-sizing: content-box;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
-}
-
-.fc-view, /* scope positioning and z-index's for everything within the view */
-.fc-view > table { /* so dragged elements can be above the view's main element */
- position: relative;
- z-index: 1;
-}
-
-/* BasicView
---------------------------------------------------------------------------------------------------*/
-
-/* day row structure */
-
-.fc-basicWeek-view .fc-content-skeleton,
-.fc-basicDay-view .fc-content-skeleton {
- /* we are sure there are no day numbers in these views, so... */
- padding-top: 1px; /* add a pixel to make sure there are 2px padding above events */
- padding-bottom: 1em; /* ensure a space at bottom of cell for user selecting/clicking */
-}
-
-.fc-basic-view .fc-body .fc-row {
- min-height: 4em; /* ensure that all rows are at least this tall */
-}
-
-/* a "rigid" row will take up a constant amount of height because content-skeleton is absolute */
-
-.fc-row.fc-rigid {
- overflow: hidden;
-}
-
-.fc-row.fc-rigid .fc-content-skeleton {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
-}
-
-/* week and day number styling */
-
-.fc-basic-view .fc-week-number,
-.fc-basic-view .fc-day-number {
- padding: 0 2px;
-}
-
-.fc-basic-view td.fc-week-number span,
-.fc-basic-view td.fc-day-number {
- padding-top: 2px;
- padding-bottom: 2px;
-}
-
-.fc-basic-view .fc-week-number {
- text-align: center;
-}
-
-.fc-basic-view .fc-week-number span {
- /* work around the way we do column resizing and ensure a minimum width */
- display: inline-block;
- min-width: 1.25em;
-}
-
-.fc-ltr .fc-basic-view .fc-day-number {
- text-align: right;
-}
-
-.fc-rtl .fc-basic-view .fc-day-number {
- text-align: left;
-}
-
-.fc-day-number.fc-other-month {
- opacity: 0.3;
- filter: alpha(opacity=30); /* for IE */
- /* opacity with small font can sometimes look too faded
- might want to set the 'color' property instead
- making day-numbers bold also fixes the problem */
-}
-
-/* AgendaView all-day area
---------------------------------------------------------------------------------------------------*/
-
-.fc-agenda-view .fc-day-grid {
- position: relative;
- z-index: 2; /* so the "more.." popover will be over the time grid */
-}
-
-.fc-agenda-view .fc-day-grid .fc-row {
- min-height: 3em; /* all-day section will never get shorter than this */
-}
-
-.fc-agenda-view .fc-day-grid .fc-row .fc-content-skeleton {
- padding-top: 1px; /* add a pixel to make sure there are 2px padding above events */
- padding-bottom: 1em; /* give space underneath events for clicking/selecting days */
-}
-
-
-/* TimeGrid axis running down the side (for both the all-day area and the slot area)
---------------------------------------------------------------------------------------------------*/
-
-.fc .fc-axis { /* .fc to overcome default cell styles */
- vertical-align: middle;
- padding: 0 4px;
- white-space: nowrap;
-}
-
-.fc-ltr .fc-axis {
- text-align: right;
-}
-
-.fc-rtl .fc-axis {
- text-align: left;
-}
-
-.ui-widget td.fc-axis {
- font-weight: normal; /* overcome jqui theme making it bold */
-}
-
-
-/* TimeGrid Structure
---------------------------------------------------------------------------------------------------*/
-
-.fc-time-grid-container, /* so scroll container's z-index is below all-day */
-.fc-time-grid { /* so slats/bg/content/etc positions get scoped within here */
- position: relative;
- z-index: 1;
-}
-
-.fc-time-grid {
- min-height: 100%; /* so if height setting is 'auto', .fc-bg stretches to fill height */
-}
-
-.fc-time-grid table { /* don't put outer borders on slats/bg/content/etc */
- border: 0 hidden transparent;
-}
-
-.fc-time-grid > .fc-bg {
- z-index: 1;
-}
-
-.fc-time-grid .fc-slats,
-.fc-time-grid > hr { /* the <hr> AgendaView injects when grid is shorter than scroller */
- position: relative;
- z-index: 2;
-}
-
-.fc-time-grid .fc-content-col {
- position: relative; /* because now-indicator lives directly inside */
-}
-
-.fc-time-grid .fc-content-skeleton {
- position: absolute;
- z-index: 3;
- top: 0;
- left: 0;
- right: 0;
-}
-
-/* divs within a cell within the fc-content-skeleton */
-
-.fc-time-grid .fc-business-container {
- position: relative;
- z-index: 1;
-}
-
-.fc-time-grid .fc-bgevent-container {
- position: relative;
- z-index: 2;
-}
-
-.fc-time-grid .fc-highlight-container {
- position: relative;
- z-index: 3;
-}
-
-.fc-time-grid .fc-event-container {
- position: relative;
- z-index: 4;
-}
-
-.fc-time-grid .fc-now-indicator-line {
- z-index: 5;
-}
-
-.fc-time-grid .fc-helper-container { /* also is fc-event-container */
- position: relative;
- z-index: 6;
-}
-
-
-/* TimeGrid Slats (lines that run horizontally)
---------------------------------------------------------------------------------------------------*/
-
-.fc-time-grid .fc-slats td {
- height: 1.5em;
- border-bottom: 0; /* each cell is responsible for its top border */
-}
-
-.fc-time-grid .fc-slats .fc-minor td {
- border-top-style: dotted;
-}
-
-.fc-time-grid .fc-slats .ui-widget-content { /* for jqui theme */
- background: none; /* see through to fc-bg */
-}
-
-
-/* TimeGrid Highlighting Slots
---------------------------------------------------------------------------------------------------*/
-
-.fc-time-grid .fc-highlight-container { /* a div within a cell within the fc-highlight-skeleton */
- position: relative; /* scopes the left/right of the fc-highlight to be in the column */
-}
-
-.fc-time-grid .fc-highlight {
- position: absolute;
- left: 0;
- right: 0;
- /* top and bottom will be in by JS */
-}
-
-
-/* TimeGrid Event Containment
---------------------------------------------------------------------------------------------------*/
-
-.fc-ltr .fc-time-grid .fc-event-container { /* space on the sides of events for LTR (default) */
- margin: 0 2.5% 0 2px;
-}
-
-.fc-rtl .fc-time-grid .fc-event-container { /* space on the sides of events for RTL */
- margin: 0 2px 0 2.5%;
-}
-
-.fc-time-grid .fc-event,
-.fc-time-grid .fc-bgevent {
- position: absolute;
- z-index: 1; /* scope inner z-index's */
-}
-
-.fc-time-grid .fc-bgevent {
- /* background events always span full width */
- left: 0;
- right: 0;
-}
-
-
-/* Generic Vertical Event
---------------------------------------------------------------------------------------------------*/
-
-.fc-v-event.fc-not-start { /* events that are continuing from another day */
- /* replace space made by the top border with padding */
- border-top-width: 0;
- padding-top: 1px;
-
- /* remove top rounded corners */
- border-top-left-radius: 0;
- border-top-right-radius: 0;
-}
-
-.fc-v-event.fc-not-end {
- /* replace space made by the top border with padding */
- border-bottom-width: 0;
- padding-bottom: 1px;
-
- /* remove bottom rounded corners */
- border-bottom-left-radius: 0;
- border-bottom-right-radius: 0;
-}
-
-
-/* TimeGrid Event Styling
-----------------------------------------------------------------------------------------------------
-We use the full "fc-time-grid-event" class instead of using descendants because the event won't
-be a descendant of the grid when it is being dragged.
-*/
-
-.fc-time-grid-event {
- overflow: hidden; /* don't let the bg flow over rounded corners */
-}
-
-.fc-time-grid-event.fc-selected {
- /* need to allow touch resizers to extend outside event's bounding box */
- /* common fc-selected styles hide the fc-bg, so don't need this anyway */
- overflow: visible;
-}
-
-.fc-time-grid-event.fc-selected .fc-bg {
- display: none; /* hide semi-white background, to appear darker */
-}
-
-.fc-time-grid-event .fc-content {
- overflow: hidden; /* for when .fc-selected */
-}
-
-.fc-time-grid-event .fc-time,
-.fc-time-grid-event .fc-title {
- padding: 0 1px;
-}
-
-.fc-time-grid-event .fc-time {
- font-size: .85em;
- white-space: nowrap;
-}
-
-/* short mode, where time and title are on the same line */
-
-.fc-time-grid-event.fc-short .fc-content {
- /* don't wrap to second line (now that contents will be inline) */
- white-space: nowrap;
-}
-
-.fc-time-grid-event.fc-short .fc-time,
-.fc-time-grid-event.fc-short .fc-title {
- /* put the time and title on the same line */
- display: inline-block;
- vertical-align: top;
-}
-
-.fc-time-grid-event.fc-short .fc-time span {
- display: none; /* don't display the full time text... */
-}
-
-.fc-time-grid-event.fc-short .fc-time:before {
- content: attr(data-start); /* ...instead, display only the start time */
-}
-
-.fc-time-grid-event.fc-short .fc-time:after {
- content: "\000A0-\000A0"; /* seperate with a dash, wrapped in nbsp's */
-}
-
-.fc-time-grid-event.fc-short .fc-title {
- font-size: .85em; /* make the title text the same size as the time */
- padding: 0; /* undo padding from above */
-}
-
-/* resizer (cursor device) */
-
-.fc-time-grid-event.fc-allow-mouse-resize .fc-resizer {
- left: 0;
- right: 0;
- bottom: 0;
- height: 8px;
- overflow: hidden;
- line-height: 8px;
- font-size: 11px;
- font-family: monospace;
- text-align: center;
- cursor: s-resize;
-}
-
-.fc-time-grid-event.fc-allow-mouse-resize .fc-resizer:after {
- content: "=";
-}
-
-/* resizer (touch device) */
-
-.fc-time-grid-event.fc-selected .fc-resizer {
- /* 10x10 dot */
- border-radius: 5px;
- border-width: 1px;
- width: 8px;
- height: 8px;
- border-style: solid;
- border-color: inherit;
- background: #fff;
- /* horizontally center */
- left: 50%;
- margin-left: -5px;
- /* center on the bottom edge */
- bottom: -5px;
-}
-
-
-/* Now Indicator
---------------------------------------------------------------------------------------------------*/
-
-.fc-time-grid .fc-now-indicator-line {
- border-top-width: 1px;
- left: 0;
- right: 0;
-}
-
-/* arrow on axis */
-
-.fc-time-grid .fc-now-indicator-arrow {
- margin-top: -5px; /* vertically center on top coordinate */
-}
-
-.fc-ltr .fc-time-grid .fc-now-indicator-arrow {
- left: 0;
- /* triangle pointing right... */
- border-width: 5px 0 5px 6px;
- border-top-color: transparent;
- border-bottom-color: transparent;
-}
-
-.fc-rtl .fc-time-grid .fc-now-indicator-arrow {
- right: 0;
- /* triangle pointing left... */
- border-width: 5px 6px 5px 0;
- border-top-color: transparent;
- border-bottom-color: transparent;
-}
diff --git a/tools/infra-dashboard/css/fullcalendar.print.css b/tools/infra-dashboard/css/fullcalendar.print.css
deleted file mode 100644
index af884fc8..00000000
--- a/tools/infra-dashboard/css/fullcalendar.print.css
+++ /dev/null
@@ -1,208 +0,0 @@
-/*!
- * FullCalendar v2.7.2 Print Stylesheet
- * Docs & License: http://fullcalendar.io/
- * (c) 2016 Adam Shaw
- */
-
-/*
- * Include this stylesheet on your page to get a more printer-friendly calendar.
- * When including this stylesheet, use the media='print' attribute of the <link> tag.
- * Make sure to include this stylesheet IN ADDITION to the regular fullcalendar.css.
- */
-
-.fc {
- max-width: 100% !important;
-}
-
-
-/* Global Event Restyling
---------------------------------------------------------------------------------------------------*/
-
-.fc-event {
- background: #fff !important;
- color: #000 !important;
- page-break-inside: avoid;
-}
-
-.fc-event .fc-resizer {
- display: none;
-}
-
-
-/* Table & Day-Row Restyling
---------------------------------------------------------------------------------------------------*/
-
-th,
-td,
-hr,
-thead,
-tbody,
-.fc-row {
- border-color: #ccc !important;
- background: #fff !important;
-}
-
-/* kill the overlaid, absolutely-positioned components */
-/* common... */
-.fc-bg,
-.fc-bgevent-skeleton,
-.fc-highlight-skeleton,
-.fc-helper-skeleton,
-/* for timegrid. within cells within table skeletons... */
-.fc-bgevent-container,
-.fc-business-container,
-.fc-highlight-container,
-.fc-helper-container {
- display: none;
-}
-
-/* don't force a min-height on rows (for DayGrid) */
-.fc tbody .fc-row {
- height: auto !important; /* undo height that JS set in distributeHeight */
- min-height: 0 !important; /* undo the min-height from each view's specific stylesheet */
-}
-
-.fc tbody .fc-row .fc-content-skeleton {
- position: static; /* undo .fc-rigid */
- padding-bottom: 0 !important; /* use a more border-friendly method for this... */
-}
-
-.fc tbody .fc-row .fc-content-skeleton tbody tr:last-child td { /* only works in newer browsers */
- padding-bottom: 1em; /* ...gives space within the skeleton. also ensures min height in a way */
-}
-
-.fc tbody .fc-row .fc-content-skeleton table {
- /* provides a min-height for the row, but only effective for IE, which exaggerates this value,
- making it look more like 3em. for other browers, it will already be this tall */
- height: 1em;
-}
-
-
-/* Undo month-view event limiting. Display all events and hide the "more" links
---------------------------------------------------------------------------------------------------*/
-
-.fc-more-cell,
-.fc-more {
- display: none !important;
-}
-
-.fc tr.fc-limited {
- display: table-row !important;
-}
-
-.fc td.fc-limited {
- display: table-cell !important;
-}
-
-.fc-popover {
- display: none; /* never display the "more.." popover in print mode */
-}
-
-
-/* TimeGrid Restyling
---------------------------------------------------------------------------------------------------*/
-
-/* undo the min-height 100% trick used to fill the container's height */
-.fc-time-grid {
- min-height: 0 !important;
-}
-
-/* don't display the side axis at all ("all-day" and time cells) */
-.fc-agenda-view .fc-axis {
- display: none;
-}
-
-/* don't display the horizontal lines */
-.fc-slats,
-.fc-time-grid hr { /* this hr is used when height is underused and needs to be filled */
- display: none !important; /* important overrides inline declaration */
-}
-
-/* let the container that holds the events be naturally positioned and create real height */
-.fc-time-grid .fc-content-skeleton {
- position: static;
-}
-
-/* in case there are no events, we still want some height */
-.fc-time-grid .fc-content-skeleton table {
- height: 4em;
-}
-
-/* kill the horizontal spacing made by the event container. event margins will be done below */
-.fc-time-grid .fc-event-container {
- margin: 0 !important;
-}
-
-
-/* TimeGrid *Event* Restyling
---------------------------------------------------------------------------------------------------*/
-
-/* naturally position events, vertically stacking them */
-.fc-time-grid .fc-event {
- position: static !important;
- margin: 3px 2px !important;
-}
-
-/* for events that continue to a future day, give the bottom border back */
-.fc-time-grid .fc-event.fc-not-end {
- border-bottom-width: 1px !important;
-}
-
-/* indicate the event continues via "..." text */
-.fc-time-grid .fc-event.fc-not-end:after {
- content: "...";
-}
-
-/* for events that are continuations from previous days, give the top border back */
-.fc-time-grid .fc-event.fc-not-start {
- border-top-width: 1px !important;
-}
-
-/* indicate the event is a continuation via "..." text */
-.fc-time-grid .fc-event.fc-not-start:before {
- content: "...";
-}
-
-/* time */
-
-/* undo a previous declaration and let the time text span to a second line */
-.fc-time-grid .fc-event .fc-time {
- white-space: normal !important;
-}
-
-/* hide the the time that is normally displayed... */
-.fc-time-grid .fc-event .fc-time span {
- display: none;
-}
-
-/* ...replace it with a more verbose version (includes AM/PM) stored in an html attribute */
-.fc-time-grid .fc-event .fc-time:after {
- content: attr(data-full);
-}
-
-
-/* Vertical Scroller & Containers
---------------------------------------------------------------------------------------------------*/
-
-/* kill the scrollbars and allow natural height */
-.fc-scroller,
-.fc-day-grid-container, /* these divs might be assigned height, which we need to cleared */
-.fc-time-grid-container { /* */
- overflow: visible !important;
- height: auto !important;
-}
-
-/* kill the horizontal border/padding used to compensate for scrollbars */
-.fc-row {
- border: 0 !important;
- margin: 0 !important;
-}
-
-
-/* Button Controls
---------------------------------------------------------------------------------------------------*/
-
-.fc-button-group,
-.fc button {
- display: none; /* don't display any button-related controls */
-}
diff --git a/tools/infra-dashboard/css/highslide.min.css b/tools/infra-dashboard/css/highslide.min.css
deleted file mode 100644
index 83bac0f4..00000000
--- a/tools/infra-dashboard/css/highslide.min.css
+++ /dev/null
@@ -1,793 +0,0 @@
-.highslide-header a,
-.highslide-loading {
- text-transform: uppercase;
- text-decoration: none;
- font-weight: 700
-}
-.highslide-container div {
- font-family: Verdana, Helvetica;
- font-size: 10pt
-}
-.highslide-container table {
- background: 0 0
-}
-.highslide {
- outline: 0;
- text-decoration: none
-}
-.highslide img {
- border: 2px solid silver
-}
-.highslide:hover img {
- border-color: gray
-}
-.highslide-active-anchor img {
- visibility: hidden
-}
-.highslide-gallery .highslide-active-anchor img {
- border-color: #000;
- visibility: visible;
- cursor: default
-}
-.highslide-image {
- border-width: 2px;
- border-style: solid;
- border-color: #fff;
- background: gray
-}
-.highslide-outline,
-.highslide-wrapper {
- background: #fff
-}
-.glossy-dark {
- background: #111
-}
-.highslide-number {
- font-weight: 700;
- color: gray;
- font-size: .9em
-}
-.highslide-caption {
- display: none;
- font-size: 1em;
- padding: 5px
-}
-.highslide-heading {
- display: none;
- font-weight: 700;
- margin: .4em
-}
-.highslide-dimming {
- position: absolute;
- background: #000
-}
-a.highslide-full-expand {
- background: url(/media/com_demo/graphics/fullexpand.gif) no-repeat;
- display: block;
- margin: 0 10px 10px 0;
- width: 34px;
- height: 34px
-}
-.highslide-loading {
- display: block;
- color: #000;
- font-size: 9px;
- padding: 3px 3px 3px 22px;
- border: 1px solid #fff;
- background-color: #fff;
- background-image: url(./media/loader.white.gif);
- background-repeat: no-repeat;
- background-position: 3px 1px
-}
-a.highslide-credits,
-a.highslide-credits i {
- padding: 2px;
- color: silver;
- text-decoration: none;
- font-size: 10px
-}
-a.highslide-credits:hover,
-a.highslide-credits:hover i {
- color: #fff;
- background-color: gray
-}
-.highslide-move,
-.highslide-move * {
- cursor: move
-}
-.highslide-viewport {
- display: none;
- position: fixed;
- width: 100%;
- height: 100%;
- z-index: 1;
- background: 0 0;
- left: 0;
- top: 0
-}
-.hidden-container,
-.highslide-overlay {
- display: none
-}
-.closebutton {
- position: relative;
- top: -15px;
- left: 15px;
- width: 30px;
- height: 30px;
- cursor: pointer;
- background: url(/media/com_demo/graphics/close.png)
-}
-.highslide-gallery ul {
- list-style-type: none;
- margin: 0;
- padding: 0
-}
-.highslide-gallery ul li {
- display: block;
- position: relative;
- float: left;
- width: 106px;
- height: 106px;
- border: 1px solid silver;
- background: #ededed;
- margin: 2px;
- line-height: 0;
- overflow: hidden
-}
-.highslide-gallery ul a {
- position: absolute;
- top: 50%;
- left: 50%
-}
-.highslide-gallery ul img {
- position: relative;
- top: -50%;
- left: -50%
-}
-html>body .highslide-gallery ul li {
- display: table;
- text-align: center
-}
-html>body .highslide-gallery ul a {
- position: static;
- display: table-cell;
- vertical-align: middle
-}
-html>body .highslide-gallery ul img {
- position: static
-}
-.highslide-controls {
- width: 195px;
- height: 40px;
- background: url(/media/com_demo/graphics/controlbar-white.gif) 0 -90px no-repeat;
- margin: 20px 15px 10px 0
-}
-.highslide-controls ul {
- position: relative;
- left: 15px;
- height: 40px;
- list-style: none;
- margin: 0;
- padding: 0;
- background: url(/media/com_demo/graphics/controlbar-white.gif) right -90px no-repeat
-}
-.highslide-controls li {
- float: left;
- padding: 5px 0;
- margin: 0;
- list-style: none
-}
-.highslide-controls a {
- background-image: url(/media/com_demo/graphics/controlbar-white.gif);
- display: block;
- float: left;
- height: 30px;
- width: 30px;
- outline: 0
-}
-.highslide-controls a.disabled,
-.highslide-controls a.disabled span {
- cursor: default
-}
-.highslide-controls a span {
- display: none;
- cursor: pointer
-}
-.highslide-controls .highslide-previous a {
- background-position: 0 0
-}
-.highslide-controls .highslide-previous a:hover {
- background-position: 0 -30px
-}
-.highslide-controls .highslide-previous a.disabled {
- background-position: 0 -60px!important
-}
-.highslide-controls .highslide-play a {
- background-position: -30px 0
-}
-.highslide-controls .highslide-play a:hover {
- background-position: -30px -30px
-}
-.highslide-controls .highslide-play a.disabled {
- background-position: -30px -60px!important
-}
-.highslide-controls .highslide-pause a {
- background-position: -60px 0
-}
-.highslide-controls .highslide-pause a:hover {
- background-position: -60px -30px
-}
-.highslide-controls .highslide-next a {
- background-position: -90px 0
-}
-.highslide-controls .highslide-next a:hover {
- background-position: -90px -30px
-}
-.highslide-controls .highslide-next a.disabled {
- background-position: -90px -60px!important
-}
-.highslide-controls .highslide-move a {
- background-position: -90pt 0
-}
-.highslide-controls .highslide-move a:hover {
- background-position: -90pt -30px
-}
-.highslide-controls .highslide-full-expand a {
- background-position: -150px 0
-}
-.highslide-controls .highslide-full-expand a:hover {
- background-position: -150px -30px
-}
-.highslide-controls .highslide-full-expand a.disabled {
- background-position: -150px -60px!important
-}
-.highslide-controls .highslide-close a {
- background-position: -180px 0
-}
-.highslide-controls .highslide-close a:hover {
- background-position: -180px -30px
-}
-.highslide-maincontent {
- display: none
-}
-.highslide-html {
- background-color: #fff
-}
-.highslide-html-content {
- display: none;
- width: 25pc;
- padding: 0 5px 5px
-}
-.highslide-header {
- padding-bottom: 5px
-}
-.highslide-header ul {
- margin: 0;
- padding: 0;
- text-align: right
-}
-.highslide-header ul li {
- display: inline;
- padding-left: 1em
-}
-.highslide-header ul li.highslide-next,
-.highslide-header ul li.highslide-previous {
- display: none
-}
-.highslide-header a {
- color: gray
-}
-.highslide-header a:hover {
- color: #000
-}
-.highslide-header .highslide-move a {
- cursor: move
-}
-.highslide-footer {
- height: 1pc
-}
-.highslide-footer .highslide-resize {
- display: block;
- float: right;
- margin-top: 5px;
- height: 11px;
- width: 11px;
- background: url(/media/com_demo/graphics/resize.gif) no-repeat
-}
-.highslide-footer .highslide-resize span {
- display: none
-}
-.highslide-resize {
- cursor: nw-resize
-}
-.draggable-header .highslide-header {
- height: 18px;
- border-bottom: 1px solid #ddd
-}
-.draggable-header .highslide-heading {
- position: absolute;
- margin: 2px .4em
-}
-.draggable-header .highslide-header .highslide-move {
- cursor: move;
- display: block;
- height: 1pc;
- position: absolute;
- right: 24px;
- top: 0;
- width: 100%;
- z-index: 1
-}
-.draggable-header .highslide-header .highslide-move * {
- display: none
-}
-.draggable-header .highslide-header .highslide-close {
- position: absolute;
- right: 2px;
- top: 2px;
- z-index: 5;
- padding: 0
-}
-.draggable-header .highslide-header .highslide-close a {
- display: block;
- height: 1pc;
- width: 1pc;
- background-image: url(/media/com_demo/graphics/closeX.png)
-}
-.draggable-header .highslide-header .highslide-close a:hover {
- background-position: 0 1pc
-}
-.draggable-header .highslide-header .highslide-close span {
- display: none
-}
-.draggable-header .highslide-maincontent {
- padding-top: 1em
-}
-.titlebar .highslide-header {
- height: 18px;
- border-bottom: 1px solid #ddd
-}
-.titlebar .highslide-heading {
- position: absolute;
- width: 90%;
- margin: 1px 0 1px 5px;
- color: #666
-}
-.titlebar .highslide-header .highslide-move {
- cursor: move;
- display: block;
- height: 1pc;
- position: absolute;
- right: 24px;
- top: 0;
- width: 100%;
- z-index: 1
-}
-.controls-in-heading .highslide-controls .highslide-move,
-.no-footer .highslide-footer,
-.text-controls .highslide-move,
-.titlebar .highslide-header .highslide-move * {
- display: none
-}
-.titlebar .highslide-header li {
- position: relative;
- top: 3px;
- z-index: 2;
- padding: 0 0 0 1em
-}
-.titlebar .highslide-maincontent {
- padding-top: 1em
-}
-.wide-border {
- background: #fff
-}
-.wide-border .highslide-image {
- border-width: 10px
-}
-.wide-border .highslide-caption {
- padding: 0 10px 10px
-}
-.borderless .highslide-image {
- border: none
-}
-.borderless .highslide-caption {
- border-bottom: 1px solid #fff;
- border-top: 1px solid #fff;
- background: silver
-}
-.outer-glow {
- background: #444
-}
-.outer-glow .highslide-image {
- border: 5px solid #444
-}
-.outer-glow .highslide-caption {
- border: 5px solid #444;
- border-top: none;
- padding: 5px;
- background-color: gray
-}
-.colored-border {
- background: #fff
-}
-.colored-border .highslide-image {
- border: 2px solid green
-}
-.colored-border .highslide-caption {
- border: 2px solid green;
- border-top: none
-}
-.dark {
- background: #111
-}
-.dark .highslide-image {
- border-color: #000 #000 #202020;
- background: gray
-}
-.dark .highslide-caption {
- color: #fff;
- background: #111
-}
-.dark .highslide-controls,
-.dark .highslide-controls a,
-.dark .highslide-controls ul {
- background-image: url(/media/com_demo/graphics/controlbar-black-border.gif)
-}
-.floating-caption .highslide-caption {
- position: absolute;
- padding: 1em 0 0;
- background: 0 0;
- color: #fff;
- border: none;
- font-weight: 700
-}
-.controls-in-heading .highslide-heading {
- color: gray;
- font-weight: 700;
- height: 20px;
- overflow: hidden;
- cursor: default;
- padding: 0 0 0 22px;
- margin: 0;
- background: url(/media/com_demo/graphics/icon.gif) 0 1px no-repeat
-}
-.controls-in-heading .highslide-controls {
- width: 105px;
- height: 20px;
- position: relative;
- margin: 0;
- top: -23px;
- left: 7px;
- background: 0 0
-}
-.controls-in-heading .highslide-controls ul {
- position: static;
- height: 20px;
- background: 0 0
-}
-.controls-in-heading .highslide-controls li {
- padding: 0
-}
-.controls-in-heading .highslide-controls a {
- background-image: url(/media/com_demo/graphics/controlbar-white-small.gif);
- height: 20px;
- width: 20px
-}
-.controls-in-heading .highslide-controls .highslide-previous a {
- background-position: 0 0
-}
-.controls-in-heading .highslide-controls .highslide-previous a:hover {
- background-position: 0 -20px
-}
-.controls-in-heading .highslide-controls .highslide-previous a.disabled {
- background-position: 0 -40px!important
-}
-.controls-in-heading .highslide-controls .highslide-play a {
- background-position: -20px 0
-}
-.controls-in-heading .highslide-controls .highslide-play a:hover {
- background-position: -20px -20px
-}
-.controls-in-heading .highslide-controls .highslide-play a.disabled {
- background-position: -20px -40px!important
-}
-.controls-in-heading .highslide-controls .highslide-pause a {
- background-position: -40px 0
-}
-.controls-in-heading .highslide-controls .highslide-pause a:hover {
- background-position: -40px -20px
-}
-.controls-in-heading .highslide-controls .highslide-next a {
- background-position: -60px 0
-}
-.controls-in-heading .highslide-controls .highslide-next a:hover {
- background-position: -60px -20px
-}
-.controls-in-heading .highslide-controls .highslide-next a.disabled {
- background-position: -60px -40px!important
-}
-.controls-in-heading .highslide-controls .highslide-full-expand a {
- background-position: -75pt 0
-}
-.controls-in-heading .highslide-controls .highslide-full-expand a:hover {
- background-position: -75pt -20px
-}
-.controls-in-heading .highslide-controls .highslide-full-expand a.disabled {
- background-position: -75pt -40px!important
-}
-.controls-in-heading .highslide-controls .highslide-close a {
- background-position: -90pt 0
-}
-.controls-in-heading .highslide-controls .highslide-close a:hover {
- background-position: -90pt -20px
-}
-.text-controls .highslide-controls {
- width: auto;
- height: auto;
- margin: 0;
- text-align: center;
- background: 0 0
-}
-.text-controls ul {
- position: static;
- background: 0 0;
- height: auto;
- left: 0
-}
-.text-controls li {
- background-image: url(/media/com_demo/graphics/controlbar-text-buttons.png);
- background-position: right top!important;
- padding: 0;
- margin-left: 15px;
- display: block;
- width: auto
-}
-.text-controls a {
- background: url(/media/com_demo/graphics/controlbar-text-buttons.png) no-repeat;
- background-position: left top!important;
- position: relative;
- left: -10px;
- display: block;
- width: auto;
- height: auto;
- text-decoration: none!important
-}
-.text-controls a span {
- background: url(/media/com_demo/graphics/controlbar-text-buttons.png) no-repeat;
- margin: 1px 2px 1px 10px;
- display: block;
- min-width: 4em;
- height: 18px;
- line-height: 18px;
- padding: 1px 0 1px 18px;
- color: #333;
- font-family: "Trebuchet MS", Arial, sans-serif;
- font-size: 9pt;
- font-weight: 700;
- white-space: nowrap
-}
-.text-controls .highslide-next {
- margin-right: 1em
-}
-.text-controls .highslide-full-expand a span {
- min-width: 0;
- margin: 1px 0;
- padding: 1px 0 1px 10px
-}
-.text-controls .highslide-close a span {
- min-width: 0
-}
-.text-controls a:hover span {
- color: #000
-}
-.text-controls a.disabled span {
- color: #999
-}
-.text-controls .highslide-previous span {
- background-position: 0 -40px
-}
-.text-controls .highslide-previous a.disabled {
- background-position: left top!important
-}
-.text-controls .highslide-previous a.disabled span {
- background-position: 0 -140px
-}
-.text-controls .highslide-play span {
- background-position: 0 -60px
-}
-.text-controls .highslide-play a.disabled {
- background-position: left top!important
-}
-.text-controls .highslide-play a.disabled span {
- background-position: 0 -10pc
-}
-.text-controls .highslide-pause span {
- background-position: 0 -5pc
-}
-.text-controls .highslide-next span {
- background-position: 0 -75pt
-}
-.text-controls .highslide-next a.disabled {
- background-position: left top!important
-}
-.text-controls .highslide-next a.disabled span {
- background-position: 0 -200px
-}
-.text-controls .highslide-full-expand span {
- background: 0 0
-}
-.text-controls .highslide-full-expand a.disabled {
- background-position: left top!important
-}
-.text-controls .highslide-close span {
- background-position: 0 -90pt
-}
-.highslide-thumbstrip {
- height: 100%
-}
-.highslide-thumbstrip div {
- overflow: hidden
-}
-.highslide-thumbstrip table {
- position: relative;
- padding: 0;
- border-collapse: collapse
-}
-.highslide-thumbstrip td {
- padding: 1px
-}
-.highslide-thumbstrip a {
- outline: 0
-}
-.highslide-thumbstrip img {
- display: block;
- border: 1px solid gray;
- margin: 0 auto
-}
-.highslide-thumbstrip .highslide-active-anchor img {
- visibility: visible
-}
-.highslide-thumbstrip .highslide-marker {
- position: absolute;
- width: 0;
- height: 0;
- border-width: 0;
- border-style: solid;
- border-color: transparent
-}
-.highslide-thumbstrip-horizontal div {
- width: auto
-}
-.highslide-thumbstrip-horizontal .highslide-scroll-up {
- display: none;
- position: absolute;
- top: 3px;
- left: 3px;
- width: 25px;
- height: 42px
-}
-.highslide-thumbstrip-horizontal .highslide-scroll-up div {
- margin-bottom: 10px;
- cursor: pointer;
- background: url(/media/com_demo/graphics/scrollarrows.png) left center no-repeat;
- height: 42px
-}
-.highslide-thumbstrip-horizontal .highslide-scroll-down {
- display: none;
- position: absolute;
- top: 3px;
- right: 3px;
- width: 25px;
- height: 42px
-}
-.highslide-thumbstrip-horizontal .highslide-scroll-down div {
- margin-bottom: 10px;
- cursor: pointer;
- background: url(/media/com_demo/graphics/scrollarrows.png) center right no-repeat;
- height: 42px
-}
-.highslide-thumbstrip-horizontal table {
- margin: 2px 0 10px
-}
-.highslide-viewport .highslide-thumbstrip-horizontal table {
- margin-left: 10px
-}
-.highslide-thumbstrip-horizontal img {
- width: auto;
- height: 40px
-}
-.highslide-thumbstrip-horizontal .highslide-marker {
- top: 47px;
- border-left-width: 6px;
- border-right-width: 6px;
- border-bottom: 6px solid gray
-}
-.highslide-viewport .highslide-thumbstrip-horizontal .highslide-marker {
- margin-left: 10px
-}
-.dark .highslide-thumbstrip-horizontal .highslide-marker,
-.highslide-viewport .highslide-thumbstrip-horizontal .highslide-marker {
- border-bottom-color: #fff!important
-}
-.highslide-thumbstrip-vertical-overlay {
- overflow: hidden!important
-}
-.highslide-thumbstrip-vertical div {
- height: 100%
-}
-.highslide-thumbstrip-vertical a {
- display: block
-}
-.highslide-thumbstrip-vertical .highslide-scroll-up {
- display: none;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 25px
-}
-.highslide-thumbstrip-vertical .highslide-scroll-up div {
- margin-left: 10px;
- cursor: pointer;
- background: url(/media/com_demo/graphics/scrollarrows.png) top center no-repeat;
- height: 25px
-}
-.highslide-thumbstrip-vertical .highslide-scroll-down {
- display: none;
- position: absolute;
- bottom: 0;
- left: 0;
- width: 100%;
- height: 25px
-}
-.highslide-thumbstrip-vertical .highslide-scroll-down div {
- margin-left: 10px;
- cursor: pointer;
- background: url(/media/com_demo/graphics/scrollarrows.png) bottom center no-repeat;
- height: 25px
-}
-.highslide-thumbstrip-vertical table {
- margin: 10px 0 0 10px
-}
-.highslide-thumbstrip-vertical img {
- max-width: 60px
-}
-.highslide-thumbstrip-vertical .highslide-marker {
- left: 0;
- margin-top: 8px;
- border-top-width: 6px;
- border-bottom-width: 6px;
- border-left: 6px solid gray
-}
-.dark .highslide-thumbstrip-vertical .highslide-marker,
-.highslide-viewport .highslide-thumbstrip-vertical .highslide-marker {
- border-left-color: #fff
-}
-.highslide-viewport .highslide-thumbstrip-float {
- overflow: auto
-}
-.highslide-thumbstrip-float ul {
- margin: 2px 0;
- padding: 0
-}
-.highslide-thumbstrip-float li {
- display: block;
- height: 60px;
- margin: 0 2px;
- list-style: none;
- float: left
-}
-.highslide-thumbstrip-float img {
- display: inline;
- border-color: silver;
- max-height: 56px
-}
-.highslide-thumbstrip-float .highslide-active-anchor img {
- border-color: #000
-}
-.highslide-thumbstrip-float .highslide-marker,
-.highslide-thumbstrip-float .highslide-scroll-down div,
-.highslide-thumbstrip-float .highslide-scroll-up div {
- display: none
-} \ No newline at end of file
diff --git a/tools/infra-dashboard/css/opnfv.css b/tools/infra-dashboard/css/opnfv.css
deleted file mode 100644
index da8aa448..00000000
--- a/tools/infra-dashboard/css/opnfv.css
+++ /dev/null
@@ -1,2479 +0,0 @@
-* {
- margin: 0;
- padding: 0;
-}
-.clearfix {
- display: inline-block;
-}
-.clearfix:after {
- content: ".";
- display: block;
- height: 0;
- clear: both;
- visibility: hidden;
-}
-* html .clearfix {
- height: 1%;
-}
-.clearfix {
- display: block;
-}
-.clearleft,
-.clearl,
-.cleft {
- clear: left;
-}
-.clearright,
-.clearr,
-.cright {
- clear: right;
-}
-.clear,
-.clearboth,
-.clearall {
- clear: both;
-}
-.floatleft,
-.fleft,
-.floatl {
- float: left;
- margin: 0 10px 5px 0;
-}
-.floatright,
-.fright,
-.floatr {
- float: right;
- margin: 0 0 5px 10px;
-}
-#skip a:link,
-#skip a:hover,
-#skip a:visited {
- position: absolute;
- left: -10000px;
- top: auto;
- width: 1px;
- height: 1px;
- overflow: hidden;
-}
-#skip a:active,
-#skip a:focus {
- position: static;
- width: auto;
- height: auto;
-}
-div.view div.views-admin-links {
- width: auto;
-}
-div.block {
- position: relative;
-}
-div.block .edit {
- display: none;
- position: absolute;
- right: -20px;
- top: -5px;
- z-index: 40;
- padding: 3px 8px 0;
- font-size: 10px;
- line-height: 16px;
- background-color: white;
- border: 1px solid #cccccc;
- -moz-border-radius: 3px;
- -webkit-border-radius: 3px;
- -moz-box-shadow: 0 1px 3px #888888;
- -webkit-box-shadow: -1px 1px 2px #666666;
-}
-div.block .edit a {
- display: block;
- border: 0;
- padding: 0;
- margin: 0;
-}
-div.block:hover .edit {
- display: block;
-}
-* {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
-}
-.container {
- max-width: 68em;
- margin-left: auto;
- margin-right: auto;
- margin-left: auto;
- margin-right: auto;
- width: 68em;
-}
-.container:after {
- content: "";
- display: table;
- clear: both;
-}
-@media screen and (max-width: 1088px) {
- .container {
- width: auto;
- }
-}
-.no-sidebars #content {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 100%;
-}
-.no-sidebars #content:last-child {
- margin-right: 0;
-}
-@media screen and (max-width: 768px) {
- .no-sidebars #content {
- float: left;
- display: block;
- margin-right: 3.22581%;
- width: 100%;
- }
- .no-sidebars #content:last-child {
- margin-right: 0;
- }
-}
-@media screen and (max-width: 480px) {
- .no-sidebars #content {
- float: left;
- display: block;
- margin-right: 6.66667%;
- width: 100%;
- }
- .no-sidebars #content:last-child {
- margin-right: 0;
- }
-}
-.one-sidebar.sidebar-second #content {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 72.88136%;
-}
-.one-sidebar.sidebar-second #content:last-child {
- margin-right: 0;
-}
-@media screen and (max-width: 768px) {
- .one-sidebar.sidebar-second #content {
- float: left;
- display: block;
- margin-right: 3.22581%;
- width: 74.19355%;
- }
- .one-sidebar.sidebar-second #content:last-child {
- margin-right: 0;
- }
-}
-@media screen and (max-width: 480px) {
- .one-sidebar.sidebar-second #content {
- float: left;
- display: block;
- margin-right: 6.66667%;
- width: 100%;
- }
- .one-sidebar.sidebar-second #content:last-child {
- margin-right: 0;
- }
-}
-.one-sidebar.sidebar-first #content {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 79.66102%;
- margin-left: 20.33898%;
-}
-.one-sidebar.sidebar-first #content:last-child {
- margin-right: 0;
-}
-@media screen and (max-width: 768px) {
- .one-sidebar.sidebar-first #content {
- float: left;
- display: block;
- margin-right: 3.22581%;
- width: 74.19355%;
- margin-left: 25.80645%;
- }
- .one-sidebar.sidebar-first #content:last-child {
- margin-right: 0;
- }
-}
-@media screen and (max-width: 480px) {
- .one-sidebar.sidebar-first #content {
- float: left;
- display: block;
- margin-right: 6.66667%;
- width: 100%;
- margin-left: 0%;
- }
- .one-sidebar.sidebar-first #content:last-child {
- margin-right: 0;
- }
-}
-.two-sidebars #content {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 52.54237%;
- margin-left: 20.33898%;
-}
-.two-sidebars #content:last-child {
- margin-right: 0;
-}
-@media screen and (max-width: 768px) {
- .two-sidebars #content {
- float: left;
- display: block;
- margin-right: 3.22581%;
- width: 48.3871%;
- margin-left: 25.80645%;
- }
- .two-sidebars #content:last-child {
- margin-right: 0;
- }
-}
-@media screen and (max-width: 480px) {
- .two-sidebars #content {
- float: left;
- display: block;
- margin-right: 6.66667%;
- width: 100%;
- margin-left: 0%;
- }
- .two-sidebars #content:last-child {
- margin-right: 0;
- }
-}
-#sidebar-first {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 18.64407%;
- margin-left: -74.57627%;
-}
-#sidebar-first:last-child {
- margin-right: 0;
-}
-.sidebar-first #sidebar-first {
- margin-left: -101.69492%;
-}
-@media screen and (max-width: 768px) {
- #sidebar-first {
- float: left;
- display: block;
- margin-right: 3.22581%;
- width: 22.58065%;
- margin-left: -77.41935%;
- }
- #sidebar-first:last-child {
- margin-right: 0;
- }
- .sidebar-first #sidebar-first {
- margin-left: -103.22581%;
- }
-}
-@media screen and (max-width: 480px) {
- #sidebar-first {
- float: left;
- display: block;
- margin-right: 6.66667%;
- width: 100%;
- margin-left: 0%;
- }
- #sidebar-first:last-child {
- margin-right: 0;
- }
- .sidebar-first #sidebar-first {
- margin-left: 0%;
- }
-}
-#sidebar-second {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 25.42373%;
- margin-left: 0%;
-}
-#sidebar-second:last-child {
- margin-right: 0;
-}
-@media screen and (max-width: 768px) {
- #sidebar-second {
- float: left;
- display: block;
- margin-right: 3.22581%;
- width: 22.58065%;
- margin-left: 0%;
- }
- #sidebar-second:last-child {
- margin-right: 0;
- }
-}
-@media screen and (max-width: 480px) {
- #sidebar-second {
- float: left;
- display: block;
- margin-right: 6.66667%;
- width: 100%;
- margin-left: 0%;
- }
- #sidebar-second:last-child {
- margin-right: 0;
- }
-}
-#footer {
- left: 0;
- width: 100%;
- height: 50px;
- position: fixed;
- bottom: 0;
-}
-#header,
-#footer,
-.mission,
-.breadcrumb,
-.node {
- clear: both;
-}
-.inner {
- padding: 0;
-}
-#navigation li {
- list-style-type: none;
- display: inline-block;
-}
-body {
- margin: 0;
- font: 14px/1.5em "Helvetica Neue", helvetica, Arial, sans-serif;
- letter-spacing: 0.03em;
-}
-a:link,
-a:visited {
- color: blue;
- text-decoration: none;
-}
-a:hover,
-a:active {
- color: red;
- text-decoration: underline;
-}
-#site-name {
- font-size: 2.2em;
- line-height: 1.3em;
- font-weight: 300;
- padding: 0 0 0.5em;
- margin: 0;
-}
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
- line-height: 1.3em;
-}
-h1 {
- font-size: 2.2em;
- font-weight: 300;
- padding: 0 0 0.5em;
- margin: 0;
-}
-h2 {
- font-size: 1.8em;
- font-weight: 300;
- margin-bottom: 0.75em;
-}
-h3 {
- font-size: 1.4em;
- margin-bottom: 1em;
- margin-top: 1em;
-}
-h4 {
- font-size: 1.2em;
- margin-top: 0.8em;
- margin-bottom: 0.8em;
-}
-h5 {
- font-size: 1.1em;
- font-weight: 600;
- margin-bottom: 0;
-}
-h6 {
- font-size: 1em;
- font-weight: bold;
-}
-p {
- margin: 0 0 1em 0;
-}
-ul,
-ol {
- margin-left: 0;
- padding-left: 0;
-}
-table {
- width: 99%;
-}
-table tbody {
- border-top: 0px;
-}
-table tr.even,
-table tr.odd,
-table tr {
- border-bottom: 1px solid #ccc;
-}
-table tr.even td,
-table tr.odd td,
-table tr td {
- padding: 10px 5px;
- vertical-align: top;
-}
-table tr.odd {
- background-color: white;
-}
-pre,
-code,
-tt {
- font: 1em "andale mono", "lucida console", monospace;
- line-height: 1.5;
-}
-pre {
- background-color: #efefef;
- display: block;
- padding: 5px;
- margin: 5px 0;
- border: 1px solid #aaaaaa;
-}
-ul {
- margin-left: 25px;
- list-style-type: disc;
-}
-ul ul {
- list-style-type: circle;
-}
-ul ul ul {
- list-style-type: square;
-}
-ul ul ul ul {
- list-style-type: circle;
-}
-ol {
- list-style-type: decimal;
-}
-ol ol {
- list-style-type: lower-alpha;
-}
-ol ol ol {
- list-style-type: decimal;
-}
-abbr {
- border-bottom: 1px dotted #666666;
- cursor: help;
- white-space: nowrap;
-}
-#edit-title {
- font-size: 24px;
- width: 99%;
-}
-#system-themes-form img {
- width: 100px;
-}
-.form-item .description {
- font-style: italic;
- line-height: 1.2em;
- font-size: 0.8em;
- margin-top: 5px;
- color: #777777;
-}
-#edit-delete {
- color: #cc0000;
-}
-div.messages {
- padding: 9px;
- margin: 1em 0;
- color: #003366;
- background: #bbddff;
- border: 1px solid #aaccee;
-}
-div.warning {
- color: #884400;
- background: #ffee66;
- border-color: #eedd55;
-}
-div.error {
- color: white;
- background: #ee6633;
- border-color: #dd5522;
-}
-div.status {
- color: #336600;
- background: #ccff88;
- border-color: #bbee77;
-}
-#block-views-developer_tools-block {
- padding-top: 48px;
- border-top: 1px solid #cccccc;
-}
-#block-views-developer_tools-block .view-content ul {
- margin: 0;
- padding: 0;
- list-style-type: none;
- list-style-image: none;
-}
-#block-views-developer_tools-block .view-content ul li {
- margin: 0;
- padding: 0;
- height: 100px;
- list-style-type: none;
- list-style-image: none;
- float: left;
- width: 50%;
- margin-bottom: 60px;
-}
-#block-views-developer_tools-block .view-content ul li .views-field-title {
- font-size: 24px;
- color: #f15922;
- text-align: center;
- margin-bottom: 10px;
- font-weight: 400;
-}
-#block-views-developer_tools-block .view-content ul li .views-field-nothing {
- text-align: justify;
-}
-#block-views-developer_tools-block .view-content ul li .views-field-nothing a {
- text-transform: uppercase;
- font-weight: 400;
- font-size: 95%;
-}
-#block-views-developer_tools-block .view-content ul .views-row-odd {
- padding-right: 20px;
-}
-#block-views-developer_tools-block .view-content ul .views-row-even {
- padding-left: 20px;
-}
-#edit-submit-resources {
- margin-top: 0px;
-}
-* {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
-}
-* {
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
-}
-a,
-a:link,
-a:visited {
- color: #41ba77;
-}
-a:hover {
- color: #373A36;
-}
-p {
- color: #373A36;
-}
-#block-menu-menu-social-links li {
- margin: 0;
- padding: 0 3px 0 0;
-}
-#block-menu-menu-social-links li a {
- display: block;
- width: 27px;
- height: 29px;
- text-indent: -9999px;
- overflow: hidden;
- background: url(/sites/all/themes/opnfv/images/optimized/social-icons1.png) no-repeat 0 0;
-}
-#block-menu-menu-social-links li a:hover {
- opacity: 0.7;
-}
-#block-menu-menu-social-links li .twitter {
- background-position: -103px 0;
-}
-#block-menu-menu-social-links li .linkedin {
- background-position: -78px 0;
-}
-#block-menu-menu-social-links li .youtube {
- background-position: -50px 0;
-}
-#block-menu-menu-social-links li .facebook {
- background-position: -26px 0;
-}
-#block-menu-menu-social-links li .gplus {
- background-position: 0 0;
-}
-#block-menu-menu-social-links li .slideshare {
- background-position: -160px 0;
-}
-#block-menu-menu-social-links li .flickr {
- background-position: -212px 0;
-}
-#block-menu-menu-social-links li .vimeo {
- background-position: -185px 0;
-}
-.feed-label {
- vertical-align: text-top;
- margin-left: 5px;
-}
-.block-menu-block a {
- color: #2E2925;
- font-size: 14px;
-}
-.block-menu-block a.active {
- color: #2E2925;
-}
-#header {
- position: relative;
-}
-@media screen and (min-width: 0) and (max-width: 460px) {
- #header {
- top: 0px;
- }
-}
-#header #block-menu-menu-social-links {
- position: relative;
- z-index: 50;
- float: right;
- right: 200px;
-}
-@media screen and (min-width: 640px) and (max-width: 768px) {
- #header #block-menu-menu-social-links {
- top: 62px;
- }
-}
-@media screen and (min-width: 0) and (max-width: 640px) {
- #header #block-menu-menu-social-links {
- right: 0;
- top: 0;
- }
-}
-#header #block-search-form,
-#header #search-block-form {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 100%;
- position: relative;
- z-index: 100;
-}
-#header #block-search-form:last-child,
-#header #search-block-form:last-child {
- margin-right: 0;
-}
-#header #block-search-form .block-inner,
-#header #search-block-form .block-inner {
- text-align: right;
-}
-#header #block-search-form .block-inner .container-inline,
-#header #search-block-form .block-inner .container-inline {
- position: absolute;
- top: -25px;
- right: 9px;
-}
-@media screen and (min-width: 640px) and (max-width: 768px) {
- #header #block-search-form .block-inner .container-inline,
- #header #search-block-form .block-inner .container-inline {
- right: 0;
- top: 36px;
- }
-}
-@media screen and (min-width: 0) and (max-width: 640px) {
- #header #block-search-form .block-inner .container-inline,
- #header #search-block-form .block-inner .container-inline {
- top: 0;
- }
-}
-#header #block-search-form .block-inner .form-text,
-#header #search-block-form .block-inner .form-text {
- width: 130px;
-}
-@media screen and (min-width: 0) and (max-width: 640px) {
- #header #block-search-form .block-inner .form-text,
- #header #search-block-form .block-inner .form-text {
- width: 84px;
- }
-}
-#header #block-search-form #edit-actions .form-submit,
-#header #search-block-form #edit-actions .form-submit {
- background: #ecedee;
- color: #2E2925;
- font-size: 10px;
- border: none;
- padding: 6px 7px;
- top: -2px;
- position: relative;
-}
-#header #block-search-form #edit-actions .form-submit:hover,
-#header #search-block-form #edit-actions .form-submit:hover {
- background: #aeb2b7;
-}
-#header .menu-block-wrapper {
- background: none;
-}
-#header .menu-block-wrapper .menu li {
- list-style: none;
- margin: 0;
-}
-#header .menu-block-wrapper .menu .menu-level-1 {
- display: inline-block;
- vertical-align: top;
- margin: 0 0.5em 0.5em 0;
- padding: 0;
-}
-@media screen and (min-width: 0) and (max-width: 500px) {
- #header .menu-block-wrapper .menu .menu-level-1 {
- width: 100%;
- }
- #header .menu-block-wrapper .menu .menu-level-1 a {
- background: url(/sites/all/themes/opnfv/images/optimized/nav-arrow.png) no-repeat right center #fff;
- }
-}
-@media screen and (min-width: 500px) and (max-width: 700px) {
- #header .menu-block-wrapper .menu .menu-level-1 {
- width: 48%;
- }
- #header .menu-block-wrapper .menu .menu-level-1 a {
- background: url(/sites/all/themes/opnfv/images/optimized/nav-arrow.png) no-repeat right center #fff;
- }
-}
-#header .menu-block-wrapper .menu .menu-level-1 > a {
- display: block;
- width: 100%;
- margin: 0 auto 0.25em;
- font-size: 0.9em;
- padding: 10px 15px;
- text-transform: uppercase;
-}
-#header .menu-block-wrapper .menu .menu-level-1 > a.selected,
-#header .menu-block-wrapper .menu .menu-level-1 > a:hover {
- background-color: #ecedee;
-}
-.no-touch #header {
- height: 103px;
-}
-.no-touch .site-menus-container {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 72.88136%;
- margin-left: 27.11864%;
-}
-.no-touch .site-menus-container:last-child {
- margin-right: 0;
-}
-@media screen and (min-width: 750px) and (max-width: 980px) {
- .no-touch .site-menus-container {
- height: 240px;
- }
-}
-@media screen and (min-width: 490px) and (max-width: 750px) {
- .no-touch .site-menus-container {
- height: 280px;
- }
-}
-.no-touch .logo-container {
- position: relative;
- z-index: 2;
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 18.64407%;
- margin-left: 0%;
-}
-.no-touch .logo-container:last-child {
- margin-right: 0;
-}
-.no-touch .logo-container-positioning {
- position: relative;
- top: 2px;
- left: 0;
-}
-@media screen and (min-width: 0) and (max-width: 460px) {
- .no-touch .logo-container-positioning {
- top: 0;
- }
-}
-.no-touch .logo-container-positioning .logo-container {
- padding-top: 0;
-}
-@media screen and (min-width: 0) and (max-width: 460px) {
- .no-touch .logo-container-positioning .logo-container {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 100%;
- }
- .no-touch .logo-container-positioning .logo-container:last-child {
- margin-right: 0;
- }
- .no-touch .logo-container-positioning .logo-container #logo {
- width: 46% !important;
- }
- .no-touch .logo-container-positioning .logo-container #logo img {
- width: 100%;
- }
-}
-.no-touch .site-menus-container-positioning {
- position: relative;
- top: -60px;
- z-index: 1;
-}
-.no-touch #site-menus .menu {
- text-align: right;
- position: relative;
-}
-@media screen and (min-width: 0) and (max-width: 768px) {
- .no-touch #header {
- height: 140px;
- }
- .no-touch #header #site-menus .menu {
- text-align: left;
- }
- .no-touch #header .site-menus-container {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 100%;
- margin-left: 0%;
- }
- .no-touch #header .site-menus-container:last-child {
- margin-right: 0;
- }
- .no-touch #header .site-menus-container-positioning {
- position: relative;
- top: 0;
- padding-top: 0;
- }
-}
-@media screen and (min-width: 490px) and (max-width: 700px) {
- .no-touch #header {
- height: 260px;
- }
-}
-@media screen and (min-width: 0) and (max-width: 500px) {
- .no-touch #header {
- height: auto;
- }
-}
-.collapsible-menu #header {
- top: 0;
-}
-.collapsible-menu #header #block-search-form .container-inline,
-.collapsible-menu #header #search-block-form .container-inline {
- position: absolute;
- top: 110px;
- right: 0;
-}
-.collapsible-menu #header #site-name {
- position: absolute;
- top: 0;
-}
-.collapsible-menu #header .logo-container-positioning {
- position: relative;
- top: -40px;
- left: -10px;
- padding: 0 0 25px;
-}
-.collapsible-menu #header .logo-container-positioning .container {
- padding-top: 15px;
-}
-@media screen and (min-width: 0) and (max-width: 460px) {
- .collapsible-menu #header .logo-container-positioning #logo {
- width: 48% !important;
- margin-top: 25px;
- height: 55px;
- }
- .collapsible-menu #header .logo-container-positioning #logo img {
- width: 100%;
- }
-}
-.collapsible-menu #header .menu-block-wrapper .menu .menu-level-1 {
- border-left: 4px solid #A3D783;
-}
-.collapsible-menu #header .menu-block-wrapper .menu .menu-level-1 > a {
- background-color: #2E2925;
- color: #fff;
- margin-bottom: 0;
- padding-bottom: 0.5em;
-}
-.collapsible-menu #header .site-menus-container-positioning {
- background: #ecedee;
- color: #fff;
- padding-top: 0;
-}
-.collapsible-menu #header .site-menus-container ul {
- margin-top: 0.75em;
-}
-.collapsible-menu #header .menu-button-wrapper {
- position: relative;
-}
-.collapsible-menu #header .menu-button-wrapper .menu-button {
- position: absolute;
- right: -15px;
- top: 10px;
- border: 1px solid #ccc;
- background: #ddd;
- padding: 4px 14px;
- border-radius: 8px 8px 8px 8px;
- -moz-border-radius: 8px 8px 8px 8px;
- -webkit-border-top-left-radius: 8px;
- -webkit-border-top-right-radius: 8px;
- -webkit-border-bottom-right-radius: 8px;
- -webkit-border-bottom-left-radius: 8px;
- color: #2E2925;
- cursor: pointer;
-}
-.collapsible-menu #header #block-menu-menu-social-links {
- position: relative;
- right: 0;
- top: 70px;
-}
-.collapsible-menu #header #block-search-form .block-inner .container-inline,
-.collapsible-menu #header #search-block-form .block-inner .container-inline {
- right: 0;
- top: 75px;
-}
-#menu-tray {
- width: 100%;
- min-height: 20px;
- position: absolute;
- z-index: 1000;
- top: 0;
- background: #ecedee;
- color: #fff;
- opacity: 0;
- -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
- box-shadow: 0 8px 7px 1px rgba(0, 0, 0, 0.45);
-}
-#menu-tray .initially-hidden {
- opacity: 0;
- -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
-}
-#menu-tray.menu-tray-transition {
- -webkit-transition: opacity 0.25s ease-in-out;
- -moz-transition: opacity 0.25s ease-in-out;
- transition: opacity 0.25s ease-in-out;
- pointer-events: auto;
- opacity: 1;
- -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
-}
-#menu-tray .menu {
- padding: 20px;
-}
-#menu-tray.docked {
- pointer-events: none;
- opacity: 0;
- -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
-}
-#menu-tray a {
- color: #fff;
- word-wrap: break-word;
-}
-#menu-tray .menu .menu-level-2 {
- display: inline-block;
- vertical-align: top;
- width: 25%;
- margin: 0 0 0.25em 0;
- padding: 0;
-}
-@media screen and (min-width: 0) and (max-width: 500px) {
- #menu-tray .menu .menu-level-2 {
- width: 100%;
- }
-}
-@media screen and (min-width: 500px) and (max-width: 700px) {
- #menu-tray .menu .menu-level-2 {
- width: 50%;
- }
-}
-@media screen and (min-width: 700px) and (max-width: 900px) {
- #menu-tray .menu .menu-level-2 {
- width: 33.33%;
- }
-}
-#menu-tray .menu .menu-level-2 > a {
- display: block;
- background: url(/sites/all/themes/opnfv/images/optimized/nav-arrow.png) no-repeat right center #2E2925;
- border-left: 5px solid #086960;
- width: 99%;
- margin: 0 auto 0.25em;
- padding: 7px;
-}
-#menu-tray .menu .menu-level-2 .link-order-1 {
- border-left: 5px solid #a4d384;
-}
-#menu-tray .menu .menu-level-2 .link-order-2 {
- border-left: 5px solid #00adbb;
-}
-#menu-tray .menu .menu-level-2 .menu {
- font-size: 12px;
- padding-top: 0;
- padding-bottom: 0;
-}
-#menu-tray .menu .menu-level-2 .menu li {
- list-style: none;
-}
-#menu-tray .menu .menu-level-2 .menu a {
- color: #000;
- border-left: none;
-}
-#footer .menu-block-wrapper {
- background: none;
-}
-#footer .menu-block-wrapper .menu li {
- list-style: none;
- margin: 0;
-}
-#footer .menu-block-wrapper .menu li a {
- word-wrap: break-word;
-}
-#footer .menu-block-wrapper .menu .menu-level-1 {
- display: inline-block;
- vertical-align: top;
- width: 25%;
- margin: 0 0 3em 0;
- padding: 0;
-}
-@media screen and (min-width: 0) and (max-width: 500px) {
- #footer .menu-block-wrapper .menu .menu-level-1 {
- width: 100%;
- }
-}
-@media screen and (min-width: 500px) and (max-width: 700px) {
- #footer .menu-block-wrapper .menu .menu-level-1 {
- width: 50%;
- }
-}
-@media screen and (min-width: 700px) and (max-width: 900px) {
- #footer .menu-block-wrapper .menu .menu-level-1 {
- width: 33.33%;
- }
-}
-#footer .menu-block-wrapper .menu .menu-level-1 > a {
- display: block;
- width: 95%;
- margin: 0 auto 0.25em;
- padding: 7px;
- text-transform: uppercase;
- background: url(/sites/all/themes/opnfv/images/optimized/nav-arrow.png) no-repeat right center #0095a2;
- border-left: 5px solid #007e88;
- color: #fff;
-}
-#footer .menu-block-wrapper .menu .menu-level-2 {
- width: 85%;
- margin: 0 auto;
- font-size: 15px;
- list-style: square;
- color: #009fac;
-}
-#footer .menu-block-wrapper .menu .menu-level-2 a {
- color: #fff;
- display: inline-block;
- padding-bottom: 7px;
- word-wrap: break-word;
-}
-#footer .menu-block-wrapper .menu .menu-level-2 > .menu {
- border-bottom: 1px solid #008792;
- margin-bottom: 1.2em;
-}
-#footer .menu-block-wrapper .menu .menu-level-3 {
- display: block;
- width: 100%;
- padding-left: 1.6em;
- border-top: 1px solid #009fac;
- background: #00a8b6;
-}
-#footer .menu-block-wrapper .menu .menu-level-3 a {
- font-size: 0.75em;
-}
-#block-menu_block-1 ul ul,
-#block-menu_block-1 .menu-level-2,
-#footer #block-menu_block-3 .block-title {
- display: none;
-}
-#block-menu-menu-social-links li {
- float: left;
- list-style: none;
-}
-.view-blogs .view-header {
- float: right;
-}
-.view-blogs .view-header a {
- text-decoration: none;
-}
-.view-blogs .view-header img {
- vertical-align: text-top;
-}
-body {
- background: #fff;
-}
-#content {
- padding: 0 20px;
- margin-bottom: 2em;
-}
-.breadcrumb a {
- text-transform: uppercase;
- font-size: 0.8em;
- padding: 0 0.35em;
-}
-.breadcrumb a:first-child {
- padding-left: 0;
-}
-.blog_usernames_blog a,
-.node-readmore a {
- color: #A3D783;
- text-transform: uppercase;
-}
-#page {
- margin-bottom: 0;
- padding-bottom: 0;
-}
-.collaborative-projects {
- background-image: -webkit-linear-gradient(right center, #D0D1D1 0, #E6E6E6 69%);
- background-image: linear-gradient(to left, #D0D1D1 0, #E6E6E6 69%);
- background-color: #D0D1D1;
- min-height: 30px;
-}
-.collaborative-projects .gray-diagonal {
- min-height: 30px;
- width: 100%;
- background: url(../media/diagonal-white.png) transparent repeat scroll top left;
-}
-.collaborative-projects #collaborative-projects-logo {
- margin-top: 10px;
- height: 14px;
- background: url(../media/collaborative-projects-logo.png) no-repeat scroll 10px center transparent;
- width: 100%;
- max-width: 400px;
- float: left;
- text-indent: -9000px;
-}
-@media screen and (min-width: 0) and (max-width: 500px) {
- .collaborative-projects #collaborative-projects-logo {
- width: 95%;
- position: relative;
- left: 8px;
- background-position: 0 center;
- -webkit-background-size: contain;
- -moz-background-size: contain;
- -o-background-size: contain;
- background-size: contain;
- }
-}
-.collaborative-projects #footer-copyright {
- padding: 16px 0px 16px 20px;
- font-size: 11px;
- line-height: 16px;
- font-weight: 300;
-}
-.collaborative-projects #footer-copyright p {
- margin: 0;
- font-family: Helvetica, Arial, "Lucida Grande", sans-serif;
-}
-.collaborative-projects #footer-copyright a {
- text-decoration: underline;
- color: #393939;
-}
-.collaborative-projects #footer-copyright a:hover {
- text-decoration: none;
- color: #0099EE;
-}
-.page-page-not-found #content {
- margin: 3em 0 5em;
- text-align: center;
-}
-.page-page-not-found #content p {
- line-height: 2em;
-}
-#block-views-members-block_2 .views-row,
-#block-views-members-block_5 .views-row,
-#block-views-members-block_6 .views-row {
- border-bottom: 1px solid #ccc;
- margin-bottom: 20px;
- padding-bottom: 20px;
-}
-#block-views-members-block_2 .member-info,
-#block-views-members-block_5 .member-info,
-#block-views-members-block_6 .member-info {
- margin-bottom: 20px;
- position: relative;
-}
-#block-views-members-block_2 .member-info:after,
-#block-views-members-block_5 .member-info:after,
-#block-views-members-block_6 .member-info:after {
- content: "";
- display: table;
- clear: both;
-}
-#block-views-members-block_2 .member-info .column-last,
-#block-views-members-block_5 .member-info .column-last,
-#block-views-members-block_6 .member-info .column-last {
- bottom: -3px;
- left: 0;
- padding-left: 120px;
- position: absolute;
- width: 100%;
-}
-#block-views-members-block_2 .member-info .column-last *,
-#block-views-members-block_5 .member-info .column-last *,
-#block-views-members-block_6 .member-info .column-last * {
- line-height: 120%;
- margin: 0;
-}
-#block-views-members-block_2 .member-info img,
-#block-views-members-block_5 .member-info img,
-#block-views-members-block_6 .member-info img {
- display: block;
-}
-#block-views-members-block_2 .member-info h3,
-#block-views-members-block_5 .member-info h3,
-#block-views-members-block_6 .member-info h3 {
- font-size: 1em;
-}
-#block-views-members-block_2 .member-info .board-member-title,
-#block-views-members-block_5 .member-info .board-member-title,
-#block-views-members-block_6 .member-info .board-member-title {
- font-weight: normal;
- padding-left: 0;
-}
-#block-views-members-block_2 p:last-child,
-#block-views-members-block_5 p:last-child,
-#block-views-members-block_6 p:last-child {
- margin-bottom: 0;
-}
-#block-views-members-block_2 .member-website,
-#block-views-members-block_5 .member-website,
-#block-views-members-block_6 .member-website {
- margin-top: 10px;
-}
-.page-news-resources .views-row,
-#block-views-resources-block_1 .views-row {
- margin-bottom: 10px;
-}
-.page-news-resources .views-row:after,
-#block-views-resources-block_1 .views-row:after {
- content: "";
- display: table;
- clear: both;
-}
-.page-news-resources .views-row .views-field-nothing,
-#block-views-resources-block_1 .views-row .views-field-nothing {
- float: left;
- width: 80%;
-}
-.page-news-resources .views-row .views-field-field-thumbnail,
-#block-views-resources-block_1 .views-row .views-field-field-thumbnail {
- float: right;
- margin: 5px 0 20px 0;
- width: 15%;
-}
-.page-news-resources .views-row .views-field-field-thumbnail img,
-#block-views-resources-block_1 .views-row .views-field-field-thumbnail img {
- display: block;
- height: auto;
- max-width: 100%;
-}
-.page-news-resources .view-empty,
-#block-views-resources-block_1 .view-empty {
- margin-bottom: 1em;
- padding: 1em;
-}
-.page-news-resources .more-link,
-#block-views-resources-block_1 .more-link {
- bottom: 2em;
- font-size: 0.8em;
- position: absolute;
- text-align: center;
- text-transform: uppercase;
- width: 100%;
-}
-#block-views-collateral-block_1 .views-row {
- margin-bottom: 10px;
-}
-#block-views-collateral-block_1 .view-empty {
- margin-bottom: 1em;
- padding: 1em;
-}
-#block-views-collateral-block_1 .more-link {
- bottom: 2em;
- font-size: 0.8em;
- position: absolute;
- text-align: center;
- text-transform: uppercase;
- width: 100%;
-}
-.not-front #block-views-news_and_announcements-block,
-.not-front #block-views-news_and_announcements-block_1,
-.not-front #block-twitter_helper-twitter_block_1,
-.not-front #block-views-events-block,
-.not-front #block-views-blogs-block,
-.not-front #block-views-faq-faq_recent,
-.not-front #block-views-resources-block_1,
-.not-front #block-views-collateral-block_1,
-.not-front #block-views-videos-block {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 32.20339%;
- height: 450px;
- margin-bottom: 2em;
- margin-right: 5px;
- background: #ecedee;
- z-index: 1;
-}
-.not-front #block-views-news_and_announcements-block:last-child,
-.not-front #block-views-news_and_announcements-block_1:last-child,
-.not-front #block-twitter_helper-twitter_block_1:last-child,
-.not-front #block-views-events-block:last-child,
-.not-front #block-views-blogs-block:last-child,
-.not-front #block-views-faq-faq_recent:last-child,
-.not-front #block-views-resources-block_1:last-child,
-.not-front #block-views-collateral-block_1:last-child,
-.not-front #block-views-videos-block:last-child {
- margin-right: 0;
-}
-@media screen and (min-width: 0) and (max-width: 700px) {
- .not-front #block-views-news_and_announcements-block,
- .not-front #block-views-news_and_announcements-block_1,
- .not-front #block-twitter_helper-twitter_block_1,
- .not-front #block-views-events-block,
- .not-front #block-views-blogs-block,
- .not-front #block-views-faq-faq_recent,
- .not-front #block-views-resources-block_1,
- .not-front #block-views-collateral-block_1,
- .not-front #block-views-videos-block {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 100%;
- height: auto;
- min-height: 300px;
- }
- .not-front #block-views-news_and_announcements-block:last-child,
- .not-front #block-views-news_and_announcements-block_1:last-child,
- .not-front #block-twitter_helper-twitter_block_1:last-child,
- .not-front #block-views-events-block:last-child,
- .not-front #block-views-blogs-block:last-child,
- .not-front #block-views-faq-faq_recent:last-child,
- .not-front #block-views-resources-block_1:last-child,
- .not-front #block-views-collateral-block_1:last-child,
- .not-front #block-views-videos-block:last-child {
- margin-right: 0;
- }
-}
-.not-front #block-views-news_and_announcements-block.block-twitter-helper,
-.not-front #block-views-news_and_announcements-block_1.block-twitter-helper,
-.not-front #block-twitter_helper-twitter_block_1.block-twitter-helper,
-.not-front #block-views-events-block.block-twitter-helper,
-.not-front #block-views-blogs-block.block-twitter-helper,
-.not-front #block-views-faq-faq_recent.block-twitter-helper,
-.not-front #block-views-resources-block_1.block-twitter-helper,
-.not-front #block-views-collateral-block_1.block-twitter-helper,
-.not-front #block-views-videos-block.block-twitter-helper {
- margin-right: 0;
-}
-.not-front #block-views-news_and_announcements-block.block-twitter-helper .all-tweets,
-.not-front #block-views-news_and_announcements-block_1.block-twitter-helper .all-tweets,
-.not-front #block-twitter_helper-twitter_block_1.block-twitter-helper .all-tweets,
-.not-front #block-views-events-block.block-twitter-helper .all-tweets,
-.not-front #block-views-blogs-block.block-twitter-helper .all-tweets,
-.not-front #block-views-faq-faq_recent.block-twitter-helper .all-tweets,
-.not-front #block-views-resources-block_1.block-twitter-helper .all-tweets,
-.not-front #block-views-collateral-block_1.block-twitter-helper .all-tweets,
-.not-front #block-views-videos-block.block-twitter-helper .all-tweets {
- position: absolute;
- bottom: 2em;
- left: 0;
- width: 100%;
- text-align: center;
- font-size: 0.8em;
- text-transform: uppercase;
-}
-@media screen and (min-width: 0) and (max-width: 700px) {
- .not-front #block-views-news_and_announcements-block.block-twitter-helper .all-tweets,
- .not-front #block-views-news_and_announcements-block_1.block-twitter-helper .all-tweets,
- .not-front #block-twitter_helper-twitter_block_1.block-twitter-helper .all-tweets,
- .not-front #block-views-events-block.block-twitter-helper .all-tweets,
- .not-front #block-views-blogs-block.block-twitter-helper .all-tweets,
- .not-front #block-views-faq-faq_recent.block-twitter-helper .all-tweets,
- .not-front #block-views-resources-block_1.block-twitter-helper .all-tweets,
- .not-front #block-views-collateral-block_1.block-twitter-helper .all-tweets,
- .not-front #block-views-videos-block.block-twitter-helper .all-tweets {
- bottom: 0.5em;
- }
-}
-.not-front #block-views-news_and_announcements-block.block-twitter-helper .block-title,
-.not-front #block-views-news_and_announcements-block_1.block-twitter-helper .block-title,
-.not-front #block-twitter_helper-twitter_block_1.block-twitter-helper .block-title,
-.not-front #block-views-events-block.block-twitter-helper .block-title,
-.not-front #block-views-blogs-block.block-twitter-helper .block-title,
-.not-front #block-views-faq-faq_recent.block-twitter-helper .block-title,
-.not-front #block-views-resources-block_1.block-twitter-helper .block-title,
-.not-front #block-views-collateral-block_1.block-twitter-helper .block-title,
-.not-front #block-views-videos-block.block-twitter-helper .block-title {
- background: #71c48f;
-}
-.not-front #block-views-news_and_announcements-block.block-twitter-helper ul,
-.not-front #block-views-news_and_announcements-block_1.block-twitter-helper ul,
-.not-front #block-twitter_helper-twitter_block_1.block-twitter-helper ul,
-.not-front #block-views-events-block.block-twitter-helper ul,
-.not-front #block-views-blogs-block.block-twitter-helper ul,
-.not-front #block-views-faq-faq_recent.block-twitter-helper ul,
-.not-front #block-views-resources-block_1.block-twitter-helper ul,
-.not-front #block-views-collateral-block_1.block-twitter-helper ul,
-.not-front #block-views-videos-block.block-twitter-helper ul {
- list-style: none;
-}
-.not-front #block-views-news_and_announcements-block.block-twitter-helper li,
-.not-front #block-views-news_and_announcements-block_1.block-twitter-helper li,
-.not-front #block-twitter_helper-twitter_block_1.block-twitter-helper li,
-.not-front #block-views-events-block.block-twitter-helper li,
-.not-front #block-views-blogs-block.block-twitter-helper li,
-.not-front #block-views-faq-faq_recent.block-twitter-helper li,
-.not-front #block-views-resources-block_1.block-twitter-helper li,
-.not-front #block-views-collateral-block_1.block-twitter-helper li,
-.not-front #block-views-videos-block.block-twitter-helper li {
- margin-bottom: 1em;
-}
-.not-front #block-views-news_and_announcements-block.block-twitter-helper li img,
-.not-front #block-views-news_and_announcements-block_1.block-twitter-helper li img,
-.not-front #block-twitter_helper-twitter_block_1.block-twitter-helper li img,
-.not-front #block-views-events-block.block-twitter-helper li img,
-.not-front #block-views-blogs-block.block-twitter-helper li img,
-.not-front #block-views-faq-faq_recent.block-twitter-helper li img,
-.not-front #block-views-resources-block_1.block-twitter-helper li img,
-.not-front #block-views-collateral-block_1.block-twitter-helper li img,
-.not-front #block-views-videos-block.block-twitter-helper li img {
- float: left;
- margin-right: 1em;
-}
-.not-front #block-views-news_and_announcements-block.block-twitter-helper li .tweet_time,
-.not-front #block-views-news_and_announcements-block_1.block-twitter-helper li .tweet_time,
-.not-front #block-twitter_helper-twitter_block_1.block-twitter-helper li .tweet_time,
-.not-front #block-views-events-block.block-twitter-helper li .tweet_time,
-.not-front #block-views-blogs-block.block-twitter-helper li .tweet_time,
-.not-front #block-views-faq-faq_recent.block-twitter-helper li .tweet_time,
-.not-front #block-views-resources-block_1.block-twitter-helper li .tweet_time,
-.not-front #block-views-collateral-block_1.block-twitter-helper li .tweet_time,
-.not-front #block-views-videos-block.block-twitter-helper li .tweet_time {
- display: block;
- font-size: 0.8em;
-}
-.not-front #block-views-news_and_announcements-block.block-twitter-helper li .tweet_text,
-.not-front #block-views-news_and_announcements-block_1.block-twitter-helper li .tweet_text,
-.not-front #block-twitter_helper-twitter_block_1.block-twitter-helper li .tweet_text,
-.not-front #block-views-events-block.block-twitter-helper li .tweet_text,
-.not-front #block-views-blogs-block.block-twitter-helper li .tweet_text,
-.not-front #block-views-faq-faq_recent.block-twitter-helper li .tweet_text,
-.not-front #block-views-resources-block_1.block-twitter-helper li .tweet_text,
-.not-front #block-views-collateral-block_1.block-twitter-helper li .tweet_text,
-.not-front #block-views-videos-block.block-twitter-helper li .tweet_text {
- font-size: 10px;
-}
-@media screen and (min-width: 900px) {
- .not-front #block-views-news_and_announcements-block.block-twitter-helper li .tweet_text,
- .not-front #block-views-news_and_announcements-block_1.block-twitter-helper li .tweet_text,
- .not-front #block-twitter_helper-twitter_block_1.block-twitter-helper li .tweet_text,
- .not-front #block-views-events-block.block-twitter-helper li .tweet_text,
- .not-front #block-views-blogs-block.block-twitter-helper li .tweet_text,
- .not-front #block-views-faq-faq_recent.block-twitter-helper li .tweet_text,
- .not-front #block-views-resources-block_1.block-twitter-helper li .tweet_text,
- .not-front #block-views-collateral-block_1.block-twitter-helper li .tweet_text,
- .not-front #block-views-videos-block.block-twitter-helper li .tweet_text {
- font-size: 0.9em;
- }
-}
-.not-front #block-views-news_and_announcements-block.block-even .block-title,
-.not-front #block-views-news_and_announcements-block_1.block-even .block-title,
-.not-front #block-twitter_helper-twitter_block_1.block-even .block-title,
-.not-front #block-views-events-block.block-even .block-title,
-.not-front #block-views-blogs-block.block-even .block-title,
-.not-front #block-views-faq-faq_recent.block-even .block-title,
-.not-front #block-views-resources-block_1.block-even .block-title,
-.not-front #block-views-collateral-block_1.block-even .block-title,
-.not-front #block-views-videos-block.block-even .block-title {
- background: #177870;
-}
-.not-front #block-views-news_and_announcements-block .block-title,
-.not-front #block-views-news_and_announcements-block_1 .block-title,
-.not-front #block-twitter_helper-twitter_block_1 .block-title,
-.not-front #block-views-events-block .block-title,
-.not-front #block-views-blogs-block .block-title,
-.not-front #block-views-faq-faq_recent .block-title,
-.not-front #block-views-resources-block_1 .block-title,
-.not-front #block-views-collateral-block_1 .block-title,
-.not-front #block-views-videos-block .block-title {
- background: #00ADBB;
- color: #fff;
- font-size: 1.25em;
- padding: .75em .5em;
- text-align: center;
- text-transform: uppercase;
-}
-.not-front #block-views-news_and_announcements-block .block-title a,
-.not-front #block-views-news_and_announcements-block_1 .block-title a,
-.not-front #block-twitter_helper-twitter_block_1 .block-title a,
-.not-front #block-views-events-block .block-title a,
-.not-front #block-views-blogs-block .block-title a,
-.not-front #block-views-faq-faq_recent .block-title a,
-.not-front #block-views-resources-block_1 .block-title a,
-.not-front #block-views-collateral-block_1 .block-title a,
-.not-front #block-views-videos-block .block-title a {
- color: #fff;
-}
-.not-front #block-views-news_and_announcements-block .view-content,
-.not-front #block-views-news_and_announcements-block_1 .view-content,
-.not-front #block-twitter_helper-twitter_block_1 .view-content,
-.not-front #block-views-events-block .view-content,
-.not-front #block-views-blogs-block .view-content,
-.not-front #block-views-faq-faq_recent .view-content,
-.not-front #block-views-resources-block_1 .view-content,
-.not-front #block-views-collateral-block_1 .view-content,
-.not-front #block-views-videos-block .view-content {
- margin-bottom: 1em;
- padding: 1em;
-}
-.not-front #block-views-news_and_announcements-block .view-footer,
-.not-front #block-views-news_and_announcements-block_1 .view-footer,
-.not-front #block-twitter_helper-twitter_block_1 .view-footer,
-.not-front #block-views-events-block .view-footer,
-.not-front #block-views-blogs-block .view-footer,
-.not-front #block-views-faq-faq_recent .view-footer,
-.not-front #block-views-resources-block_1 .view-footer,
-.not-front #block-views-collateral-block_1 .view-footer,
-.not-front #block-views-videos-block .view-footer {
- text-transform: uppercase;
- font-size: 0.8em;
- position: absolute;
- bottom: 2em;
- width: 100%;
- text-align: center;
-}
-@media screen and (min-width: 0) and (max-width: 700px) {
- .not-front #block-views-news_and_announcements-block .view-footer,
- .not-front #block-views-news_and_announcements-block_1 .view-footer,
- .not-front #block-twitter_helper-twitter_block_1 .view-footer,
- .not-front #block-views-events-block .view-footer,
- .not-front #block-views-blogs-block .view-footer,
- .not-front #block-views-faq-faq_recent .view-footer,
- .not-front #block-views-resources-block_1 .view-footer,
- .not-front #block-views-collateral-block_1 .view-footer,
- .not-front #block-views-videos-block .view-footer {
- bottom: 0.5em;
- }
-}
-.not-front .view-blogs .block-row,
-.not-front .view-events .block-row,
-.not-front .view-news-and-announcements .block-row,
-.not-front .view-videos .block-row {
- margin-bottom: 1.5em;
-}
-.not-front .view-blogs .views-field,
-.not-front .view-events .views-field,
-.not-front .view-news-and-announcements .views-field,
-.not-front .view-videos .views-field {
- margin-bottom: 0.25em;
-}
-.not-front .view-blogs .views-field-type,
-.not-front .view-blogs .views-field-field-event-address,
-.not-front .view-events .views-field-type,
-.not-front .view-events .views-field-field-event-address,
-.not-front .view-news-and-announcements .views-field-type,
-.not-front .view-news-and-announcements .views-field-field-event-address,
-.not-front .view-videos .views-field-type,
-.not-front .view-videos .views-field-field-event-address {
- font-style: italic;
- font-size: 0.95em;
-}
-.not-front .view-blogs .views-field-title,
-.not-front .view-events .views-field-title,
-.not-front .view-news-and-announcements .views-field-title,
-.not-front .view-videos .views-field-title {
- font-size: 11px;
-}
-@media screen and (min-width: 900px) {
- .not-front .view-blogs .views-field-title,
- .not-front .view-events .views-field-title,
- .not-front .view-news-and-announcements .views-field-title,
- .not-front .view-videos .views-field-title {
- font-size: 1.1em;
- }
-}
-.not-front .view-blogs .views-field-created,
-.not-front .view-events .views-field-created,
-.not-front .view-news-and-announcements .views-field-created,
-.not-front .view-videos .views-field-created {
- font-style: italic;
- font-size: 0.8em;
-}
-.not-front #block-views-faq-faq_recent .more-link {
- position: absolute;
- width: 100%;
- text-align: center;
- bottom: 30px;
-}
-.not-front .view-videos .views-row {
- display: block;
- height: 150px;
- margin-bottom: 1em;
-}
-.not-front .view-videos .view-empty {
- padding: 1em;
-}
-.not-front .view-videos .views-field-nothing {
- position: relative;
- float: left;
- margin-right: 10px;
-}
-.not-front .view-videos .views-field-nothing a {
- text-transform: uppercase;
-}
-.not-front .view-videos .views-field-body {
- margin-top: 20px;
- font-size: 10px;
-}
-@media screen and (min-width: 900px) {
- .not-front .view-videos .views-field-body {
- font-size: 0.9em;
- }
-}
-.front .title {
- display: none;
-}
-.front #content {
- padding-top: 20px;
- max-width: 68em;
- margin-left: auto;
- margin-right: auto;
-}
-.front #content:after {
- content: "";
- display: table;
- clear: both;
-}
-.front .custom_home_block {
- background: transparent none repeat scroll 0 0 !important;
- clear: both !important;
- color: #000 !important;
- height: auto !important;
- width: 100% !important;
- font-size: 0.8em !important;
- margin-top: 0px !important;
- margin-bottom: 5px !important;
-}
-.front .custom_home_block .content {
- padding: 0px !important;
-}
-.front .custom_home_block .content p {
- margin: 0px;
-}
-.front .custom_home_block img {
- width: 100%;
-}
-.front .block-views,
-.front .block-block,
-.front .block-twitter-helper {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 32.20339%;
- height: 500px;
- margin-bottom: 2em;
- background: #ecedee;
-}
-.front .block-views:last-child,
-.front .block-block:last-child,
-.front .block-twitter-helper:last-child {
- margin-right: 0;
-}
-@media screen and (min-width: 0) and (max-width: 700px) {
- .front .block-views,
- .front .block-block,
- .front .block-twitter-helper {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 100%;
- height: auto;
- }
- .front .block-views:last-child,
- .front .block-block:last-child,
- .front .block-twitter-helper:last-child {
- margin-right: 0;
- }
-}
-.front .block-views.block-twitter-helper,
-.front .block-block.block-twitter-helper,
-.front .block-twitter-helper.block-twitter-helper {
- margin-right: 0;
-}
-.front .block-views.block-twitter-helper .all-tweets,
-.front .block-block.block-twitter-helper .all-tweets,
-.front .block-twitter-helper.block-twitter-helper .all-tweets {
- position: absolute;
- bottom: 2em;
- left: 0;
- width: 100%;
- text-align: center;
- font-size: 0.8em;
- text-transform: uppercase;
-}
-@media screen and (min-width: 0) and (max-width: 700px) {
- .front .block-views.block-twitter-helper .all-tweets,
- .front .block-block.block-twitter-helper .all-tweets,
- .front .block-twitter-helper.block-twitter-helper .all-tweets {
- bottom: 0.5em;
- }
-}
-.front .block-views.block-twitter-helper .block-title,
-.front .block-block.block-twitter-helper .block-title,
-.front .block-twitter-helper.block-twitter-helper .block-title {
- background: #71c48f;
-}
-.front .block-views.block-twitter-helper ul,
-.front .block-block.block-twitter-helper ul,
-.front .block-twitter-helper.block-twitter-helper ul {
- list-style: none;
-}
-.front .block-views.block-twitter-helper li,
-.front .block-block.block-twitter-helper li,
-.front .block-twitter-helper.block-twitter-helper li {
- margin-bottom: 1em;
-}
-.front .block-views.block-twitter-helper li img,
-.front .block-block.block-twitter-helper li img,
-.front .block-twitter-helper.block-twitter-helper li img {
- float: left;
- margin-right: 1em;
-}
-.front .block-views.block-twitter-helper li .tweet_time,
-.front .block-block.block-twitter-helper li .tweet_time,
-.front .block-twitter-helper.block-twitter-helper li .tweet_time {
- display: block;
- font-size: 0.8em;
-}
-.front .block-views.block-twitter-helper li .tweet_text,
-.front .block-block.block-twitter-helper li .tweet_text,
-.front .block-twitter-helper.block-twitter-helper li .tweet_text {
- font-size: 10px;
-}
-@media screen and (min-width: 900px) {
- .front .block-views.block-twitter-helper li .tweet_text,
- .front .block-block.block-twitter-helper li .tweet_text,
- .front .block-twitter-helper.block-twitter-helper li .tweet_text {
- font-size: 0.9em;
- }
-}
-.front .block-views.block-even .block-title,
-.front .block-block.block-even .block-title,
-.front .block-twitter-helper.block-even .block-title {
- background: #177870;
-}
-.front .block-views .block-title,
-.front .block-block .block-title,
-.front .block-twitter-helper .block-title {
- background: #00ADBB;
- color: #fff;
- font-size: 1.25em;
- padding: .75em .5em;
- text-align: center;
- text-transform: uppercase;
-}
-.front .block-views .block-title a,
-.front .block-block .block-title a,
-.front .block-twitter-helper .block-title a {
- color: #fff;
-}
-.front .block-views .content,
-.front .block-block .content,
-.front .block-twitter-helper .content {
- padding: 1em;
-}
-.front .block-views .view-content,
-.front .block-block .view-content,
-.front .block-twitter-helper .view-content {
- margin-bottom: 1em;
-}
-.front .block-views .view-footer,
-.front .block-block .view-footer,
-.front .block-twitter-helper .view-footer {
- text-transform: uppercase;
- font-size: 0.8em;
- position: absolute;
- bottom: 2em;
- width: 100%;
- text-align: center;
-}
-@media screen and (min-width: 0) and (max-width: 700px) {
- .front .block-views .view-footer,
- .front .block-block .view-footer,
- .front .block-twitter-helper .view-footer {
- bottom: 0.5em;
- }
-}
-.front #content-area {
- display: inline-flex;
- height: auto;
- flex-flow: row wrap;
-}
-.front #block-block-1,
-.front #block-block-2,
-.front #block-block-3 {
- background: none;
- height: auto;
- display: inline-flex;
- margin-bottom: 0;
-}
-@media screen and (min-width: 900px) {
- .front #block-block-1,
- .front #block-block-2,
- .front #block-block-3 {
- width: 32%;
- }
-}
-.front #block-block-1 .block-title,
-.front #block-block-2 .block-title,
-.front #block-block-3 .block-title {
- background: transparent;
- margin-bottom: 0;
- padding: 0;
-}
-.front #block-block-1 .block-title-link,
-.front #block-block-2 .block-title-link,
-.front #block-block-3 .block-title-link {
- background-position: 50% 10px;
- background-repeat: no-repeat;
- color: #373A36;
- display: block;
- margin: auto;
- padding-top: 110px;
- width: 100%;
-}
-.front #block-block-1 .content,
-.front #block-block-2 .content,
-.front #block-block-3 .content {
- text-align: center;
-}
-.front #block-block-1 .block-title-link {
- background-image: url(/sites/all/themes/opnfv/images/optimized/OPNFV_Icon_About.png);
-}
-.front #block-block-2 .block-title-link {
- background-image: url(/sites/all/themes/opnfv/images/optimized/OPNFV_Icon_GettingStarted.png);
-}
-.front #block-block-3 {
- margin-right: 0;
-}
-.front #block-block-3 .block-title-link {
- background-image: url(/sites/all/themes/opnfv/images/optimized/OPNFV_Icon_GetInvolved.png);
-}
-.front #block-system-main {
- clear: both;
-}
-.front .view-blogs .views-row,
-.front .view-events .views-row {
- margin-bottom: 1.5em;
-}
-.front .view-blogs .views-field,
-.front .view-events .views-field {
- margin-bottom: 0.25em;
-}
-.front .view-blogs .views-field-type,
-.front .view-blogs .views-field-field-event-address,
-.front .view-events .views-field-type,
-.front .view-events .views-field-field-event-address {
- font-style: italic;
- font-size: 0.95em;
-}
-.front .view-blogs .views-field-title,
-.front .view-events .views-field-title {
- font-size: 1.1em;
-}
-.front .view-blogs .views-field-created,
-.front .view-events .views-field-created {
- font-style: italic;
- font-size: 0.8em;
-}
-.front #block-views-members_by_level-block,
-.front #block-views-members_by_level-block_1,
-.front #block-views-members-slider {
- height: 100%;
- background-color: transparent;
- width: 100%;
-}
-.front .flex-control-nav {
- display: none;
-}
-.front .views-field-field-member-logo .field-content {
- line-height: 40px;
- text-align: center;
- width: 100%;
-}
-.front .views-field-field-member-logo .field-content img {
- display: inline-block;
- height: auto;
- max-width: 100%;
- vertical-align: middle;
- width: auto;
-}
-#highlighted {
- margin-bottom: -221px;
-}
-#highlighted .block-views {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 100%;
- height: auto;
- margin-bottom: 0;
- background: none;
-}
-#highlighted .block-views:last-child {
- margin-right: 0;
-}
-.logged-in #highlighted {
- margin-bottom: -216px;
-}
-.flexslider {
- background: transparent;
- border: none;
- border-radius: none;
- box-shadow: none;
-}
-.flexslider .flex-direction-nav a:before {
- color: #A3D783;
-}
-.flexslider .flex-direction-nav a:hover {
- text-decoration: none;
-}
-.flexslider .slides {
- overflow: hidden;
-}
-.flexslider .slides img {
- height: auto;
- margin-left: auto;
- margin-right: auto;
- max-width: 100%;
-}
-.flexslider .views-field-nothing {
- display: none;
-}
-.view-front-page-slideshow {
- max-height: 180px;
- overflow: hidden;
-}
-@media screen and (min-width: 981px) {
- .view-front-page-slideshow .flexslider .slides img {
- height: 180px;
- }
-}
-a.frontpage-slider__video-link,
-a.frontpage-slider__video-link:visited {
- display: block;
- height: 100%;
- left: 0;
- position: absolute;
- overflow: hidden;
- text-indent: -999em;
- top: 0;
- width: 100%;
- z-index: 1;
-}
-.view-members-by-level .view-content {
- text-align: center;
-}
-.view-members-by-level .view-content h3 {
- text-align: left;
-}
-.view-members-by-level .field-content,
-.view-members-by-level .views-field-field-member-logo,
-.view-members-by-level .views-row {
- display: inline-block;
-}
-.view-members-by-level .flexslider {
- background-color: transparent;
-}
-.view-members-by-level img {
- margin-right: 10px;
-}
-@media screen and (min-width: 0) and (max-width: 670px) {
- .flexslider .views-field-nothing {
- position: static;
- opacity: 0.8;
- }
- .touch .flexslider .flex-direction-nav {
- display: none;
- }
-}
-.view-events .views-row {
- margin-bottom: 2em;
-}
-.view-events .views-field {
- margin-bottom: 0.5em;
-}
-.view-events .learn-more {
- margin: 0.5em 0;
-}
-.view-events .views-field-title {
- font-size: 1.25em;
-}
-.view-events .views-field-created {
- font-style: italic;
- font-size: 0.8em;
-}
-.view-events .views-field-field-event-address {
- font-style: italic;
-}
-.node-event img {
- max-width: 100%;
- height: auto;
-}
-.node-event .field {
- margin-bottom: 0.5em;
-}
-.node-event .field-label {
- margin-right: 0.25em;
- text-transform: uppercase;
- font-size: 0.8em;
-}
-.node-event .field-name-field-event-image {
- margin-bottom: 2em;
- border-bottom: 1px solid #ecedee;
-}
-.node-event .field-name-body {
- margin: 2em 0;
- padding-top: 3em;
- border-top: 1px solid #ecedee;
-}
-.node-event .field-name-body .field-label {
- margin-bottom: 1em;
-}
-.view-main-menu-links {
- max-width: 68em;
- margin-left: auto;
- margin-right: auto;
- margin-top: 2em;
- border-top: 1px solid #ecedee;
- padding-top: 4em;
-}
-.view-main-menu-links:after {
- content: "";
- display: table;
- clear: both;
-}
-.view-main-menu-links ul {
- margin: 0;
- padding: 0;
-}
-.view-main-menu-links ul li {
- margin: 0;
- padding: 0;
-}
-.view-main-menu-links .views-row {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 49.15254%;
- margin-bottom: 4em;
- padding-right: 4em;
-}
-.view-main-menu-links .views-row:last-child {
- margin-right: 0;
-}
-@media screen and (min-width: 0) and (max-width: 700px) {
- .view-main-menu-links .views-row {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 100%;
- padding-right: 0;
- }
- .view-main-menu-links .views-row:last-child {
- margin-right: 0;
- }
-}
-.view-main-menu-links .views-row .views-field-title {
- font-size: 1.5em;
- margin-bottom: 1em;
- text-align: center;
-}
-.view-main-menu-links .views-row .views-field-body {
- margin-bottom: 0.5em;
-}
-.view-main-menu-links .views-row .views-field-description a {
- display: block;
- margin-top: 0.5em;
-}
-.view-main-menu-links .views-row.views-row-even {
- margin-right: 0;
-}
-.view-main-menu-links .views-row.views-row-odd {
- clear: left;
-}
-body.node-type-landing-page #content-header {
- left: 0;
- position: absolute;
- top: 20px;
- width: 100%;
- z-index: 1;
-}
-.node-landing-page {
- display: block;
- height: 100%;
- left: 0;
- overflow: auto;
- position: fixed;
- top: 0;
- width: 100%;
-}
-.node-landing-page.with-background {
- background-color: #000;
- background-position: center bottom;
- background-repeat: no-repeat;
- background-size: cover;
-}
-.node-landing-page .content {
- color: #fff;
- margin: 50px auto;
- text-shadow: 0 1px 1px rgba(0, 0, 0, 0.75);
-}
-.node-landing-page .content:after {
- content: "";
- display: table;
- clear: both;
-}
-@media screen and (min-width: 700px) {
- .node-landing-page .content {
- margin-top: 120px;
- max-width: 68em;
- }
-}
-.node-landing-page .content a,
-.node-landing-page .content a:visited {
- color: #00ADBB;
-}
-.node-landing-page .content p {
- color: #fff;
-}
-.node-landing-page .content h2 {
- text-align: center;
-}
-.node-landing-page .content h2 a,
-.node-landing-page .content h2 a:visited {
- color: #fff;
-}
-.node-landing-page .content img {
- display: inline-block;
- height: auto;
- max-width: 100%;
-}
-.node-landing-page .field-name-field-header-first-column,
-.node-landing-page .field-name-field-header-last-column,
-.node-landing-page .field-name-field-content-first-column,
-.node-landing-page .field-name-field-content-last-column {
- padding: 0 20px;
-}
-@media screen and (min-width: 700px) {
- .node-landing-page .field-name-field-header-first-column,
- .node-landing-page .field-name-field-header-last-column,
- .node-landing-page .field-name-field-content-first-column,
- .node-landing-page .field-name-field-content-last-column {
- float: left;
- width: 49%;
- }
-}
-@media screen and (min-width: 700px) {
- .node-landing-page .field-name-field-header-first-column,
- .node-landing-page .field-name-field-content-last-column {
- float: right;
- }
-}
-.node-landing-page .field-name-field-content-first-column {
- margin-bottom: 40px;
-}
-@media screen and (min-width: 700px) {
- .node-landing-page .field-name-field-content-first-column {
- margin-bottom: 0;
- }
-}
-.page-resources-library .view-resources .views-row {
- margin-bottom: 2em;
-}
-.page-resources-library .view-resources .opnfv-resources-date {
- font-style: italic;
- font-size: 0.8em;
-}
-.page-resources-library .view-resources .opnfv-resources-title {
- font-size: 1.25em;
- margin-bottom: 0.5em;
-}
-.page-resources-library .view-resources .views-field-field-thumbnail {
- float: right;
- margin: 5px 0 20px 20px;
-}
-.page-resources-library .view-resources .views-field-field-thumbnail img {
- display: block;
- height: auto;
- max-width: 100%;
-}
-.page-blog .view-blogs .views-row,
-.page-news-faq-blog .view-blogs .views-row {
- margin-bottom: 2em;
-}
-.page-blog .view-blogs .views-field,
-.page-news-faq-blog .view-blogs .views-field {
- margin-bottom: 0.5em;
-}
-.page-blog .view-blogs .learn-more,
-.page-news-faq-blog .view-blogs .learn-more {
- margin: 0.5em 0;
-}
-.page-blog .view-blogs .views-field-title,
-.page-news-faq-blog .view-blogs .views-field-title {
- font-size: 1.25em;
-}
-.page-blog .view-blogs .views-field-created,
-.page-news-faq-blog .view-blogs .views-field-created {
- font-style: italic;
- font-size: 0.8em;
-}
-.node-blog {
- margin-bottom: 3em;
-}
-.node-blog .addtoany_list {
- display: block;
- padding-bottom: 20px;
-}
-.node-blog .blog_usernames_blog {
- display: none;
-}
-#header #header-region {
- clear: both;
-}
-#header .container {
- padding: 0px 20px 0;
-}
-#header #logo {
- float: left;
- display: block;
- margin-right: 1.69492%;
- width: 18.64407%;
- margin-bottom: 1em;
-}
-#header #logo:last-child {
- margin-right: 0;
-}
-#header #site-name {
- margin-top: 20px;
-}
-#header #site-name a {
- text-indent: -9999px;
- display: inline-block;
-}
-.banner-top {
- background-color: #fff;
- height: 180px;
-}
-@media screen and (min-width: 980px) {
- .banner-top {
- background: #00ADBB url(/sites/all/themes/opnfv/images/optimized/banner-bg.png) repeat 50% 50%;
- height: 180px;
- }
-}
-.sidebar .block {
- margin-bottom: 1.5em;
- background: #ecedee;
-}
-.sidebar .block .content {
- padding: 0 1em .5em;
-}
-.sidebar .block .view-content {
- margin-bottom: 1em;
-}
-.sidebar .block .view-footer {
- text-transform: uppercase;
- font-size: 0.8em;
-}
-.sidebar .block-title {
- font-size: 1em;
- color: #fff;
- background: #177870;
- padding: .5em;
-}
-#footer {
- background: #00ADBB;
-}
-#footer .container {
- padding: 20px 20px 30px;
-}
-#footer #block-block-4 {
- display: none;
-}
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-main,
-nav,
-section,
-summary {
- display: block;
-}
-audio,
-canvas,
-video {
- display: inline-block;
-}
-audio:not([controls]) {
- display: none;
- height: 0;
-}
-[hidden] {
- display: none;
-}
-html {
- font-family: sans-serif;
- -webkit-text-size-adjust: 100%;
- -ms-text-size-adjust: 100%;
-}
-body {
- margin: 0;
-}
-a:focus {
- outline: thin dotted;
-}
-a:active,
-a:hover {
- outline: 0;
-}
-h1 {
- font-size: 2em;
- margin: 0.67em 0;
-}
-abbr[title] {
- border-bottom: 1px dotted;
-}
-b,
-strong {
- font-weight: bold;
-}
-dfn {
- font-style: italic;
-}
-hr {
- -moz-box-sizing: content-box;
- box-sizing: content-box;
- height: 0;
-}
-mark {
- background: #ff0;
- color: #000;
-}
-code,
-kbd,
-pre,
-samp {
- font-family: monospace, serif;
- font-size: 1em;
-}
-pre {
- white-space: pre-wrap;
-}
-q {
- quotes: "\201C" "\201D" "\2018" "\2019";
-}
-small {
- font-size: 80%;
-}
-sub,
-sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
-}
-sup {
- top: -0.5em;
-}
-sub {
- bottom: -0.25em;
-}
-img {
- border: 0;
-}
-svg:not(:root) {
- overflow: hidden;
-}
-figure {
- margin: 0;
-}
-fieldset {
- border: 1px solid #c0c0c0;
- margin: 0 2px;
- padding: 0.35em 0.625em 0.75em;
-}
-legend {
- border: 0;
- padding: 0;
-}
-button,
-input,
-select,
-textarea {
- font-family: inherit;
- font-size: 100%;
- margin: 0;
-}
-button,
-input {
- line-height: normal;
-}
-button,
-select {
- text-transform: none;
-}
-button,
-html input[type="button"],
-input[type="reset"],
-input[type="submit"] {
- -webkit-appearance: button;
- cursor: pointer;
-}
-button[disabled],
-html input[disabled] {
- cursor: default;
-}
-input[type="checkbox"],
-input[type="radio"] {
- box-sizing: border-box;
- padding: 0;
-}
-input[type="search"] {
- -webkit-appearance: textfield;
- -moz-box-sizing: content-box;
- -webkit-box-sizing: content-box;
- box-sizing: content-box;
-}
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
- -webkit-appearance: none;
-}
-button::-moz-focus-inner,
-input::-moz-focus-inner {
- border: 0;
- padding: 0;
-}
-textarea {
- overflow: auto;
- vertical-align: top;
-}
-table {
- border-collapse: collapse;
- border-spacing: 0;
-}
diff --git a/tools/infra-dashboard/css/source-sans-pro.css b/tools/infra-dashboard/css/source-sans-pro.css
deleted file mode 100644
index 91314f03..00000000
--- a/tools/infra-dashboard/css/source-sans-pro.css
+++ /dev/null
@@ -1,96 +0,0 @@
-/* vietnamese */
-@font-face {
- font-family: 'Source Sans Pro';
- font-style: normal;
- font-weight: 200;
- src: local('Source Sans Pro ExtraLight'), local('SourceSansPro-ExtraLight'), url(../fonts/SourceSansPro-ExtraLight.ttf) format('truetype');
- unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
-}
-/* latin-ext */
-@font-face {
- font-family: 'Source Sans Pro';
- font-style: normal;
- font-weight: 200;
- src: local('Source Sans Pro ExtraLight'), local('SourceSansPro-ExtraLight'), url(../fonts/SourceSansPro-ExtraLight.ttf) format('truetype');
- unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
-}
-/* latin */
-@font-face {
- font-family: 'Source Sans Pro';
- font-style: normal;
- font-weight: 200;
- src: local('Source Sans Pro ExtraLight'), local('SourceSansPro-ExtraLight'), url(../fonts/SourceSansPro-ExtraLight.ttf) format('truetype');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
-}
-/* vietnamese */
-@font-face {
- font-family: 'Source Sans Pro';
- font-style: normal;
- font-weight: 400;
- src: local('Source Sans Pro'), local('SourceSansPro-Regular'), url(../fonts/SourceSansPro-Regular.ttf) format('truetype');
- unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
-}
-/* latin-ext */
-@font-face {
- font-family: 'Source Sans Pro';
- font-style: normal;
- font-weight: 400;
- src: local('Source Sans Pro'), local('SourceSansPro-Regular'), url(../fonts/SourceSansPro-Regular.ttf) format('truetype');
- unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
-}
-/* latin */
-@font-face {
- font-family: 'Source Sans Pro';
- font-style: normal;
- font-weight: 400;
- src: local('Source Sans Pro'), local('SourceSansPro-Regular'), url(../fonts/SourceSansPro-Regular.ttf) format('truetype');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
-}
-/* vietnamese */
-@font-face {
- font-family: 'Source Sans Pro';
- font-style: normal;
- font-weight: 700;
- src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(../fonts/SourceSansPro-Bold.ttf) format('truetype');
- unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
-}
-/* latin-ext */
-@font-face {
- font-family: 'Source Sans Pro';
- font-style: normal;
- font-weight: 700;
- src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(../fonts/SourceSansPro-Bold.ttf) format('truetype');
- unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
-}
-/* latin */
-@font-face {
- font-family: 'Source Sans Pro';
- font-style: normal;
- font-weight: 700;
- src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), url(../fonts/SourceSansPro-Bold.ttf) format('truetype');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
-}
-/* vietnamese */
-@font-face {
- font-family: 'Source Sans Pro';
- font-style: italic;
- font-weight: 400;
- src: local('Source Sans Pro Italic'), local('SourceSansPro-It'), url(../fonts/SourceSansPro-Italic.ttf) format('truetype');
- unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
-}
-/* latin-ext */
-@font-face {
- font-family: 'Source Sans Pro';
- font-style: italic;
- font-weight: 400;
- src: local('Source Sans Pro Italic'), local('SourceSansPro-It'), url(../fonts/SourceSansPro-Italic.ttf) format('truetype');
- unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
-}
-/* latin */
-@font-face {
- font-family: 'Source Sans Pro';
- font-style: italic;
- font-weight: 400;
- src: local('Source Sans Pro Italic'), local('SourceSansPro-It'), url(../fonts/SourceSansPro-Italic.ttf) format('truetype');
- unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
-}
diff --git a/tools/infra-dashboard/css/template.css b/tools/infra-dashboard/css/template.css
deleted file mode 100644
index 688ac04d..00000000
--- a/tools/infra-dashboard/css/template.css
+++ /dev/null
@@ -1,802 +0,0 @@
-/*
-*/
-body {
- background-color: #15151d;
- color: #313131;
- font-family: 'Source Sans Pro', sans-serif;
- font-size: 16px;
- min-width: 300px;
-}
-h1,
-.h1 {
- font-size: 2em;
- margin: 0.67em 0;
- font-weight: bolder;
- text-transform: uppercase;
-}
-h2,
-.h2 {
- font-size: 1.5em;
- margin: 0.83em 0;
- font-weight: bolder;
- text-transform: uppercase;
-}
-h3 {
- font-size: 1.17em;
- margin: 1em 0;
- font-weight: bolder;
- text-transform: uppercase;
-}
-h4 {
- font-weight: bolder;
- text-transform: uppercase;
-}
-h5 {
-
- font-weight: bolder;
- text-transform: uppercase;
-}
-p {
- font-size: 16px;
-}
-a {
- color: #68CDA0;
- outline: none;
- text-decoration: none;
-}
-ul,
-ol {
- padding: 0;
- margin: 0 0 10px 25px;
-}
-.table-responsive {
- overflow-x: auto;
-}
-img {
- max-width: 100%;
-}
-a:focus,
-a:hover {
- color: #90ef7f;
- text-decoration: none;
-}
-.btn {
- text-transform: uppercase;
- font-weight: bolder;
-}
-.btn-default {
- background-color: #90ef7f;
- color: #313131;
- border: 0;
- border-radius: 2px;
-}
-.btn-default:hover {
- background-color: #90ef7f;
- color: #000000;
-}
-.btn-sm {
- padding: 13px 18px;
-}
-button,
-.button {
- font-size: 12px;
- line-height: 1;
- display: inline-block;
- text-transform: uppercase;
- font-weight: bolder;
- padding: 16px 18px;
- background-color: #90ef7f;
- color: #313131;
- border: 0;
- border-radius: 2px;
- margin: 1px;
- text-align: center;
-}
-button:hover,
-.button:hover {
- background-color: #90ef7f;
- color: #000000;
-}
-.pagination>li>a, .pagination>li>span {
- color: #FFFFFF;
- background-color: #0095A2;
- border: 1px solid silver;
-}
-.pagination>li>a:hover, .pagination>li>span:hover, .pagination>li>a:focus, .pagination>li>span:focus {
- color: white;
- background-color: #68CDA0;
-}
-.pagination>li>span:hover, .pagination>li>span:focus {
- background-color: #0095A2;
-}
-/*
-* Menu
-*/
-#menu {
- background-color: #007E88;
- color: #ffffff;
-}
-#menu #menu-second a {
- font-size: 12px;
-}
-#menu-second .navbar-nav>li>a {
- padding-bottom: 5px;
-}
-#menu-second .navbar-nav>li>a {
- padding-top: 10px;
-}
-#menu .navbar-default {
- background-color: #FFFFFF;
- color: inherit;
- border-radius: 0;
- border: 0;
- margin-bottom: 0;
-}
-#menu .navbar-brand {
- height: auto;
- max-width: 360px;
- margin: -0 0;
- padding: 0;
-}
-#menu .navbar-brand img {
- max-width: 100%;
- width: 100%;
- height: auto;
-}
-#menu a {
- font-size: 20px;
- font-weight: normal;
- color: #000000;
- text-transform: uppercase;
-}
-#menu a:hover {
- color: #90ef7f;
-}
-#menu .navbar-default .navbar-nav>.active>a,
-#menu .navbar-default .navbar-nav>.active>a:hover,
-#menu .navbar-default .navbar-nav>.active>a:focus {
- background-color: inherit;
- color: #68CDA0;
- font-weight: bolder;
-}
-#menu .navbar-default .navbar-nav>.open>a,
-#menu .navbar-default .navbar-nav>.open>a:hover,
-#menu .navbar-default .navbar-nav>.open>a:focus {
- background-color: #ECEDEE;
- color: #000000;
-}
-#menu .dropdown-menu {
- background-color: #ECEDEE;
- margin-top: -1px;
- margin-left: -1px;
- border-radius: 0;
-}
-#menu .dropdown-menu>li>a:hover,
-#menu .dropdown-menu>li>a:focus {
- background-color: inherit;
-}
-#menu .dropdown-menu>.active>a,
-#menu .dropdown-menu>.active>a:hover,
-#menu .dropdown-menu>.active>a:focus {
- background-color: inherit;
- font-weight: bold;
-}
-#menu .dropdown-menu>li>a {
- font-size: 16px;
- text-transform: none;
-}
-
-.highcharts-iframe {
- border: none;
-}
-
-/*
-*Embedded youtube
-*/
-.video-slot {
- padding: 2em;
-}
-.video-container-outer {
- max-width: 800px;
- margin: 0 auto;
-}
-.video-container {
- position:relative;
- padding-bottom:56.25%;
- height:0;
- overflow:hidden;
-}
-.video-container iframe {
- position:absolute;
- top:0;
- left:0;
- width:100%;
- height:100%;
-}
-/*
-* End: Menu
-*/
-.item-page {
- max-width: 760px;
- margin: auto;
-}
-.item-page img {
- margin-bottom: 30px;
-}
-
-.image-wrapper {
- background-color: #f9f9f9;
- padding: 30px;
- margin-bottom: 30px;
- text-align: center;
-}
-.image-wrapper img {
- margin: 0;
-}
-
-.blog img {
- margin-bottom: 30px;
-}
-
-.article-info {
- font-size: 14px;
- color: silver;
- margin-bottom: 20px;
-}
-
-dl.article-info dt {
- display: none;
-}
-
-dl.article-info dd {
- font-size: 14px;
- display: inline;
- color: silver;
- margin-bottom: 20px;
-}
-
-dl.article-info dd:after {
- content: " \25CF ";
-}
-
-dl.article-info dd:last-child:after {
- content: none;
-}
-
-hr {
- width: 100%;
- border-top: 1px solid silver;
- display: inline-block;
-}
-
-
-
-/*
-* Component
-#000000
-*/
-#hs-component {
- background-color: #000000;
- padding: 30px 0;
-}
-#hs-component .container {
- background-color: white;
- padding: 30px;
-}
-/*
-* End: Component
-*/
-/*
-* Footer
-*/
-footer {
- background-color: #15151d;
- color: #000000;
-}
-#footer .container {
- padding: 30px 0;
-}
-#footer a {
- color: inherit;
-}
-#footer a:hover {
- color: #90ef7f;
-}
-#footer .socials a {
- margin-left: 10px;
-}
-/*
-* End: Footer
-*/
-
-/*
-======
-=== Responsive CSS
-======
-*/
-@media screen and (min-width: 768px) {
- #footer .socials {
- text-align: right;
- }
- #menu .container {
- padding: 0;
- }
- #menu span.toggle-arrow {
- display: none;
- }
- #menu-container {
- width: 600px;
- float: right;
- }
- #menu .dropdown.active:hover>a,
- #menu .dropdown.active:hover>a:hover,
- #menu .dropdown:hover>a {
- background-color: #ECEDEE;
- color: #000000;
- }
- #menu .dropdown:hover>.dropdown-menu {
- display: block;
- }
- #menu .dropdown-menu {
- padding: 5px 20px;
- }
- #menu .dropdown-menu a {
- border-bottom: 2px solid #007E88;
- text-align: right;
- padding: 10px 0;
- }
- #menu .dropdown-menu li:last-child a {
- border-bottom: 0;
- }
- #menu .collapse.navbar-collapse {
- padding: 0;
- }
-}
-@media screen and (max-width: 767px) {
- #menu .container {
- padding-bottom: 30px;
- padding-top: 30px;
- }
- #menu .navbar-header {
- position: relative;
- margin: 0;
- }
- #menu .navbar-header .navbar-toggle {
- position: absolute;
- bottom: 0;
- right: 0;
- margin: 0;
- height: 40px;
- width: 40px;
- font-size: 30px;
- text-align: center;
- padding: 0;
- color: #000000;
- border: 0;
- border-radius: 0;
- cursor: pointer;
- -moz-transform: rotate(-180deg);
- -moz-transform: rotate(-180deg);
- -moz-transition: -moz-transform 250ms ease-out 0s;
- -ms-transform: rotate(-180deg);
- -o-transform: rotate(-180deg);
- -o-transition: -o-transform 250ms ease-out 0s;
- -webkit-transform: rotate(-180deg);
- -webkit-transition: -webkit-transform 250ms ease-out 0s;
- transform: rotate(-180deg);
- transition: transform 250ms ease-out 0s;
- background-color: #ECEDEE;
- }
- #menu .navbar-header .navbar-toggle:hover {
- color: #90ef7f;
- }
- #menu .navbar-header .navbar-toggle.collapsed {
- -moz-transform: rotate(0deg);
- -moz-transition: -moz-transform 250ms ease-out 0s;
- -ms-transform: rotate(0deg);
- -o-transform: rotate(0deg);
- -o-transition: -o-transform 250ms ease-out 0s;
- -webkit-transform: rotate(0deg);
- -webkit-transition: -webkit-transform 250ms ease-out 0s;
- transform: rotate(0deg);
- transition: transform 250ms ease-out 0s;
- background-color: inherit;
- }
- #menu .navbar-header .navbar-toggle.collapsed:after {
- font-family: "FontAwesome";
- content: '\f0c9';
- }
- #menu .navbar-header .navbar-toggle:after {
- font-family: "FontAwesome";
- content: '\f00d';
- }
- #menu .navbar-brand {
- width: 75%;
- }
- #menu .dropdown span.toggle-arrow:after {
- font-family: "FontAwesome";
- content: '\f105';
- }
- #menu .dropdown.open span.toggle-arrow:after {
- font-family: "FontAwesome";
- content: '\f107';
- }
- #menu .navbar-collapse {
- border: 0;
- background-color: #ECEDEE;
- text-align: right;
- margin: 0;
- }
- #menu ul.navbar-nav {
- float: none !important;
- }
- #menu .dropdown-menu {
- text-align: right;
- }
- #menu .navbar-nav {
- margin: 0 -15px;
- }
- #menu .nav>li {
- border-bottom: 2px solid #007E88;
- }
- #hs-component {
- padding: 0;
- }
- #footer {
- text-align: center;
- }
-}
-
-/*
-==================
-=== About Us page
-==================
-* TODO: find better logic for this
-*/
-#about-us h1,
-#about-us h2 {
- text-align: center;
-}
-#about-us h2 {
- margin-top: 2em;
-}
-#about-us #company-container img {
- width: 100%;
-}
-#about-us .image-container {
- text-align: center;
-}
-/* Company section */
-
-/* Products section */
-#about-us #products-container div > div {
- margin-top: 20px;
- margin-bottom: 10px;
-}
-
-/* Numbers section */
-#about-us #numbers-container {
- text-align: center;
-}
-#about-us #numbers-container p {
- padding: 15px;
- background-color: #ddd;
- width: 220px;
- min-height: 130px;
- margin: 15px;
- display: inline-block;
- vertical-align: top;
- text-align: left;
- box-sizing: content-box;
-}
-
-/* Employee section */
-#about-us #employees-container {
- text-align: center;
-}
-#about-us .employee {
- display: inline-block;
- width: 210px;
- margin: 15px;
- vertical-align: top;
-}
-#about-us .employee .image-container {
- padding: 5px;
-}
-#about-us .employee .image-container.no-image {
- height: 210px;
-}
-#about-us .employee .image-container img {
- max-height: 200px;
- max-width: 200px;
- background-color: #000000;
- margin-bottom: 0;
-}
-#about-us .employee .description p {
- text-align: left;
-}
-#about-us .employee p.name {
- font-weight: bold;
- font-size: 18px;
- text-align: center;
-}
-
-/* Facts section */
-#about-us #facts-container {
- word-break: break-word;
- /*text-align: center;*/
- width: 50%;
- float: left;
-}
-
-/* Press section */
-#about-us #press-container {
- width: 50%;
- float: left;
-}
-@media screen and (max-width: 767px) {
- #about-us .employee .image-container.no-image {
- height: auto;
- }
- #about-us #facts-container,
- #about-us #press-container {
- width: 100%;
- float: none;
- }
- #about-us #numbers-container p {
- width: auto;
- min-height: 0px !important;
- }
-}
-/*
-=======================
-=== END About Us page
-=======================
-*/
-/*
-=======================
-=== Product Pages
-=======================
-*/
-.text-center {
- text-align: center;
-}
-.product-buttons .button {
- max-width: 200px;
- width: 100%;
-}
-/*
-=======================
-=== END Product Pages
-=======================
-*/
-.datatable th, .datatable td {
- border: 1px solid silver;
- padding: 2px 5px;
-}
-.datatable th {
- text-align: left;
-}
-.intro h4 {
- clear: both;
- padding-top: 1em;
-}
-.intro img {
- margin-bottom: 1em;
- border: 1px solid silver;
- max-width: 164px;
-}
-.intro img.float-left {
- margin-right: 2em;
-}
-.intro img.float-right {
- margin-left: 2em;
-}
-.float-right {
- float: right;
-}
-.float-left {
- float: left;
-}
-table.category {
- width: 100%;
-}
-table.category .cat-list-row1 {
- background-color: #000000;
-}
-
-/*
-====
-===
-====
-*/
-
-/* Sidebar */
-#hs-component > div.sidebar-container {
- padding: 0;
-}
-.nav-sidebar {
- margin: 0 -15px;
-}
-.nav-sidebar > li {
- display: block;
- background-color: #007E88;
- border-top: 1px solid #0095A2;
- color: white;
- font-size: 20px;
- font-weight: 200;
- text-transform: uppercase;
-}
-.nav-sidebar > li:last-child {
- border-bottom: 1px solid #0095A2;
-}
-.nav-sidebar > li.active {
- background-color: #0095A2;
- font-weight: bold;
-}
-.nav-sidebar > li > div {
- position: relative;
- padding: 10px;
- padding-right: 40px;
- cursor: pointer;
-}
-/* Toggle */
-.toggle {
- position: absolute;
- right: 10px;
- top: 10px;
-}
-.active > .toggle::after {
- font-family: "FontAwesome";
- content: '\f107';
-}
-.toggle::after {
- font-family: "FontAwesome";
- content: '\f105';
-}
-.nav-sidebar > li > ul {
- /*display: none;*/
-}
-.nav-sidebar > li > ul {
- /*display: block;*/
- list-style: none;
- margin: 0;
-}
-.nav-sidebar > li > ul > li {
- border-top: 1px solid #007E88;
- text-transform: none;
- padding: 10px;
- line-height: 1;
-}
-.nav-sidebar > li.active > ul > li.active::after {
- content: '';
- width: 0;
- height: 0;
- position: absolute;
- right: -10px;
- border-top: 10px solid transparent;
- border-bottom: 10px solid transparent;
- border-left: 10px solid #0095A2;
- z-index: 1;
-}
-.nav-sidebar > li > ul > li > a {
- color: white;
- font-size: 16px;
- font-weight: 100;
-}
-.nav-sidebar > li.active > ul > li.active > a {
- color: #68CDA0;
- font-weight: bold;
-}
-.nav-sidebar > li.active > ul > li > a:focus,
-.nav-sidebar > li.active > ul > li > a:hover {
- color: #90ef7f;
-}
-.sidebar-wrapper {
- position: relative;
-}
-.sidebar {
- z-index: 2;
- background-color: #007E88;
-}
-.sidebar-eq {
- z-index: 1;
- background-color: white;
-}
-.sidebar-fill {
- position: absolute;
- height: 100%;
- background-color: #007E88;
- left: 0;
- top: 0;
- z-index: 0;
-}
-.sidebar-eq-fill {
- position: absolute;
- height: 100%;
- background-color: white;
- right: 0;
- top: 0;
- z-index: 0;
-}
-@media screen and (max-width: 500px) {
- .intro img {
- display: none;
- }
-}
-@media screen and (max-width: 768px) {
- .sidebar-wrapper {
- position: relative;
- overflow: hidden;
- }
- .sidebar-wrapper .sidebar {
- position: absolute;
- top: 0;
- left: 0;
- z-index: 9;
- visibility: hidden;
- height: 100%;
- overflow-x: hidden;
- overflow-y: auto;
- -webkit-transition: all 0.5s;
- transition: all 0.5s;
- }
- .sidebar-wrapper.toggled .sidebar {
- visibility: visible;
- -webkit-transition: -webkit-transform 0.5s;
- transition: transform 0.5s;
- }
- .toggled .nav-sidebar > li.active > ul > li.active::after {
- display: none;
- }
- .sidebar-wrapper .sidebar-eq {
- position: relative;
- left: 0;
- z-index: 10;
- padding-top: 42px;
- /*height: 100%;*/
- -webkit-transition: -webkit-transform 0.5s;
- transition: transform 0.5s;
- }
- .sidebar-wrapper.toggled .sidebar-eq {
- -webkit-transform: translate3d(75%, 0, 0);
- transform: translate3d(75%, 0, 0);
- }
- .sidebar-wrapper.toggled .sidebar-eq:after {
- width: 100%;
- height: 100%;
- opacity: 1;
- -webkit-transition: opacity 0.5s;
- transition: opacity 0.5s;
- }
- .sidebar-wrapper .sidebar-eq:after {
- position: absolute;
- top: 0;
- right: 0;
- width: 0;
- height: 0;
- background: rgba(0,0,0,0.2);
- content: '';
- opacity: 0;
- -webkit-transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
- transition: opacity 0.5s, width 0.1s 0.5s, height 0.1s 0.5s;
- }
- #sidebar-toggle {
- position: absolute;
- top: 0;
- left: 0;
- background-color: #007E88;
- color: white;
- border-radius: 0;
- z-index: 100;
- cursor: pointer;
- padding: 10px;
- visibility: visible;
- }
- #sidebar-toggle:after {
- content: "Show Sidebar";
- }
- .toggled #sidebar-toggle:after {
- content: "Hide Sidebar";
- }
-}
diff --git a/tools/infra-dashboard/css/theme.css b/tools/infra-dashboard/css/theme.css
deleted file mode 100644
index 59ae59f0..00000000
--- a/tools/infra-dashboard/css/theme.css
+++ /dev/null
@@ -1,387 +0,0 @@
-.container {
- width: 100%
-}
-#hs-component {
- background-color: inherit;
- padding: 0
-}
-#hs-component .container {
- padding: 0;
- width: 100%
-}
-#comp-menu {
- background-color: #FFFFFF;
- z-index: 1;
- padding: 0
-}
-#comp-menu .cont,
-.demo {
- padding: 0 50px
-}
-#comp-menu h2,
-#comp-menu h2 a {
- color: #000000;
- font-weight: lighter;
- text-transform: inherit
-}
-#comp-menu h2 a:hover {
- color: #8085e8
-}
-
-.blink_me {
- animation: blinker 1.5s linear infinite;
-}
-
-@keyframes blinker {
- 20% { opacity: 0.4; }
-}
-
-
-a.btn.btn-theme {
- color: #eeeaea;
- background-color: #007E88;
- border: 1px solid #007E88;
- border-bottom: 0;
- border-radius: 0;
- font-weight: 400;
- margin: 0 5px 0 0
-}
-a.btn.btn-theme:hover {
- color: #90ef7f
-}
-
-
-.btn-book {
- color: #fff;
- background-color: #337ab7;
- border-color: #2e6da4;
- display: inline-block;
- white-space: nowrap;
- vertical-align: middle;
- border: 1px solid transparent;
- touch-action: manipulation;
- cursor: pointer;
- padding: 2px 6px;
- font-size: 10px;
- font-weight: bold;
- line-height: 1.1333333;
- border-radius: 6px;
- background-image: linear-gradient(to bottom,#337ab7 0,#265a88 100%);
-}
-
-a.btn.btn-theme.noselected {
- background-color: #FFF;
- color: #313131;
- opacity: 1
-}
-
-a.btn.btn-theme.disabled {
- background-color: #FFF;
- color: #313131;
- opacity: 1
-}
-.demo {
- background-color: #f6f6f6
-}
-.demo .demo-name {
- color: #000000;
- font-weight: lighter;
- text-transform: none;
- padding-left: 15px;
- text-align: center;
- display: inline;
- margin: 0 10px
-}
-#chart-switcher {
- text-align: center;
- padding: 30px 0
-}
-.demo #chart-switcher #next-example,
-.demo #chart-switcher #previous-example {
- font-size: 30px;
- padding: 0 10px;
- color: #888
-}
-#demo-buttons {
- text-align: center;
- padding: 30px 0
-}
-#demo-buttons a {
- background-color: #ddd
-}
-#demo-buttons a:hover {
- background-color: #40818b
-}
-.demo .chart-container {
- position: relative;
- background-color: #fff;
- padding: 30px 0
-}
-.demo .chart-container #previous-example {
- position: absolute;
- top: 50%;
- left: -30px;
- font-size: 70px;
- color: #888
-}
-.demo .chart-container #next-example {
- position: absolute;
- top: 50%;
- right: -30px;
- font-size: 70px;
- color: #888
-}
-.sidebar-eq-fill {
- background-color: #f6f6f6
-}
-@media screen and (max-width: 400px) {
- #chart-switcher,
- .demo .chart-container,
- .sidebar-wrapper .sidebar-eq {
- padding: 0
- }
- #small-switcher {
- text-align: center
- }
- .demo #chart-switcher #next-example,
- .demo #chart-switcher #previous-example {
- font-size: 20px
- }
- #sidebar-close {
- position: absolute;
- top: 0;
- left: 0;
- background-color: #FFFFFF;
- color: #fff;
- border-radius: 0;
- z-index: 100;
- cursor: pointer;
- padding: 10px;
- visibility: hidden
- }
- .toggled #sidebar-close {
- visibility: visible
- }
-}
-@media screen and (min-width: 400px) and (max-width: 768px) {
- .demo {
- padding: 15px
- }
- #sidebar-close {
- position: absolute;
- top: 0;
- left: 0;
- background-color: #FFFFFF;
- color: #fff;
- border-radius: 0;
- z-index: 100;
- cursor: pointer;
- padding: 10px;
- visibility: hidden
- }
- .toggled #sidebar-close {
- visibility: visible
- }
-}
-#hs-below {
- background-color: #eeeaea;
- font-size: 18px;
- line-height: 26px
-}
-#hs-below h3 {
- font-size: 30px;
- line-height: 30px;
- font-weight: bolder;
- margin-top: 0;
- margin-bottom: 15px
-}
-#hs-below p,
-ul {
- font-size: 1pc
-}
-#hs-below .box {
- position: relative;
- background-color: #fff;
- padding: 14px 22px
-}
-#hs-below .box .box-content {
- margin-bottom: 40px
-}
-#hs-below .box .button {
- position: absolute;
- bottom: 0;
- margin-bottom: 10px
-}
-#hs-below .box.purple {
- border-bottom: 8px solid #8085e8
-}
-#hs-below .box.green {
- border-bottom: 8px solid #90ef7f
-}
-#hs-below .box .book {
- text-align: center
-}
-#hs-below .box .book img {
- max-height: 200px
-}
-@media screen and (max-width: 768px) {
- #hs-below h3 {
- margin-top: 30px
- }
- #hs-below .box-1 h3 {
- margin-top: 0
- }
- #hs-below .box .book {
- text-align: left
- }
-}
-@media screen and (min-width: 768px) and (max-width: 992px) {
- #hs-below h3 {
- margin-top: 30px
- }
- #hs-below .box-1 h3,
- #hs-below .box-2 h3 {
- margin-top: 0
- }
- #hs-below .box-1 .box,
- #hs-below .box-2 .box {
- min-height: 260px
- }
- #hs-below .box-3 .box,
- #hs-below .box-4 .box {
- min-height: 280px
- }
-}
-@media screen and (min-width: 992px) and (max-width: 1200px) {
- #hs-below h3 {
- margin-top: 30px
- }
- #hs-below .box-1 h3,
- #hs-below .box-2 h3 {
- margin-top: 0
- }
- #hs-below .box-1 .box,
- #hs-below .box-2 .box {
- min-height: 255px
- }
- #hs-below .box-3 .box,
- #hs-below .box-4 .box {
- min-height: 280px
- }
-}
-@media screen and (min-width: 1200px) {
- #hs-below .box {
- min-height: 390px
- }
-}
-#hs-bottom,
-#hs-bottom a {
- color: #eeeaea
-}
-#hs-bottom {
- background-color: #FFFFFF;
- font-size: 1pc;
- line-height: 20px
-}
-#hs-bottom a:focus,
-#hs-bottom a:hover {
- color: #90ef7f
-}
-#hs-bottom a.button {
- color: #313131
-}
-#hs-bottom a.button:focus,
-#hs-bottom a.button:hover {
- color: #eeeaea
-}
-#hs-bottom h3 {
- font-size: 24px;
- line-height: 24px;
- font-weight: lighter
-}
-#hs-bottom h4 {
- font-size: 14px
-}
-#hs-bottom .grayed {
- color: #d6d1d1;
- margin: 0
-}
-@media screen and (max-width: 768px) {
- #hs-bottom [class*=col-] {
- border-bottom: 1px dotted #eeeaea;
- padding-bottom: 15px
- }
- #hs-bottom [class*=col-]:nth-child(1) h3 {
- margin-top: 0
- }
- #hs-bottom [class*=col-]:last-child {
- border-bottom: 0;
- padding-bottom: 0
- }
-}
-@media screen and (min-width: 768px) and (max-width: 992px) {
- #hs-bottom [class*=col-] {
- min-height: 350px;
- border-right: 1px dotted #eeeaea
- }
- #hs-bottom [class*=col-]:last-child,
- #hs-bottom [class*=col-]:nth-child(2) {
- border-right: 0
- }
-}
-@media screen and (min-width: 992px) and (max-width: 1200px) {
- #hs-bottom [class*=col-] {
- min-height: 300px;
- border-right: 1px dotted #eeeaea
- }
- #hs-bottom [class*=col-]:last-child,
- #hs-bottom [class*=col-]:nth-child(2) {
- border-right: 0
- }
-}
-@media screen and (min-width: 1200px) {
- #hs-bottom [class*=col-] {
- min-height: 25pc;
- border-right: 1px dotted #eeeaea
- }
- #hs-bottom [class*=col-]:last-child {
- border-right: 0
- }
-}
-
-
-
-.button{
- border:1px solid #333;
- background:#6479fd;
-}
-.button:hover{
- background:#a4a9fd;
-}
-.dialog{
- border:5px solid #666;
- padding:10px;
- background:#3A3A3A;
- position:absolute;
- display:none;
-}
-.dialog label{
- display:inline-block;
- color:#cecece;
-}
-input[type=text]{
- border:1px solid #333;
- display:inline-block;
- margin:5px;
-}
-#btnOK{
- border:1px solid #000;
- background:#ff9999;
- margin:5px;
-}
-
-#btnOK:hover{
- border:1px solid #000;
- background:#ffacac;
-}
-
diff --git a/tools/infra-dashboard/fonts/SourceSansPro-Bold.ttf b/tools/infra-dashboard/fonts/SourceSansPro-Bold.ttf
deleted file mode 100644
index 62a0a4d9..00000000
--- a/tools/infra-dashboard/fonts/SourceSansPro-Bold.ttf
+++ /dev/null
Binary files differ
diff --git a/tools/infra-dashboard/fonts/SourceSansPro-ExtraLight.ttf b/tools/infra-dashboard/fonts/SourceSansPro-ExtraLight.ttf
deleted file mode 100644
index e28a62a1..00000000
--- a/tools/infra-dashboard/fonts/SourceSansPro-ExtraLight.ttf
+++ /dev/null
Binary files differ
diff --git a/tools/infra-dashboard/fonts/SourceSansPro-Regular.ttf b/tools/infra-dashboard/fonts/SourceSansPro-Regular.ttf
deleted file mode 100644
index ffe27865..00000000
--- a/tools/infra-dashboard/fonts/SourceSansPro-Regular.ttf
+++ /dev/null
Binary files differ
diff --git a/tools/infra-dashboard/fonts/fontawesome-webfont.ttf b/tools/infra-dashboard/fonts/fontawesome-webfont.ttf
deleted file mode 100644
index 26dea795..00000000
--- a/tools/infra-dashboard/fonts/fontawesome-webfont.ttf
+++ /dev/null
Binary files differ
diff --git a/tools/infra-dashboard/fonts/fontawesome-webfont.woff b/tools/infra-dashboard/fonts/fontawesome-webfont.woff
deleted file mode 100644
index dc35ce3c..00000000
--- a/tools/infra-dashboard/fonts/fontawesome-webfont.woff
+++ /dev/null
Binary files differ
diff --git a/tools/infra-dashboard/fonts/fontawesome-webfont.woff2 b/tools/infra-dashboard/fonts/fontawesome-webfont.woff2
deleted file mode 100644
index 500e5172..00000000
--- a/tools/infra-dashboard/fonts/fontawesome-webfont.woff2
+++ /dev/null
Binary files differ
diff --git a/tools/infra-dashboard/fonts/source-sans-pro.black.ttf b/tools/infra-dashboard/fonts/source-sans-pro.black.ttf
deleted file mode 100644
index f3730088..00000000
--- a/tools/infra-dashboard/fonts/source-sans-pro.black.ttf
+++ /dev/null
Binary files differ
diff --git a/tools/infra-dashboard/index.php b/tools/infra-dashboard/index.php
deleted file mode 100644
index afd18b98..00000000
--- a/tools/infra-dashboard/index.php
+++ /dev/null
@@ -1,355 +0,0 @@
-<!DOCTYPE html>
-<html>
- <head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8" />
- <title>OPNFV Pharos Dashboard | OPNFV</title>
- <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" type="text/css" />
- <link rel="stylesheet" href="./css/dataTables.bootstrap.min.css" type="text/css" />
- <script src="//code.jquery.com/jquery-1.10.2.js"></script>
- <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
- <script src="http://www.itsyndicate.ca/gssi/jquery/jquery.crypt.js"></script>
- <script src="https://cdn.datatables.net/1.10.11/js/jquery.dataTables.min.js"></script>
- <script src="https://cdn.datatables.net/1.10.11/js/dataTables.bootstrap.min.js"></script>
- <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css"/>
-
- <link rel="stylesheet" href="./css/template.css" type="text/css" />
- <link rel="stylesheet" href="./css/theme.css" type="text/css" />
- <link rel="stylesheet" href="./css/opnfv.css" type="text/css" />
-
- <link href='./css/fullcalendar.css' rel='stylesheet' />
- <link href='./css/fullcalendar.print.css' rel='stylesheet' media='print' />
- <script src='./js/moment.min.js'></script>
- <script src='./js/fullcalendar.js'></script>
-
-
- <style>
- fieldset { padding:0; border:0; margin-top:15px; }
- input.text { margin-bottom:2px; width:90%; padding: .2em; font-size:14px; }
- input { display:block; font-size:14px; }
- label {font-size:14px;}
- .ui-dialog .ui-state-error { padding: .3em; }
- .validateTips { border: 1px solid transparent; padding: 0.3em; }
- .booked_day span {
- color: red !important; /* should only apply to may 6 and 8 */
- }
- </style>
-
- <script type="text/javascript">
- $(document).ready(function() {
-
- function getParameterByName(name, url) {
- if (!url) url = window.location.href;
- name = name.replace(/[\[\]]/g, "\\$&");
- var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
- results = regex.exec(url);
- if (!results) return null;
- if (!results[2]) return '';
- return decodeURIComponent(results[2].replace(/\+/g, " "));
- }
-
- function selectTab(name) {
- $("#container").empty();
- var imgName = './media/ajax-loader.gif';
- document.getElementById('container')
- .innerHTML = '<img style="position: relative;left: 50%;" src="' + imgName + '" />';
- if (name == "devpods") {
- $( "#btn_cipods" ).addClass( "noselected" );
- $( "#btn_devpods" ).removeClass( "noselected" );
- $( "#btn_slaves" ).addClass( "noselected" );
- var key = Math.random();
- $("#container").load("pages/dev_pods.php?key="+key);
- $('#hd_page').attr('value', "devpods");
- }
- else if (name == "slaves") {
- $( "#btn_cipods" ).addClass( "noselected" );
- $( "#btn_devpods" ).addClass( "noselected" );
- $( "#btn_slaves" ).removeClass( "noselected" );
- $("#container").load("pages/slaves.php");
- $('#hd_page').attr('value', "slaves");
- }
- else {
- $( "#btn_cipods" ).removeClass( "noselected" );
- $( "#btn_devpods" ).addClass( "noselected" );
- $( "#btn_slaves" ).addClass( "noselected" );
- $("#container").load("pages/ci_pods.php");
- $('#hd_page').attr('value', "cipods");
- }
- }
-
-
- var page = getParameterByName('page');
- if (page == "devpods") selectTab("devpods");
- else if (page == "slaves") selectTab("slaves");
- else selectTab("cipods");
-
-
- $( "#btn_cipods" ).click(function() {
- selectTab("cipods");
- });
- $( "#btn_devpods" ).click(function() {
- selectTab("devpods");
- });
- $( "#btn_slaves" ).click(function() {
- selectTab("slaves");
- });
- } );
-
-
-
- $(function() {
- var dialog, form,
- login_email = $( "#login_email" ),
- login_password = $( "#login_password" ),
- allFields = $( [] ).add( login_email ).add( login_password ),
- emailRegex = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
-
- function checkLength( o, n, min, max ) {
- if ( o.val().length > max || o.val().length < min ) {
- o.addClass( "ui-state-error" );
- return false;
- } else {
- return true;
- }
- }
-
- function checkRegexp( o, regexp, n ) {
- if ( !( regexp.test( o.val() ) ) ) {
- o.addClass( "ui-state-error" );
- return false;
- } else {
- return true;
- }
- }
-
-
- function login() {
- var valid = true;
- email = $( "#login_email" );
- password = $( "#login_password" );
- allFields.removeClass( "ui-state-error" );
-
- valid = valid && checkLength( email, "email", 6, 80 );
- valid = valid && checkLength( password, "password", 5, 16 );
-
- valid = valid && checkRegexp( email, emailRegex, "eg. ui@jquery.com" );
- valid = valid && checkRegexp( password, /^([0-9a-zA-Z])+$/, "Password field only allow : a-z 0-9" );
-
-
- if ( valid ) {
- var email = $('#login_email').val();
- var password = $('#login_password').val();
- var passwordMD5 = $().crypt({
- method: "md5",
- source: password
- });
- $.ajax({
- type: 'POST',
- url: "utils/login.php",
- data: {action: 'login', email: email, password: passwordMD5},
- success: function(data){
- //alert(data);
- json = JSON.parse(data);
- if (json.result == 1) {
- alert("Wrong password.")
- } else if (json.result == 2){
- alert("User not registered.")
- } else {
- var page = $('#hd_page').val();
- location.href = location.protocol + '//' + location.host + location.pathname + "?page=" + page;
- }
- },
- error: function(data){
- alert(data)
- }
- });
-
- }
- }
-
- dialog_login = $( "#dialog-login" ).dialog({
- autoOpen: false,
- height: 225,
- width: 400,
- modal: true,
- resizable:false,
- buttons: {
- "Login": login,
- Cancel: function() {
- dialog_login.dialog( "close" );
- }
- },
- close: function() {
- form[ 0 ].reset();
- allFields.removeClass( "ui-state-error" );
- }
- });
-
- form = dialog_login.find( "form" ).on( "submit", function( event ) {
- event.preventDefault();
- login();
- });
-
-
- $( "#login_text" ).on( "click", function() {
- dialog_login.dialog( "open" );
- });
-
- $( "#logout" ).on( "click", function() {
- $.ajax({
- type: 'POST',
- url: "utils/login.php",
- data: {action: 'logout'},
- success: function(data){
- var page = $('#hd_page').val();
- location.href = location.protocol + '//' + location.host + location.pathname + "?page=" + page;
- },
- error: function(data){
- alert(data)
- }
- });
- });
- });
- </script>
- </head>
-
-
- <body>
-
- <?php
- session_start();
- ?>
-
- <div class="collaborative-projects">
- <div class="gray-diagonal">
- <div class="container">
- <a id="collaborative-projects-logo" href="http://collabprojects.linuxfoundation.org">Linux Foundation Collaborative Projects</a>
- </div>
- </div>
- </div>
-
-
- <div id="menu">
- <nav class="navbar navbar-default" role="navigation">
- <div class="container">
- <div class="navbar-header">
- <a class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
- <span class="sr-only">Toggle navigation</span>
- </a>
- <a class="navbar-brand" href="https://www.opnfv.org/" title="OPNFV">
- <img src="https://www.opnfv.org/sites/all/themes/opnfv/logo.png" alt="OPNFV" />
- </a>
- </div>
- <div class="collapse navbar-collapse">
- <div id="menu-container">
- <div id="menu-second" class="hidden-xs">
- <ul class="nav navbar-nav pull-right">
-
- <li class="item-112">
- <a target="_blank" href="https://www.opnfv.org/" >About Us</a>
- </li>
- <li class="item-113 deeper dropdown">
- <a target="_blank" href="#" class="dropdown-toggle" data-toggle="dropdown">Dodumentation
- <span class="toggle-arrow"></span>
- </a>
- <ul class="dropdown-menu" role="menu">
- <li class="item-121">
- <a target="_blank" href="http://artifacts.opnfv.org/pharos/docs/" >Pharos</a>
- </li>
- <li class="item-122">
- <a target="_blank" href="" >Releng</a>
- </li>
- </ul>
- </li>
- <li class="item-218">
- <a target="_blank" href="https://wiki.opnfv.org/" >OPNFV Wiki</a>
- </li>
- <li class="item-114">
- <a target="_blank" href="" >Contact</a>
- </li>
- <li class="item-112">
- <?php
-
- if (isset($_SESSION['user_id'])) {
- echo '<a style="cursor: pointer;" id="logout">Logout</a>';
- }
- else {
- echo '<a style="cursor: pointer;" id="login_text">Login</a>';
- }
- ?>
-
- </li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- </nav>
- </div>
-
-
- <div id="hs-component">
- <div class="container">
- <div id="wrap" class="sidebar-wrapper">
- <div id="comp-menu" class="col-lg-12 col-md-12 col-sm-12 col-xs-12 hidden-xs">
- <?php
- if (isset($_SESSION['user_id'])) {
- echo '<div style="float:right;text-align:right;top:0;margin-right:18px">';
- echo 'current user: '.$_SESSION['user_name'];
- echo '</div>';
- }
- ?>
- <h2 class="demo-name">Pharos Infrastructure</h2>
-
- <div class="btn-group theme">
- <a id="btn_cipods" class="btn btn-theme noselected">CI PODs</a>
- <a id="btn_devpods" class="btn btn-theme noselected">DEVELOPMENT PODs</a>
- <a id="btn_slaves" class="btn btn-theme noselected">JENKINS SLAVES</a>
- </div>
-
- <div style="min-width: 310px; height: 2px; margin: 0 auto; background-color: #007E88"></div>
- <div style="min-width: 310px; height: 20px; margin: 0 auto; background-color: #ffffff"></div>
- </div>
-
- <div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
- </div>
- </div>
- </div>
-
-
-
- <div id="dialog-login" title="Login">
- <form>
- <table>
- <tr>
- <td><label for="login_email">Email</label></td>
- <td><input type="text" label="Email" name="login_email" id="login_email" value="" size="30" class="text ui-widget-content ui-corner-all"/></td>
- </tr>
- <td><label for="login_password">Password</label></td>
- <td><input type="password" name="login_password" id="login_password" size="30" value="" class="text ui-widget-content ui-corner-all"/></td>
- <tr>
- </tr>
- </table>
- <input type="submit" tabindex="-1" style="position:absolute; top:-100px"/>
- </form>
- </div>
-
-
- <div id="footer" style="float:bottom">
- <div class="container">
- <div class="col-lg-6 col-md-6 col-sm-6 col-xs-12">
- <div id="zt-footer-copy">
- Maintained by jose.lausuch@ericsson.com.
- </div>
- </div>
- <div class="socials"></div>
- </div>
-
- <?php
- echo '<input type="hidden" id="hd_user_id" value="'.$_SESSION['user_id'].'"/>';
- echo '<input type="hidden" id="hd_user_email" value="'.$_SESSION['user_email'].'"/>';
- echo '<input type="hidden" id="hd_user_name" value="'.$_SESSION['user_name'].'"/>';
- ?>
- <input type="hidden" id="hd_page" value="cipods"/>
-
- </body>
-</html>
diff --git a/tools/infra-dashboard/js/bootstrap.js b/tools/infra-dashboard/js/bootstrap.js
deleted file mode 100644
index b2ff4e83..00000000
--- a/tools/infra-dashboard/js/bootstrap.js
+++ /dev/null
@@ -1,2118 +0,0 @@
-/*!
- * Bootstrap v3.2.0 (http://getbootstrap.com)
- * Copyright 2011-2014 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- */
-
-/*!
- * Generated using the Bootstrap Customizer (http://getbootstrap.com/customize/?id=e82eeb1f3b04b506268e)
- * Config saved to config.json and https://gist.github.com/e82eeb1f3b04b506268e
- */
-if (typeof jQuery === "undefined") { throw new Error("Bootstrap's JavaScript requires jQuery") }
-
-/* ========================================================================
- * Bootstrap: alert.js v3.2.0
- * http://getbootstrap.com/javascript/#alerts
- * ========================================================================
- * Copyright 2011-2014 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // ALERT CLASS DEFINITION
- // ======================
-
- var dismiss = '[data-dismiss="alert"]'
- var Alert = function (el) {
- $(el).on('click', dismiss, this.close)
- }
-
- Alert.VERSION = '3.2.0'
-
- Alert.prototype.close = function (e) {
- var $this = $(this)
- var selector = $this.attr('data-target')
-
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
- }
-
- var $parent = $(selector)
-
- if (e) e.preventDefault()
-
- if (!$parent.length) {
- $parent = $this.hasClass('alert') ? $this : $this.parent()
- }
-
- $parent.trigger(e = $.Event('close.bs.alert'))
-
- if (e.isDefaultPrevented()) return
-
- $parent.removeClass('in')
-
- function removeElement() {
- // detach from parent, fire event then clean up data
- $parent.detach().trigger('closed.bs.alert').remove()
- }
-
- $.support.transition && $parent.hasClass('fade') ?
- $parent
- .one('bsTransitionEnd', removeElement)
- .emulateTransitionEnd(150) :
- removeElement()
- }
-
-
- // ALERT PLUGIN DEFINITION
- // =======================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.alert')
-
- if (!data) $this.data('bs.alert', (data = new Alert(this)))
- if (typeof option == 'string') data[option].call($this)
- })
- }
-
- var old = $.fn.alert
-
- $.fn.alert = Plugin
- $.fn.alert.Constructor = Alert
-
-
- // ALERT NO CONFLICT
- // =================
-
- $.fn.alert.noConflict = function () {
- $.fn.alert = old
- return this
- }
-
-
- // ALERT DATA-API
- // ==============
-
- $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: button.js v3.2.0
- * http://getbootstrap.com/javascript/#buttons
- * ========================================================================
- * Copyright 2011-2014 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // BUTTON PUBLIC CLASS DEFINITION
- // ==============================
-
- var Button = function (element, options) {
- this.$element = $(element)
- this.options = $.extend({}, Button.DEFAULTS, options)
- this.isLoading = false
- }
-
- Button.VERSION = '3.2.0'
-
- Button.DEFAULTS = {
- loadingText: 'loading...'
- }
-
- Button.prototype.setState = function (state) {
- var d = 'disabled'
- var $el = this.$element
- var val = $el.is('input') ? 'val' : 'html'
- var data = $el.data()
-
- state = state + 'Text'
-
- if (data.resetText == null) $el.data('resetText', $el[val]())
-
- $el[val](data[state] == null ? this.options[state] : data[state])
-
- // push to event loop to allow forms to submit
- setTimeout($.proxy(function () {
- if (state == 'loadingText') {
- this.isLoading = true
- $el.addClass(d).attr(d, d)
- } else if (this.isLoading) {
- this.isLoading = false
- $el.removeClass(d).removeAttr(d)
- }
- }, this), 0)
- }
-
- Button.prototype.toggle = function () {
- var changed = true
- var $parent = this.$element.closest('[data-toggle="buttons"]')
-
- if ($parent.length) {
- var $input = this.$element.find('input')
- if ($input.prop('type') == 'radio') {
- if ($input.prop('checked') && this.$element.hasClass('active')) changed = false
- else $parent.find('.active').removeClass('active')
- }
- if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')
- }
-
- if (changed) this.$element.toggleClass('active')
- }
-
-
- // BUTTON PLUGIN DEFINITION
- // ========================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.button')
- var options = typeof option == 'object' && option
-
- if (!data) $this.data('bs.button', (data = new Button(this, options)))
-
- if (option == 'toggle') data.toggle()
- else if (option) data.setState(option)
- })
- }
-
- var old = $.fn.button
-
- $.fn.button = Plugin
- $.fn.button.Constructor = Button
-
-
- // BUTTON NO CONFLICT
- // ==================
-
- $.fn.button.noConflict = function () {
- $.fn.button = old
- return this
- }
-
-
- // BUTTON DATA-API
- // ===============
-
- $(document).on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
- var $btn = $(e.target)
- if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
- Plugin.call($btn, 'toggle')
- e.preventDefault()
- })
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: carousel.js v3.2.0
- * http://getbootstrap.com/javascript/#carousel
- * ========================================================================
- * Copyright 2011-2014 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // CAROUSEL CLASS DEFINITION
- // =========================
-
- var Carousel = function (element, options) {
- this.$element = $(element).on('keydown.bs.carousel', $.proxy(this.keydown, this))
- this.$indicators = this.$element.find('.carousel-indicators')
- this.options = options
- this.paused =
- this.sliding =
- this.interval =
- this.$active =
- this.$items = null
-
- this.options.pause == 'hover' && this.$element
- .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
- .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
- }
-
- Carousel.VERSION = '3.2.0'
-
- Carousel.DEFAULTS = {
- interval: 5000,
- pause: 'hover',
- wrap: true
- }
-
- Carousel.prototype.keydown = function (e) {
- switch (e.which) {
- case 37: this.prev(); break
- case 39: this.next(); break
- default: return
- }
-
- e.preventDefault()
- }
-
- Carousel.prototype.cycle = function (e) {
- e || (this.paused = false)
-
- this.interval && clearInterval(this.interval)
-
- this.options.interval
- && !this.paused
- && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
-
- return this
- }
-
- Carousel.prototype.getItemIndex = function (item) {
- this.$items = item.parent().children('.item')
- return this.$items.index(item || this.$active)
- }
-
- Carousel.prototype.to = function (pos) {
- var that = this
- var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
-
- if (pos > (this.$items.length - 1) || pos < 0) return
-
- if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
- if (activeIndex == pos) return this.pause().cycle()
-
- return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
- }
-
- Carousel.prototype.pause = function (e) {
- e || (this.paused = true)
-
- if (this.$element.find('.next, .prev').length && $.support.transition) {
- this.$element.trigger($.support.transition.end)
- this.cycle(true)
- }
-
- this.interval = clearInterval(this.interval)
-
- return this
- }
-
- Carousel.prototype.next = function () {
- if (this.sliding) return
- return this.slide('next')
- }
-
- Carousel.prototype.prev = function () {
- if (this.sliding) return
- return this.slide('prev')
- }
-
- Carousel.prototype.slide = function (type, next) {
- var $active = this.$element.find('.item.active')
- var $next = next || $active[type]()
- var isCycling = this.interval
- var direction = type == 'next' ? 'left' : 'right'
- var fallback = type == 'next' ? 'first' : 'last'
- var that = this
-
- if (!$next.length) {
- if (!this.options.wrap) return
- $next = this.$element.find('.item')[fallback]()
- }
-
- if ($next.hasClass('active')) return (this.sliding = false)
-
- var relatedTarget = $next[0]
- var slideEvent = $.Event('slide.bs.carousel', {
- relatedTarget: relatedTarget,
- direction: direction
- })
- this.$element.trigger(slideEvent)
- if (slideEvent.isDefaultPrevented()) return
-
- this.sliding = true
-
- isCycling && this.pause()
-
- if (this.$indicators.length) {
- this.$indicators.find('.active').removeClass('active')
- var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
- $nextIndicator && $nextIndicator.addClass('active')
- }
-
- var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
- if ($.support.transition && this.$element.hasClass('slide')) {
- $next.addClass(type)
- $next[0].offsetWidth // force reflow
- $active.addClass(direction)
- $next.addClass(direction)
- $active
- .one('bsTransitionEnd', function () {
- $next.removeClass([type, direction].join(' ')).addClass('active')
- $active.removeClass(['active', direction].join(' '))
- that.sliding = false
- setTimeout(function () {
- that.$element.trigger(slidEvent)
- }, 0)
- })
- .emulateTransitionEnd($active.css('transition-duration').slice(0, -1) * 1000)
- } else {
- $active.removeClass('active')
- $next.addClass('active')
- this.sliding = false
- this.$element.trigger(slidEvent)
- }
-
- isCycling && this.cycle()
-
- return this
- }
-
-
- // CAROUSEL PLUGIN DEFINITION
- // ==========================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.carousel')
- var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
- var action = typeof option == 'string' ? option : options.slide
-
- if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
- if (typeof option == 'number') data.to(option)
- else if (action) data[action]()
- else if (options.interval) data.pause().cycle()
- })
- }
-
- var old = $.fn.carousel
-
- $.fn.carousel = Plugin
- $.fn.carousel.Constructor = Carousel
-
-
- // CAROUSEL NO CONFLICT
- // ====================
-
- $.fn.carousel.noConflict = function () {
- $.fn.carousel = old
- return this
- }
-
-
- // CAROUSEL DATA-API
- // =================
-
- $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
- var href
- var $this = $(this)
- var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
- if (!$target.hasClass('carousel')) return
- var options = $.extend({}, $target.data(), $this.data())
- var slideIndex = $this.attr('data-slide-to')
- if (slideIndex) options.interval = false
-
- Plugin.call($target, options)
-
- if (slideIndex) {
- $target.data('bs.carousel').to(slideIndex)
- }
-
- e.preventDefault()
- })
-
- $(window).on('load', function () {
- $('[data-ride="carousel"]').each(function () {
- var $carousel = $(this)
- Plugin.call($carousel, $carousel.data())
- })
- })
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: dropdown.js v3.2.0
- * http://getbootstrap.com/javascript/#dropdowns
- * ========================================================================
- * Copyright 2011-2014 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // DROPDOWN CLASS DEFINITION
- // =========================
-
- var backdrop = '.dropdown-backdrop'
- var toggle = '[data-toggle="dropdown"]'
- var Dropdown = function (element) {
- $(element).on('click.bs.dropdown', this.toggle)
- }
-
- Dropdown.VERSION = '3.2.0'
-
- Dropdown.prototype.toggle = function (e) {
- var $this = $(this)
-
- if ($this.is('.disabled, :disabled')) return
-
- var $parent = getParent($this)
- var isActive = $parent.hasClass('open')
-
- clearMenus()
-
- if (!isActive) {
- if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
- // if mobile we use a backdrop because click events don't delegate
- $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
- }
-
- var relatedTarget = { relatedTarget: this }
- $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
-
- if (e.isDefaultPrevented()) return
-
- $this.trigger('focus')
-
- $parent
- .toggleClass('open')
- .trigger('shown.bs.dropdown', relatedTarget)
- }
-
- return false
- }
-
- Dropdown.prototype.keydown = function (e) {
- if (!/(38|40|27)/.test(e.keyCode)) return
-
- var $this = $(this)
-
- e.preventDefault()
- e.stopPropagation()
-
- if ($this.is('.disabled, :disabled')) return
-
- var $parent = getParent($this)
- var isActive = $parent.hasClass('open')
-
- if (!isActive || (isActive && e.keyCode == 27)) {
- if (e.which == 27) $parent.find(toggle).trigger('focus')
- return $this.trigger('click')
- }
-
- var desc = ' li:not(.divider):visible a'
- var $items = $parent.find('[role="menu"]' + desc + ', [role="listbox"]' + desc)
-
- if (!$items.length) return
-
- var index = $items.index($items.filter(':focus'))
-
- if (e.keyCode == 38 && index > 0) index-- // up
- if (e.keyCode == 40 && index < $items.length - 1) index++ // down
- if (!~index) index = 0
-
- $items.eq(index).trigger('focus')
- }
-
- function clearMenus(e) {
- if (e && e.which === 3) return
- $(backdrop).remove()
- $(toggle).each(function () {
- var $parent = getParent($(this))
- var relatedTarget = { relatedTarget: this }
- if (!$parent.hasClass('open')) return
- $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
- if (e.isDefaultPrevented()) return
- $parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
- })
- }
-
- function getParent($this) {
- var selector = $this.attr('data-target')
-
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
- }
-
- var $parent = selector && $(selector)
-
- return $parent && $parent.length ? $parent : $this.parent()
- }
-
-
- // DROPDOWN PLUGIN DEFINITION
- // ==========================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.dropdown')
-
- if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
- if (typeof option == 'string') data[option].call($this)
- })
- }
-
- var old = $.fn.dropdown
-
- $.fn.dropdown = Plugin
- $.fn.dropdown.Constructor = Dropdown
-
-
- // DROPDOWN NO CONFLICT
- // ====================
-
- $.fn.dropdown.noConflict = function () {
- $.fn.dropdown = old
- return this
- }
-
-
- // APPLY TO STANDARD DROPDOWN ELEMENTS
- // ===================================
-
- $(document)
- .on('click.bs.dropdown.data-api', clearMenus)
- .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
- .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
- .on('keydown.bs.dropdown.data-api', toggle + ', [role="menu"], [role="listbox"]', Dropdown.prototype.keydown)
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: modal.js v3.2.0
- * http://getbootstrap.com/javascript/#modals
- * ========================================================================
- * Copyright 2011-2014 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // MODAL CLASS DEFINITION
- // ======================
-
- var Modal = function (element, options) {
- this.options = options
- this.$body = $(document.body)
- this.$element = $(element)
- this.$backdrop =
- this.isShown = null
- this.scrollbarWidth = 0
-
- if (this.options.remote) {
- this.$element
- .find('.modal-content')
- .load(this.options.remote, $.proxy(function () {
- this.$element.trigger('loaded.bs.modal')
- }, this))
- }
- }
-
- Modal.VERSION = '3.2.0'
-
- Modal.DEFAULTS = {
- backdrop: true,
- keyboard: true,
- show: true
- }
-
- Modal.prototype.toggle = function (_relatedTarget) {
- return this.isShown ? this.hide() : this.show(_relatedTarget)
- }
-
- Modal.prototype.show = function (_relatedTarget) {
- var that = this
- var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
-
- this.$element.trigger(e)
-
- if (this.isShown || e.isDefaultPrevented()) return
-
- this.isShown = true
-
- this.checkScrollbar()
- this.$body.addClass('modal-open')
-
- this.setScrollbar()
- this.escape()
-
- this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
-
- this.backdrop(function () {
- var transition = $.support.transition && that.$element.hasClass('fade')
-
- if (!that.$element.parent().length) {
- that.$element.appendTo(that.$body) // don't move modals dom position
- }
-
- that.$element
- .show()
- .scrollTop(0)
-
- if (transition) {
- that.$element[0].offsetWidth // force reflow
- }
-
- that.$element
- .addClass('in')
- .attr('aria-hidden', false)
-
- that.enforceFocus()
-
- var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
-
- transition ?
- that.$element.find('.modal-dialog') // wait for modal to slide in
- .one('bsTransitionEnd', function () {
- that.$element.trigger('focus').trigger(e)
- })
- .emulateTransitionEnd(300) :
- that.$element.trigger('focus').trigger(e)
- })
- }
-
- Modal.prototype.hide = function (e) {
- if (e) e.preventDefault()
-
- e = $.Event('hide.bs.modal')
-
- this.$element.trigger(e)
-
- if (!this.isShown || e.isDefaultPrevented()) return
-
- this.isShown = false
-
- this.$body.removeClass('modal-open')
-
- this.resetScrollbar()
- this.escape()
-
- $(document).off('focusin.bs.modal')
-
- this.$element
- .removeClass('in')
- .attr('aria-hidden', true)
- .off('click.dismiss.bs.modal')
-
- $.support.transition && this.$element.hasClass('fade') ?
- this.$element
- .one('bsTransitionEnd', $.proxy(this.hideModal, this))
- .emulateTransitionEnd(300) :
- this.hideModal()
- }
-
- Modal.prototype.enforceFocus = function () {
- $(document)
- .off('focusin.bs.modal') // guard against infinite focus loop
- .on('focusin.bs.modal', $.proxy(function (e) {
- if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {
- this.$element.trigger('focus')
- }
- }, this))
- }
-
- Modal.prototype.escape = function () {
- if (this.isShown && this.options.keyboard) {
- this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {
- e.which == 27 && this.hide()
- }, this))
- } else if (!this.isShown) {
- this.$element.off('keyup.dismiss.bs.modal')
- }
- }
-
- Modal.prototype.hideModal = function () {
- var that = this
- this.$element.hide()
- this.backdrop(function () {
- that.$element.trigger('hidden.bs.modal')
- })
- }
-
- Modal.prototype.removeBackdrop = function () {
- this.$backdrop && this.$backdrop.remove()
- this.$backdrop = null
- }
-
- Modal.prototype.backdrop = function (callback) {
- var that = this
- var animate = this.$element.hasClass('fade') ? 'fade' : ''
-
- if (this.isShown && this.options.backdrop) {
- var doAnimate = $.support.transition && animate
-
- this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
- .appendTo(this.$body)
-
- this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
- if (e.target !== e.currentTarget) return
- this.options.backdrop == 'static'
- ? this.$element[0].focus.call(this.$element[0])
- : this.hide.call(this)
- }, this))
-
- if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
-
- this.$backdrop.addClass('in')
-
- if (!callback) return
-
- doAnimate ?
- this.$backdrop
- .one('bsTransitionEnd', callback)
- .emulateTransitionEnd(150) :
- callback()
-
- } else if (!this.isShown && this.$backdrop) {
- this.$backdrop.removeClass('in')
-
- var callbackRemove = function () {
- that.removeBackdrop()
- callback && callback()
- }
- $.support.transition && this.$element.hasClass('fade') ?
- this.$backdrop
- .one('bsTransitionEnd', callbackRemove)
- .emulateTransitionEnd(150) :
- callbackRemove()
-
- } else if (callback) {
- callback()
- }
- }
-
- Modal.prototype.checkScrollbar = function () {
- if (document.body.clientWidth >= window.innerWidth) return
- this.scrollbarWidth = this.scrollbarWidth || this.measureScrollbar()
- }
-
- Modal.prototype.setScrollbar = function () {
- var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
- if (this.scrollbarWidth) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
- }
-
- Modal.prototype.resetScrollbar = function () {
- this.$body.css('padding-right', '')
- }
-
- Modal.prototype.measureScrollbar = function () { // thx walsh
- var scrollDiv = document.createElement('div')
- scrollDiv.className = 'modal-scrollbar-measure'
- this.$body.append(scrollDiv)
- var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
- this.$body[0].removeChild(scrollDiv)
- return scrollbarWidth
- }
-
-
- // MODAL PLUGIN DEFINITION
- // =======================
-
- function Plugin(option, _relatedTarget) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.modal')
- var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
-
- if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
- if (typeof option == 'string') data[option](_relatedTarget)
- else if (options.show) data.show(_relatedTarget)
- })
- }
-
- var old = $.fn.modal
-
- $.fn.modal = Plugin
- $.fn.modal.Constructor = Modal
-
-
- // MODAL NO CONFLICT
- // =================
-
- $.fn.modal.noConflict = function () {
- $.fn.modal = old
- return this
- }
-
-
- // MODAL DATA-API
- // ==============
-
- $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
- var $this = $(this)
- var href = $this.attr('href')
- var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
- var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
-
- if ($this.is('a')) e.preventDefault()
-
- $target.one('show.bs.modal', function (showEvent) {
- if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
- $target.one('hidden.bs.modal', function () {
- $this.is(':visible') && $this.trigger('focus')
- })
- })
- Plugin.call($target, option, this)
- })
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: tooltip.js v3.2.0
- * http://getbootstrap.com/javascript/#tooltip
- * Inspired by the original jQuery.tipsy by Jason Frame
- * ========================================================================
- * Copyright 2011-2014 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // TOOLTIP PUBLIC CLASS DEFINITION
- // ===============================
-
- var Tooltip = function (element, options) {
- this.type =
- this.options =
- this.enabled =
- this.timeout =
- this.hoverState =
- this.$element = null
-
- this.init('tooltip', element, options)
- }
-
- Tooltip.VERSION = '3.2.0'
-
- Tooltip.DEFAULTS = {
- animation: true,
- placement: 'top',
- selector: false,
- template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
- trigger: 'hover focus',
- title: '',
- delay: 0,
- html: false,
- container: false,
- viewport: {
- selector: 'body',
- padding: 0
- }
- }
-
- Tooltip.prototype.init = function (type, element, options) {
- this.enabled = true
- this.type = type
- this.$element = $(element)
- this.options = this.getOptions(options)
- this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
-
- var triggers = this.options.trigger.split(' ')
-
- for (var i = triggers.length; i--;) {
- var trigger = triggers[i]
-
- if (trigger == 'click') {
- this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
- } else if (trigger != 'manual') {
- var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin'
- var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
-
- this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
- this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
- }
- }
-
- this.options.selector ?
- (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
- this.fixTitle()
- }
-
- Tooltip.prototype.getDefaults = function () {
- return Tooltip.DEFAULTS
- }
-
- Tooltip.prototype.getOptions = function (options) {
- options = $.extend({}, this.getDefaults(), this.$element.data(), options)
-
- if (options.delay && typeof options.delay == 'number') {
- options.delay = {
- show: options.delay,
- hide: options.delay
- }
- }
-
- return options
- }
-
- Tooltip.prototype.getDelegateOptions = function () {
- var options = {}
- var defaults = this.getDefaults()
-
- this._options && $.each(this._options, function (key, value) {
- if (defaults[key] != value) options[key] = value
- })
-
- return options
- }
-
- Tooltip.prototype.enter = function (obj) {
- var self = obj instanceof this.constructor ?
- obj : $(obj.currentTarget).data('bs.' + this.type)
-
- if (!self) {
- self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
- $(obj.currentTarget).data('bs.' + this.type, self)
- }
-
- clearTimeout(self.timeout)
-
- self.hoverState = 'in'
-
- if (!self.options.delay || !self.options.delay.show) return self.show()
-
- self.timeout = setTimeout(function () {
- if (self.hoverState == 'in') self.show()
- }, self.options.delay.show)
- }
-
- Tooltip.prototype.leave = function (obj) {
- var self = obj instanceof this.constructor ?
- obj : $(obj.currentTarget).data('bs.' + this.type)
-
- if (!self) {
- self = new this.constructor(obj.currentTarget, this.getDelegateOptions())
- $(obj.currentTarget).data('bs.' + this.type, self)
- }
-
- clearTimeout(self.timeout)
-
- self.hoverState = 'out'
-
- if (!self.options.delay || !self.options.delay.hide) return self.hide()
-
- self.timeout = setTimeout(function () {
- if (self.hoverState == 'out') self.hide()
- }, self.options.delay.hide)
- }
-
- Tooltip.prototype.show = function () {
- var e = $.Event('show.bs.' + this.type)
-
- if (this.hasContent() && this.enabled) {
- this.$element.trigger(e)
-
- var inDom = $.contains(document.documentElement, this.$element[0])
- if (e.isDefaultPrevented() || !inDom) return
- var that = this
-
- var $tip = this.tip()
-
- var tipId = this.getUID(this.type)
-
- this.setContent()
- $tip.attr('id', tipId)
- this.$element.attr('aria-describedby', tipId)
-
- if (this.options.animation) $tip.addClass('fade')
-
- var placement = typeof this.options.placement == 'function' ?
- this.options.placement.call(this, $tip[0], this.$element[0]) :
- this.options.placement
-
- var autoToken = /\s?auto?\s?/i
- var autoPlace = autoToken.test(placement)
- if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
-
- $tip
- .detach()
- .css({ top: 0, left: 0, display: 'block' })
- .addClass(placement)
- .data('bs.' + this.type, this)
-
- this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
-
- var pos = this.getPosition()
- var actualWidth = $tip[0].offsetWidth
- var actualHeight = $tip[0].offsetHeight
-
- if (autoPlace) {
- var orgPlacement = placement
- var $parent = this.$element.parent()
- var parentDim = this.getPosition($parent)
-
- placement = placement == 'bottom' && pos.top + pos.height + actualHeight - parentDim.scroll > parentDim.height ? 'top' :
- placement == 'top' && pos.top - parentDim.scroll - actualHeight < 0 ? 'bottom' :
- placement == 'right' && pos.right + actualWidth > parentDim.width ? 'left' :
- placement == 'left' && pos.left - actualWidth < parentDim.left ? 'right' :
- placement
-
- $tip
- .removeClass(orgPlacement)
- .addClass(placement)
- }
-
- var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
-
- this.applyPlacement(calculatedOffset, placement)
-
- var complete = function () {
- that.$element.trigger('shown.bs.' + that.type)
- that.hoverState = null
- }
-
- $.support.transition && this.$tip.hasClass('fade') ?
- $tip
- .one('bsTransitionEnd', complete)
- .emulateTransitionEnd(150) :
- complete()
- }
- }
-
- Tooltip.prototype.applyPlacement = function (offset, placement) {
- var $tip = this.tip()
- var width = $tip[0].offsetWidth
- var height = $tip[0].offsetHeight
-
- // manually read margins because getBoundingClientRect includes difference
- var marginTop = parseInt($tip.css('margin-top'), 10)
- var marginLeft = parseInt($tip.css('margin-left'), 10)
-
- // we must check for NaN for ie 8/9
- if (isNaN(marginTop)) marginTop = 0
- if (isNaN(marginLeft)) marginLeft = 0
-
- offset.top = offset.top + marginTop
- offset.left = offset.left + marginLeft
-
- // $.fn.offset doesn't round pixel values
- // so we use setOffset directly with our own function B-0
- $.offset.setOffset($tip[0], $.extend({
- using: function (props) {
- $tip.css({
- top: Math.round(props.top),
- left: Math.round(props.left)
- })
- }
- }, offset), 0)
-
- $tip.addClass('in')
-
- // check to see if placing tip in new offset caused the tip to resize itself
- var actualWidth = $tip[0].offsetWidth
- var actualHeight = $tip[0].offsetHeight
-
- if (placement == 'top' && actualHeight != height) {
- offset.top = offset.top + height - actualHeight
- }
-
- var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
-
- if (delta.left) offset.left += delta.left
- else offset.top += delta.top
-
- var arrowDelta = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
- var arrowPosition = delta.left ? 'left' : 'top'
- var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight'
-
- $tip.offset(offset)
- this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition)
- }
-
- Tooltip.prototype.replaceArrow = function (delta, dimension, position) {
- this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '')
- }
-
- Tooltip.prototype.setContent = function () {
- var $tip = this.tip()
- var title = this.getTitle()
-
- $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
- $tip.removeClass('fade in top bottom left right')
- }
-
- Tooltip.prototype.hide = function () {
- var that = this
- var $tip = this.tip()
- var e = $.Event('hide.bs.' + this.type)
-
- this.$element.removeAttr('aria-describedby')
-
- function complete() {
- if (that.hoverState != 'in') $tip.detach()
- that.$element.trigger('hidden.bs.' + that.type)
- }
-
- this.$element.trigger(e)
-
- if (e.isDefaultPrevented()) return
-
- $tip.removeClass('in')
-
- $.support.transition && this.$tip.hasClass('fade') ?
- $tip
- .one('bsTransitionEnd', complete)
- .emulateTransitionEnd(150) :
- complete()
-
- this.hoverState = null
-
- return this
- }
-
- Tooltip.prototype.fixTitle = function () {
- var $e = this.$element
- if ($e.attr('title') || typeof ($e.attr('data-original-title')) != 'string') {
- $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
- }
- }
-
- Tooltip.prototype.hasContent = function () {
- return this.getTitle()
- }
-
- Tooltip.prototype.getPosition = function ($element) {
- $element = $element || this.$element
- var el = $element[0]
- var isBody = el.tagName == 'BODY'
- return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, {
- scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(),
- width: isBody ? $(window).width() : $element.outerWidth(),
- height: isBody ? $(window).height() : $element.outerHeight()
- }, isBody ? { top: 0, left: 0 } : $element.offset())
- }
-
- Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
- return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
- placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
- placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
- /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }
-
- }
-
- Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
- var delta = { top: 0, left: 0 }
- if (!this.$viewport) return delta
-
- var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
- var viewportDimensions = this.getPosition(this.$viewport)
-
- if (/right|left/.test(placement)) {
- var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll
- var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
- if (topEdgeOffset < viewportDimensions.top) { // top overflow
- delta.top = viewportDimensions.top - topEdgeOffset
- } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
- delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset
- }
- } else {
- var leftEdgeOffset = pos.left - viewportPadding
- var rightEdgeOffset = pos.left + viewportPadding + actualWidth
- if (leftEdgeOffset < viewportDimensions.left) { // left overflow
- delta.left = viewportDimensions.left - leftEdgeOffset
- } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
- delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
- }
- }
-
- return delta
- }
-
- Tooltip.prototype.getTitle = function () {
- var title
- var $e = this.$element
- var o = this.options
-
- title = $e.attr('data-original-title')
- || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
-
- return title
- }
-
- Tooltip.prototype.getUID = function (prefix) {
- do prefix += ~~(Math.random() * 1000000)
- while (document.getElementById(prefix))
- return prefix
- }
-
- Tooltip.prototype.tip = function () {
- return (this.$tip = this.$tip || $(this.options.template))
- }
-
- Tooltip.prototype.arrow = function () {
- return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))
- }
-
- Tooltip.prototype.validate = function () {
- if (!this.$element[0].parentNode) {
- this.hide()
- this.$element = null
- this.options = null
- }
- }
-
- Tooltip.prototype.enable = function () {
- this.enabled = true
- }
-
- Tooltip.prototype.disable = function () {
- this.enabled = false
- }
-
- Tooltip.prototype.toggleEnabled = function () {
- this.enabled = !this.enabled
- }
-
- Tooltip.prototype.toggle = function (e) {
- var self = this
- if (e) {
- self = $(e.currentTarget).data('bs.' + this.type)
- if (!self) {
- self = new this.constructor(e.currentTarget, this.getDelegateOptions())
- $(e.currentTarget).data('bs.' + this.type, self)
- }
- }
-
- self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
- }
-
- Tooltip.prototype.destroy = function () {
- clearTimeout(this.timeout)
- this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
- }
-
-
- // TOOLTIP PLUGIN DEFINITION
- // =========================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.tooltip')
- var options = typeof option == 'object' && option
-
- if (!data && option == 'destroy') return
- if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- var old = $.fn.tooltip
-
- $.fn.tooltip = Plugin
- $.fn.tooltip.Constructor = Tooltip
-
-
- // TOOLTIP NO CONFLICT
- // ===================
-
- $.fn.tooltip.noConflict = function () {
- $.fn.tooltip = old
- return this
- }
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: popover.js v3.2.0
- * http://getbootstrap.com/javascript/#popovers
- * ========================================================================
- * Copyright 2011-2014 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // POPOVER PUBLIC CLASS DEFINITION
- // ===============================
-
- var Popover = function (element, options) {
- this.init('popover', element, options)
- }
-
- if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
-
- Popover.VERSION = '3.2.0'
-
- Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
- placement: 'right',
- trigger: 'click',
- content: '',
- template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
- })
-
-
- // NOTE: POPOVER EXTENDS tooltip.js
- // ================================
-
- Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
-
- Popover.prototype.constructor = Popover
-
- Popover.prototype.getDefaults = function () {
- return Popover.DEFAULTS
- }
-
- Popover.prototype.setContent = function () {
- var $tip = this.tip()
- var title = this.getTitle()
- var content = this.getContent()
-
- $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
- $tip.find('.popover-content').empty()[ // we use append for html objects to maintain js events
- this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
- ](content)
-
- $tip.removeClass('fade top bottom left right in')
-
- // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
- // this manually by checking the contents.
- if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
- }
-
- Popover.prototype.hasContent = function () {
- return this.getTitle() || this.getContent()
- }
-
- Popover.prototype.getContent = function () {
- var $e = this.$element
- var o = this.options
-
- return $e.attr('data-content')
- || (typeof o.content == 'function' ?
- o.content.call($e[0]) :
- o.content)
- }
-
- Popover.prototype.arrow = function () {
- return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
- }
-
- Popover.prototype.tip = function () {
- if (!this.$tip) this.$tip = $(this.options.template)
- return this.$tip
- }
-
-
- // POPOVER PLUGIN DEFINITION
- // =========================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.popover')
- var options = typeof option == 'object' && option
-
- if (!data && option == 'destroy') return
- if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- var old = $.fn.popover
-
- $.fn.popover = Plugin
- $.fn.popover.Constructor = Popover
-
-
- // POPOVER NO CONFLICT
- // ===================
-
- $.fn.popover.noConflict = function () {
- $.fn.popover = old
- return this
- }
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: tab.js v3.2.0
- * http://getbootstrap.com/javascript/#tabs
- * ========================================================================
- * Copyright 2011-2014 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // TAB CLASS DEFINITION
- // ====================
-
- var Tab = function (element) {
- this.element = $(element)
- }
-
- Tab.VERSION = '3.2.0'
-
- Tab.prototype.show = function () {
- var $this = this.element
- var $ul = $this.closest('ul:not(.dropdown-menu)')
- var selector = $this.data('target')
-
- if (!selector) {
- selector = $this.attr('href')
- selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
- }
-
- if ($this.parent('li').hasClass('active')) return
-
- var previous = $ul.find('.active:last a')[0]
- var e = $.Event('show.bs.tab', {
- relatedTarget: previous
- })
-
- $this.trigger(e)
-
- if (e.isDefaultPrevented()) return
-
- var $target = $(selector)
-
- this.activate($this.closest('li'), $ul)
- this.activate($target, $target.parent(), function () {
- $this.trigger({
- type: 'shown.bs.tab',
- relatedTarget: previous
- })
- })
- }
-
- Tab.prototype.activate = function (element, container, callback) {
- var $active = container.find('> .active')
- var transition = callback
- && $.support.transition
- && $active.hasClass('fade')
-
- function next() {
- $active
- .removeClass('active')
- .find('> .dropdown-menu > .active')
- .removeClass('active')
-
- element.addClass('active')
-
- if (transition) {
- element[0].offsetWidth // reflow for transition
- element.addClass('in')
- } else {
- element.removeClass('fade')
- }
-
- if (element.parent('.dropdown-menu')) {
- element.closest('li.dropdown').addClass('active')
- }
-
- callback && callback()
- }
-
- transition ?
- $active
- .one('bsTransitionEnd', next)
- .emulateTransitionEnd(150) :
- next()
-
- $active.removeClass('in')
- }
-
-
- // TAB PLUGIN DEFINITION
- // =====================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.tab')
-
- if (!data) $this.data('bs.tab', (data = new Tab(this)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- var old = $.fn.tab
-
- $.fn.tab = Plugin
- $.fn.tab.Constructor = Tab
-
-
- // TAB NO CONFLICT
- // ===============
-
- $.fn.tab.noConflict = function () {
- $.fn.tab = old
- return this
- }
-
-
- // TAB DATA-API
- // ============
-
- $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
- e.preventDefault()
- Plugin.call($(this), 'show')
- })
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: affix.js v3.2.0
- * http://getbootstrap.com/javascript/#affix
- * ========================================================================
- * Copyright 2011-2014 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // AFFIX CLASS DEFINITION
- // ======================
-
- var Affix = function (element, options) {
- this.options = $.extend({}, Affix.DEFAULTS, options)
-
- this.$target = $(this.options.target)
- .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
- .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
-
- this.$element = $(element)
- this.affixed =
- this.unpin =
- this.pinnedOffset = null
-
- this.checkPosition()
- }
-
- Affix.VERSION = '3.2.0'
-
- Affix.RESET = 'affix affix-top affix-bottom'
-
- Affix.DEFAULTS = {
- offset: 0,
- target: window
- }
-
- Affix.prototype.getPinnedOffset = function () {
- if (this.pinnedOffset) return this.pinnedOffset
- this.$element.removeClass(Affix.RESET).addClass('affix')
- var scrollTop = this.$target.scrollTop()
- var position = this.$element.offset()
- return (this.pinnedOffset = position.top - scrollTop)
- }
-
- Affix.prototype.checkPositionWithEventLoop = function () {
- setTimeout($.proxy(this.checkPosition, this), 1)
- }
-
- Affix.prototype.checkPosition = function () {
- if (!this.$element.is(':visible')) return
-
- var scrollHeight = $(document).height()
- var scrollTop = this.$target.scrollTop()
- var position = this.$element.offset()
- var offset = this.options.offset
- var offsetTop = offset.top
- var offsetBottom = offset.bottom
-
- if (typeof offset != 'object') offsetBottom = offsetTop = offset
- if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
- if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
-
- var affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ? false :
- offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :
- offsetTop != null && (scrollTop <= offsetTop) ? 'top' : false
-
- if (this.affixed === affix) return
- if (this.unpin != null) this.$element.css('top', '')
-
- var affixType = 'affix' + (affix ? '-' + affix : '')
- var e = $.Event(affixType + '.bs.affix')
-
- this.$element.trigger(e)
-
- if (e.isDefaultPrevented()) return
-
- this.affixed = affix
- this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
-
- this.$element
- .removeClass(Affix.RESET)
- .addClass(affixType)
- .trigger($.Event(affixType.replace('affix', 'affixed')))
-
- if (affix == 'bottom') {
- this.$element.offset({
- top: scrollHeight - this.$element.height() - offsetBottom
- })
- }
- }
-
-
- // AFFIX PLUGIN DEFINITION
- // =======================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.affix')
- var options = typeof option == 'object' && option
-
- if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- var old = $.fn.affix
-
- $.fn.affix = Plugin
- $.fn.affix.Constructor = Affix
-
-
- // AFFIX NO CONFLICT
- // =================
-
- $.fn.affix.noConflict = function () {
- $.fn.affix = old
- return this
- }
-
-
- // AFFIX DATA-API
- // ==============
-
- $(window).on('load', function () {
- $('[data-spy="affix"]').each(function () {
- var $spy = $(this)
- var data = $spy.data()
-
- data.offset = data.offset || {}
-
- if (data.offsetBottom) data.offset.bottom = data.offsetBottom
- if (data.offsetTop) data.offset.top = data.offsetTop
-
- Plugin.call($spy, data)
- })
- })
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: collapse.js v3.2.0
- * http://getbootstrap.com/javascript/#collapse
- * ========================================================================
- * Copyright 2011-2014 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // COLLAPSE PUBLIC CLASS DEFINITION
- // ================================
-
- var Collapse = function (element, options) {
- this.$element = $(element)
- this.options = $.extend({}, Collapse.DEFAULTS, options)
- this.transitioning = null
-
- if (this.options.parent) this.$parent = $(this.options.parent)
- if (this.options.toggle) this.toggle()
- }
-
- Collapse.VERSION = '3.2.0'
-
- Collapse.DEFAULTS = {
- toggle: true
- }
-
- Collapse.prototype.dimension = function () {
- var hasWidth = this.$element.hasClass('width')
- return hasWidth ? 'width' : 'height'
- }
-
- Collapse.prototype.show = function () {
- if (this.transitioning || this.$element.hasClass('in')) return
-
- var startEvent = $.Event('show.bs.collapse')
- this.$element.trigger(startEvent)
- if (startEvent.isDefaultPrevented()) return
-
- var actives = this.$parent && this.$parent.find('> .panel > .in')
-
- if (actives && actives.length) {
- var hasData = actives.data('bs.collapse')
- if (hasData && hasData.transitioning) return
- Plugin.call(actives, 'hide')
- hasData || actives.data('bs.collapse', null)
- }
-
- var dimension = this.dimension()
-
- this.$element
- .removeClass('collapse')
- .addClass('collapsing')[dimension](0)
-
- this.transitioning = 1
-
- var complete = function () {
- this.$element
- .removeClass('collapsing')
- .addClass('collapse in')[dimension]('')
- this.transitioning = 0
- this.$element
- .trigger('shown.bs.collapse')
- }
-
- if (!$.support.transition) return complete.call(this)
-
- var scrollSize = $.camelCase(['scroll', dimension].join('-'))
-
- this.$element
- .one('bsTransitionEnd', $.proxy(complete, this))
- .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize])
- }
-
- Collapse.prototype.hide = function () {
- if (this.transitioning || !this.$element.hasClass('in')) return
-
- var startEvent = $.Event('hide.bs.collapse')
- this.$element.trigger(startEvent)
- if (startEvent.isDefaultPrevented()) return
-
- var dimension = this.dimension()
-
- this.$element[dimension](this.$element[dimension]())[0].offsetHeight
-
- this.$element
- .addClass('collapsing')
- .removeClass('collapse')
- .removeClass('in')
-
- this.transitioning = 1
-
- var complete = function () {
- this.transitioning = 0
- this.$element
- .trigger('hidden.bs.collapse')
- .removeClass('collapsing')
- .addClass('collapse')
- }
-
- if (!$.support.transition) return complete.call(this)
-
- this.$element
- [dimension](0)
- .one('bsTransitionEnd', $.proxy(complete, this))
- .emulateTransitionEnd(350)
- }
-
- Collapse.prototype.toggle = function () {
- this[this.$element.hasClass('in') ? 'hide' : 'show']()
- }
-
-
- // COLLAPSE PLUGIN DEFINITION
- // ==========================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.collapse')
- var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
-
- if (!data && options.toggle && option == 'show') option = !option
- if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- var old = $.fn.collapse
-
- $.fn.collapse = Plugin
- $.fn.collapse.Constructor = Collapse
-
-
- // COLLAPSE NO CONFLICT
- // ====================
-
- $.fn.collapse.noConflict = function () {
- $.fn.collapse = old
- return this
- }
-
-
- // COLLAPSE DATA-API
- // =================
-
- $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
- var href
- var $this = $(this)
- var target = $this.attr('data-target')
- || e.preventDefault()
- || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
- var $target = $(target)
- var data = $target.data('bs.collapse')
- var option = data ? 'toggle' : $this.data()
- var parent = $this.attr('data-parent')
- var $parent = parent && $(parent)
-
- if (!data || !data.transitioning) {
- if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed')
- $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
- }
-
- Plugin.call($target, option)
- })
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: scrollspy.js v3.2.0
- * http://getbootstrap.com/javascript/#scrollspy
- * ========================================================================
- * Copyright 2011-2014 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // SCROLLSPY CLASS DEFINITION
- // ==========================
-
- function ScrollSpy(element, options) {
- var process = $.proxy(this.process, this)
-
- this.$body = $('body')
- this.$scrollElement = $(element).is('body') ? $(window) : $(element)
- this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
- this.selector = (this.options.target || '') + ' .nav li > a'
- this.offsets = []
- this.targets = []
- this.activeTarget = null
- this.scrollHeight = 0
-
- this.$scrollElement.on('scroll.bs.scrollspy', process)
- this.refresh()
- this.process()
- }
-
- ScrollSpy.VERSION = '3.2.0'
-
- ScrollSpy.DEFAULTS = {
- offset: 10
- }
-
- ScrollSpy.prototype.getScrollHeight = function () {
- return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
- }
-
- ScrollSpy.prototype.refresh = function () {
- var offsetMethod = 'offset'
- var offsetBase = 0
-
- if (!$.isWindow(this.$scrollElement[0])) {
- offsetMethod = 'position'
- offsetBase = this.$scrollElement.scrollTop()
- }
-
- this.offsets = []
- this.targets = []
- this.scrollHeight = this.getScrollHeight()
-
- var self = this
-
- this.$body
- .find(this.selector)
- .map(function () {
- var $el = $(this)
- var href = $el.data('target') || $el.attr('href')
- var $href = /^#./.test(href) && $(href)
-
- return ($href
- && $href.length
- && $href.is(':visible')
- && [[$href[offsetMethod]().top + offsetBase, href]]) || null
- })
- .sort(function (a, b) { return a[0] - b[0] })
- .each(function () {
- self.offsets.push(this[0])
- self.targets.push(this[1])
- })
- }
-
- ScrollSpy.prototype.process = function () {
- var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
- var scrollHeight = this.getScrollHeight()
- var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
- var offsets = this.offsets
- var targets = this.targets
- var activeTarget = this.activeTarget
- var i
-
- if (this.scrollHeight != scrollHeight) {
- this.refresh()
- }
-
- if (scrollTop >= maxScroll) {
- return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
- }
-
- if (activeTarget && scrollTop <= offsets[0]) {
- return activeTarget != (i = targets[0]) && this.activate(i)
- }
-
- for (i = offsets.length; i--;) {
- activeTarget != targets[i]
- && scrollTop >= offsets[i]
- && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
- && this.activate(targets[i])
- }
- }
-
- ScrollSpy.prototype.activate = function (target) {
- this.activeTarget = target
-
- $(this.selector)
- .parentsUntil(this.options.target, '.active')
- .removeClass('active')
-
- var selector = this.selector +
- '[data-target="' + target + '"],' +
- this.selector + '[href="' + target + '"]'
-
- var active = $(selector)
- .parents('li')
- .addClass('active')
-
- if (active.parent('.dropdown-menu').length) {
- active = active
- .closest('li.dropdown')
- .addClass('active')
- }
-
- active.trigger('activate.bs.scrollspy')
- }
-
-
- // SCROLLSPY PLUGIN DEFINITION
- // ===========================
-
- function Plugin(option) {
- return this.each(function () {
- var $this = $(this)
- var data = $this.data('bs.scrollspy')
- var options = typeof option == 'object' && option
-
- if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
- if (typeof option == 'string') data[option]()
- })
- }
-
- var old = $.fn.scrollspy
-
- $.fn.scrollspy = Plugin
- $.fn.scrollspy.Constructor = ScrollSpy
-
-
- // SCROLLSPY NO CONFLICT
- // =====================
-
- $.fn.scrollspy.noConflict = function () {
- $.fn.scrollspy = old
- return this
- }
-
-
- // SCROLLSPY DATA-API
- // ==================
-
- $(window).on('load.bs.scrollspy.data-api', function () {
- $('[data-spy="scroll"]').each(function () {
- var $spy = $(this)
- Plugin.call($spy, $spy.data())
- })
- })
-
-}(jQuery);
-
-/* ========================================================================
- * Bootstrap: transition.js v3.2.0
- * http://getbootstrap.com/javascript/#transitions
- * ========================================================================
- * Copyright 2011-2014 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- * ======================================================================== */
-
-
-+function ($) {
- 'use strict';
-
- // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
- // ============================================================
-
- function transitionEnd() {
- var el = document.createElement('bootstrap')
-
- var transEndEventNames = {
- WebkitTransition : 'webkitTransitionEnd',
- MozTransition : 'transitionend',
- OTransition : 'oTransitionEnd otransitionend',
- transition : 'transitionend'
- }
-
- for (var name in transEndEventNames) {
- if (el.style[name] !== undefined) {
- return { end: transEndEventNames[name] }
- }
- }
-
- return false // explicit for ie8 ( ._.)
- }
-
- // http://blog.alexmaccaw.com/css-transitions
- $.fn.emulateTransitionEnd = function (duration) {
- var called = false
- var $el = this
- $(this).one('bsTransitionEnd', function () { called = true })
- var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
- setTimeout(callback, duration)
- return this
- }
-
- $(function () {
- $.support.transition = transitionEnd()
-
- if (!$.support.transition) return
-
- $.event.special.bsTransitionEnd = {
- bindType: $.support.transition.end,
- delegateType: $.support.transition.end,
- handle: function (e) {
- if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)
- }
- }
- })
-
-}(jQuery);
diff --git a/tools/infra-dashboard/js/fullcalendar.js b/tools/infra-dashboard/js/fullcalendar.js
deleted file mode 100644
index 958ca245..00000000
--- a/tools/infra-dashboard/js/fullcalendar.js
+++ /dev/null
@@ -1,12670 +0,0 @@
-/*!
- * FullCalendar v2.7.2
- * Docs & License: http://fullcalendar.io/
- * (c) 2016 Adam Shaw
- */
-
-(function(factory) {
- if (typeof define === 'function' && define.amd) {
- define([ 'jquery', 'moment' ], factory);
- }
- else if (typeof exports === 'object') { // Node/CommonJS
- module.exports = factory(require('jquery'), require('moment'));
- }
- else {
- factory(jQuery, moment);
- }
-})(function($, moment) {
-
-;;
-
-var FC = $.fullCalendar = {
- version: "2.7.2",
- internalApiVersion: 3
-};
-var fcViews = FC.views = {};
-
-
-$.fn.fullCalendar = function(options) {
- var args = Array.prototype.slice.call(arguments, 1); // for a possible method call
- var res = this; // what this function will return (this jQuery object by default)
-
- this.each(function(i, _element) { // loop each DOM element involved
- var element = $(_element);
- var calendar = element.data('fullCalendar'); // get the existing calendar object (if any)
- var singleRes; // the returned value of this single method call
-
- // a method call
- if (typeof options === 'string') {
- if (calendar && $.isFunction(calendar[options])) {
- singleRes = calendar[options].apply(calendar, args);
- if (!i) {
- res = singleRes; // record the first method call result
- }
- if (options === 'destroy') { // for the destroy method, must remove Calendar object data
- element.removeData('fullCalendar');
- }
- }
- }
- // a new calendar initialization
- else if (!calendar) { // don't initialize twice
- calendar = new Calendar(element, options);
- element.data('fullCalendar', calendar);
- calendar.render();
- }
- });
-
- return res;
-};
-
-
-var complexOptions = [ // names of options that are objects whose properties should be combined
- 'header',
- 'buttonText',
- 'buttonIcons',
- 'themeButtonIcons'
-];
-
-
-// Merges an array of option objects into a single object
-function mergeOptions(optionObjs) {
- return mergeProps(optionObjs, complexOptions);
-}
-
-
-// Given options specified for the calendar's constructor, massages any legacy options into a non-legacy form.
-// Converts View-Option-Hashes into the View-Specific-Options format.
-function massageOverrides(input) {
- var overrides = { views: input.views || {} }; // the output. ensure a `views` hash
- var subObj;
-
- // iterate through all option override properties (except `views`)
- $.each(input, function(name, val) {
- if (name != 'views') {
-
- // could the value be a legacy View-Option-Hash?
- if (
- $.isPlainObject(val) &&
- !/(time|duration|interval)$/i.test(name) && // exclude duration options. might be given as objects
- $.inArray(name, complexOptions) == -1 // complex options aren't allowed to be View-Option-Hashes
- ) {
- subObj = null;
-
- // iterate through the properties of this possible View-Option-Hash value
- $.each(val, function(subName, subVal) {
-
- // is the property targeting a view?
- if (/^(month|week|day|default|basic(Week|Day)?|agenda(Week|Day)?)$/.test(subName)) {
- if (!overrides.views[subName]) { // ensure the view-target entry exists
- overrides.views[subName] = {};
- }
- overrides.views[subName][name] = subVal; // record the value in the `views` object
- }
- else { // a non-View-Option-Hash property
- if (!subObj) {
- subObj = {};
- }
- subObj[subName] = subVal; // accumulate these unrelated values for later
- }
- });
-
- if (subObj) { // non-View-Option-Hash properties? transfer them as-is
- overrides[name] = subObj;
- }
- }
- else {
- overrides[name] = val; // transfer normal options as-is
- }
- }
- });
-
- return overrides;
-}
-
-;;
-
-// exports
-FC.intersectRanges = intersectRanges;
-FC.applyAll = applyAll;
-FC.debounce = debounce;
-FC.isInt = isInt;
-FC.htmlEscape = htmlEscape;
-FC.cssToStr = cssToStr;
-FC.proxy = proxy;
-FC.capitaliseFirstLetter = capitaliseFirstLetter;
-
-
-/* FullCalendar-specific DOM Utilities
-----------------------------------------------------------------------------------------------------------------------*/
-
-
-// Given the scrollbar widths of some other container, create borders/margins on rowEls in order to match the left
-// and right space that was offset by the scrollbars. A 1-pixel border first, then margin beyond that.
-function compensateScroll(rowEls, scrollbarWidths) {
- if (scrollbarWidths.left) {
- rowEls.css({
- 'border-left-width': 1,
- 'margin-left': scrollbarWidths.left - 1
- });
- }
- if (scrollbarWidths.right) {
- rowEls.css({
- 'border-right-width': 1,
- 'margin-right': scrollbarWidths.right - 1
- });
- }
-}
-
-
-// Undoes compensateScroll and restores all borders/margins
-function uncompensateScroll(rowEls) {
- rowEls.css({
- 'margin-left': '',
- 'margin-right': '',
- 'border-left-width': '',
- 'border-right-width': ''
- });
-}
-
-
-// Make the mouse cursor express that an event is not allowed in the current area
-function disableCursor() {
- $('body').addClass('fc-not-allowed');
-}
-
-
-// Returns the mouse cursor to its original look
-function enableCursor() {
- $('body').removeClass('fc-not-allowed');
-}
-
-
-// Given a total available height to fill, have `els` (essentially child rows) expand to accomodate.
-// By default, all elements that are shorter than the recommended height are expanded uniformly, not considering
-// any other els that are already too tall. if `shouldRedistribute` is on, it considers these tall rows and
-// reduces the available height.
-function distributeHeight(els, availableHeight, shouldRedistribute) {
-
- // *FLOORING NOTE*: we floor in certain places because zoom can give inaccurate floating-point dimensions,
- // and it is better to be shorter than taller, to avoid creating unnecessary scrollbars.
-
- var minOffset1 = Math.floor(availableHeight / els.length); // for non-last element
- var minOffset2 = Math.floor(availableHeight - minOffset1 * (els.length - 1)); // for last element *FLOORING NOTE*
- var flexEls = []; // elements that are allowed to expand. array of DOM nodes
- var flexOffsets = []; // amount of vertical space it takes up
- var flexHeights = []; // actual css height
- var usedHeight = 0;
-
- undistributeHeight(els); // give all elements their natural height
-
- // find elements that are below the recommended height (expandable).
- // important to query for heights in a single first pass (to avoid reflow oscillation).
- els.each(function(i, el) {
- var minOffset = i === els.length - 1 ? minOffset2 : minOffset1;
- var naturalOffset = $(el).outerHeight(true);
-
- if (naturalOffset < minOffset) {
- flexEls.push(el);
- flexOffsets.push(naturalOffset);
- flexHeights.push($(el).height());
- }
- else {
- // this element stretches past recommended height (non-expandable). mark the space as occupied.
- usedHeight += naturalOffset;
- }
- });
-
- // readjust the recommended height to only consider the height available to non-maxed-out rows.
- if (shouldRedistribute) {
- availableHeight -= usedHeight;
- minOffset1 = Math.floor(availableHeight / flexEls.length);
- minOffset2 = Math.floor(availableHeight - minOffset1 * (flexEls.length - 1)); // *FLOORING NOTE*
- }
-
- // assign heights to all expandable elements
- $(flexEls).each(function(i, el) {
- var minOffset = i === flexEls.length - 1 ? minOffset2 : minOffset1;
- var naturalOffset = flexOffsets[i];
- var naturalHeight = flexHeights[i];
- var newHeight = minOffset - (naturalOffset - naturalHeight); // subtract the margin/padding
-
- if (naturalOffset < minOffset) { // we check this again because redistribution might have changed things
- $(el).height(newHeight);
- }
- });
-}
-
-
-// Undoes distrubuteHeight, restoring all els to their natural height
-function undistributeHeight(els) {
- els.height('');
-}
-
-
-// Given `els`, a jQuery set of <td> cells, find the cell with the largest natural width and set the widths of all the
-// cells to be that width.
-// PREREQUISITE: if you want a cell to take up width, it needs to have a single inner element w/ display:inline
-function matchCellWidths(els) {
- var maxInnerWidth = 0;
-
- els.find('> span').each(function(i, innerEl) {
- var innerWidth = $(innerEl).outerWidth();
- if (innerWidth > maxInnerWidth) {
- maxInnerWidth = innerWidth;
- }
- });
-
- maxInnerWidth++; // sometimes not accurate of width the text needs to stay on one line. insurance
-
- els.width(maxInnerWidth);
-
- return maxInnerWidth;
-}
-
-
-// Given one element that resides inside another,
-// Subtracts the height of the inner element from the outer element.
-function subtractInnerElHeight(outerEl, innerEl) {
- var both = outerEl.add(innerEl);
- var diff;
-
- // effin' IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked
- both.css({
- position: 'relative', // cause a reflow, which will force fresh dimension recalculation
- left: -1 // ensure reflow in case the el was already relative. negative is less likely to cause new scroll
- });
- diff = outerEl.outerHeight() - innerEl.outerHeight(); // grab the dimensions
- both.css({ position: '', left: '' }); // undo hack
-
- return diff;
-}
-
-
-/* Element Geom Utilities
-----------------------------------------------------------------------------------------------------------------------*/
-
-FC.getOuterRect = getOuterRect;
-FC.getClientRect = getClientRect;
-FC.getContentRect = getContentRect;
-FC.getScrollbarWidths = getScrollbarWidths;
-
-
-// borrowed from https://github.com/jquery/jquery-ui/blob/1.11.0/ui/core.js#L51
-function getScrollParent(el) {
- var position = el.css('position'),
- scrollParent = el.parents().filter(function() {
- var parent = $(this);
- return (/(auto|scroll)/).test(
- parent.css('overflow') + parent.css('overflow-y') + parent.css('overflow-x')
- );
- }).eq(0);
-
- return position === 'fixed' || !scrollParent.length ? $(el[0].ownerDocument || document) : scrollParent;
-}
-
-
-// Queries the outer bounding area of a jQuery element.
-// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).
-// Origin is optional.
-function getOuterRect(el, origin) {
- var offset = el.offset();
- var left = offset.left - (origin ? origin.left : 0);
- var top = offset.top - (origin ? origin.top : 0);
-
- return {
- left: left,
- right: left + el.outerWidth(),
- top: top,
- bottom: top + el.outerHeight()
- };
-}
-
-
-// Queries the area within the margin/border/scrollbars of a jQuery element. Does not go within the padding.
-// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).
-// Origin is optional.
-// NOTE: should use clientLeft/clientTop, but very unreliable cross-browser.
-function getClientRect(el, origin) {
- var offset = el.offset();
- var scrollbarWidths = getScrollbarWidths(el);
- var left = offset.left + getCssFloat(el, 'border-left-width') + scrollbarWidths.left - (origin ? origin.left : 0);
- var top = offset.top + getCssFloat(el, 'border-top-width') + scrollbarWidths.top - (origin ? origin.top : 0);
-
- return {
- left: left,
- right: left + el[0].clientWidth, // clientWidth includes padding but NOT scrollbars
- top: top,
- bottom: top + el[0].clientHeight // clientHeight includes padding but NOT scrollbars
- };
-}
-
-
-// Queries the area within the margin/border/padding of a jQuery element. Assumed not to have scrollbars.
-// Returns a rectangle with absolute coordinates: left, right (exclusive), top, bottom (exclusive).
-// Origin is optional.
-function getContentRect(el, origin) {
- var offset = el.offset(); // just outside of border, margin not included
- var left = offset.left + getCssFloat(el, 'border-left-width') + getCssFloat(el, 'padding-left') -
- (origin ? origin.left : 0);
- var top = offset.top + getCssFloat(el, 'border-top-width') + getCssFloat(el, 'padding-top') -
- (origin ? origin.top : 0);
-
- return {
- left: left,
- right: left + el.width(),
- top: top,
- bottom: top + el.height()
- };
-}
-
-
-// Returns the computed left/right/top/bottom scrollbar widths for the given jQuery element.
-// NOTE: should use clientLeft/clientTop, but very unreliable cross-browser.
-function getScrollbarWidths(el) {
- var leftRightWidth = el.innerWidth() - el[0].clientWidth; // the paddings cancel out, leaving the scrollbars
- var widths = {
- left: 0,
- right: 0,
- top: 0,
- bottom: el.innerHeight() - el[0].clientHeight // the paddings cancel out, leaving the bottom scrollbar
- };
-
- if (getIsLeftRtlScrollbars() && el.css('direction') == 'rtl') { // is the scrollbar on the left side?
- widths.left = leftRightWidth;
- }
- else {
- widths.right = leftRightWidth;
- }
-
- return widths;
-}
-
-
-// Logic for determining if, when the element is right-to-left, the scrollbar appears on the left side
-
-var _isLeftRtlScrollbars = null;
-
-function getIsLeftRtlScrollbars() { // responsible for caching the computation
- if (_isLeftRtlScrollbars === null) {
- _isLeftRtlScrollbars = computeIsLeftRtlScrollbars();
- }
- return _isLeftRtlScrollbars;
-}
-
-function computeIsLeftRtlScrollbars() { // creates an offscreen test element, then removes it
- var el = $('<div><div/></div>')
- .css({
- position: 'absolute',
- top: -1000,
- left: 0,
- border: 0,
- padding: 0,
- overflow: 'scroll',
- direction: 'rtl'
- })
- .appendTo('body');
- var innerEl = el.children();
- var res = innerEl.offset().left > el.offset().left; // is the inner div shifted to accommodate a left scrollbar?
- el.remove();
- return res;
-}
-
-
-// Retrieves a jQuery element's computed CSS value as a floating-point number.
-// If the queried value is non-numeric (ex: IE can return "medium" for border width), will just return zero.
-function getCssFloat(el, prop) {
- return parseFloat(el.css(prop)) || 0;
-}
-
-
-/* Mouse / Touch Utilities
-----------------------------------------------------------------------------------------------------------------------*/
-
-FC.preventDefault = preventDefault;
-
-
-// Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)
-function isPrimaryMouseButton(ev) {
- return ev.which == 1 && !ev.ctrlKey;
-}
-
-
-function getEvX(ev) {
- if (ev.pageX !== undefined) {
- return ev.pageX;
- }
- var touches = ev.originalEvent.touches;
- if (touches) {
- return touches[0].pageX;
- }
-}
-
-
-function getEvY(ev) {
- if (ev.pageY !== undefined) {
- return ev.pageY;
- }
- var touches = ev.originalEvent.touches;
- if (touches) {
- return touches[0].pageY;
- }
-}
-
-
-function getEvIsTouch(ev) {
- return /^touch/.test(ev.type);
-}
-
-
-function preventSelection(el) {
- el.addClass('fc-unselectable')
- .on('selectstart', preventDefault);
-}
-
-
-// Stops a mouse/touch event from doing it's native browser action
-function preventDefault(ev) {
- ev.preventDefault();
-}
-
-
-// attach a handler to get called when ANY scroll action happens on the page.
-// this was impossible to do with normal on/off because 'scroll' doesn't bubble.
-// http://stackoverflow.com/a/32954565/96342
-// returns `true` on success.
-function bindAnyScroll(handler) {
- if (window.addEventListener) {
- window.addEventListener('scroll', handler, true); // useCapture=true
- return true;
- }
- return false;
-}
-
-
-// undoes bindAnyScroll. must pass in the original function.
-// returns `true` on success.
-function unbindAnyScroll(handler) {
- if (window.removeEventListener) {
- window.removeEventListener('scroll', handler, true); // useCapture=true
- return true;
- }
- return false;
-}
-
-
-/* General Geometry Utils
-----------------------------------------------------------------------------------------------------------------------*/
-
-FC.intersectRects = intersectRects;
-
-// Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false
-function intersectRects(rect1, rect2) {
- var res = {
- left: Math.max(rect1.left, rect2.left),
- right: Math.min(rect1.right, rect2.right),
- top: Math.max(rect1.top, rect2.top),
- bottom: Math.min(rect1.bottom, rect2.bottom)
- };
-
- if (res.left < res.right && res.top < res.bottom) {
- return res;
- }
- return false;
-}
-
-
-// Returns a new point that will have been moved to reside within the given rectangle
-function constrainPoint(point, rect) {
- return {
- left: Math.min(Math.max(point.left, rect.left), rect.right),
- top: Math.min(Math.max(point.top, rect.top), rect.bottom)
- };
-}
-
-
-// Returns a point that is the center of the given rectangle
-function getRectCenter(rect) {
- return {
- left: (rect.left + rect.right) / 2,
- top: (rect.top + rect.bottom) / 2
- };
-}
-
-
-// Subtracts point2's coordinates from point1's coordinates, returning a delta
-function diffPoints(point1, point2) {
- return {
- left: point1.left - point2.left,
- top: point1.top - point2.top
- };
-}
-
-
-/* Object Ordering by Field
-----------------------------------------------------------------------------------------------------------------------*/
-
-FC.parseFieldSpecs = parseFieldSpecs;
-FC.compareByFieldSpecs = compareByFieldSpecs;
-FC.compareByFieldSpec = compareByFieldSpec;
-FC.flexibleCompare = flexibleCompare;
-
-
-function parseFieldSpecs(input) {
- var specs = [];
- var tokens = [];
- var i, token;
-
- if (typeof input === 'string') {
- tokens = input.split(/\s*,\s*/);
- }
- else if (typeof input === 'function') {
- tokens = [ input ];
- }
- else if ($.isArray(input)) {
- tokens = input;
- }
-
- for (i = 0; i < tokens.length; i++) {
- token = tokens[i];
-
- if (typeof token === 'string') {
- specs.push(
- token.charAt(0) == '-' ?
- { field: token.substring(1), order: -1 } :
- { field: token, order: 1 }
- );
- }
- else if (typeof token === 'function') {
- specs.push({ func: token });
- }
- }
-
- return specs;
-}
-
-
-function compareByFieldSpecs(obj1, obj2, fieldSpecs) {
- var i;
- var cmp;
-
- for (i = 0; i < fieldSpecs.length; i++) {
- cmp = compareByFieldSpec(obj1, obj2, fieldSpecs[i]);
- if (cmp) {
- return cmp;
- }
- }
-
- return 0;
-}
-
-
-function compareByFieldSpec(obj1, obj2, fieldSpec) {
- if (fieldSpec.func) {
- return fieldSpec.func(obj1, obj2);
- }
- return flexibleCompare(obj1[fieldSpec.field], obj2[fieldSpec.field]) *
- (fieldSpec.order || 1);
-}
-
-
-function flexibleCompare(a, b) {
- if (!a && !b) {
- return 0;
- }
- if (b == null) {
- return -1;
- }
- if (a == null) {
- return 1;
- }
- if ($.type(a) === 'string' || $.type(b) === 'string') {
- return String(a).localeCompare(String(b));
- }
- return a - b;
-}
-
-
-/* FullCalendar-specific Misc Utilities
-----------------------------------------------------------------------------------------------------------------------*/
-
-
-// Computes the intersection of the two ranges. Returns undefined if no intersection.
-// Expects all dates to be normalized to the same timezone beforehand.
-// TODO: move to date section?
-function intersectRanges(subjectRange, constraintRange) {
- var subjectStart = subjectRange.start;
- var subjectEnd = subjectRange.end;
- var constraintStart = constraintRange.start;
- var constraintEnd = constraintRange.end;
- var segStart, segEnd;
- var isStart, isEnd;
-
- if (subjectEnd > constraintStart && subjectStart < constraintEnd) { // in bounds at all?
-
- if (subjectStart >= constraintStart) {
- segStart = subjectStart.clone();
- isStart = true;
- }
- else {
- segStart = constraintStart.clone();
- isStart = false;
- }
-
- if (subjectEnd <= constraintEnd) {
- segEnd = subjectEnd.clone();
- isEnd = true;
- }
- else {
- segEnd = constraintEnd.clone();
- isEnd = false;
- }
-
- return {
- start: segStart,
- end: segEnd,
- isStart: isStart,
- isEnd: isEnd
- };
- }
-}
-
-
-/* Date Utilities
-----------------------------------------------------------------------------------------------------------------------*/
-
-FC.computeIntervalUnit = computeIntervalUnit;
-FC.divideRangeByDuration = divideRangeByDuration;
-FC.divideDurationByDuration = divideDurationByDuration;
-FC.multiplyDuration = multiplyDuration;
-FC.durationHasTime = durationHasTime;
-
-var dayIDs = [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ];
-var intervalUnits = [ 'year', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond' ];
-
-
-// Diffs the two moments into a Duration where full-days are recorded first, then the remaining time.
-// Moments will have their timezones normalized.
-function diffDayTime(a, b) {
- return moment.duration({
- days: a.clone().stripTime().diff(b.clone().stripTime(), 'days'),
- ms: a.time() - b.time() // time-of-day from day start. disregards timezone
- });
-}
-
-
-// Diffs the two moments via their start-of-day (regardless of timezone). Produces whole-day durations.
-function diffDay(a, b) {
- return moment.duration({
- days: a.clone().stripTime().diff(b.clone().stripTime(), 'days')
- });
-}
-
-
-// Diffs two moments, producing a duration, made of a whole-unit-increment of the given unit. Uses rounding.
-function diffByUnit(a, b, unit) {
- return moment.duration(
- Math.round(a.diff(b, unit, true)), // returnFloat=true
- unit
- );
-}
-
-
-// Computes the unit name of the largest whole-unit period of time.
-// For example, 48 hours will be "days" whereas 49 hours will be "hours".
-// Accepts start/end, a range object, or an original duration object.
-function computeIntervalUnit(start, end) {
- var i, unit;
- var val;
-
- for (i = 0; i < intervalUnits.length; i++) {
- unit = intervalUnits[i];
- val = computeRangeAs(unit, start, end);
-
- if (val >= 1 && isInt(val)) {
- break;
- }
- }
-
- return unit; // will be "milliseconds" if nothing else matches
-}
-
-
-// Computes the number of units (like "hours") in the given range.
-// Range can be a {start,end} object, separate start/end args, or a Duration.
-// Results are based on Moment's .as() and .diff() methods, so results can depend on internal handling
-// of month-diffing logic (which tends to vary from version to version).
-function computeRangeAs(unit, start, end) {
-
- if (end != null) { // given start, end
- return end.diff(start, unit, true);
- }
- else if (moment.isDuration(start)) { // given duration
- return start.as(unit);
- }
- else { // given { start, end } range object
- return start.end.diff(start.start, unit, true);
- }
-}
-
-
-// Intelligently divides a range (specified by a start/end params) by a duration
-function divideRangeByDuration(start, end, dur) {
- var months;
-
- if (durationHasTime(dur)) {
- return (end - start) / dur;
- }
- months = dur.asMonths();
- if (Math.abs(months) >= 1 && isInt(months)) {
- return end.diff(start, 'months', true) / months;
- }
- return end.diff(start, 'days', true) / dur.asDays();
-}
-
-
-// Intelligently divides one duration by another
-function divideDurationByDuration(dur1, dur2) {
- var months1, months2;
-
- if (durationHasTime(dur1) || durationHasTime(dur2)) {
- return dur1 / dur2;
- }
- months1 = dur1.asMonths();
- months2 = dur2.asMonths();
- if (
- Math.abs(months1) >= 1 && isInt(months1) &&
- Math.abs(months2) >= 1 && isInt(months2)
- ) {
- return months1 / months2;
- }
- return dur1.asDays() / dur2.asDays();
-}
-
-
-// Intelligently multiplies a duration by a number
-function multiplyDuration(dur, n) {
- var months;
-
- if (durationHasTime(dur)) {
- return moment.duration(dur * n);
- }
- months = dur.asMonths();
- if (Math.abs(months) >= 1 && isInt(months)) {
- return moment.duration({ months: months * n });
- }
- return moment.duration({ days: dur.asDays() * n });
-}
-
-
-// Returns a boolean about whether the given duration has any time parts (hours/minutes/seconds/ms)
-function durationHasTime(dur) {
- return Boolean(dur.hours() || dur.minutes() || dur.seconds() || dur.milliseconds());
-}
-
-
-function isNativeDate(input) {
- return Object.prototype.toString.call(input) === '[object Date]' || input instanceof Date;
-}
-
-
-// Returns a boolean about whether the given input is a time string, like "06:40:00" or "06:00"
-function isTimeString(str) {
- return /^\d+\:\d+(?:\:\d+\.?(?:\d{3})?)?$/.test(str);
-}
-
-
-/* Logging and Debug
-----------------------------------------------------------------------------------------------------------------------*/
-
-FC.log = function() {
- var console = window.console;
-
- if (console && console.log) {
- return console.log.apply(console, arguments);
- }
-};
-
-FC.warn = function() {
- var console = window.console;
-
- if (console && console.warn) {
- return console.warn.apply(console, arguments);
- }
- else {
- return FC.log.apply(FC, arguments);
- }
-};
-
-
-/* General Utilities
-----------------------------------------------------------------------------------------------------------------------*/
-
-var hasOwnPropMethod = {}.hasOwnProperty;
-
-
-// Merges an array of objects into a single object.
-// The second argument allows for an array of property names who's object values will be merged together.
-function mergeProps(propObjs, complexProps) {
- var dest = {};
- var i, name;
- var complexObjs;
- var j, val;
- var props;
-
- if (complexProps) {
- for (i = 0; i < complexProps.length; i++) {
- name = complexProps[i];
- complexObjs = [];
-
- // collect the trailing object values, stopping when a non-object is discovered
- for (j = propObjs.length - 1; j >= 0; j--) {
- val = propObjs[j][name];
-
- if (typeof val === 'object') {
- complexObjs.unshift(val);
- }
- else if (val !== undefined) {
- dest[name] = val; // if there were no objects, this value will be used
- break;
- }
- }
-
- // if the trailing values were objects, use the merged value
- if (complexObjs.length) {
- dest[name] = mergeProps(complexObjs);
- }
- }
- }
-
- // copy values into the destination, going from last to first
- for (i = propObjs.length - 1; i >= 0; i--) {
- props = propObjs[i];
-
- for (name in props) {
- if (!(name in dest)) { // if already assigned by previous props or complex props, don't reassign
- dest[name] = props[name];
- }
- }
- }
-
- return dest;
-}
-
-
-// Create an object that has the given prototype. Just like Object.create
-function createObject(proto) {
- var f = function() {};
- f.prototype = proto;
- return new f();
-}
-
-
-function copyOwnProps(src, dest) {
- for (var name in src) {
- if (hasOwnProp(src, name)) {
- dest[name] = src[name];
- }
- }
-}
-
-
-// Copies over certain methods with the same names as Object.prototype methods. Overcomes an IE<=8 bug:
-// https://developer.mozilla.org/en-US/docs/ECMAScript_DontEnum_attribute#JScript_DontEnum_Bug
-function copyNativeMethods(src, dest) {
- var names = [ 'constructor', 'toString', 'valueOf' ];
- var i, name;
-
- for (i = 0; i < names.length; i++) {
- name = names[i];
-
- if (src[name] !== Object.prototype[name]) {
- dest[name] = src[name];
- }
- }
-}
-
-
-function hasOwnProp(obj, name) {
- return hasOwnPropMethod.call(obj, name);
-}
-
-
-// Is the given value a non-object non-function value?
-function isAtomic(val) {
- return /undefined|null|boolean|number|string/.test($.type(val));
-}
-
-
-function applyAll(functions, thisObj, args) {
- if ($.isFunction(functions)) {
- functions = [ functions ];
- }
- if (functions) {
- var i;
- var ret;
- for (i=0; i<functions.length; i++) {
- ret = functions[i].apply(thisObj, args) || ret;
- }
- return ret;
- }
-}
-
-
-function firstDefined() {
- for (var i=0; i<arguments.length; i++) {
- if (arguments[i] !== undefined) {
- return arguments[i];
- }
- }
-}
-
-
-function htmlEscape(s) {
- return (s + '').replace(/&/g, '&amp;')
- .replace(/</g, '&lt;')
- .replace(/>/g, '&gt;')
- .replace(/'/g, '&#039;')
- .replace(/"/g, '&quot;')
- .replace(/\n/g, '<br />');
-}
-
-
-function stripHtmlEntities(text) {
- return text.replace(/&.*?;/g, '');
-}
-
-
-// Given a hash of CSS properties, returns a string of CSS.
-// Uses property names as-is (no camel-case conversion). Will not make statements for null/undefined values.
-function cssToStr(cssProps) {
- var statements = [];
-
- $.each(cssProps, function(name, val) {
- if (val != null) {
- statements.push(name + ':' + val);
- }
- });
-
- return statements.join(';');
-}
-
-
-function capitaliseFirstLetter(str) {
- return str.charAt(0).toUpperCase() + str.slice(1);
-}
-
-
-function compareNumbers(a, b) { // for .sort()
- return a - b;
-}
-
-
-function isInt(n) {
- return n % 1 === 0;
-}
-
-
-// Returns a method bound to the given object context.
-// Just like one of the jQuery.proxy signatures, but without the undesired behavior of treating the same method with
-// different contexts as identical when binding/unbinding events.
-function proxy(obj, methodName) {
- var method = obj[methodName];
-
- return function() {
- return method.apply(obj, arguments);
- };
-}
-
-
-// Returns a function, that, as long as it continues to be invoked, will not
-// be triggered. The function will be called after it stops being called for
-// N milliseconds. If `immediate` is passed, trigger the function on the
-// leading edge, instead of the trailing.
-// https://github.com/jashkenas/underscore/blob/1.6.0/underscore.js#L714
-function debounce(func, wait, immediate) {
- var timeout, args, context, timestamp, result;
-
- var later = function() {
- var last = +new Date() - timestamp;
- if (last < wait) {
- timeout = setTimeout(later, wait - last);
- }
- else {
- timeout = null;
- if (!immediate) {
- result = func.apply(context, args);
- context = args = null;
- }
- }
- };
-
- return function() {
- context = this;
- args = arguments;
- timestamp = +new Date();
- var callNow = immediate && !timeout;
- if (!timeout) {
- timeout = setTimeout(later, wait);
- }
- if (callNow) {
- result = func.apply(context, args);
- context = args = null;
- }
- return result;
- };
-}
-
-;;
-
-var ambigDateOfMonthRegex = /^\s*\d{4}-\d\d$/;
-var ambigTimeOrZoneRegex =
- /^\s*\d{4}-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?)?$/;
-var newMomentProto = moment.fn; // where we will attach our new methods
-var oldMomentProto = $.extend({}, newMomentProto); // copy of original moment methods
-var allowValueOptimization;
-var setUTCValues; // function defined below
-var setLocalValues; // function defined below
-
-
-// Creating
-// -------------------------------------------------------------------------------------------------
-
-// Creates a new moment, similar to the vanilla moment(...) constructor, but with
-// extra features (ambiguous time, enhanced formatting). When given an existing moment,
-// it will function as a clone (and retain the zone of the moment). Anything else will
-// result in a moment in the local zone.
-FC.moment = function() {
- return makeMoment(arguments);
-};
-
-// Sames as FC.moment, but forces the resulting moment to be in the UTC timezone.
-FC.moment.utc = function() {
- var mom = makeMoment(arguments, true);
-
- // Force it into UTC because makeMoment doesn't guarantee it
- // (if given a pre-existing moment for example)
- if (mom.hasTime()) { // don't give ambiguously-timed moments a UTC zone
- mom.utc();
- }
-
- return mom;
-};
-
-// Same as FC.moment, but when given an ISO8601 string, the timezone offset is preserved.
-// ISO8601 strings with no timezone offset will become ambiguously zoned.
-FC.moment.parseZone = function() {
- return makeMoment(arguments, true, true);
-};
-
-// Builds an enhanced moment from args. When given an existing moment, it clones. When given a
-// native Date, or called with no arguments (the current time), the resulting moment will be local.
-// Anything else needs to be "parsed" (a string or an array), and will be affected by:
-// parseAsUTC - if there is no zone information, should we parse the input in UTC?
-// parseZone - if there is zone information, should we force the zone of the moment?
-function makeMoment(args, parseAsUTC, parseZone) {
- var input = args[0];
- var isSingleString = args.length == 1 && typeof input === 'string';
- var isAmbigTime;
- var isAmbigZone;
- var ambigMatch;
- var mom;
-
- if (moment.isMoment(input)) {
- mom = moment.apply(null, args); // clone it
- transferAmbigs(input, mom); // the ambig flags weren't transfered with the clone
- }
- else if (isNativeDate(input) || input === undefined) {
- mom = moment.apply(null, args); // will be local
- }
- else { // "parsing" is required
- isAmbigTime = false;
- isAmbigZone = false;
-
- if (isSingleString) {
- if (ambigDateOfMonthRegex.test(input)) {
- // accept strings like '2014-05', but convert to the first of the month
- input += '-01';
- args = [ input ]; // for when we pass it on to moment's constructor
- isAmbigTime = true;
- isAmbigZone = true;
- }
- else if ((ambigMatch = ambigTimeOrZoneRegex.exec(input))) {
- isAmbigTime = !ambigMatch[5]; // no time part?
- isAmbigZone = true;
- }
- }
- else if ($.isArray(input)) {
- // arrays have no timezone information, so assume ambiguous zone
- isAmbigZone = true;
- }
- // otherwise, probably a string with a format
-
- if (parseAsUTC || isAmbigTime) {
- mom = moment.utc.apply(moment, args);
- }
- else {
- mom = moment.apply(null, args);
- }
-
- if (isAmbigTime) {
- mom._ambigTime = true;
- mom._ambigZone = true; // ambiguous time always means ambiguous zone
- }
- else if (parseZone) { // let's record the inputted zone somehow
- if (isAmbigZone) {
- mom._ambigZone = true;
- }
- else if (isSingleString) {
- if (mom.utcOffset) {
- mom.utcOffset(input); // if not a valid zone, will assign UTC
- }
- else {
- mom.zone(input); // for moment-pre-2.9
- }
- }
- }
- }
-
- mom._fullCalendar = true; // flag for extended functionality
-
- return mom;
-}
-
-
-// A clone method that works with the flags related to our enhanced functionality.
-// In the future, use moment.momentProperties
-newMomentProto.clone = function() {
- var mom = oldMomentProto.clone.apply(this, arguments);
-
- // these flags weren't transfered with the clone
- transferAmbigs(this, mom);
- if (this._fullCalendar) {
- mom._fullCalendar = true;
- }
-
- return mom;
-};
-
-
-// Week Number
-// -------------------------------------------------------------------------------------------------
-
-
-// Returns the week number, considering the locale's custom week number calcuation
-// `weeks` is an alias for `week`
-newMomentProto.week = newMomentProto.weeks = function(input) {
- var weekCalc = (this._locale || this._lang) // works pre-moment-2.8
- ._fullCalendar_weekCalc;
-
- if (input == null && typeof weekCalc === 'function') { // custom function only works for getter
- return weekCalc(this);
- }
- else if (weekCalc === 'ISO') {
- return oldMomentProto.isoWeek.apply(this, arguments); // ISO getter/setter
- }
-
- return oldMomentProto.week.apply(this, arguments); // local getter/setter
-};
-
-
-// Time-of-day
-// -------------------------------------------------------------------------------------------------
-
-// GETTER
-// Returns a Duration with the hours/minutes/seconds/ms values of the moment.
-// If the moment has an ambiguous time, a duration of 00:00 will be returned.
-//
-// SETTER
-// You can supply a Duration, a Moment, or a Duration-like argument.
-// When setting the time, and the moment has an ambiguous time, it then becomes unambiguous.
-newMomentProto.time = function(time) {
-
- // Fallback to the original method (if there is one) if this moment wasn't created via FullCalendar.
- // `time` is a generic enough method name where this precaution is necessary to avoid collisions w/ other plugins.
- if (!this._fullCalendar) {
- return oldMomentProto.time.apply(this, arguments);
- }
-
- if (time == null) { // getter
- return moment.duration({
- hours: this.hours(),
- minutes: this.minutes(),
- seconds: this.seconds(),
- milliseconds: this.milliseconds()
- });
- }
- else { // setter
-
- this._ambigTime = false; // mark that the moment now has a time
-
- if (!moment.isDuration(time) && !moment.isMoment(time)) {
- time = moment.duration(time);
- }
-
- // The day value should cause overflow (so 24 hours becomes 00:00:00 of next day).
- // Only for Duration times, not Moment times.
- var dayHours = 0;
- if (moment.isDuration(time)) {
- dayHours = Math.floor(time.asDays()) * 24;
- }
-
- // We need to set the individual fields.
- // Can't use startOf('day') then add duration. In case of DST at start of day.
- return this.hours(dayHours + time.hours())
- .minutes(time.minutes())
- .seconds(time.seconds())
- .milliseconds(time.milliseconds());
- }
-};
-
-// Converts the moment to UTC, stripping out its time-of-day and timezone offset,
-// but preserving its YMD. A moment with a stripped time will display no time
-// nor timezone offset when .format() is called.
-newMomentProto.stripTime = function() {
- var a;
-
- if (!this._ambigTime) {
-
- // get the values before any conversion happens
- a = this.toArray(); // array of y/m/d/h/m/s/ms
-
- // TODO: use keepLocalTime in the future
- this.utc(); // set the internal UTC flag (will clear the ambig flags)
- setUTCValues(this, a.slice(0, 3)); // set the year/month/date. time will be zero
-
- // Mark the time as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(),
- // which clears all ambig flags. Same with setUTCValues with moment-timezone.
- this._ambigTime = true;
- this._ambigZone = true; // if ambiguous time, also ambiguous timezone offset
- }
-
- return this; // for chaining
-};
-
-// Returns if the moment has a non-ambiguous time (boolean)
-newMomentProto.hasTime = function() {
- return !this._ambigTime;
-};
-
-
-// Timezone
-// -------------------------------------------------------------------------------------------------
-
-// Converts the moment to UTC, stripping out its timezone offset, but preserving its
-// YMD and time-of-day. A moment with a stripped timezone offset will display no
-// timezone offset when .format() is called.
-// TODO: look into Moment's keepLocalTime functionality
-newMomentProto.stripZone = function() {
- var a, wasAmbigTime;
-
- if (!this._ambigZone) {
-
- // get the values before any conversion happens
- a = this.toArray(); // array of y/m/d/h/m/s/ms
- wasAmbigTime = this._ambigTime;
-
- this.utc(); // set the internal UTC flag (might clear the ambig flags, depending on Moment internals)
- setUTCValues(this, a); // will set the year/month/date/hours/minutes/seconds/ms
-
- // the above call to .utc()/.utcOffset() unfortunately might clear the ambig flags, so restore
- this._ambigTime = wasAmbigTime || false;
-
- // Mark the zone as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(),
- // which clears the ambig flags. Same with setUTCValues with moment-timezone.
- this._ambigZone = true;
- }
-
- return this; // for chaining
-};
-
-// Returns of the moment has a non-ambiguous timezone offset (boolean)
-newMomentProto.hasZone = function() {
- return !this._ambigZone;
-};
-
-
-// this method implicitly marks a zone
-newMomentProto.local = function() {
- var a = this.toArray(); // year,month,date,hours,minutes,seconds,ms as an array
- var wasAmbigZone = this._ambigZone;
-
- oldMomentProto.local.apply(this, arguments);
-
- // ensure non-ambiguous
- // this probably already happened via local() -> utcOffset(), but don't rely on Moment's internals
- this._ambigTime = false;
- this._ambigZone = false;
-
- if (wasAmbigZone) {
- // If the moment was ambiguously zoned, the date fields were stored as UTC.
- // We want to preserve these, but in local time.
- // TODO: look into Moment's keepLocalTime functionality
- setLocalValues(this, a);
- }
-
- return this; // for chaining
-};
-
-
-// implicitly marks a zone
-newMomentProto.utc = function() {
- oldMomentProto.utc.apply(this, arguments);
-
- // ensure non-ambiguous
- // this probably already happened via utc() -> utcOffset(), but don't rely on Moment's internals
- this._ambigTime = false;
- this._ambigZone = false;
-
- return this;
-};
-
-
-// methods for arbitrarily manipulating timezone offset.
-// should clear time/zone ambiguity when called.
-$.each([
- 'zone', // only in moment-pre-2.9. deprecated afterwards
- 'utcOffset'
-], function(i, name) {
- if (oldMomentProto[name]) { // original method exists?
-
- // this method implicitly marks a zone (will probably get called upon .utc() and .local())
- newMomentProto[name] = function(tzo) {
-
- if (tzo != null) { // setter
- // these assignments needs to happen before the original zone method is called.
- // I forget why, something to do with a browser crash.
- this._ambigTime = false;
- this._ambigZone = false;
- }
-
- return oldMomentProto[name].apply(this, arguments);
- };
- }
-});
-
-
-// Formatting
-// -------------------------------------------------------------------------------------------------
-
-newMomentProto.format = function() {
- if (this._fullCalendar && arguments[0]) { // an enhanced moment? and a format string provided?
- return formatDate(this, arguments[0]); // our extended formatting
- }
- if (this._ambigTime) {
- return oldMomentFormat(this, 'YYYY-MM-DD');
- }
- if (this._ambigZone) {
- return oldMomentFormat(this, 'YYYY-MM-DD[T]HH:mm:ss');
- }
- return oldMomentProto.format.apply(this, arguments);
-};
-
-newMomentProto.toISOString = function() {
- if (this._ambigTime) {
- return oldMomentFormat(this, 'YYYY-MM-DD');
- }
- if (this._ambigZone) {
- return oldMomentFormat(this, 'YYYY-MM-DD[T]HH:mm:ss');
- }
- return oldMomentProto.toISOString.apply(this, arguments);
-};
-
-
-// Querying
-// -------------------------------------------------------------------------------------------------
-
-// Is the moment within the specified range? `end` is exclusive.
-// FYI, this method is not a standard Moment method, so always do our enhanced logic.
-newMomentProto.isWithin = function(start, end) {
- var a = commonlyAmbiguate([ this, start, end ]);
- return a[0] >= a[1] && a[0] < a[2];
-};
-
-// When isSame is called with units, timezone ambiguity is normalized before the comparison happens.
-// If no units specified, the two moments must be identically the same, with matching ambig flags.
-newMomentProto.isSame = function(input, units) {
- var a;
-
- // only do custom logic if this is an enhanced moment
- if (!this._fullCalendar) {
- return oldMomentProto.isSame.apply(this, arguments);
- }
-
- if (units) {
- a = commonlyAmbiguate([ this, input ], true); // normalize timezones but don't erase times
- return oldMomentProto.isSame.call(a[0], a[1], units);
- }
- else {
- input = FC.moment.parseZone(input); // normalize input
- return oldMomentProto.isSame.call(this, input) &&
- Boolean(this._ambigTime) === Boolean(input._ambigTime) &&
- Boolean(this._ambigZone) === Boolean(input._ambigZone);
- }
-};
-
-// Make these query methods work with ambiguous moments
-$.each([
- 'isBefore',
- 'isAfter'
-], function(i, methodName) {
- newMomentProto[methodName] = function(input, units) {
- var a;
-
- // only do custom logic if this is an enhanced moment
- if (!this._fullCalendar) {
- return oldMomentProto[methodName].apply(this, arguments);
- }
-
- a = commonlyAmbiguate([ this, input ]);
- return oldMomentProto[methodName].call(a[0], a[1], units);
- };
-});
-
-
-// Misc Internals
-// -------------------------------------------------------------------------------------------------
-
-// given an array of moment-like inputs, return a parallel array w/ moments similarly ambiguated.
-// for example, of one moment has ambig time, but not others, all moments will have their time stripped.
-// set `preserveTime` to `true` to keep times, but only normalize zone ambiguity.
-// returns the original moments if no modifications are necessary.
-function commonlyAmbiguate(inputs, preserveTime) {
- var anyAmbigTime = false;
- var anyAmbigZone = false;
- var len = inputs.length;
- var moms = [];
- var i, mom;
-
- // parse inputs into real moments and query their ambig flags
- for (i = 0; i < len; i++) {
- mom = inputs[i];
- if (!moment.isMoment(mom)) {
- mom = FC.moment.parseZone(mom);
- }
- anyAmbigTime = anyAmbigTime || mom._ambigTime;
- anyAmbigZone = anyAmbigZone || mom._ambigZone;
- moms.push(mom);
- }
-
- // strip each moment down to lowest common ambiguity
- // use clones to avoid modifying the original moments
- for (i = 0; i < len; i++) {
- mom = moms[i];
- if (!preserveTime && anyAmbigTime && !mom._ambigTime) {
- moms[i] = mom.clone().stripTime();
- }
- else if (anyAmbigZone && !mom._ambigZone) {
- moms[i] = mom.clone().stripZone();
- }
- }
-
- return moms;
-}
-
-// Transfers all the flags related to ambiguous time/zone from the `src` moment to the `dest` moment
-// TODO: look into moment.momentProperties for this.
-function transferAmbigs(src, dest) {
- if (src._ambigTime) {
- dest._ambigTime = true;
- }
- else if (dest._ambigTime) {
- dest._ambigTime = false;
- }
-
- if (src._ambigZone) {
- dest._ambigZone = true;
- }
- else if (dest._ambigZone) {
- dest._ambigZone = false;
- }
-}
-
-
-// Sets the year/month/date/etc values of the moment from the given array.
-// Inefficient because it calls each individual setter.
-function setMomentValues(mom, a) {
- mom.year(a[0] || 0)
- .month(a[1] || 0)
- .date(a[2] || 0)
- .hours(a[3] || 0)
- .minutes(a[4] || 0)
- .seconds(a[5] || 0)
- .milliseconds(a[6] || 0);
-}
-
-// Can we set the moment's internal date directly?
-allowValueOptimization = '_d' in moment() && 'updateOffset' in moment;
-
-// Utility function. Accepts a moment and an array of the UTC year/month/date/etc values to set.
-// Assumes the given moment is already in UTC mode.
-setUTCValues = allowValueOptimization ? function(mom, a) {
- // simlate what moment's accessors do
- mom._d.setTime(Date.UTC.apply(Date, a));
- moment.updateOffset(mom, false); // keepTime=false
-} : setMomentValues;
-
-// Utility function. Accepts a moment and an array of the local year/month/date/etc values to set.
-// Assumes the given moment is already in local mode.
-setLocalValues = allowValueOptimization ? function(mom, a) {
- // simlate what moment's accessors do
- mom._d.setTime(+new Date( // FYI, there is now way to apply an array of args to a constructor
- a[0] || 0,
- a[1] || 0,
- a[2] || 0,
- a[3] || 0,
- a[4] || 0,
- a[5] || 0,
- a[6] || 0
- ));
- moment.updateOffset(mom, false); // keepTime=false
-} : setMomentValues;
-
-;;
-
-// Single Date Formatting
-// -------------------------------------------------------------------------------------------------
-
-
-// call this if you want Moment's original format method to be used
-function oldMomentFormat(mom, formatStr) {
- return oldMomentProto.format.call(mom, formatStr); // oldMomentProto defined in moment-ext.js
-}
-
-
-// Formats `date` with a Moment formatting string, but allow our non-zero areas and
-// additional token.
-function formatDate(date, formatStr) {
- return formatDateWithChunks(date, getFormatStringChunks(formatStr));
-}
-
-
-function formatDateWithChunks(date, chunks) {
- var s = '';
- var i;
-
- for (i=0; i<chunks.length; i++) {
- s += formatDateWithChunk(date, chunks[i]);
- }
-
- return s;
-}
-
-
-// addition formatting tokens we want recognized
-var tokenOverrides = {
- t: function(date) { // "a" or "p"
- return oldMomentFormat(date, 'a').charAt(0);
- },
- T: function(date) { // "A" or "P"
- return oldMomentFormat(date, 'A').charAt(0);
- }
-};
-
-
-function formatDateWithChunk(date, chunk) {
- var token;
- var maybeStr;
-
- if (typeof chunk === 'string') { // a literal string
- return chunk;
- }
- else if ((token = chunk.token)) { // a token, like "YYYY"
- if (tokenOverrides[token]) {
- return tokenOverrides[token](date); // use our custom token
- }
- return oldMomentFormat(date, token);
- }
- else if (chunk.maybe) { // a grouping of other chunks that must be non-zero
- maybeStr = formatDateWithChunks(date, chunk.maybe);
- if (maybeStr.match(/[1-9]/)) {
- return maybeStr;
- }
- }
-
- return '';
-}
-
-
-// Date Range Formatting
-// -------------------------------------------------------------------------------------------------
-// TODO: make it work with timezone offset
-
-// Using a formatting string meant for a single date, generate a range string, like
-// "Sep 2 - 9 2013", that intelligently inserts a separator where the dates differ.
-// If the dates are the same as far as the format string is concerned, just return a single
-// rendering of one date, without any separator.
-function formatRange(date1, date2, formatStr, separator, isRTL) {
- var localeData;
-
- date1 = FC.moment.parseZone(date1);
- date2 = FC.moment.parseZone(date2);
-
- localeData = (date1.localeData || date1.lang).call(date1); // works with moment-pre-2.8
-
- // Expand localized format strings, like "LL" -> "MMMM D YYYY"
- formatStr = localeData.longDateFormat(formatStr) || formatStr;
- // BTW, this is not important for `formatDate` because it is impossible to put custom tokens
- // or non-zero areas in Moment's localized format strings.
-
- separator = separator || ' - ';
-
- return formatRangeWithChunks(
- date1,
- date2,
- getFormatStringChunks(formatStr),
- separator,
- isRTL
- );
-}
-FC.formatRange = formatRange; // expose
-
-
-function formatRangeWithChunks(date1, date2, chunks, separator, isRTL) {
- var unzonedDate1 = date1.clone().stripZone(); // for formatSimilarChunk
- var unzonedDate2 = date2.clone().stripZone(); // "
- var chunkStr; // the rendering of the chunk
- var leftI;
- var leftStr = '';
- var rightI;
- var rightStr = '';
- var middleI;
- var middleStr1 = '';
- var middleStr2 = '';
- var middleStr = '';
-
- // Start at the leftmost side of the formatting string and continue until you hit a token
- // that is not the same between dates.
- for (leftI=0; leftI<chunks.length; leftI++) {
- chunkStr = formatSimilarChunk(date1, date2, unzonedDate1, unzonedDate2, chunks[leftI]);
- if (chunkStr === false) {
- break;
- }
- leftStr += chunkStr;
- }
-
- // Similarly, start at the rightmost side of the formatting string and move left
- for (rightI=chunks.length-1; rightI>leftI; rightI--) {
- chunkStr = formatSimilarChunk(date1, date2, unzonedDate1, unzonedDate2, chunks[rightI]);
- if (chunkStr === false) {
- break;
- }
- rightStr = chunkStr + rightStr;
- }
-
- // The area in the middle is different for both of the dates.
- // Collect them distinctly so we can jam them together later.
- for (middleI=leftI; middleI<=rightI; middleI++) {
- middleStr1 += formatDateWithChunk(date1, chunks[middleI]);
- middleStr2 += formatDateWithChunk(date2, chunks[middleI]);
- }
-
- if (middleStr1 || middleStr2) {
- if (isRTL) {
- middleStr = middleStr2 + separator + middleStr1;
- }
- else {
- middleStr = middleStr1 + separator + middleStr2;
- }
- }
-
- return leftStr + middleStr + rightStr;
-}
-
-
-var similarUnitMap = {
- Y: 'year',
- M: 'month',
- D: 'day', // day of month
- d: 'day', // day of week
- // prevents a separator between anything time-related...
- A: 'second', // AM/PM
- a: 'second', // am/pm
- T: 'second', // A/P
- t: 'second', // a/p
- H: 'second', // hour (24)
- h: 'second', // hour (12)
- m: 'second', // minute
- s: 'second' // second
-};
-// TODO: week maybe?
-
-
-// Given a formatting chunk, and given that both dates are similar in the regard the
-// formatting chunk is concerned, format date1 against `chunk`. Otherwise, return `false`.
-function formatSimilarChunk(date1, date2, unzonedDate1, unzonedDate2, chunk) {
- var token;
- var unit;
-
- if (typeof chunk === 'string') { // a literal string
- return chunk;
- }
- else if ((token = chunk.token)) {
- unit = similarUnitMap[token.charAt(0)];
-
- // are the dates the same for this unit of measurement?
- // use the unzoned dates for this calculation because unreliable when near DST (bug #2396)
- if (unit && unzonedDate1.isSame(unzonedDate2, unit)) {
- return oldMomentFormat(date1, token); // would be the same if we used `date2`
- // BTW, don't support custom tokens
- }
- }
-
- return false; // the chunk is NOT the same for the two dates
- // BTW, don't support splitting on non-zero areas
-}
-
-
-// Chunking Utils
-// -------------------------------------------------------------------------------------------------
-
-
-var formatStringChunkCache = {};
-
-
-function getFormatStringChunks(formatStr) {
- if (formatStr in formatStringChunkCache) {
- return formatStringChunkCache[formatStr];
- }
- return (formatStringChunkCache[formatStr] = chunkFormatString(formatStr));
-}
-
-
-// Break the formatting string into an array of chunks
-function chunkFormatString(formatStr) {
- var chunks = [];
- var chunker = /\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g; // TODO: more descrimination
- var match;
-
- while ((match = chunker.exec(formatStr))) {
- if (match[1]) { // a literal string inside [ ... ]
- chunks.push(match[1]);
- }
- else if (match[2]) { // non-zero formatting inside ( ... )
- chunks.push({ maybe: chunkFormatString(match[2]) });
- }
- else if (match[3]) { // a formatting token
- chunks.push({ token: match[3] });
- }
- else if (match[5]) { // an unenclosed literal string
- chunks.push(match[5]);
- }
- }
-
- return chunks;
-}
-
-;;
-
-FC.Class = Class; // export
-
-// Class that all other classes will inherit from
-function Class() { }
-
-
-// Called on a class to create a subclass.
-// Last argument contains instance methods. Any argument before the last are considered mixins.
-Class.extend = function() {
- var len = arguments.length;
- var i;
- var members;
-
- for (i = 0; i < len; i++) {
- members = arguments[i];
- if (i < len - 1) { // not the last argument?
- mixIntoClass(this, members);
- }
- }
-
- return extendClass(this, members || {}); // members will be undefined if no arguments
-};
-
-
-// Adds new member variables/methods to the class's prototype.
-// Can be called with another class, or a plain object hash containing new members.
-Class.mixin = function(members) {
- mixIntoClass(this, members);
-};
-
-
-function extendClass(superClass, members) {
- var subClass;
-
- // ensure a constructor for the subclass, forwarding all arguments to the super-constructor if it doesn't exist
- if (hasOwnProp(members, 'constructor')) {
- subClass = members.constructor;
- }
- if (typeof subClass !== 'function') {
- subClass = members.constructor = function() {
- superClass.apply(this, arguments);
- };
- }
-
- // build the base prototype for the subclass, which is an new object chained to the superclass's prototype
- subClass.prototype = createObject(superClass.prototype);
-
- // copy each member variable/method onto the the subclass's prototype
- copyOwnProps(members, subClass.prototype);
- copyNativeMethods(members, subClass.prototype); // hack for IE8
-
- // copy over all class variables/methods to the subclass, such as `extend` and `mixin`
- copyOwnProps(superClass, subClass);
-
- return subClass;
-}
-
-
-function mixIntoClass(theClass, members) {
- copyOwnProps(members, theClass.prototype); // TODO: copyNativeMethods?
-}
-;;
-
-var EmitterMixin = FC.EmitterMixin = {
-
- callbackHash: null,
-
-
- on: function(name, callback) {
- this.loopCallbacks(name, 'add', [ callback ]);
-
- return this; // for chaining
- },
-
-
- off: function(name, callback) {
- this.loopCallbacks(name, 'remove', [ callback ]);
-
- return this; // for chaining
- },
-
-
- trigger: function(name) { // args...
- var args = Array.prototype.slice.call(arguments, 1);
-
- this.triggerWith(name, this, args);
-
- return this; // for chaining
- },
-
-
- triggerWith: function(name, context, args) {
- this.loopCallbacks(name, 'fireWith', [ context, args ]);
-
- return this; // for chaining
- },
-
-
- /*
- Given an event name string with possible namespaces,
- call the given methodName on all the internal Callback object with the given arguments.
- */
- loopCallbacks: function(name, methodName, args) {
- var parts = name.split('.'); // "click.namespace" -> [ "click", "namespace" ]
- var i, part;
- var callbackObj;
-
- for (i = 0; i < parts.length; i++) {
- part = parts[i];
- if (part) { // in case no event name like "click"
- callbackObj = this.ensureCallbackObj((i ? '.' : '') + part); // put periods in front of namespaces
- callbackObj[methodName].apply(callbackObj, args);
- }
- }
- },
-
-
- ensureCallbackObj: function(name) {
- if (!this.callbackHash) {
- this.callbackHash = {};
- }
- if (!this.callbackHash[name]) {
- this.callbackHash[name] = $.Callbacks();
- }
- return this.callbackHash[name];
- }
-
-};
-;;
-
-/*
-Utility methods for easily listening to events on another object,
-and more importantly, easily unlistening from them.
-*/
-var ListenerMixin = FC.ListenerMixin = (function() {
- var guid = 0;
- var ListenerMixin = {
-
- listenerId: null,
-
- /*
- Given an `other` object that has on/off methods, bind the given `callback` to an event by the given name.
- The `callback` will be called with the `this` context of the object that .listenTo is being called on.
- Can be called:
- .listenTo(other, eventName, callback)
- OR
- .listenTo(other, {
- eventName1: callback1,
- eventName2: callback2
- })
- */
- listenTo: function(other, arg, callback) {
- if (typeof arg === 'object') { // given dictionary of callbacks
- for (var eventName in arg) {
- if (arg.hasOwnProperty(eventName)) {
- this.listenTo(other, eventName, arg[eventName]);
- }
- }
- }
- else if (typeof arg === 'string') {
- other.on(
- arg + '.' + this.getListenerNamespace(), // use event namespacing to identify this object
- $.proxy(callback, this) // always use `this` context
- // the usually-undesired jQuery guid behavior doesn't matter,
- // because we always unbind via namespace
- );
- }
- },
-
- /*
- Causes the current object to stop listening to events on the `other` object.
- `eventName` is optional. If omitted, will stop listening to ALL events on `other`.
- */
- stopListeningTo: function(other, eventName) {
- other.off((eventName || '') + '.' + this.getListenerNamespace());
- },
-
- /*
- Returns a string, unique to this object, to be used for event namespacing
- */
- getListenerNamespace: function() {
- if (this.listenerId == null) {
- this.listenerId = guid++;
- }
- return '_listener' + this.listenerId;
- }
-
- };
- return ListenerMixin;
-})();
-;;
-
-// simple class for toggle a `isIgnoringMouse` flag on delay
-// initMouseIgnoring must first be called, with a millisecond delay setting.
-var MouseIgnorerMixin = {
-
- isIgnoringMouse: false, // bool
- delayUnignoreMouse: null, // method
-
-
- initMouseIgnoring: function(delay) {
- this.delayUnignoreMouse = debounce(proxy(this, 'unignoreMouse'), delay || 1000);
- },
-
-
- // temporarily ignore mouse actions on segments
- tempIgnoreMouse: function() {
- this.isIgnoringMouse = true;
- this.delayUnignoreMouse();
- },
-
-
- // delayUnignoreMouse eventually calls this
- unignoreMouse: function() {
- this.isIgnoringMouse = false;
- }
-
-};
-
-;;
-
-/* A rectangular panel that is absolutely positioned over other content
-------------------------------------------------------------------------------------------------------------------------
-Options:
- - className (string)
- - content (HTML string or jQuery element set)
- - parentEl
- - top
- - left
- - right (the x coord of where the right edge should be. not a "CSS" right)
- - autoHide (boolean)
- - show (callback)
- - hide (callback)
-*/
-
-var Popover = Class.extend(ListenerMixin, {
-
- isHidden: true,
- options: null,
- el: null, // the container element for the popover. generated by this object
- margin: 10, // the space required between the popover and the edges of the scroll container
-
-
- constructor: function(options) {
- this.options = options || {};
- },
-
-
- // Shows the popover on the specified position. Renders it if not already
- show: function() {
- if (this.isHidden) {
- if (!this.el) {
- this.render();
- }
- this.el.show();
- this.position();
- this.isHidden = false;
- this.trigger('show');
- }
- },
-
-
- // Hides the popover, through CSS, but does not remove it from the DOM
- hide: function() {
- if (!this.isHidden) {
- this.el.hide();
- this.isHidden = true;
- this.trigger('hide');
- }
- },
-
-
- // Creates `this.el` and renders content inside of it
- render: function() {
- var _this = this;
- var options = this.options;
-
- this.el = $('<div class="fc-popover"/>')
- .addClass(options.className || '')
- .css({
- // position initially to the top left to avoid creating scrollbars
- top: 0,
- left: 0
- })
- .append(options.content)
- .appendTo(options.parentEl);
-
- // when a click happens on anything inside with a 'fc-close' className, hide the popover
- this.el.on('click', '.fc-close', function() {
- _this.hide();
- });
-
- if (options.autoHide) {
- this.listenTo($(document), 'mousedown', this.documentMousedown);
- }
- },
-
-
- // Triggered when the user clicks *anywhere* in the document, for the autoHide feature
- documentMousedown: function(ev) {
- // only hide the popover if the click happened outside the popover
- if (this.el && !$(ev.target).closest(this.el).length) {
- this.hide();
- }
- },
-
-
- // Hides and unregisters any handlers
- removeElement: function() {
- this.hide();
-
- if (this.el) {
- this.el.remove();
- this.el = null;
- }
-
- this.stopListeningTo($(document), 'mousedown');
- },
-
-
- // Positions the popover optimally, using the top/left/right options
- position: function() {
- var options = this.options;
- var origin = this.el.offsetParent().offset();
- var width = this.el.outerWidth();
- var height = this.el.outerHeight();
- var windowEl = $(window);
- var viewportEl = getScrollParent(this.el);
- var viewportTop;
- var viewportLeft;
- var viewportOffset;
- var top; // the "position" (not "offset") values for the popover
- var left; //
-
- // compute top and left
- top = options.top || 0;
- if (options.left !== undefined) {
- left = options.left;
- }
- else if (options.right !== undefined) {
- left = options.right - width; // derive the left value from the right value
- }
- else {
- left = 0;
- }
-
- if (viewportEl.is(window) || viewportEl.is(document)) { // normalize getScrollParent's result
- viewportEl = windowEl;
- viewportTop = 0; // the window is always at the top left
- viewportLeft = 0; // (and .offset() won't work if called here)
- }
- else {
- viewportOffset = viewportEl.offset();
- viewportTop = viewportOffset.top;
- viewportLeft = viewportOffset.left;
- }
-
- // if the window is scrolled, it causes the visible area to be further down
- viewportTop += windowEl.scrollTop();
- viewportLeft += windowEl.scrollLeft();
-
- // constrain to the view port. if constrained by two edges, give precedence to top/left
- if (options.viewportConstrain !== false) {
- top = Math.min(top, viewportTop + viewportEl.outerHeight() - height - this.margin);
- top = Math.max(top, viewportTop + this.margin);
- left = Math.min(left, viewportLeft + viewportEl.outerWidth() - width - this.margin);
- left = Math.max(left, viewportLeft + this.margin);
- }
-
- this.el.css({
- top: top - origin.top,
- left: left - origin.left
- });
- },
-
-
- // Triggers a callback. Calls a function in the option hash of the same name.
- // Arguments beyond the first `name` are forwarded on.
- // TODO: better code reuse for this. Repeat code
- trigger: function(name) {
- if (this.options[name]) {
- this.options[name].apply(this, Array.prototype.slice.call(arguments, 1));
- }
- }
-
-});
-
-;;
-
-/*
-A cache for the left/right/top/bottom/width/height values for one or more elements.
-Works with both offset (from topleft document) and position (from offsetParent).
-
-options:
-- els
-- isHorizontal
-- isVertical
-*/
-var CoordCache = FC.CoordCache = Class.extend({
-
- els: null, // jQuery set (assumed to be siblings)
- forcedOffsetParentEl: null, // options can override the natural offsetParent
- origin: null, // {left,top} position of offsetParent of els
- boundingRect: null, // constrain cordinates to this rectangle. {left,right,top,bottom} or null
- isHorizontal: false, // whether to query for left/right/width
- isVertical: false, // whether to query for top/bottom/height
-
- // arrays of coordinates (offsets from topleft of document)
- lefts: null,
- rights: null,
- tops: null,
- bottoms: null,
-
-
- constructor: function(options) {
- this.els = $(options.els);
- this.isHorizontal = options.isHorizontal;
- this.isVertical = options.isVertical;
- this.forcedOffsetParentEl = options.offsetParent ? $(options.offsetParent) : null;
- },
-
-
- // Queries the els for coordinates and stores them.
- // Call this method before using and of the get* methods below.
- build: function() {
- var offsetParentEl = this.forcedOffsetParentEl || this.els.eq(0).offsetParent();
-
- this.origin = offsetParentEl.offset();
- this.boundingRect = this.queryBoundingRect();
-
- if (this.isHorizontal) {
- this.buildElHorizontals();
- }
- if (this.isVertical) {
- this.buildElVerticals();
- }
- },
-
-
- // Destroys all internal data about coordinates, freeing memory
- clear: function() {
- this.origin = null;
- this.boundingRect = null;
- this.lefts = null;
- this.rights = null;
- this.tops = null;
- this.bottoms = null;
- },
-
-
- // When called, if coord caches aren't built, builds them
- ensureBuilt: function() {
- if (!this.origin) {
- this.build();
- }
- },
-
-
- // Compute and return what the elements' bounding rectangle is, from the user's perspective.
- // Right now, only returns a rectangle if constrained by an overflow:scroll element.
- queryBoundingRect: function() {
- var scrollParentEl = getScrollParent(this.els.eq(0));
-
- if (!scrollParentEl.is(document)) {
- return getClientRect(scrollParentEl);
- }
- },
-
-
- // Populates the left/right internal coordinate arrays
- buildElHorizontals: function() {
- var lefts = [];
- var rights = [];
-
- this.els.each(function(i, node) {
- var el = $(node);
- var left = el.offset().left;
- var width = el.outerWidth();
-
- lefts.push(left);
- rights.push(left + width);
- });
-
- this.lefts = lefts;
- this.rights = rights;
- },
-
-
- // Populates the top/bottom internal coordinate arrays
- buildElVerticals: function() {
- var tops = [];
- var bottoms = [];
-
- this.els.each(function(i, node) {
- var el = $(node);
- var top = el.offset().top;
- var height = el.outerHeight();
-
- tops.push(top);
- bottoms.push(top + height);
- });
-
- this.tops = tops;
- this.bottoms = bottoms;
- },
-
-
- // Given a left offset (from document left), returns the index of the el that it horizontally intersects.
- // If no intersection is made, or outside of the boundingRect, returns undefined.
- getHorizontalIndex: function(leftOffset) {
- this.ensureBuilt();
-
- var boundingRect = this.boundingRect;
- var lefts = this.lefts;
- var rights = this.rights;
- var len = lefts.length;
- var i;
-
- if (!boundingRect || (leftOffset >= boundingRect.left && leftOffset < boundingRect.right)) {
- for (i = 0; i < len; i++) {
- if (leftOffset >= lefts[i] && leftOffset < rights[i]) {
- return i;
- }
- }
- }
- },
-
-
- // Given a top offset (from document top), returns the index of the el that it vertically intersects.
- // If no intersection is made, or outside of the boundingRect, returns undefined.
- getVerticalIndex: function(topOffset) {
- this.ensureBuilt();
-
- var boundingRect = this.boundingRect;
- var tops = this.tops;
- var bottoms = this.bottoms;
- var len = tops.length;
- var i;
-
- if (!boundingRect || (topOffset >= boundingRect.top && topOffset < boundingRect.bottom)) {
- for (i = 0; i < len; i++) {
- if (topOffset >= tops[i] && topOffset < bottoms[i]) {
- return i;
- }
- }
- }
- },
-
-
- // Gets the left offset (from document left) of the element at the given index
- getLeftOffset: function(leftIndex) {
- this.ensureBuilt();
- return this.lefts[leftIndex];
- },
-
-
- // Gets the left position (from offsetParent left) of the element at the given index
- getLeftPosition: function(leftIndex) {
- this.ensureBuilt();
- return this.lefts[leftIndex] - this.origin.left;
- },
-
-
- // Gets the right offset (from document left) of the element at the given index.
- // This value is NOT relative to the document's right edge, like the CSS concept of "right" would be.
- getRightOffset: function(leftIndex) {
- this.ensureBuilt();
- return this.rights[leftIndex];
- },
-
-
- // Gets the right position (from offsetParent left) of the element at the given index.
- // This value is NOT relative to the offsetParent's right edge, like the CSS concept of "right" would be.
- getRightPosition: function(leftIndex) {
- this.ensureBuilt();
- return this.rights[leftIndex] - this.origin.left;
- },
-
-
- // Gets the width of the element at the given index
- getWidth: function(leftIndex) {
- this.ensureBuilt();
- return this.rights[leftIndex] - this.lefts[leftIndex];
- },
-
-
- // Gets the top offset (from document top) of the element at the given index
- getTopOffset: function(topIndex) {
- this.ensureBuilt();
- return this.tops[topIndex];
- },
-
-
- // Gets the top position (from offsetParent top) of the element at the given position
- getTopPosition: function(topIndex) {
- this.ensureBuilt();
- return this.tops[topIndex] - this.origin.top;
- },
-
- // Gets the bottom offset (from the document top) of the element at the given index.
- // This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of "bottom" would be.
- getBottomOffset: function(topIndex) {
- this.ensureBuilt();
- return this.bottoms[topIndex];
- },
-
-
- // Gets the bottom position (from the offsetParent top) of the element at the given index.
- // This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of "bottom" would be.
- getBottomPosition: function(topIndex) {
- this.ensureBuilt();
- return this.bottoms[topIndex] - this.origin.top;
- },
-
-
- // Gets the height of the element at the given index
- getHeight: function(topIndex) {
- this.ensureBuilt();
- return this.bottoms[topIndex] - this.tops[topIndex];
- }
-
-});
-
-;;
-
-/* Tracks a drag's mouse movement, firing various handlers
-----------------------------------------------------------------------------------------------------------------------*/
-// TODO: use Emitter
-
-var DragListener = FC.DragListener = Class.extend(ListenerMixin, MouseIgnorerMixin, {
-
- options: null,
-
- // for IE8 bug-fighting behavior
- subjectEl: null,
- subjectHref: null,
-
- // coordinates of the initial mousedown
- originX: null,
- originY: null,
-
- // the wrapping element that scrolls, or MIGHT scroll if there's overflow.
- // TODO: do this for wrappers that have overflow:hidden as well.
- scrollEl: null,
-
- isInteracting: false,
- isDistanceSurpassed: false,
- isDelayEnded: false,
- isDragging: false,
- isTouch: false,
-
- delay: null,
- delayTimeoutId: null,
- minDistance: null,
-
- handleTouchScrollProxy: null, // calls handleTouchScroll, always bound to `this`
-
-
- constructor: function(options) {
- this.options = options || {};
- this.handleTouchScrollProxy = proxy(this, 'handleTouchScroll');
- this.initMouseIgnoring(500);
- },
-
-
- // Interaction (high-level)
- // -----------------------------------------------------------------------------------------------------------------
-
-
- startInteraction: function(ev, extraOptions) {
- var isTouch = getEvIsTouch(ev);
-
- if (ev.type === 'mousedown') {
- if (this.isIgnoringMouse) {
- return;
- }
- else if (!isPrimaryMouseButton(ev)) {
- return;
- }
- else {
- ev.preventDefault(); // prevents native selection in most browsers
- }
- }
-
- if (!this.isInteracting) {
-
- // process options
- extraOptions = extraOptions || {};
- this.delay = firstDefined(extraOptions.delay, this.options.delay, 0);
- this.minDistance = firstDefined(extraOptions.distance, this.options.distance, 0);
- this.subjectEl = this.options.subjectEl;
-
- this.isInteracting = true;
- this.isTouch = isTouch;
- this.isDelayEnded = false;
- this.isDistanceSurpassed = false;
-
- this.originX = getEvX(ev);
- this.originY = getEvY(ev);
- this.scrollEl = getScrollParent($(ev.target));
-
- this.bindHandlers();
- this.initAutoScroll();
- this.handleInteractionStart(ev);
- this.startDelay(ev);
-
- if (!this.minDistance) {
- this.handleDistanceSurpassed(ev);
- }
- }
- },
-
-
- handleInteractionStart: function(ev) {
- this.trigger('interactionStart', ev);
- },
-
-
- endInteraction: function(ev, isCancelled) {
- if (this.isInteracting) {
- this.endDrag(ev);
-
- if (this.delayTimeoutId) {
- clearTimeout(this.delayTimeoutId);
- this.delayTimeoutId = null;
- }
-
- this.destroyAutoScroll();
- this.unbindHandlers();
-
- this.isInteracting = false;
- this.handleInteractionEnd(ev, isCancelled);
-
- // a touchstart+touchend on the same element will result in the following addition simulated events:
- // mouseover + mouseout + click
- // let's ignore these bogus events
- if (this.isTouch) {
- this.tempIgnoreMouse();
- }
- }
- },
-
-
- handleInteractionEnd: function(ev, isCancelled) {
- this.trigger('interactionEnd', ev, isCancelled || false);
- },
-
-
- // Binding To DOM
- // -----------------------------------------------------------------------------------------------------------------
-
-
- bindHandlers: function() {
- var _this = this;
- var touchStartIgnores = 1;
-
- if (this.isTouch) {
- this.listenTo($(document), {
- touchmove: this.handleTouchMove,
- touchend: this.endInteraction,
- touchcancel: this.endInteraction,
-
- // Sometimes touchend doesn't fire
- // (can't figure out why. touchcancel doesn't fire either. has to do with scrolling?)
- // If another touchstart happens, we know it's bogus, so cancel the drag.
- // touchend will continue to be broken until user does a shorttap/scroll, but this is best we can do.
- touchstart: function(ev) {
- if (touchStartIgnores) { // bindHandlers is called from within a touchstart,
- touchStartIgnores--; // and we don't want this to fire immediately, so ignore.
- }
- else {
- _this.endInteraction(ev, true); // isCancelled=true
- }
- }
- });
-
- // listen to ALL scroll actions on the page
- if (
- !bindAnyScroll(this.handleTouchScrollProxy) && // hopefully this works and short-circuits the rest
- this.scrollEl // otherwise, attach a single handler to this
- ) {
- this.listenTo(this.scrollEl, 'scroll', this.handleTouchScroll);
- }
- }
- else {
- this.listenTo($(document), {
- mousemove: this.handleMouseMove,
- mouseup: this.endInteraction
- });
- }
-
- this.listenTo($(document), {
- selectstart: preventDefault, // don't allow selection while dragging
- contextmenu: preventDefault // long taps would open menu on Chrome dev tools
- });
- },
-
-
- unbindHandlers: function() {
- this.stopListeningTo($(document));
-
- // unbind scroll listening
- unbindAnyScroll(this.handleTouchScrollProxy);
- if (this.scrollEl) {
- this.stopListeningTo(this.scrollEl, 'scroll');
- }
- },
-
-
- // Drag (high-level)
- // -----------------------------------------------------------------------------------------------------------------
-
-
- // extraOptions ignored if drag already started
- startDrag: function(ev, extraOptions) {
- this.startInteraction(ev, extraOptions); // ensure interaction began
-
- if (!this.isDragging) {
- this.isDragging = true;
- this.handleDragStart(ev);
- }
- },
-
-
- handleDragStart: function(ev) {
- this.trigger('dragStart', ev);
- this.initHrefHack();
- },
-
-
- handleMove: function(ev) {
- var dx = getEvX(ev) - this.originX;
- var dy = getEvY(ev) - this.originY;
- var minDistance = this.minDistance;
- var distanceSq; // current distance from the origin, squared
-
- if (!this.isDistanceSurpassed) {
- distanceSq = dx * dx + dy * dy;
- if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem
- this.handleDistanceSurpassed(ev);
- }
- }
-
- if (this.isDragging) {
- this.handleDrag(dx, dy, ev);
- }
- },
-
-
- // Called while the mouse is being moved and when we know a legitimate drag is taking place
- handleDrag: function(dx, dy, ev) {
- this.trigger('drag', dx, dy, ev);
- this.updateAutoScroll(ev); // will possibly cause scrolling
- },
-
-
- endDrag: function(ev) {
- if (this.isDragging) {
- this.isDragging = false;
- this.handleDragEnd(ev);
- }
- },
-
-
- handleDragEnd: function(ev) {
- this.trigger('dragEnd', ev);
- this.destroyHrefHack();
- },
-
-
- // Delay
- // -----------------------------------------------------------------------------------------------------------------
-
-
- startDelay: function(initialEv) {
- var _this = this;
-
- if (this.delay) {
- this.delayTimeoutId = setTimeout(function() {
- _this.handleDelayEnd(initialEv);
- }, this.delay);
- }
- else {
- this.handleDelayEnd(initialEv);
- }
- },
-
-
- handleDelayEnd: function(initialEv) {
- this.isDelayEnded = true;
-
- if (this.isDistanceSurpassed) {
- this.startDrag(initialEv);
- }
- },
-
-
- // Distance
- // -----------------------------------------------------------------------------------------------------------------
-
-
- handleDistanceSurpassed: function(ev) {
- this.isDistanceSurpassed = true;
-
- if (this.isDelayEnded) {
- this.startDrag(ev);
- }
- },
-
-
- // Mouse / Touch
- // -----------------------------------------------------------------------------------------------------------------
-
-
- handleTouchMove: function(ev) {
- // prevent inertia and touchmove-scrolling while dragging
- if (this.isDragging) {
- ev.preventDefault();
- }
-
- this.handleMove(ev);
- },
-
-
- handleMouseMove: function(ev) {
- this.handleMove(ev);
- },
-
-
- // Scrolling (unrelated to auto-scroll)
- // -----------------------------------------------------------------------------------------------------------------
-
-
- handleTouchScroll: function(ev) {
- // if the drag is being initiated by touch, but a scroll happens before
- // the drag-initiating delay is over, cancel the drag
- if (!this.isDragging) {
- this.endInteraction(ev, true); // isCancelled=true
- }
- },
-
-
- // <A> HREF Hack
- // -----------------------------------------------------------------------------------------------------------------
-
-
- initHrefHack: function() {
- var subjectEl = this.subjectEl;
-
- // remove a mousedown'd <a>'s href so it is not visited (IE8 bug)
- if ((this.subjectHref = subjectEl ? subjectEl.attr('href') : null)) {
- subjectEl.removeAttr('href');
- }
- },
-
-
- destroyHrefHack: function() {
- var subjectEl = this.subjectEl;
- var subjectHref = this.subjectHref;
-
- // restore a mousedown'd <a>'s href (for IE8 bug)
- setTimeout(function() { // must be outside of the click's execution
- if (subjectHref) {
- subjectEl.attr('href', subjectHref);
- }
- }, 0);
- },
-
-
- // Utils
- // -----------------------------------------------------------------------------------------------------------------
-
-
- // Triggers a callback. Calls a function in the option hash of the same name.
- // Arguments beyond the first `name` are forwarded on.
- trigger: function(name) {
- if (this.options[name]) {
- this.options[name].apply(this, Array.prototype.slice.call(arguments, 1));
- }
- // makes _methods callable by event name. TODO: kill this
- if (this['_' + name]) {
- this['_' + name].apply(this, Array.prototype.slice.call(arguments, 1));
- }
- }
-
-
-});
-
-;;
-/*
-this.scrollEl is set in DragListener
-*/
-DragListener.mixin({
-
- isAutoScroll: false,
-
- scrollBounds: null, // { top, bottom, left, right }
- scrollTopVel: null, // pixels per second
- scrollLeftVel: null, // pixels per second
- scrollIntervalId: null, // ID of setTimeout for scrolling animation loop
-
- // defaults
- scrollSensitivity: 30, // pixels from edge for scrolling to start
- scrollSpeed: 200, // pixels per second, at maximum speed
- scrollIntervalMs: 50, // millisecond wait between scroll increment
-
-
- initAutoScroll: function() {
- var scrollEl = this.scrollEl;
-
- this.isAutoScroll =
- this.options.scroll &&
- scrollEl &&
- !scrollEl.is(window) &&
- !scrollEl.is(document);
-
- if (this.isAutoScroll) {
- // debounce makes sure rapid calls don't happen
- this.listenTo(scrollEl, 'scroll', debounce(this.handleDebouncedScroll, 100));
- }
- },
-
-
- destroyAutoScroll: function() {
- this.endAutoScroll(); // kill any animation loop
-
- // remove the scroll handler if there is a scrollEl
- if (this.isAutoScroll) {
- this.stopListeningTo(this.scrollEl, 'scroll'); // will probably get removed by unbindHandlers too :(
- }
- },
-
-
- // Computes and stores the bounding rectangle of scrollEl
- computeScrollBounds: function() {
- if (this.isAutoScroll) {
- this.scrollBounds = getOuterRect(this.scrollEl);
- // TODO: use getClientRect in future. but prevents auto scrolling when on top of scrollbars
- }
- },
-
-
- // Called when the dragging is in progress and scrolling should be updated
- updateAutoScroll: function(ev) {
- var sensitivity = this.scrollSensitivity;
- var bounds = this.scrollBounds;
- var topCloseness, bottomCloseness;
- var leftCloseness, rightCloseness;
- var topVel = 0;
- var leftVel = 0;
-
- if (bounds) { // only scroll if scrollEl exists
-
- // compute closeness to edges. valid range is from 0.0 - 1.0
- topCloseness = (sensitivity - (getEvY(ev) - bounds.top)) / sensitivity;
- bottomCloseness = (sensitivity - (bounds.bottom - getEvY(ev))) / sensitivity;
- leftCloseness = (sensitivity - (getEvX(ev) - bounds.left)) / sensitivity;
- rightCloseness = (sensitivity - (bounds.right - getEvX(ev))) / sensitivity;
-
- // translate vertical closeness into velocity.
- // mouse must be completely in bounds for velocity to happen.
- if (topCloseness >= 0 && topCloseness <= 1) {
- topVel = topCloseness * this.scrollSpeed * -1; // negative. for scrolling up
- }
- else if (bottomCloseness >= 0 && bottomCloseness <= 1) {
- topVel = bottomCloseness * this.scrollSpeed;
- }
-
- // translate horizontal closeness into velocity
- if (leftCloseness >= 0 && leftCloseness <= 1) {
- leftVel = leftCloseness * this.scrollSpeed * -1; // negative. for scrolling left
- }
- else if (rightCloseness >= 0 && rightCloseness <= 1) {
- leftVel = rightCloseness * this.scrollSpeed;
- }
- }
-
- this.setScrollVel(topVel, leftVel);
- },
-
-
- // Sets the speed-of-scrolling for the scrollEl
- setScrollVel: function(topVel, leftVel) {
-
- this.scrollTopVel = topVel;
- this.scrollLeftVel = leftVel;
-
- this.constrainScrollVel(); // massages into realistic values
-
- // if there is non-zero velocity, and an animation loop hasn't already started, then START
- if ((this.scrollTopVel || this.scrollLeftVel) && !this.scrollIntervalId) {
- this.scrollIntervalId = setInterval(
- proxy(this, 'scrollIntervalFunc'), // scope to `this`
- this.scrollIntervalMs
- );
- }
- },
-
-
- // Forces scrollTopVel and scrollLeftVel to be zero if scrolling has already gone all the way
- constrainScrollVel: function() {
- var el = this.scrollEl;
-
- if (this.scrollTopVel < 0) { // scrolling up?
- if (el.scrollTop() <= 0) { // already scrolled all the way up?
- this.scrollTopVel = 0;
- }
- }
- else if (this.scrollTopVel > 0) { // scrolling down?
- if (el.scrollTop() + el[0].clientHeight >= el[0].scrollHeight) { // already scrolled all the way down?
- this.scrollTopVel = 0;
- }
- }
-
- if (this.scrollLeftVel < 0) { // scrolling left?
- if (el.scrollLeft() <= 0) { // already scrolled all the left?
- this.scrollLeftVel = 0;
- }
- }
- else if (this.scrollLeftVel > 0) { // scrolling right?
- if (el.scrollLeft() + el[0].clientWidth >= el[0].scrollWidth) { // already scrolled all the way right?
- this.scrollLeftVel = 0;
- }
- }
- },
-
-
- // This function gets called during every iteration of the scrolling animation loop
- scrollIntervalFunc: function() {
- var el = this.scrollEl;
- var frac = this.scrollIntervalMs / 1000; // considering animation frequency, what the vel should be mult'd by
-
- // change the value of scrollEl's scroll
- if (this.scrollTopVel) {
- el.scrollTop(el.scrollTop() + this.scrollTopVel * frac);
- }
- if (this.scrollLeftVel) {
- el.scrollLeft(el.scrollLeft() + this.scrollLeftVel * frac);
- }
-
- this.constrainScrollVel(); // since the scroll values changed, recompute the velocities
-
- // if scrolled all the way, which causes the vels to be zero, stop the animation loop
- if (!this.scrollTopVel && !this.scrollLeftVel) {
- this.endAutoScroll();
- }
- },
-
-
- // Kills any existing scrolling animation loop
- endAutoScroll: function() {
- if (this.scrollIntervalId) {
- clearInterval(this.scrollIntervalId);
- this.scrollIntervalId = null;
-
- this.handleScrollEnd();
- }
- },
-
-
- // Get called when the scrollEl is scrolled (NOTE: this is delayed via debounce)
- handleDebouncedScroll: function() {
- // recompute all coordinates, but *only* if this is *not* part of our scrolling animation
- if (!this.scrollIntervalId) {
- this.handleScrollEnd();
- }
- },
-
-
- // Called when scrolling has stopped, whether through auto scroll, or the user scrolling
- handleScrollEnd: function() {
- }
-
-});
-;;
-
-/* Tracks mouse movements over a component and raises events about which hit the mouse is over.
-------------------------------------------------------------------------------------------------------------------------
-options:
-- subjectEl
-- subjectCenter
-*/
-
-var HitDragListener = DragListener.extend({
-
- component: null, // converts coordinates to hits
- // methods: prepareHits, releaseHits, queryHit
-
- origHit: null, // the hit the mouse was over when listening started
- hit: null, // the hit the mouse is over
- coordAdjust: null, // delta that will be added to the mouse coordinates when computing collisions
-
-
- constructor: function(component, options) {
- DragListener.call(this, options); // call the super-constructor
-
- this.component = component;
- },
-
-
- // Called when drag listening starts (but a real drag has not necessarily began).
- // ev might be undefined if dragging was started manually.
- handleInteractionStart: function(ev) {
- var subjectEl = this.subjectEl;
- var subjectRect;
- var origPoint;
- var point;
-
- this.computeCoords();
-
- if (ev) {
- origPoint = { left: getEvX(ev), top: getEvY(ev) };
- point = origPoint;
-
- // constrain the point to bounds of the element being dragged
- if (subjectEl) {
- subjectRect = getOuterRect(subjectEl); // used for centering as well
- point = constrainPoint(point, subjectRect);
- }
-
- this.origHit = this.queryHit(point.left, point.top);
-
- // treat the center of the subject as the collision point?
- if (subjectEl && this.options.subjectCenter) {
-
- // only consider the area the subject overlaps the hit. best for large subjects.
- // TODO: skip this if hit didn't supply left/right/top/bottom
- if (this.origHit) {
- subjectRect = intersectRects(this.origHit, subjectRect) ||
- subjectRect; // in case there is no intersection
- }
-
- point = getRectCenter(subjectRect);
- }
-
- this.coordAdjust = diffPoints(point, origPoint); // point - origPoint
- }
- else {
- this.origHit = null;
- this.coordAdjust = null;
- }
-
- // call the super-method. do it after origHit has been computed
- DragListener.prototype.handleInteractionStart.apply(this, arguments);
- },
-
-
- // Recomputes the drag-critical positions of elements
- computeCoords: function() {
- this.component.prepareHits();
- this.computeScrollBounds(); // why is this here??????
- },
-
-
- // Called when the actual drag has started
- handleDragStart: function(ev) {
- var hit;
-
- DragListener.prototype.handleDragStart.apply(this, arguments); // call the super-method
-
- // might be different from this.origHit if the min-distance is large
- hit = this.queryHit(getEvX(ev), getEvY(ev));
-
- // report the initial hit the mouse is over
- // especially important if no min-distance and drag starts immediately
- if (hit) {
- this.handleHitOver(hit);
- }
- },
-
-
- // Called when the drag moves
- handleDrag: function(dx, dy, ev) {
- var hit;
-
- DragListener.prototype.handleDrag.apply(this, arguments); // call the super-method
-
- hit = this.queryHit(getEvX(ev), getEvY(ev));
-
- if (!isHitsEqual(hit, this.hit)) { // a different hit than before?
- if (this.hit) {
- this.handleHitOut();
- }
- if (hit) {
- this.handleHitOver(hit);
- }
- }
- },
-
-
- // Called when dragging has been stopped
- handleDragEnd: function() {
- this.handleHitDone();
- DragListener.prototype.handleDragEnd.apply(this, arguments); // call the super-method
- },
-
-
- // Called when a the mouse has just moved over a new hit
- handleHitOver: function(hit) {
- var isOrig = isHitsEqual(hit, this.origHit);
-
- this.hit = hit;
-
- this.trigger('hitOver', this.hit, isOrig, this.origHit);
- },
-
-
- // Called when the mouse has just moved out of a hit
- handleHitOut: function() {
- if (this.hit) {
- this.trigger('hitOut', this.hit);
- this.handleHitDone();
- this.hit = null;
- }
- },
-
-
- // Called after a hitOut. Also called before a dragStop
- handleHitDone: function() {
- if (this.hit) {
- this.trigger('hitDone', this.hit);
- }
- },
-
-
- // Called when the interaction ends, whether there was a real drag or not
- handleInteractionEnd: function() {
- DragListener.prototype.handleInteractionEnd.apply(this, arguments); // call the super-method
-
- this.origHit = null;
- this.hit = null;
-
- this.component.releaseHits();
- },
-
-
- // Called when scrolling has stopped, whether through auto scroll, or the user scrolling
- handleScrollEnd: function() {
- DragListener.prototype.handleScrollEnd.apply(this, arguments); // call the super-method
-
- this.computeCoords(); // hits' absolute positions will be in new places. recompute
- },
-
-
- // Gets the hit underneath the coordinates for the given mouse event
- queryHit: function(left, top) {
-
- if (this.coordAdjust) {
- left += this.coordAdjust.left;
- top += this.coordAdjust.top;
- }
-
- return this.component.queryHit(left, top);
- }
-
-});
-
-
-// Returns `true` if the hits are identically equal. `false` otherwise. Must be from the same component.
-// Two null values will be considered equal, as two "out of the component" states are the same.
-function isHitsEqual(hit0, hit1) {
-
- if (!hit0 && !hit1) {
- return true;
- }
-
- if (hit0 && hit1) {
- return hit0.component === hit1.component &&
- isHitPropsWithin(hit0, hit1) &&
- isHitPropsWithin(hit1, hit0); // ensures all props are identical
- }
-
- return false;
-}
-
-
-// Returns true if all of subHit's non-standard properties are within superHit
-function isHitPropsWithin(subHit, superHit) {
- for (var propName in subHit) {
- if (!/^(component|left|right|top|bottom)$/.test(propName)) {
- if (subHit[propName] !== superHit[propName]) {
- return false;
- }
- }
- }
- return true;
-}
-
-;;
-
-/* Creates a clone of an element and lets it track the mouse as it moves
-----------------------------------------------------------------------------------------------------------------------*/
-
-var MouseFollower = Class.extend(ListenerMixin, {
-
- options: null,
-
- sourceEl: null, // the element that will be cloned and made to look like it is dragging
- el: null, // the clone of `sourceEl` that will track the mouse
- parentEl: null, // the element that `el` (the clone) will be attached to
-
- // the initial position of el, relative to the offset parent. made to match the initial offset of sourceEl
- top0: null,
- left0: null,
-
- // the absolute coordinates of the initiating touch/mouse action
- y0: null,
- x0: null,
-
- // the number of pixels the mouse has moved from its initial position
- topDelta: null,
- leftDelta: null,
-
- isFollowing: false,
- isHidden: false,
- isAnimating: false, // doing the revert animation?
-
- constructor: function(sourceEl, options) {
- this.options = options = options || {};
- this.sourceEl = sourceEl;
- this.parentEl = options.parentEl ? $(options.parentEl) : sourceEl.parent(); // default to sourceEl's parent
- },
-
-
- // Causes the element to start following the mouse
- start: function(ev) {
- if (!this.isFollowing) {
- this.isFollowing = true;
-
- this.y0 = getEvY(ev);
- this.x0 = getEvX(ev);
- this.topDelta = 0;
- this.leftDelta = 0;
-
- if (!this.isHidden) {
- this.updatePosition();
- }
-
- if (getEvIsTouch(ev)) {
- this.listenTo($(document), 'touchmove', this.handleMove);
- }
- else {
- this.listenTo($(document), 'mousemove', this.handleMove);
- }
- }
- },
-
-
- // Causes the element to stop following the mouse. If shouldRevert is true, will animate back to original position.
- // `callback` gets invoked when the animation is complete. If no animation, it is invoked immediately.
- stop: function(shouldRevert, callback) {
- var _this = this;
- var revertDuration = this.options.revertDuration;
-
- function complete() {
- this.isAnimating = false;
- _this.removeElement();
-
- this.top0 = this.left0 = null; // reset state for future updatePosition calls
-
- if (callback) {
- callback();
- }
- }
-
- if (this.isFollowing && !this.isAnimating) { // disallow more than one stop animation at a time
- this.isFollowing = false;
-
- this.stopListeningTo($(document));
-
- if (shouldRevert && revertDuration && !this.isHidden) { // do a revert animation?
- this.isAnimating = true;
- this.el.animate({
- top: this.top0,
- left: this.left0
- }, {
- duration: revertDuration,
- complete: complete
- });
- }
- else {
- complete();
- }
- }
- },
-
-
- // Gets the tracking element. Create it if necessary
- getEl: function() {
- var el = this.el;
-
- if (!el) {
- this.sourceEl.width(); // hack to force IE8 to compute correct bounding box
- el = this.el = this.sourceEl.clone()
- .addClass(this.options.additionalClass || '')
- .css({
- position: 'absolute',
- visibility: '', // in case original element was hidden (commonly through hideEvents())
- display: this.isHidden ? 'none' : '', // for when initially hidden
- margin: 0,
- right: 'auto', // erase and set width instead
- bottom: 'auto', // erase and set height instead
- width: this.sourceEl.width(), // explicit height in case there was a 'right' value
- height: this.sourceEl.height(), // explicit width in case there was a 'bottom' value
- opacity: this.options.opacity || '',
- zIndex: this.options.zIndex
- });
-
- // we don't want long taps or any mouse interaction causing selection/menus.
- // would use preventSelection(), but that prevents selectstart, causing problems.
- el.addClass('fc-unselectable');
-
- el.appendTo(this.parentEl);
- }
-
- return el;
- },
-
-
- // Removes the tracking element if it has already been created
- removeElement: function() {
- if (this.el) {
- this.el.remove();
- this.el = null;
- }
- },
-
-
- // Update the CSS position of the tracking element
- updatePosition: function() {
- var sourceOffset;
- var origin;
-
- this.getEl(); // ensure this.el
-
- // make sure origin info was computed
- if (this.top0 === null) {
- this.sourceEl.width(); // hack to force IE8 to compute correct bounding box
- sourceOffset = this.sourceEl.offset();
- origin = this.el.offsetParent().offset();
- this.top0 = sourceOffset.top - origin.top;
- this.left0 = sourceOffset.left - origin.left;
- }
-
- this.el.css({
- top: this.top0 + this.topDelta,
- left: this.left0 + this.leftDelta
- });
- },
-
-
- // Gets called when the user moves the mouse
- handleMove: function(ev) {
- this.topDelta = getEvY(ev) - this.y0;
- this.leftDelta = getEvX(ev) - this.x0;
-
- if (!this.isHidden) {
- this.updatePosition();
- }
- },
-
-
- // Temporarily makes the tracking element invisible. Can be called before following starts
- hide: function() {
- if (!this.isHidden) {
- this.isHidden = true;
- if (this.el) {
- this.el.hide();
- }
- }
- },
-
-
- // Show the tracking element after it has been temporarily hidden
- show: function() {
- if (this.isHidden) {
- this.isHidden = false;
- this.updatePosition();
- this.getEl().show();
- }
- }
-
-});
-
-;;
-
-/* An abstract class comprised of a "grid" of areas that each represent a specific datetime
-----------------------------------------------------------------------------------------------------------------------*/
-
-var Grid = FC.Grid = Class.extend(ListenerMixin, MouseIgnorerMixin, {
-
- view: null, // a View object
- isRTL: null, // shortcut to the view's isRTL option
-
- start: null,
- end: null,
-
- el: null, // the containing element
- elsByFill: null, // a hash of jQuery element sets used for rendering each fill. Keyed by fill name.
-
- // derived from options
- eventTimeFormat: null,
- displayEventTime: null,
- displayEventEnd: null,
-
- minResizeDuration: null, // TODO: hack. set by subclasses. minumum event resize duration
-
- // if defined, holds the unit identified (ex: "year" or "month") that determines the level of granularity
- // of the date areas. if not defined, assumes to be day and time granularity.
- // TODO: port isTimeScale into same system?
- largeUnit: null,
-
- dayDragListener: null,
- segDragListener: null,
- segResizeListener: null,
- externalDragListener: null,
-
-
- constructor: function(view) {
- this.view = view;
- this.isRTL = view.opt('isRTL');
- this.elsByFill = {};
-
- this.dayDragListener = this.buildDayDragListener();
- this.initMouseIgnoring();
- },
-
-
- /* Options
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Generates the format string used for event time text, if not explicitly defined by 'timeFormat'
- computeEventTimeFormat: function() {
- return this.view.opt('smallTimeFormat');
- },
-
-
- // Determines whether events should have their end times displayed, if not explicitly defined by 'displayEventTime'.
- // Only applies to non-all-day events.
- computeDisplayEventTime: function() {
- return true;
- },
-
-
- // Determines whether events should have their end times displayed, if not explicitly defined by 'displayEventEnd'
- computeDisplayEventEnd: function() {
- return true;
- },
-
-
- /* Dates
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Tells the grid about what period of time to display.
- // Any date-related internal data should be generated.
- setRange: function(range) {
- this.start = range.start.clone();
- this.end = range.end.clone();
-
- this.rangeUpdated();
- this.processRangeOptions();
- },
-
-
- // Called when internal variables that rely on the range should be updated
- rangeUpdated: function() {
- },
-
-
- // Updates values that rely on options and also relate to range
- processRangeOptions: function() {
- var view = this.view;
- var displayEventTime;
- var displayEventEnd;
-
- this.eventTimeFormat =
- view.opt('eventTimeFormat') ||
- view.opt('timeFormat') || // deprecated
- this.computeEventTimeFormat();
-
- displayEventTime = view.opt('displayEventTime');
- if (displayEventTime == null) {
- displayEventTime = this.computeDisplayEventTime(); // might be based off of range
- }
-
- displayEventEnd = view.opt('displayEventEnd');
- if (displayEventEnd == null) {
- displayEventEnd = this.computeDisplayEventEnd(); // might be based off of range
- }
-
- this.displayEventTime = displayEventTime;
- this.displayEventEnd = displayEventEnd;
- },
-
-
- // Converts a span (has unzoned start/end and any other grid-specific location information)
- // into an array of segments (pieces of events whose format is decided by the grid).
- spanToSegs: function(span) {
- // subclasses must implement
- },
-
-
- // Diffs the two dates, returning a duration, based on granularity of the grid
- // TODO: port isTimeScale into this system?
- diffDates: function(a, b) {
- if (this.largeUnit) {
- return diffByUnit(a, b, this.largeUnit);
- }
- else {
- return diffDayTime(a, b);
- }
- },
-
-
- /* Hit Area
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Called before one or more queryHit calls might happen. Should prepare any cached coordinates for queryHit
- prepareHits: function() {
- },
-
-
- // Called when queryHit calls have subsided. Good place to clear any coordinate caches.
- releaseHits: function() {
- },
-
-
- // Given coordinates from the topleft of the document, return data about the date-related area underneath.
- // Can return an object with arbitrary properties (although top/right/left/bottom are encouraged).
- // Must have a `grid` property, a reference to this current grid. TODO: avoid this
- // The returned object will be processed by getHitSpan and getHitEl.
- queryHit: function(leftOffset, topOffset) {
- },
-
-
- // Given position-level information about a date-related area within the grid,
- // should return an object with at least a start/end date. Can provide other information as well.
- getHitSpan: function(hit) {
- },
-
-
- // Given position-level information about a date-related area within the grid,
- // should return a jQuery element that best represents it. passed to dayClick callback.
- getHitEl: function(hit) {
- },
-
-
- /* Rendering
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Sets the container element that the grid should render inside of.
- // Does other DOM-related initializations.
- setElement: function(el) {
- this.el = el;
- preventSelection(el);
-
- this.bindDayHandler('touchstart', this.dayTouchStart);
- this.bindDayHandler('mousedown', this.dayMousedown);
-
- // attach event-element-related handlers. in Grid.events
- // same garbage collection note as above.
- this.bindSegHandlers();
-
- this.bindGlobalHandlers();
- },
-
-
- bindDayHandler: function(name, handler) {
- var _this = this;
-
- // attach a handler to the grid's root element.
- // jQuery will take care of unregistering them when removeElement gets called.
- this.el.on(name, function(ev) {
- if (
- !$(ev.target).is('.fc-event-container *, .fc-more') && // not an an event element, or "more.." link
- !$(ev.target).closest('.fc-popover').length // not on a popover (like the "more.." events one)
- ) {
- return handler.call(_this, ev);
- }
- });
- },
-
-
- // Removes the grid's container element from the DOM. Undoes any other DOM-related attachments.
- // DOES NOT remove any content beforehand (doesn't clear events or call unrenderDates), unlike View
- removeElement: function() {
- this.unbindGlobalHandlers();
- this.clearDragListeners();
-
- this.el.remove();
-
- // NOTE: we don't null-out this.el for the same reasons we don't do it within View::removeElement
- },
-
-
- // Renders the basic structure of grid view before any content is rendered
- renderSkeleton: function() {
- // subclasses should implement
- },
-
-
- // Renders the grid's date-related content (like areas that represent days/times).
- // Assumes setRange has already been called and the skeleton has already been rendered.
- renderDates: function() {
- // subclasses should implement
- },
-
-
- // Unrenders the grid's date-related content
- unrenderDates: function() {
- // subclasses should implement
- },
-
-
- /* Handlers
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Binds DOM handlers to elements that reside outside the grid, such as the document
- bindGlobalHandlers: function() {
- this.listenTo($(document), {
- dragstart: this.externalDragStart, // jqui
- sortstart: this.externalDragStart // jqui
- });
- },
-
-
- // Unbinds DOM handlers from elements that reside outside the grid
- unbindGlobalHandlers: function() {
- this.stopListeningTo($(document));
- },
-
-
- // Process a mousedown on an element that represents a day. For day clicking and selecting.
- dayMousedown: function(ev) {
- if (!this.isIgnoringMouse) {
- this.dayDragListener.startInteraction(ev, {
- //distance: 5, // needs more work if we want dayClick to fire correctly
- });
- }
- },
-
-
- dayTouchStart: function(ev) {
- var view = this.view;
-
- // HACK to prevent a user's clickaway for unselecting a range or an event
- // from causing a dayClick.
- if (view.isSelected || view.selectedEvent) {
- this.tempIgnoreMouse();
- }
-
- this.dayDragListener.startInteraction(ev, {
- delay: this.view.opt('longPressDelay')
- });
- },
-
-
- // Creates a listener that tracks the user's drag across day elements.
- // For day clicking and selecting.
- buildDayDragListener: function() {
- var _this = this;
- var view = this.view;
- var isSelectable = view.opt('selectable');
- var dayClickHit; // null if invalid dayClick
- var selectionSpan; // null if invalid selection
-
- // this listener tracks a mousedown on a day element, and a subsequent drag.
- // if the drag ends on the same day, it is a 'dayClick'.
- // if 'selectable' is enabled, this listener also detects selections.
- var dragListener = new HitDragListener(this, {
- scroll: view.opt('dragScroll'),
- interactionStart: function() {
- dayClickHit = dragListener.origHit; // for dayClick, where no dragging happens
- },
- dragStart: function() {
- view.unselect(); // since we could be rendering a new selection, we want to clear any old one
- },
- hitOver: function(hit, isOrig, origHit) {
- if (origHit) { // click needs to have started on a hit
-
- // if user dragged to another cell at any point, it can no longer be a dayClick
- if (!isOrig) {
- dayClickHit = null;
- }
-
- if (isSelectable) {
- selectionSpan = _this.computeSelection(
- _this.getHitSpan(origHit),
- _this.getHitSpan(hit)
- );
- if (selectionSpan) {
- _this.renderSelection(selectionSpan);
- }
- else if (selectionSpan === false) {
- disableCursor();
- }
- }
- }
- },
- hitOut: function() {
- dayClickHit = null;
- selectionSpan = null;
- _this.unrenderSelection();
- enableCursor();
- },
- interactionEnd: function(ev, isCancelled) {
- if (!isCancelled) {
- if (
- dayClickHit &&
- !_this.isIgnoringMouse // see hack in dayTouchStart
- ) {
- view.triggerDayClick(
- _this.getHitSpan(dayClickHit),
- _this.getHitEl(dayClickHit),
- ev
- );
- }
- if (selectionSpan) {
- // the selection will already have been rendered. just report it
- view.reportSelection(selectionSpan, ev);
- }
- enableCursor();
- }
- }
- });
-
- return dragListener;
- },
-
-
- // Kills all in-progress dragging.
- // Useful for when public API methods that result in re-rendering are invoked during a drag.
- // Also useful for when touch devices misbehave and don't fire their touchend.
- clearDragListeners: function() {
- this.dayDragListener.endInteraction();
-
- if (this.segDragListener) {
- this.segDragListener.endInteraction(); // will clear this.segDragListener
- }
- if (this.segResizeListener) {
- this.segResizeListener.endInteraction(); // will clear this.segResizeListener
- }
- if (this.externalDragListener) {
- this.externalDragListener.endInteraction(); // will clear this.externalDragListener
- }
- },
-
-
- /* Event Helper
- ------------------------------------------------------------------------------------------------------------------*/
- // TODO: should probably move this to Grid.events, like we did event dragging / resizing
-
-
- // Renders a mock event at the given event location, which contains zoned start/end properties.
- // Returns all mock event elements.
- renderEventLocationHelper: function(eventLocation, sourceSeg) {
- var fakeEvent = this.fabricateHelperEvent(eventLocation, sourceSeg);
-
- return this.renderHelper(fakeEvent, sourceSeg); // do the actual rendering
- },
-
-
- // Builds a fake event given zoned event date properties and a segment is should be inspired from.
- // The range's end can be null, in which case the mock event that is rendered will have a null end time.
- // `sourceSeg` is the internal segment object involved in the drag. If null, something external is dragging.
- fabricateHelperEvent: function(eventLocation, sourceSeg) {
- var fakeEvent = sourceSeg ? createObject(sourceSeg.event) : {}; // mask the original event object if possible
-
- fakeEvent.start = eventLocation.start.clone();
- fakeEvent.end = eventLocation.end ? eventLocation.end.clone() : null;
- fakeEvent.allDay = null; // force it to be freshly computed by normalizeEventDates
- this.view.calendar.normalizeEventDates(fakeEvent);
-
- // this extra className will be useful for differentiating real events from mock events in CSS
- fakeEvent.className = (fakeEvent.className || []).concat('fc-helper');
-
- // if something external is being dragged in, don't render a resizer
- if (!sourceSeg) {
- fakeEvent.editable = false;
- }
-
- return fakeEvent;
- },
-
-
- // Renders a mock event. Given zoned event date properties.
- // Must return all mock event elements.
- renderHelper: function(eventLocation, sourceSeg) {
- // subclasses must implement
- },
-
-
- // Unrenders a mock event
- unrenderHelper: function() {
- // subclasses must implement
- },
-
-
- /* Selection
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders a visual indication of a selection. Will highlight by default but can be overridden by subclasses.
- // Given a span (unzoned start/end and other misc data)
- renderSelection: function(span) {
- this.renderHighlight(span);
- },
-
-
- // Unrenders any visual indications of a selection. Will unrender a highlight by default.
- unrenderSelection: function() {
- this.unrenderHighlight();
- },
-
-
- // Given the first and last date-spans of a selection, returns another date-span object.
- // Subclasses can override and provide additional data in the span object. Will be passed to renderSelection().
- // Will return false if the selection is invalid and this should be indicated to the user.
- // Will return null/undefined if a selection invalid but no error should be reported.
- computeSelection: function(span0, span1) {
- var span = this.computeSelectionSpan(span0, span1);
-
- if (span && !this.view.calendar.isSelectionSpanAllowed(span)) {
- return false;
- }
-
- return span;
- },
-
-
- // Given two spans, must return the combination of the two.
- // TODO: do this separation of concerns (combining VS validation) for event dnd/resize too.
- computeSelectionSpan: function(span0, span1) {
- var dates = [ span0.start, span0.end, span1.start, span1.end ];
-
- dates.sort(compareNumbers); // sorts chronologically. works with Moments
-
- return { start: dates[0].clone(), end: dates[3].clone() };
- },
-
-
- /* Highlight
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders an emphasis on the given date range. Given a span (unzoned start/end and other misc data)
- renderHighlight: function(span) {
- this.renderFill('highlight', this.spanToSegs(span));
- },
-
-
- // Unrenders the emphasis on a date range
- unrenderHighlight: function() {
- this.unrenderFill('highlight');
- },
-
-
- // Generates an array of classNames for rendering the highlight. Used by the fill system.
- highlightSegClasses: function() {
- return [ 'fc-highlight' ];
- },
-
-
- /* Business Hours
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- renderBusinessHours: function() {
- },
-
-
- unrenderBusinessHours: function() {
- },
-
-
- /* Now Indicator
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- getNowIndicatorUnit: function() {
- },
-
-
- renderNowIndicator: function(date) {
- },
-
-
- unrenderNowIndicator: function() {
- },
-
-
- /* Fill System (highlight, background events, business hours)
- --------------------------------------------------------------------------------------------------------------------
- TODO: remove this system. like we did in TimeGrid
- */
-
-
- // Renders a set of rectangles over the given segments of time.
- // MUST RETURN a subset of segs, the segs that were actually rendered.
- // Responsible for populating this.elsByFill. TODO: better API for expressing this requirement
- renderFill: function(type, segs) {
- // subclasses must implement
- },
-
-
- // Unrenders a specific type of fill that is currently rendered on the grid
- unrenderFill: function(type) {
- var el = this.elsByFill[type];
-
- if (el) {
- el.remove();
- delete this.elsByFill[type];
- }
- },
-
-
- // Renders and assigns an `el` property for each fill segment. Generic enough to work with different types.
- // Only returns segments that successfully rendered.
- // To be harnessed by renderFill (implemented by subclasses).
- // Analagous to renderFgSegEls.
- renderFillSegEls: function(type, segs) {
- var _this = this;
- var segElMethod = this[type + 'SegEl'];
- var html = '';
- var renderedSegs = [];
- var i;
-
- if (segs.length) {
-
- // build a large concatenation of segment HTML
- for (i = 0; i < segs.length; i++) {
- html += this.fillSegHtml(type, segs[i]);
- }
-
- // Grab individual elements from the combined HTML string. Use each as the default rendering.
- // Then, compute the 'el' for each segment.
- $(html).each(function(i, node) {
- var seg = segs[i];
- var el = $(node);
-
- // allow custom filter methods per-type
- if (segElMethod) {
- el = segElMethod.call(_this, seg, el);
- }
-
- if (el) { // custom filters did not cancel the render
- el = $(el); // allow custom filter to return raw DOM node
-
- // correct element type? (would be bad if a non-TD were inserted into a table for example)
- if (el.is(_this.fillSegTag)) {
- seg.el = el;
- renderedSegs.push(seg);
- }
- }
- });
- }
-
- return renderedSegs;
- },
-
-
- fillSegTag: 'div', // subclasses can override
-
-
- // Builds the HTML needed for one fill segment. Generic enought o work with different types.
- fillSegHtml: function(type, seg) {
-
- // custom hooks per-type
- var classesMethod = this[type + 'SegClasses'];
- var cssMethod = this[type + 'SegCss'];
-
- var classes = classesMethod ? classesMethod.call(this, seg) : [];
- var css = cssToStr(cssMethod ? cssMethod.call(this, seg) : {});
-
- return '<' + this.fillSegTag +
- (classes.length ? ' class="' + classes.join(' ') + '"' : '') +
- (css ? ' style="' + css + '"' : '') +
- ' />';
- },
-
-
-
- /* Generic rendering utilities for subclasses
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Computes HTML classNames for a single-day element
- getDayClasses: function(date) {
- var view = this.view;
- var today = view.calendar.getNow();
- var classes = [ 'fc-' + dayIDs[date.day()] ];
-
- if (
- view.intervalDuration.as('months') == 1 &&
- date.month() != view.intervalStart.month()
- ) {
- classes.push('fc-other-month');
- }
-
- if (date.isSame(today, 'day')) {
- classes.push(
- 'fc-today',
- view.highlightStateClass
- );
- }
- else if (date < today) {
- classes.push('fc-past');
- }
- else {
- classes.push('fc-future');
- }
-
- return classes;
- }
-
-});
-
-;;
-
-/* Event-rendering and event-interaction methods for the abstract Grid class
-----------------------------------------------------------------------------------------------------------------------*/
-
-Grid.mixin({
-
- mousedOverSeg: null, // the segment object the user's mouse is over. null if over nothing
- isDraggingSeg: false, // is a segment being dragged? boolean
- isResizingSeg: false, // is a segment being resized? boolean
- isDraggingExternal: false, // jqui-dragging an external element? boolean
- segs: null, // the *event* segments currently rendered in the grid. TODO: rename to `eventSegs`
-
-
- // Renders the given events onto the grid
- renderEvents: function(events) {
- var bgEvents = [];
- var fgEvents = [];
- var i;
-
- for (i = 0; i < events.length; i++) {
- (isBgEvent(events[i]) ? bgEvents : fgEvents).push(events[i]);
- }
-
- this.segs = [].concat( // record all segs
- this.renderBgEvents(bgEvents),
- this.renderFgEvents(fgEvents)
- );
- },
-
-
- renderBgEvents: function(events) {
- var segs = this.eventsToSegs(events);
-
- // renderBgSegs might return a subset of segs, segs that were actually rendered
- return this.renderBgSegs(segs) || segs;
- },
-
-
- renderFgEvents: function(events) {
- var segs = this.eventsToSegs(events);
-
- // renderFgSegs might return a subset of segs, segs that were actually rendered
- return this.renderFgSegs(segs) || segs;
- },
-
-
- // Unrenders all events currently rendered on the grid
- unrenderEvents: function() {
- this.handleSegMouseout(); // trigger an eventMouseout if user's mouse is over an event
- this.clearDragListeners();
-
- this.unrenderFgSegs();
- this.unrenderBgSegs();
-
- this.segs = null;
- },
-
-
- // Retrieves all rendered segment objects currently rendered on the grid
- getEventSegs: function() {
- return this.segs || [];
- },
-
-
- /* Foreground Segment Rendering
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders foreground event segments onto the grid. May return a subset of segs that were rendered.
- renderFgSegs: function(segs) {
- // subclasses must implement
- },
-
-
- // Unrenders all currently rendered foreground segments
- unrenderFgSegs: function() {
- // subclasses must implement
- },
-
-
- // Renders and assigns an `el` property for each foreground event segment.
- // Only returns segments that successfully rendered.
- // A utility that subclasses may use.
- renderFgSegEls: function(segs, disableResizing) {
- var view = this.view;
- var html = '';
- var renderedSegs = [];
- var i;
-
- if (segs.length) { // don't build an empty html string
-
- // build a large concatenation of event segment HTML
- for (i = 0; i < segs.length; i++) {
- html += this.fgSegHtml(segs[i], disableResizing);
- }
-
- // Grab individual elements from the combined HTML string. Use each as the default rendering.
- // Then, compute the 'el' for each segment. An el might be null if the eventRender callback returned false.
- $(html).each(function(i, node) {
- var seg = segs[i];
- var el = view.resolveEventEl(seg.event, $(node));
-
- if (el) {
- el.data('fc-seg', seg); // used by handlers
- seg.el = el;
- renderedSegs.push(seg);
- }
- });
- }
-
- return renderedSegs;
- },
-
-
- // Generates the HTML for the default rendering of a foreground event segment. Used by renderFgSegEls()
- fgSegHtml: function(seg, disableResizing) {
- // subclasses should implement
- },
-
-
- /* Background Segment Rendering
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders the given background event segments onto the grid.
- // Returns a subset of the segs that were actually rendered.
- renderBgSegs: function(segs) {
- return this.renderFill('bgEvent', segs);
- },
-
-
- // Unrenders all the currently rendered background event segments
- unrenderBgSegs: function() {
- this.unrenderFill('bgEvent');
- },
-
-
- // Renders a background event element, given the default rendering. Called by the fill system.
- bgEventSegEl: function(seg, el) {
- return this.view.resolveEventEl(seg.event, el); // will filter through eventRender
- },
-
-
- // Generates an array of classNames to be used for the default rendering of a background event.
- // Called by the fill system.
- bgEventSegClasses: function(seg) {
- var event = seg.event;
- var source = event.source || {};
-
- return [ 'fc-bgevent' ].concat(
- event.className,
- source.className || []
- );
- },
-
-
- // Generates a semicolon-separated CSS string to be used for the default rendering of a background event.
- // Called by the fill system.
- bgEventSegCss: function(seg) {
- return {
- 'background-color': this.getSegSkinCss(seg)['background-color']
- };
- },
-
-
- // Generates an array of classNames to be used for the rendering business hours overlay. Called by the fill system.
- businessHoursSegClasses: function(seg) {
- return [ 'fc-nonbusiness', 'fc-bgevent' ];
- },
-
-
- /* Handlers
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Attaches event-element-related handlers to the container element and leverage bubbling
- bindSegHandlers: function() {
- this.bindSegHandler('touchstart', this.handleSegTouchStart);
- this.bindSegHandler('touchend', this.handleSegTouchEnd);
- this.bindSegHandler('mouseenter', this.handleSegMouseover);
- this.bindSegHandler('mouseleave', this.handleSegMouseout);
- this.bindSegHandler('mousedown', this.handleSegMousedown);
- this.bindSegHandler('click', this.handleSegClick);
- },
-
-
- // Executes a handler for any a user-interaction on a segment.
- // Handler gets called with (seg, ev), and with the `this` context of the Grid
- bindSegHandler: function(name, handler) {
- var _this = this;
-
- this.el.on(name, '.fc-event-container > *', function(ev) {
- var seg = $(this).data('fc-seg'); // grab segment data. put there by View::renderEvents
-
- // only call the handlers if there is not a drag/resize in progress
- if (seg && !_this.isDraggingSeg && !_this.isResizingSeg) {
- return handler.call(_this, seg, ev); // context will be the Grid
- }
- });
- },
-
-
- handleSegClick: function(seg, ev) {
- return this.view.trigger('eventClick', seg.el[0], seg.event, ev); // can return `false` to cancel
- },
-
-
- // Updates internal state and triggers handlers for when an event element is moused over
- handleSegMouseover: function(seg, ev) {
- if (
- !this.isIgnoringMouse &&
- !this.mousedOverSeg
- ) {
- this.mousedOverSeg = seg;
- seg.el.addClass('fc-allow-mouse-resize');
- this.view.trigger('eventMouseover', seg.el[0], seg.event, ev);
- }
- },
-
-
- // Updates internal state and triggers handlers for when an event element is moused out.
- // Can be given no arguments, in which case it will mouseout the segment that was previously moused over.
- handleSegMouseout: function(seg, ev) {
- ev = ev || {}; // if given no args, make a mock mouse event
-
- if (this.mousedOverSeg) {
- seg = seg || this.mousedOverSeg; // if given no args, use the currently moused-over segment
- this.mousedOverSeg = null;
- seg.el.removeClass('fc-allow-mouse-resize');
- this.view.trigger('eventMouseout', seg.el[0], seg.event, ev);
- }
- },
-
-
- handleSegMousedown: function(seg, ev) {
- var isResizing = this.startSegResize(seg, ev, { distance: 5 });
-
- if (!isResizing && this.view.isEventDraggable(seg.event)) {
- this.buildSegDragListener(seg)
- .startInteraction(ev, {
- distance: 5
- });
- }
- },
-
-
- handleSegTouchStart: function(seg, ev) {
- var view = this.view;
- var event = seg.event;
- var isSelected = view.isEventSelected(event);
- var isDraggable = view.isEventDraggable(event);
- var isResizable = view.isEventResizable(event);
- var isResizing = false;
- var dragListener;
-
- if (isSelected && isResizable) {
- // only allow resizing of the event is selected
- isResizing = this.startSegResize(seg, ev);
- }
-
- if (!isResizing && (isDraggable || isResizable)) { // allowed to be selected?
-
- dragListener = isDraggable ?
- this.buildSegDragListener(seg) :
- this.buildSegSelectListener(seg); // seg isn't draggable, but still needs to be selected
-
- dragListener.startInteraction(ev, { // won't start if already started
- delay: isSelected ? 0 : this.view.opt('longPressDelay') // do delay if not already selected
- });
- }
-
- // a long tap simulates a mouseover. ignore this bogus mouseover.
- this.tempIgnoreMouse();
- },
-
-
- handleSegTouchEnd: function(seg, ev) {
- // touchstart+touchend = click, which simulates a mouseover.
- // ignore this bogus mouseover.
- this.tempIgnoreMouse();
- },
-
-
- // returns boolean whether resizing actually started or not.
- // assumes the seg allows resizing.
- // `dragOptions` are optional.
- startSegResize: function(seg, ev, dragOptions) {
- if ($(ev.target).is('.fc-resizer')) {
- this.buildSegResizeListener(seg, $(ev.target).is('.fc-start-resizer'))
- .startInteraction(ev, dragOptions);
- return true;
- }
- return false;
- },
-
-
-
- /* Event Dragging
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Builds a listener that will track user-dragging on an event segment.
- // Generic enough to work with any type of Grid.
- // Has side effect of setting/unsetting `segDragListener`
- buildSegDragListener: function(seg) {
- var _this = this;
- var view = this.view;
- var calendar = view.calendar;
- var el = seg.el;
- var event = seg.event;
- var isDragging;
- var mouseFollower; // A clone of the original element that will move with the mouse
- var dropLocation; // zoned event date properties
-
- if (this.segDragListener) {
- return this.segDragListener;
- }
-
- // Tracks mouse movement over the *view's* coordinate map. Allows dragging and dropping between subcomponents
- // of the view.
- var dragListener = this.segDragListener = new HitDragListener(view, {
- scroll: view.opt('dragScroll'),
- subjectEl: el,
- subjectCenter: true,
- interactionStart: function(ev) {
- isDragging = false;
- mouseFollower = new MouseFollower(seg.el, {
- additionalClass: 'fc-dragging',
- parentEl: view.el,
- opacity: dragListener.isTouch ? null : view.opt('dragOpacity'),
- revertDuration: view.opt('dragRevertDuration'),
- zIndex: 2 // one above the .fc-view
- });
- mouseFollower.hide(); // don't show until we know this is a real drag
- mouseFollower.start(ev);
- },
- dragStart: function(ev) {
- if (dragListener.isTouch && !view.isEventSelected(event)) {
- // if not previously selected, will fire after a delay. then, select the event
- view.selectEvent(event);
- }
- isDragging = true;
- _this.handleSegMouseout(seg, ev); // ensure a mouseout on the manipulated event has been reported
- _this.segDragStart(seg, ev);
- view.hideEvent(event); // hide all event segments. our mouseFollower will take over
- },
- hitOver: function(hit, isOrig, origHit) {
- var dragHelperEls;
-
- // starting hit could be forced (DayGrid.limit)
- if (seg.hit) {
- origHit = seg.hit;
- }
-
- // since we are querying the parent view, might not belong to this grid
- dropLocation = _this.computeEventDrop(
- origHit.component.getHitSpan(origHit),
- hit.component.getHitSpan(hit),
- event
- );
-
- if (dropLocation && !calendar.isEventSpanAllowed(_this.eventToSpan(dropLocation), event)) {
- disableCursor();
- dropLocation = null;
- }
-
- // if a valid drop location, have the subclass render a visual indication
- if (dropLocation && (dragHelperEls = view.renderDrag(dropLocation, seg))) {
-
- dragHelperEls.addClass('fc-dragging');
- if (!dragListener.isTouch) {
- _this.applyDragOpacity(dragHelperEls);
- }
-
- mouseFollower.hide(); // if the subclass is already using a mock event "helper", hide our own
- }
- else {
- mouseFollower.show(); // otherwise, have the helper follow the mouse (no snapping)
- }
-
- if (isOrig) {
- dropLocation = null; // needs to have moved hits to be a valid drop
- }
- },
- hitOut: function() { // called before mouse moves to a different hit OR moved out of all hits
- view.unrenderDrag(); // unrender whatever was done in renderDrag
- mouseFollower.show(); // show in case we are moving out of all hits
- dropLocation = null;
- },
- hitDone: function() { // Called after a hitOut OR before a dragEnd
- enableCursor();
- },
- interactionEnd: function(ev) {
- // do revert animation if hasn't changed. calls a callback when finished (whether animation or not)
- mouseFollower.stop(!dropLocation, function() {
- if (isDragging) {
- view.unrenderDrag();
- view.showEvent(event);
- _this.segDragStop(seg, ev);
- }
- if (dropLocation) {
- view.reportEventDrop(event, dropLocation, this.largeUnit, el, ev);
- }
- });
- _this.segDragListener = null;
- }
- });
-
- return dragListener;
- },
-
-
- // seg isn't draggable, but let's use a generic DragListener
- // simply for the delay, so it can be selected.
- // Has side effect of setting/unsetting `segDragListener`
- buildSegSelectListener: function(seg) {
- var _this = this;
- var view = this.view;
- var event = seg.event;
-
- if (this.segDragListener) {
- return this.segDragListener;
- }
-
- var dragListener = this.segDragListener = new DragListener({
- dragStart: function(ev) {
- if (dragListener.isTouch && !view.isEventSelected(event)) {
- // if not previously selected, will fire after a delay. then, select the event
- view.selectEvent(event);
- }
- },
- interactionEnd: function(ev) {
- _this.segDragListener = null;
- }
- });
-
- return dragListener;
- },
-
-
- // Called before event segment dragging starts
- segDragStart: function(seg, ev) {
- this.isDraggingSeg = true;
- this.view.trigger('eventDragStart', seg.el[0], seg.event, ev, {}); // last argument is jqui dummy
- },
-
-
- // Called after event segment dragging stops
- segDragStop: function(seg, ev) {
- this.isDraggingSeg = false;
- this.view.trigger('eventDragStop', seg.el[0], seg.event, ev, {}); // last argument is jqui dummy
- },
-
-
- // Given the spans an event drag began, and the span event was dropped, calculates the new zoned start/end/allDay
- // values for the event. Subclasses may override and set additional properties to be used by renderDrag.
- // A falsy returned value indicates an invalid drop.
- // DOES NOT consider overlap/constraint.
- computeEventDrop: function(startSpan, endSpan, event) {
- var calendar = this.view.calendar;
- var dragStart = startSpan.start;
- var dragEnd = endSpan.start;
- var delta;
- var dropLocation; // zoned event date properties
-
- if (dragStart.hasTime() === dragEnd.hasTime()) {
- delta = this.diffDates(dragEnd, dragStart);
-
- // if an all-day event was in a timed area and it was dragged to a different time,
- // guarantee an end and adjust start/end to have times
- if (event.allDay && durationHasTime(delta)) {
- dropLocation = {
- start: event.start.clone(),
- end: calendar.getEventEnd(event), // will be an ambig day
- allDay: false // for normalizeEventTimes
- };
- calendar.normalizeEventTimes(dropLocation);
- }
- // othewise, work off existing values
- else {
- dropLocation = {
- start: event.start.clone(),
- end: event.end ? event.end.clone() : null,
- allDay: event.allDay // keep it the same
- };
- }
-
- dropLocation.start.add(delta);
- if (dropLocation.end) {
- dropLocation.end.add(delta);
- }
- }
- else {
- // if switching from day <-> timed, start should be reset to the dropped date, and the end cleared
- dropLocation = {
- start: dragEnd.clone(),
- end: null, // end should be cleared
- allDay: !dragEnd.hasTime()
- };
- }
-
- return dropLocation;
- },
-
-
- // Utility for apply dragOpacity to a jQuery set
- applyDragOpacity: function(els) {
- var opacity = this.view.opt('dragOpacity');
-
- if (opacity != null) {
- els.each(function(i, node) {
- // Don't use jQuery (will set an IE filter), do it the old fashioned way.
- // In IE8, a helper element will disappears if there's a filter.
- node.style.opacity = opacity;
- });
- }
- },
-
-
- /* External Element Dragging
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Called when a jQuery UI drag is initiated anywhere in the DOM
- externalDragStart: function(ev, ui) {
- var view = this.view;
- var el;
- var accept;
-
- if (view.opt('droppable')) { // only listen if this setting is on
- el = $((ui ? ui.item : null) || ev.target);
-
- // Test that the dragged element passes the dropAccept selector or filter function.
- // FYI, the default is "*" (matches all)
- accept = view.opt('dropAccept');
- if ($.isFunction(accept) ? accept.call(el[0], el) : el.is(accept)) {
- if (!this.isDraggingExternal) { // prevent double-listening if fired twice
- this.listenToExternalDrag(el, ev, ui);
- }
- }
- }
- },
-
-
- // Called when a jQuery UI drag starts and it needs to be monitored for dropping
- listenToExternalDrag: function(el, ev, ui) {
- var _this = this;
- var calendar = this.view.calendar;
- var meta = getDraggedElMeta(el); // extra data about event drop, including possible event to create
- var dropLocation; // a null value signals an unsuccessful drag
-
- // listener that tracks mouse movement over date-associated pixel regions
- var dragListener = _this.externalDragListener = new HitDragListener(this, {
- interactionStart: function() {
- _this.isDraggingExternal = true;
- },
- hitOver: function(hit) {
- dropLocation = _this.computeExternalDrop(
- hit.component.getHitSpan(hit), // since we are querying the parent view, might not belong to this grid
- meta
- );
-
- if ( // invalid hit?
- dropLocation &&
- !calendar.isExternalSpanAllowed(_this.eventToSpan(dropLocation), dropLocation, meta.eventProps)
- ) {
- disableCursor();
- dropLocation = null;
- }
-
- if (dropLocation) {
- _this.renderDrag(dropLocation); // called without a seg parameter
- }
- },
- hitOut: function() {
- dropLocation = null; // signal unsuccessful
- },
- hitDone: function() { // Called after a hitOut OR before a dragEnd
- enableCursor();
- _this.unrenderDrag();
- },
- interactionEnd: function(ev) {
- if (dropLocation) { // element was dropped on a valid hit
- _this.view.reportExternalDrop(meta, dropLocation, el, ev, ui);
- }
- _this.isDraggingExternal = false;
- _this.externalDragListener = null;
- }
- });
-
- dragListener.startDrag(ev); // start listening immediately
- },
-
-
- // Given a hit to be dropped upon, and misc data associated with the jqui drag (guaranteed to be a plain object),
- // returns the zoned start/end dates for the event that would result from the hypothetical drop. end might be null.
- // Returning a null value signals an invalid drop hit.
- // DOES NOT consider overlap/constraint.
- computeExternalDrop: function(span, meta) {
- var calendar = this.view.calendar;
- var dropLocation = {
- start: calendar.applyTimezone(span.start), // simulate a zoned event start date
- end: null
- };
-
- // if dropped on an all-day span, and element's metadata specified a time, set it
- if (meta.startTime && !dropLocation.start.hasTime()) {
- dropLocation.start.time(meta.startTime);
- }
-
- if (meta.duration) {
- dropLocation.end = dropLocation.start.clone().add(meta.duration);
- }
-
- return dropLocation;
- },
-
-
-
- /* Drag Rendering (for both events and an external elements)
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders a visual indication of an event or external element being dragged.
- // `dropLocation` contains hypothetical start/end/allDay values the event would have if dropped. end can be null.
- // `seg` is the internal segment object that is being dragged. If dragging an external element, `seg` is null.
- // A truthy returned value indicates this method has rendered a helper element.
- // Must return elements used for any mock events.
- renderDrag: function(dropLocation, seg) {
- // subclasses must implement
- },
-
-
- // Unrenders a visual indication of an event or external element being dragged
- unrenderDrag: function() {
- // subclasses must implement
- },
-
-
- /* Resizing
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Creates a listener that tracks the user as they resize an event segment.
- // Generic enough to work with any type of Grid.
- buildSegResizeListener: function(seg, isStart) {
- var _this = this;
- var view = this.view;
- var calendar = view.calendar;
- var el = seg.el;
- var event = seg.event;
- var eventEnd = calendar.getEventEnd(event);
- var isDragging;
- var resizeLocation; // zoned event date properties. falsy if invalid resize
-
- // Tracks mouse movement over the *grid's* coordinate map
- var dragListener = this.segResizeListener = new HitDragListener(this, {
- scroll: view.opt('dragScroll'),
- subjectEl: el,
- interactionStart: function() {
- isDragging = false;
- },
- dragStart: function(ev) {
- isDragging = true;
- _this.handleSegMouseout(seg, ev); // ensure a mouseout on the manipulated event has been reported
- _this.segResizeStart(seg, ev);
- },
- hitOver: function(hit, isOrig, origHit) {
- var origHitSpan = _this.getHitSpan(origHit);
- var hitSpan = _this.getHitSpan(hit);
-
- resizeLocation = isStart ?
- _this.computeEventStartResize(origHitSpan, hitSpan, event) :
- _this.computeEventEndResize(origHitSpan, hitSpan, event);
-
- if (resizeLocation) {
- if (!calendar.isEventSpanAllowed(_this.eventToSpan(resizeLocation), event)) {
- disableCursor();
- resizeLocation = null;
- }
- // no change? (TODO: how does this work with timezones?)
- else if (resizeLocation.start.isSame(event.start) && resizeLocation.end.isSame(eventEnd)) {
- resizeLocation = null;
- }
- }
-
- if (resizeLocation) {
- view.hideEvent(event);
- _this.renderEventResize(resizeLocation, seg);
- }
- },
- hitOut: function() { // called before mouse moves to a different hit OR moved out of all hits
- resizeLocation = null;
- },
- hitDone: function() { // resets the rendering to show the original event
- _this.unrenderEventResize();
- view.showEvent(event);
- enableCursor();
- },
- interactionEnd: function(ev) {
- if (isDragging) {
- _this.segResizeStop(seg, ev);
- }
- if (resizeLocation) { // valid date to resize to?
- view.reportEventResize(event, resizeLocation, this.largeUnit, el, ev);
- }
- _this.segResizeListener = null;
- }
- });
-
- return dragListener;
- },
-
-
- // Called before event segment resizing starts
- segResizeStart: function(seg, ev) {
- this.isResizingSeg = true;
- this.view.trigger('eventResizeStart', seg.el[0], seg.event, ev, {}); // last argument is jqui dummy
- },
-
-
- // Called after event segment resizing stops
- segResizeStop: function(seg, ev) {
- this.isResizingSeg = false;
- this.view.trigger('eventResizeStop', seg.el[0], seg.event, ev, {}); // last argument is jqui dummy
- },
-
-
- // Returns new date-information for an event segment being resized from its start
- computeEventStartResize: function(startSpan, endSpan, event) {
- return this.computeEventResize('start', startSpan, endSpan, event);
- },
-
-
- // Returns new date-information for an event segment being resized from its end
- computeEventEndResize: function(startSpan, endSpan, event) {
- return this.computeEventResize('end', startSpan, endSpan, event);
- },
-
-
- // Returns new zoned date information for an event segment being resized from its start OR end
- // `type` is either 'start' or 'end'.
- // DOES NOT consider overlap/constraint.
- computeEventResize: function(type, startSpan, endSpan, event) {
- var calendar = this.view.calendar;
- var delta = this.diffDates(endSpan[type], startSpan[type]);
- var resizeLocation; // zoned event date properties
- var defaultDuration;
-
- // build original values to work from, guaranteeing a start and end
- resizeLocation = {
- start: event.start.clone(),
- end: calendar.getEventEnd(event),
- allDay: event.allDay
- };
-
- // if an all-day event was in a timed area and was resized to a time, adjust start/end to have times
- if (resizeLocation.allDay && durationHasTime(delta)) {
- resizeLocation.allDay = false;
- calendar.normalizeEventTimes(resizeLocation);
- }
-
- resizeLocation[type].add(delta); // apply delta to start or end
-
- // if the event was compressed too small, find a new reasonable duration for it
- if (!resizeLocation.start.isBefore(resizeLocation.end)) {
-
- defaultDuration =
- this.minResizeDuration || // TODO: hack
- (event.allDay ?
- calendar.defaultAllDayEventDuration :
- calendar.defaultTimedEventDuration);
-
- if (type == 'start') { // resizing the start?
- resizeLocation.start = resizeLocation.end.clone().subtract(defaultDuration);
- }
- else { // resizing the end?
- resizeLocation.end = resizeLocation.start.clone().add(defaultDuration);
- }
- }
-
- return resizeLocation;
- },
-
-
- // Renders a visual indication of an event being resized.
- // `range` has the updated dates of the event. `seg` is the original segment object involved in the drag.
- // Must return elements used for any mock events.
- renderEventResize: function(range, seg) {
- // subclasses must implement
- },
-
-
- // Unrenders a visual indication of an event being resized.
- unrenderEventResize: function() {
- // subclasses must implement
- },
-
-
- /* Rendering Utils
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Compute the text that should be displayed on an event's element.
- // `range` can be the Event object itself, or something range-like, with at least a `start`.
- // If event times are disabled, or the event has no time, will return a blank string.
- // If not specified, formatStr will default to the eventTimeFormat setting,
- // and displayEnd will default to the displayEventEnd setting.
- getEventTimeText: function(range, formatStr, displayEnd) {
-
- if (formatStr == null) {
- formatStr = this.eventTimeFormat;
- }
-
- if (displayEnd == null) {
- displayEnd = this.displayEventEnd;
- }
-
- if (this.displayEventTime && range.start.hasTime()) {
- if (displayEnd && range.end) {
- return this.view.formatRange(range, formatStr);
- }
- else {
- return range.start.format(formatStr);
- }
- }
-
- return '';
- },
-
-
- // Generic utility for generating the HTML classNames for an event segment's element
- getSegClasses: function(seg, isDraggable, isResizable) {
- var view = this.view;
- var event = seg.event;
- var classes = [
- 'fc-event',
- seg.isStart ? 'fc-start' : 'fc-not-start',
- seg.isEnd ? 'fc-end' : 'fc-not-end'
- ].concat(
- event.className,
- event.source ? event.source.className : []
- );
-
- if (isDraggable) {
- classes.push('fc-draggable');
- }
- if (isResizable) {
- classes.push('fc-resizable');
- }
-
- // event is currently selected? attach a className.
- if (view.isEventSelected(event)) {
- classes.push('fc-selected');
- }
-
- return classes;
- },
-
-
- // Utility for generating event skin-related CSS properties
- getSegSkinCss: function(seg) {
- var event = seg.event;
- var view = this.view;
- var source = event.source || {};
- var eventColor = event.color;
- var sourceColor = source.color;
- var optionColor = view.opt('eventColor');
-
- return {
- 'background-color':
- event.backgroundColor ||
- eventColor ||
- source.backgroundColor ||
- sourceColor ||
- view.opt('eventBackgroundColor') ||
- optionColor,
- 'border-color':
- event.borderColor ||
- eventColor ||
- source.borderColor ||
- sourceColor ||
- view.opt('eventBorderColor') ||
- optionColor,
- color:
- event.textColor ||
- source.textColor ||
- view.opt('eventTextColor')
- };
- },
-
-
- /* Converting events -> eventRange -> eventSpan -> eventSegs
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Generates an array of segments for the given single event
- // Can accept an event "location" as well (which only has start/end and no allDay)
- eventToSegs: function(event) {
- return this.eventsToSegs([ event ]);
- },
-
-
- eventToSpan: function(event) {
- return this.eventToSpans(event)[0];
- },
-
-
- // Generates spans (always unzoned) for the given event.
- // Does not do any inverting for inverse-background events.
- // Can accept an event "location" as well (which only has start/end and no allDay)
- eventToSpans: function(event) {
- var range = this.eventToRange(event);
- return this.eventRangeToSpans(range, event);
- },
-
-
-
- // Converts an array of event objects into an array of event segment objects.
- // A custom `segSliceFunc` may be given for arbitrarily slicing up events.
- // Doesn't guarantee an order for the resulting array.
- eventsToSegs: function(allEvents, segSliceFunc) {
- var _this = this;
- var eventsById = groupEventsById(allEvents);
- var segs = [];
-
- $.each(eventsById, function(id, events) {
- var ranges = [];
- var i;
-
- for (i = 0; i < events.length; i++) {
- ranges.push(_this.eventToRange(events[i]));
- }
-
- // inverse-background events (utilize only the first event in calculations)
- if (isInverseBgEvent(events[0])) {
- ranges = _this.invertRanges(ranges);
-
- for (i = 0; i < ranges.length; i++) {
- segs.push.apply(segs, // append to
- _this.eventRangeToSegs(ranges[i], events[0], segSliceFunc));
- }
- }
- // normal event ranges
- else {
- for (i = 0; i < ranges.length; i++) {
- segs.push.apply(segs, // append to
- _this.eventRangeToSegs(ranges[i], events[i], segSliceFunc));
- }
- }
- });
-
- return segs;
- },
-
-
- // Generates the unzoned start/end dates an event appears to occupy
- // Can accept an event "location" as well (which only has start/end and no allDay)
- eventToRange: function(event) {
- return {
- start: event.start.clone().stripZone(),
- end: (
- event.end ?
- event.end.clone() :
- // derive the end from the start and allDay. compute allDay if necessary
- this.view.calendar.getDefaultEventEnd(
- event.allDay != null ?
- event.allDay :
- !event.start.hasTime(),
- event.start
- )
- ).stripZone()
- };
- },
-
-
- // Given an event's range (unzoned start/end), and the event itself,
- // slice into segments (using the segSliceFunc function if specified)
- eventRangeToSegs: function(range, event, segSliceFunc) {
- var spans = this.eventRangeToSpans(range, event);
- var segs = [];
- var i;
-
- for (i = 0; i < spans.length; i++) {
- segs.push.apply(segs, // append to
- this.eventSpanToSegs(spans[i], event, segSliceFunc));
- }
-
- return segs;
- },
-
-
- // Given an event's unzoned date range, return an array of "span" objects.
- // Subclasses can override.
- eventRangeToSpans: function(range, event) {
- return [ $.extend({}, range) ]; // copy into a single-item array
- },
-
-
- // Given an event's span (unzoned start/end and other misc data), and the event itself,
- // slices into segments and attaches event-derived properties to them.
- eventSpanToSegs: function(span, event, segSliceFunc) {
- var segs = segSliceFunc ? segSliceFunc(span) : this.spanToSegs(span);
- var i, seg;
-
- for (i = 0; i < segs.length; i++) {
- seg = segs[i];
- seg.event = event;
- seg.eventStartMS = +span.start; // TODO: not the best name after making spans unzoned
- seg.eventDurationMS = span.end - span.start;
- }
-
- return segs;
- },
-
-
- // Produces a new array of range objects that will cover all the time NOT covered by the given ranges.
- // SIDE EFFECT: will mutate the given array and will use its date references.
- invertRanges: function(ranges) {
- var view = this.view;
- var viewStart = view.start.clone(); // need a copy
- var viewEnd = view.end.clone(); // need a copy
- var inverseRanges = [];
- var start = viewStart; // the end of the previous range. the start of the new range
- var i, range;
-
- // ranges need to be in order. required for our date-walking algorithm
- ranges.sort(compareRanges);
-
- for (i = 0; i < ranges.length; i++) {
- range = ranges[i];
-
- // add the span of time before the event (if there is any)
- if (range.start > start) { // compare millisecond time (skip any ambig logic)
- inverseRanges.push({
- start: start,
- end: range.start
- });
- }
-
- start = range.end;
- }
-
- // add the span of time after the last event (if there is any)
- if (start < viewEnd) { // compare millisecond time (skip any ambig logic)
- inverseRanges.push({
- start: start,
- end: viewEnd
- });
- }
-
- return inverseRanges;
- },
-
-
- sortEventSegs: function(segs) {
- segs.sort(proxy(this, 'compareEventSegs'));
- },
-
-
- // A cmp function for determining which segments should take visual priority
- compareEventSegs: function(seg1, seg2) {
- return seg1.eventStartMS - seg2.eventStartMS || // earlier events go first
- seg2.eventDurationMS - seg1.eventDurationMS || // tie? longer events go first
- seg2.event.allDay - seg1.event.allDay || // tie? put all-day events first (booleans cast to 0/1)
- compareByFieldSpecs(seg1.event, seg2.event, this.view.eventOrderSpecs);
- }
-
-});
-
-
-/* Utilities
-----------------------------------------------------------------------------------------------------------------------*/
-
-
-function isBgEvent(event) { // returns true if background OR inverse-background
- var rendering = getEventRendering(event);
- return rendering === 'background' || rendering === 'inverse-background';
-}
-FC.isBgEvent = isBgEvent; // export
-
-
-function isInverseBgEvent(event) {
- return getEventRendering(event) === 'inverse-background';
-}
-
-
-function getEventRendering(event) {
- return firstDefined((event.source || {}).rendering, event.rendering);
-}
-
-
-function groupEventsById(events) {
- var eventsById = {};
- var i, event;
-
- for (i = 0; i < events.length; i++) {
- event = events[i];
- (eventsById[event._id] || (eventsById[event._id] = [])).push(event);
- }
-
- return eventsById;
-}
-
-
-// A cmp function for determining which non-inverted "ranges" (see above) happen earlier
-function compareRanges(range1, range2) {
- return range1.start - range2.start; // earlier ranges go first
-}
-
-
-/* External-Dragging-Element Data
-----------------------------------------------------------------------------------------------------------------------*/
-
-// Require all HTML5 data-* attributes used by FullCalendar to have this prefix.
-// A value of '' will query attributes like data-event. A value of 'fc' will query attributes like data-fc-event.
-FC.dataAttrPrefix = '';
-
-// Given a jQuery element that might represent a dragged FullCalendar event, returns an intermediate data structure
-// to be used for Event Object creation.
-// A defined `.eventProps`, even when empty, indicates that an event should be created.
-function getDraggedElMeta(el) {
- var prefix = FC.dataAttrPrefix;
- var eventProps; // properties for creating the event, not related to date/time
- var startTime; // a Duration
- var duration;
- var stick;
-
- if (prefix) { prefix += '-'; }
- eventProps = el.data(prefix + 'event') || null;
-
- if (eventProps) {
- if (typeof eventProps === 'object') {
- eventProps = $.extend({}, eventProps); // make a copy
- }
- else { // something like 1 or true. still signal event creation
- eventProps = {};
- }
-
- // pluck special-cased date/time properties
- startTime = eventProps.start;
- if (startTime == null) { startTime = eventProps.time; } // accept 'time' as well
- duration = eventProps.duration;
- stick = eventProps.stick;
- delete eventProps.start;
- delete eventProps.time;
- delete eventProps.duration;
- delete eventProps.stick;
- }
-
- // fallback to standalone attribute values for each of the date/time properties
- if (startTime == null) { startTime = el.data(prefix + 'start'); }
- if (startTime == null) { startTime = el.data(prefix + 'time'); } // accept 'time' as well
- if (duration == null) { duration = el.data(prefix + 'duration'); }
- if (stick == null) { stick = el.data(prefix + 'stick'); }
-
- // massage into correct data types
- startTime = startTime != null ? moment.duration(startTime) : null;
- duration = duration != null ? moment.duration(duration) : null;
- stick = Boolean(stick);
-
- return { eventProps: eventProps, startTime: startTime, duration: duration, stick: stick };
-}
-
-
-;;
-
-/*
-A set of rendering and date-related methods for a visual component comprised of one or more rows of day columns.
-Prerequisite: the object being mixed into needs to be a *Grid*
-*/
-var DayTableMixin = FC.DayTableMixin = {
-
- breakOnWeeks: false, // should create a new row for each week?
- dayDates: null, // whole-day dates for each column. left to right
- dayIndices: null, // for each day from start, the offset
- daysPerRow: null,
- rowCnt: null,
- colCnt: null,
- colHeadFormat: null,
-
-
- // Populates internal variables used for date calculation and rendering
- updateDayTable: function() {
- var view = this.view;
- var date = this.start.clone();
- var dayIndex = -1;
- var dayIndices = [];
- var dayDates = [];
- var daysPerRow;
- var firstDay;
- var rowCnt;
-
- while (date.isBefore(this.end)) { // loop each day from start to end
- if (view.isHiddenDay(date)) {
- dayIndices.push(dayIndex + 0.5); // mark that it's between indices
- }
- else {
- dayIndex++;
- dayIndices.push(dayIndex);
- dayDates.push(date.clone());
- }
- date.add(1, 'days');
- }
-
- if (this.breakOnWeeks) {
- // count columns until the day-of-week repeats
- firstDay = dayDates[0].day();
- for (daysPerRow = 1; daysPerRow < dayDates.length; daysPerRow++) {
- if (dayDates[daysPerRow].day() == firstDay) {
- break;
- }
- }
- rowCnt = Math.ceil(dayDates.length / daysPerRow);
- }
- else {
- rowCnt = 1;
- daysPerRow = dayDates.length;
- }
-
- this.dayDates = dayDates;
- this.dayIndices = dayIndices;
- this.daysPerRow = daysPerRow;
- this.rowCnt = rowCnt;
-
- this.updateDayTableCols();
- },
-
-
- // Computes and assigned the colCnt property and updates any options that may be computed from it
- updateDayTableCols: function() {
- this.colCnt = this.computeColCnt();
- this.colHeadFormat = this.view.opt('columnFormat') || this.computeColHeadFormat();
- },
-
-
- // Determines how many columns there should be in the table
- computeColCnt: function() {
- return this.daysPerRow;
- },
-
-
- // Computes the ambiguously-timed moment for the given cell
- getCellDate: function(row, col) {
- return this.dayDates[
- this.getCellDayIndex(row, col)
- ].clone();
- },
-
-
- // Computes the ambiguously-timed date range for the given cell
- getCellRange: function(row, col) {
- var start = this.getCellDate(row, col);
- var end = start.clone().add(1, 'days');
-
- return { start: start, end: end };
- },
-
-
- // Returns the number of day cells, chronologically, from the first of the grid (0-based)
- getCellDayIndex: function(row, col) {
- return row * this.daysPerRow + this.getColDayIndex(col);
- },
-
-
- // Returns the numner of day cells, chronologically, from the first cell in *any given row*
- getColDayIndex: function(col) {
- if (this.isRTL) {
- return this.colCnt - 1 - col;
- }
- else {
- return col;
- }
- },
-
-
- // Given a date, returns its chronolocial cell-index from the first cell of the grid.
- // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.
- // If before the first offset, returns a negative number.
- // If after the last offset, returns an offset past the last cell offset.
- // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.
- getDateDayIndex: function(date) {
- var dayIndices = this.dayIndices;
- var dayOffset = date.diff(this.start, 'days');
-
- if (dayOffset < 0) {
- return dayIndices[0] - 1;
- }
- else if (dayOffset >= dayIndices.length) {
- return dayIndices[dayIndices.length - 1] + 1;
- }
- else {
- return dayIndices[dayOffset];
- }
- },
-
-
- /* Options
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Computes a default column header formatting string if `colFormat` is not explicitly defined
- computeColHeadFormat: function() {
- // if more than one week row, or if there are a lot of columns with not much space,
- // put just the day numbers will be in each cell
- if (this.rowCnt > 1 || this.colCnt > 10) {
- return 'ddd'; // "Sat"
- }
- // multiple days, so full single date string WON'T be in title text
- else if (this.colCnt > 1) {
- return this.view.opt('dayOfMonthFormat'); // "Sat 12/10"
- }
- // single day, so full single date string will probably be in title text
- else {
- return 'dddd'; // "Saturday"
- }
- },
-
-
- /* Slicing
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Slices up a date range into a segment for every week-row it intersects with
- sliceRangeByRow: function(range) {
- var daysPerRow = this.daysPerRow;
- var normalRange = this.view.computeDayRange(range); // make whole-day range, considering nextDayThreshold
- var rangeFirst = this.getDateDayIndex(normalRange.start); // inclusive first index
- var rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')); // inclusive last index
- var segs = [];
- var row;
- var rowFirst, rowLast; // inclusive day-index range for current row
- var segFirst, segLast; // inclusive day-index range for segment
-
- for (row = 0; row < this.rowCnt; row++) {
- rowFirst = row * daysPerRow;
- rowLast = rowFirst + daysPerRow - 1;
-
- // intersect segment's offset range with the row's
- segFirst = Math.max(rangeFirst, rowFirst);
- segLast = Math.min(rangeLast, rowLast);
-
- // deal with in-between indices
- segFirst = Math.ceil(segFirst); // in-between starts round to next cell
- segLast = Math.floor(segLast); // in-between ends round to prev cell
-
- if (segFirst <= segLast) { // was there any intersection with the current row?
- segs.push({
- row: row,
-
- // normalize to start of row
- firstRowDayIndex: segFirst - rowFirst,
- lastRowDayIndex: segLast - rowFirst,
-
- // must be matching integers to be the segment's start/end
- isStart: segFirst === rangeFirst,
- isEnd: segLast === rangeLast
- });
- }
- }
-
- return segs;
- },
-
-
- // Slices up a date range into a segment for every day-cell it intersects with.
- // TODO: make more DRY with sliceRangeByRow somehow.
- sliceRangeByDay: function(range) {
- var daysPerRow = this.daysPerRow;
- var normalRange = this.view.computeDayRange(range); // make whole-day range, considering nextDayThreshold
- var rangeFirst = this.getDateDayIndex(normalRange.start); // inclusive first index
- var rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')); // inclusive last index
- var segs = [];
- var row;
- var rowFirst, rowLast; // inclusive day-index range for current row
- var i;
- var segFirst, segLast; // inclusive day-index range for segment
-
- for (row = 0; row < this.rowCnt; row++) {
- rowFirst = row * daysPerRow;
- rowLast = rowFirst + daysPerRow - 1;
-
- for (i = rowFirst; i <= rowLast; i++) {
-
- // intersect segment's offset range with the row's
- segFirst = Math.max(rangeFirst, i);
- segLast = Math.min(rangeLast, i);
-
- // deal with in-between indices
- segFirst = Math.ceil(segFirst); // in-between starts round to next cell
- segLast = Math.floor(segLast); // in-between ends round to prev cell
-
- if (segFirst <= segLast) { // was there any intersection with the current row?
- segs.push({
- row: row,
-
- // normalize to start of row
- firstRowDayIndex: segFirst - rowFirst,
- lastRowDayIndex: segLast - rowFirst,
-
- // must be matching integers to be the segment's start/end
- isStart: segFirst === rangeFirst,
- isEnd: segLast === rangeLast
- });
- }
- }
- }
-
- return segs;
- },
-
-
- /* Header Rendering
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- renderHeadHtml: function() {
- var view = this.view;
-
- return '' +
- '<div class="fc-row ' + view.widgetHeaderClass + '">' +
- '<table>' +
- '<thead>' +
- this.renderHeadTrHtml() +
- '</thead>' +
- '</table>' +
- '</div>';
- },
-
-
- renderHeadIntroHtml: function() {
- return this.renderIntroHtml(); // fall back to generic
- },
-
-
- renderHeadTrHtml: function() {
- return '' +
- '<tr>' +
- (this.isRTL ? '' : this.renderHeadIntroHtml()) +
- this.renderHeadDateCellsHtml() +
- (this.isRTL ? this.renderHeadIntroHtml() : '') +
- '</tr>';
- },
-
-
- renderHeadDateCellsHtml: function() {
- var htmls = [];
- var col, date;
-
- for (col = 0; col < this.colCnt; col++) {
- date = this.getCellDate(0, col);
- htmls.push(this.renderHeadDateCellHtml(date));
- }
-
- return htmls.join('');
- },
-
-
- // TODO: when internalApiVersion, accept an object for HTML attributes
- // (colspan should be no different)
- renderHeadDateCellHtml: function(date, colspan, otherAttrs) {
- var view = this.view;
-
- return '' +
- '<th class="fc-day-header ' + view.widgetHeaderClass + ' fc-' + dayIDs[date.day()] + '"' +
- (this.rowCnt == 1 ?
- ' data-date="' + date.format('YYYY-MM-DD') + '"' :
- '') +
- (colspan > 1 ?
- ' colspan="' + colspan + '"' :
- '') +
- (otherAttrs ?
- ' ' + otherAttrs :
- '') +
- '>' +
- htmlEscape(date.format(this.colHeadFormat)) +
- '</th>';
- },
-
-
- /* Background Rendering
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- renderBgTrHtml: function(row) {
- return '' +
- '<tr>' +
- (this.isRTL ? '' : this.renderBgIntroHtml(row)) +
- this.renderBgCellsHtml(row) +
- (this.isRTL ? this.renderBgIntroHtml(row) : '') +
- '</tr>';
- },
-
-
- renderBgIntroHtml: function(row) {
- return this.renderIntroHtml(); // fall back to generic
- },
-
-
- renderBgCellsHtml: function(row) {
- var htmls = [];
- var col, date;
-
- for (col = 0; col < this.colCnt; col++) {
- date = this.getCellDate(row, col);
- htmls.push(this.renderBgCellHtml(date));
- }
-
- return htmls.join('');
- },
-
-
- renderBgCellHtml: function(date, otherAttrs) {
- var view = this.view;
- var classes = this.getDayClasses(date);
-
- classes.unshift('fc-day', view.widgetContentClass);
-
- return '<td class="' + classes.join(' ') + '"' +
- ' data-date="' + date.format('YYYY-MM-DD') + '"' + // if date has a time, won't format it
- (otherAttrs ?
- ' ' + otherAttrs :
- '') +
- '></td>';
- },
-
-
- /* Generic
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Generates the default HTML intro for any row. User classes should override
- renderIntroHtml: function() {
- },
-
-
- // TODO: a generic method for dealing with <tr>, RTL, intro
- // when increment internalApiVersion
- // wrapTr (scheduler)
-
-
- /* Utils
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Applies the generic "intro" and "outro" HTML to the given cells.
- // Intro means the leftmost cell when the calendar is LTR and the rightmost cell when RTL. Vice-versa for outro.
- bookendCells: function(trEl) {
- var introHtml = this.renderIntroHtml();
-
- if (introHtml) {
- if (this.isRTL) {
- trEl.append(introHtml);
- }
- else {
- trEl.prepend(introHtml);
- }
- }
- }
-
-};
-
-;;
-
-/* A component that renders a grid of whole-days that runs horizontally. There can be multiple rows, one per week.
-----------------------------------------------------------------------------------------------------------------------*/
-
-var DayGrid = FC.DayGrid = Grid.extend(DayTableMixin, {
-
- numbersVisible: false, // should render a row for day/week numbers? set by outside view. TODO: make internal
- bottomCoordPadding: 0, // hack for extending the hit area for the last row of the coordinate grid
-
- rowEls: null, // set of fake row elements
- cellEls: null, // set of whole-day elements comprising the row's background
- helperEls: null, // set of cell skeleton elements for rendering the mock event "helper"
-
- rowCoordCache: null,
- colCoordCache: null,
-
-
- // Renders the rows and columns into the component's `this.el`, which should already be assigned.
- // isRigid determins whether the individual rows should ignore the contents and be a constant height.
- // Relies on the view's colCnt and rowCnt. In the future, this component should probably be self-sufficient.
- renderDates: function(isRigid) {
- var view = this.view;
- var rowCnt = this.rowCnt;
- var colCnt = this.colCnt;
- var html = '';
- var row;
- var col;
-
- for (row = 0; row < rowCnt; row++) {
- html += this.renderDayRowHtml(row, isRigid);
- }
- this.el.html(html);
-
- this.rowEls = this.el.find('.fc-row');
- this.cellEls = this.el.find('.fc-day');
-
- this.rowCoordCache = new CoordCache({
- els: this.rowEls,
- isVertical: true
- });
- this.colCoordCache = new CoordCache({
- els: this.cellEls.slice(0, this.colCnt), // only the first row
- isHorizontal: true
- });
-
- // trigger dayRender with each cell's element
- for (row = 0; row < rowCnt; row++) {
- for (col = 0; col < colCnt; col++) {
- view.trigger(
- 'dayRender',
- null,
- this.getCellDate(row, col),
- this.getCellEl(row, col)
- );
- }
- }
- },
-
-
- unrenderDates: function() {
- this.removeSegPopover();
- },
-
-
- renderBusinessHours: function() {
- var events = this.view.calendar.getBusinessHoursEvents(true); // wholeDay=true
- var segs = this.eventsToSegs(events);
-
- this.renderFill('businessHours', segs, 'bgevent');
- },
-
-
- // Generates the HTML for a single row, which is a div that wraps a table.
- // `row` is the row number.
- renderDayRowHtml: function(row, isRigid) {
- var view = this.view;
- var classes = [ 'fc-row', 'fc-week', view.widgetContentClass ];
-
- if (isRigid) {
- classes.push('fc-rigid');
- }
-
- return '' +
- '<div class="' + classes.join(' ') + '">' +
- '<div class="fc-bg">' +
- '<table>' +
- this.renderBgTrHtml(row) +
- '</table>' +
- '</div>' +
- '<div class="fc-content-skeleton">' +
- '<table>' +
- (this.numbersVisible ?
- '<thead>' +
- this.renderNumberTrHtml(row) +
- '</thead>' :
- ''
- ) +
- '</table>' +
- '</div>' +
- '</div>';
- },
-
-
- /* Grid Number Rendering
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- renderNumberTrHtml: function(row) {
- return '' +
- '<tr>' +
- (this.isRTL ? '' : this.renderNumberIntroHtml(row)) +
- this.renderNumberCellsHtml(row) +
- (this.isRTL ? this.renderNumberIntroHtml(row) : '') +
- '</tr>';
- },
-
-
- renderNumberIntroHtml: function(row) {
- return this.renderIntroHtml();
- },
-
-
- renderNumberCellsHtml: function(row) {
- var htmls = [];
- var col, date;
-
- for (col = 0; col < this.colCnt; col++) {
- date = this.getCellDate(row, col);
- htmls.push(this.renderNumberCellHtml(date));
- }
-
- return htmls.join('');
- },
-
-
- // Generates the HTML for the <td>s of the "number" row in the DayGrid's content skeleton.
- // The number row will only exist if either day numbers or week numbers are turned on.
- renderNumberCellHtml: function(date) {
- var classes;
-
- if (!this.view.dayNumbersVisible) { // if there are week numbers but not day numbers
- return '<td/>'; // will create an empty space above events :(
- }
-
- classes = this.getDayClasses(date);
- classes.unshift('fc-day-number');
-
- return '' +
- '<td class="' + classes.join(' ') + '" data-date="' + date.format() + '">' +
- date.date() +
- '</td>';
- },
-
-
- /* Options
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Computes a default event time formatting string if `timeFormat` is not explicitly defined
- computeEventTimeFormat: function() {
- return this.view.opt('extraSmallTimeFormat'); // like "6p" or "6:30p"
- },
-
-
- // Computes a default `displayEventEnd` value if one is not expliclty defined
- computeDisplayEventEnd: function() {
- return this.colCnt == 1; // we'll likely have space if there's only one day
- },
-
-
- /* Dates
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- rangeUpdated: function() {
- this.updateDayTable();
- },
-
-
- // Slices up the given span (unzoned start/end with other misc data) into an array of segments
- spanToSegs: function(span) {
- var segs = this.sliceRangeByRow(span);
- var i, seg;
-
- for (i = 0; i < segs.length; i++) {
- seg = segs[i];
- if (this.isRTL) {
- seg.leftCol = this.daysPerRow - 1 - seg.lastRowDayIndex;
- seg.rightCol = this.daysPerRow - 1 - seg.firstRowDayIndex;
- }
- else {
- seg.leftCol = seg.firstRowDayIndex;
- seg.rightCol = seg.lastRowDayIndex;
- }
- }
-
- return segs;
- },
-
-
- /* Hit System
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- prepareHits: function() {
- this.colCoordCache.build();
- this.rowCoordCache.build();
- this.rowCoordCache.bottoms[this.rowCnt - 1] += this.bottomCoordPadding; // hack
- },
-
-
- releaseHits: function() {
- this.colCoordCache.clear();
- this.rowCoordCache.clear();
- },
-
-
- queryHit: function(leftOffset, topOffset) {
- var col = this.colCoordCache.getHorizontalIndex(leftOffset);
- var row = this.rowCoordCache.getVerticalIndex(topOffset);
-
- if (row != null && col != null) {
- return this.getCellHit(row, col);
- }
- },
-
-
- getHitSpan: function(hit) {
- return this.getCellRange(hit.row, hit.col);
- },
-
-
- getHitEl: function(hit) {
- return this.getCellEl(hit.row, hit.col);
- },
-
-
- /* Cell System
- ------------------------------------------------------------------------------------------------------------------*/
- // FYI: the first column is the leftmost column, regardless of date
-
-
- getCellHit: function(row, col) {
- return {
- row: row,
- col: col,
- component: this, // needed unfortunately :(
- left: this.colCoordCache.getLeftOffset(col),
- right: this.colCoordCache.getRightOffset(col),
- top: this.rowCoordCache.getTopOffset(row),
- bottom: this.rowCoordCache.getBottomOffset(row)
- };
- },
-
-
- getCellEl: function(row, col) {
- return this.cellEls.eq(row * this.colCnt + col);
- },
-
-
- /* Event Drag Visualization
- ------------------------------------------------------------------------------------------------------------------*/
- // TODO: move to DayGrid.event, similar to what we did with Grid's drag methods
-
-
- // Renders a visual indication of an event or external element being dragged.
- // `eventLocation` has zoned start and end (optional)
- renderDrag: function(eventLocation, seg) {
-
- // always render a highlight underneath
- this.renderHighlight(this.eventToSpan(eventLocation));
-
- // if a segment from the same calendar but another component is being dragged, render a helper event
- if (seg && !seg.el.closest(this.el).length) {
-
- return this.renderEventLocationHelper(eventLocation, seg); // returns mock event elements
- }
- },
-
-
- // Unrenders any visual indication of a hovering event
- unrenderDrag: function() {
- this.unrenderHighlight();
- this.unrenderHelper();
- },
-
-
- /* Event Resize Visualization
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders a visual indication of an event being resized
- renderEventResize: function(eventLocation, seg) {
- this.renderHighlight(this.eventToSpan(eventLocation));
- return this.renderEventLocationHelper(eventLocation, seg); // returns mock event elements
- },
-
-
- // Unrenders a visual indication of an event being resized
- unrenderEventResize: function() {
- this.unrenderHighlight();
- this.unrenderHelper();
- },
-
-
- /* Event Helper
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders a mock "helper" event. `sourceSeg` is the associated internal segment object. It can be null.
- renderHelper: function(event, sourceSeg) {
- var helperNodes = [];
- var segs = this.eventToSegs(event);
- var rowStructs;
-
- segs = this.renderFgSegEls(segs); // assigns each seg's el and returns a subset of segs that were rendered
- rowStructs = this.renderSegRows(segs);
-
- // inject each new event skeleton into each associated row
- this.rowEls.each(function(row, rowNode) {
- var rowEl = $(rowNode); // the .fc-row
- var skeletonEl = $('<div class="fc-helper-skeleton"><table/></div>'); // will be absolutely positioned
- var skeletonTop;
-
- // If there is an original segment, match the top position. Otherwise, put it at the row's top level
- if (sourceSeg && sourceSeg.row === row) {
- skeletonTop = sourceSeg.el.position().top;
- }
- else {
- skeletonTop = rowEl.find('.fc-content-skeleton tbody').position().top;
- }
-
- skeletonEl.css('top', skeletonTop)
- .find('table')
- .append(rowStructs[row].tbodyEl);
-
- rowEl.append(skeletonEl);
- helperNodes.push(skeletonEl[0]);
- });
-
- return ( // must return the elements rendered
- this.helperEls = $(helperNodes) // array -> jQuery set
- );
- },
-
-
- // Unrenders any visual indication of a mock helper event
- unrenderHelper: function() {
- if (this.helperEls) {
- this.helperEls.remove();
- this.helperEls = null;
- }
- },
-
-
- /* Fill System (highlight, background events, business hours)
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- fillSegTag: 'td', // override the default tag name
-
-
- // Renders a set of rectangles over the given segments of days.
- // Only returns segments that successfully rendered.
- renderFill: function(type, segs, className) {
- var nodes = [];
- var i, seg;
- var skeletonEl;
-
- segs = this.renderFillSegEls(type, segs); // assignes `.el` to each seg. returns successfully rendered segs
-
- for (i = 0; i < segs.length; i++) {
- seg = segs[i];
- skeletonEl = this.renderFillRow(type, seg, className);
- this.rowEls.eq(seg.row).append(skeletonEl);
- nodes.push(skeletonEl[0]);
- }
-
- this.elsByFill[type] = $(nodes);
-
- return segs;
- },
-
-
- // Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered.
- renderFillRow: function(type, seg, className) {
- var colCnt = this.colCnt;
- var startCol = seg.leftCol;
- var endCol = seg.rightCol + 1;
- var skeletonEl;
- var trEl;
-
- className = className || type.toLowerCase();
-
- skeletonEl = $(
- '<div class="fc-' + className + '-skeleton">' +
- '<table><tr/></table>' +
- '</div>'
- );
- trEl = skeletonEl.find('tr');
-
- if (startCol > 0) {
- trEl.append('<td colspan="' + startCol + '"/>');
- }
-
- trEl.append(
- seg.el.attr('colspan', endCol - startCol)
- );
-
- if (endCol < colCnt) {
- trEl.append('<td colspan="' + (colCnt - endCol) + '"/>');
- }
-
- this.bookendCells(trEl);
-
- return skeletonEl;
- }
-
-});
-
-;;
-
-/* Event-rendering methods for the DayGrid class
-----------------------------------------------------------------------------------------------------------------------*/
-
-DayGrid.mixin({
-
- rowStructs: null, // an array of objects, each holding information about a row's foreground event-rendering
-
-
- // Unrenders all events currently rendered on the grid
- unrenderEvents: function() {
- this.removeSegPopover(); // removes the "more.." events popover
- Grid.prototype.unrenderEvents.apply(this, arguments); // calls the super-method
- },
-
-
- // Retrieves all rendered segment objects currently rendered on the grid
- getEventSegs: function() {
- return Grid.prototype.getEventSegs.call(this) // get the segments from the super-method
- .concat(this.popoverSegs || []); // append the segments from the "more..." popover
- },
-
-
- // Renders the given background event segments onto the grid
- renderBgSegs: function(segs) {
-
- // don't render timed background events
- var allDaySegs = $.grep(segs, function(seg) {
- return seg.event.allDay;
- });
-
- return Grid.prototype.renderBgSegs.call(this, allDaySegs); // call the super-method
- },
-
-
- // Renders the given foreground event segments onto the grid
- renderFgSegs: function(segs) {
- var rowStructs;
-
- // render an `.el` on each seg
- // returns a subset of the segs. segs that were actually rendered
- segs = this.renderFgSegEls(segs);
-
- rowStructs = this.rowStructs = this.renderSegRows(segs);
-
- // append to each row's content skeleton
- this.rowEls.each(function(i, rowNode) {
- $(rowNode).find('.fc-content-skeleton > table').append(
- rowStructs[i].tbodyEl
- );
- });
-
- return segs; // return only the segs that were actually rendered
- },
-
-
- // Unrenders all currently rendered foreground event segments
- unrenderFgSegs: function() {
- var rowStructs = this.rowStructs || [];
- var rowStruct;
-
- while ((rowStruct = rowStructs.pop())) {
- rowStruct.tbodyEl.remove();
- }
-
- this.rowStructs = null;
- },
-
-
- // Uses the given events array to generate <tbody> elements that should be appended to each row's content skeleton.
- // Returns an array of rowStruct objects (see the bottom of `renderSegRow`).
- // PRECONDITION: each segment shoud already have a rendered and assigned `.el`
- renderSegRows: function(segs) {
- var rowStructs = [];
- var segRows;
- var row;
-
- segRows = this.groupSegRows(segs); // group into nested arrays
-
- // iterate each row of segment groupings
- for (row = 0; row < segRows.length; row++) {
- rowStructs.push(
- this.renderSegRow(row, segRows[row])
- );
- }
-
- return rowStructs;
- },
-
-
- // Builds the HTML to be used for the default element for an individual segment
- fgSegHtml: function(seg, disableResizing) {
- var view = this.view;
- var event = seg.event;
- var isDraggable = view.isEventDraggable(event);
- var isResizableFromStart = !disableResizing && event.allDay &&
- seg.isStart && view.isEventResizableFromStart(event);
- var isResizableFromEnd = !disableResizing && event.allDay &&
- seg.isEnd && view.isEventResizableFromEnd(event);
- var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd);
- var skinCss = cssToStr(this.getSegSkinCss(seg));
- var timeHtml = '';
- var timeText;
- var titleHtml;
-
- classes.unshift('fc-day-grid-event', 'fc-h-event');
-
- // Only display a timed events time if it is the starting segment
- if (seg.isStart) {
- timeText = this.getEventTimeText(event);
- if (timeText) {
- timeHtml = '<span class="fc-time">' + htmlEscape(timeText) + '</span>';
- }
- }
-
- titleHtml =
- '<span class="fc-title">' +
- (htmlEscape(event.title || '') || '&nbsp;') + // we always want one line of height
- '</span>';
-
- return '<a class="' + classes.join(' ') + '"' +
- (event.url ?
- ' href="' + htmlEscape(event.url) + '"' :
- ''
- ) +
- (skinCss ?
- ' style="' + skinCss + '"' :
- ''
- ) +
- '>' +
- '<div class="fc-content">' +
- (this.isRTL ?
- titleHtml + ' ' + timeHtml : // put a natural space in between
- timeHtml + ' ' + titleHtml //
- ) +
- '</div>' +
- (isResizableFromStart ?
- '<div class="fc-resizer fc-start-resizer" />' :
- ''
- ) +
- (isResizableFromEnd ?
- '<div class="fc-resizer fc-end-resizer" />' :
- ''
- ) +
- '</a>';
- },
-
-
- // Given a row # and an array of segments all in the same row, render a <tbody> element, a skeleton that contains
- // the segments. Returns object with a bunch of internal data about how the render was calculated.
- // NOTE: modifies rowSegs
- renderSegRow: function(row, rowSegs) {
- var colCnt = this.colCnt;
- var segLevels = this.buildSegLevels(rowSegs); // group into sub-arrays of levels
- var levelCnt = Math.max(1, segLevels.length); // ensure at least one level
- var tbody = $('<tbody/>');
- var segMatrix = []; // lookup for which segments are rendered into which level+col cells
- var cellMatrix = []; // lookup for all <td> elements of the level+col matrix
- var loneCellMatrix = []; // lookup for <td> elements that only take up a single column
- var i, levelSegs;
- var col;
- var tr;
- var j, seg;
- var td;
-
- // populates empty cells from the current column (`col`) to `endCol`
- function emptyCellsUntil(endCol) {
- while (col < endCol) {
- // try to grab a cell from the level above and extend its rowspan. otherwise, create a fresh cell
- td = (loneCellMatrix[i - 1] || [])[col];
- if (td) {
- td.attr(
- 'rowspan',
- parseInt(td.attr('rowspan') || 1, 10) + 1
- );
- }
- else {
- td = $('<td/>');
- tr.append(td);
- }
- cellMatrix[i][col] = td;
- loneCellMatrix[i][col] = td;
- col++;
- }
- }
-
- for (i = 0; i < levelCnt; i++) { // iterate through all levels
- levelSegs = segLevels[i];
- col = 0;
- tr = $('<tr/>');
-
- segMatrix.push([]);
- cellMatrix.push([]);
- loneCellMatrix.push([]);
-
- // levelCnt might be 1 even though there are no actual levels. protect against this.
- // this single empty row is useful for styling.
- if (levelSegs) {
- for (j = 0; j < levelSegs.length; j++) { // iterate through segments in level
- seg = levelSegs[j];
-
- emptyCellsUntil(seg.leftCol);
-
- // create a container that occupies or more columns. append the event element.
- td = $('<td class="fc-event-container"/>').append(seg.el);
- if (seg.leftCol != seg.rightCol) {
- td.attr('colspan', seg.rightCol - seg.leftCol + 1);
- }
- else { // a single-column segment
- loneCellMatrix[i][col] = td;
- }
-
- while (col <= seg.rightCol) {
- cellMatrix[i][col] = td;
- segMatrix[i][col] = seg;
- col++;
- }
-
- tr.append(td);
- }
- }
-
- emptyCellsUntil(colCnt); // finish off the row
- this.bookendCells(tr);
- tbody.append(tr);
- }
-
- return { // a "rowStruct"
- row: row, // the row number
- tbodyEl: tbody,
- cellMatrix: cellMatrix,
- segMatrix: segMatrix,
- segLevels: segLevels,
- segs: rowSegs
- };
- },
-
-
- // Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels.
- // NOTE: modifies segs
- buildSegLevels: function(segs) {
- var levels = [];
- var i, seg;
- var j;
-
- // Give preference to elements with certain criteria, so they have
- // a chance to be closer to the top.
- this.sortEventSegs(segs);
-
- for (i = 0; i < segs.length; i++) {
- seg = segs[i];
-
- // loop through levels, starting with the topmost, until the segment doesn't collide with other segments
- for (j = 0; j < levels.length; j++) {
- if (!isDaySegCollision(seg, levels[j])) {
- break;
- }
- }
- // `j` now holds the desired subrow index
- seg.level = j;
-
- // create new level array if needed and append segment
- (levels[j] || (levels[j] = [])).push(seg);
- }
-
- // order segments left-to-right. very important if calendar is RTL
- for (j = 0; j < levels.length; j++) {
- levels[j].sort(compareDaySegCols);
- }
-
- return levels;
- },
-
-
- // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row
- groupSegRows: function(segs) {
- var segRows = [];
- var i;
-
- for (i = 0; i < this.rowCnt; i++) {
- segRows.push([]);
- }
-
- for (i = 0; i < segs.length; i++) {
- segRows[segs[i].row].push(segs[i]);
- }
-
- return segRows;
- }
-
-});
-
-
-// Computes whether two segments' columns collide. They are assumed to be in the same row.
-function isDaySegCollision(seg, otherSegs) {
- var i, otherSeg;
-
- for (i = 0; i < otherSegs.length; i++) {
- otherSeg = otherSegs[i];
-
- if (
- otherSeg.leftCol <= seg.rightCol &&
- otherSeg.rightCol >= seg.leftCol
- ) {
- return true;
- }
- }
-
- return false;
-}
-
-
-// A cmp function for determining the leftmost event
-function compareDaySegCols(a, b) {
- return a.leftCol - b.leftCol;
-}
-
-;;
-
-/* Methods relate to limiting the number events for a given day on a DayGrid
-----------------------------------------------------------------------------------------------------------------------*/
-// NOTE: all the segs being passed around in here are foreground segs
-
-DayGrid.mixin({
-
- segPopover: null, // the Popover that holds events that can't fit in a cell. null when not visible
- popoverSegs: null, // an array of segment objects that the segPopover holds. null when not visible
-
-
- removeSegPopover: function() {
- if (this.segPopover) {
- this.segPopover.hide(); // in handler, will call segPopover's removeElement
- }
- },
-
-
- // Limits the number of "levels" (vertically stacking layers of events) for each row of the grid.
- // `levelLimit` can be false (don't limit), a number, or true (should be computed).
- limitRows: function(levelLimit) {
- var rowStructs = this.rowStructs || [];
- var row; // row #
- var rowLevelLimit;
-
- for (row = 0; row < rowStructs.length; row++) {
- this.unlimitRow(row);
-
- if (!levelLimit) {
- rowLevelLimit = false;
- }
- else if (typeof levelLimit === 'number') {
- rowLevelLimit = levelLimit;
- }
- else {
- rowLevelLimit = this.computeRowLevelLimit(row);
- }
-
- if (rowLevelLimit !== false) {
- this.limitRow(row, rowLevelLimit);
- }
- }
- },
-
-
- // Computes the number of levels a row will accomodate without going outside its bounds.
- // Assumes the row is "rigid" (maintains a constant height regardless of what is inside).
- // `row` is the row number.
- computeRowLevelLimit: function(row) {
- var rowEl = this.rowEls.eq(row); // the containing "fake" row div
- var rowHeight = rowEl.height(); // TODO: cache somehow?
- var trEls = this.rowStructs[row].tbodyEl.children();
- var i, trEl;
- var trHeight;
-
- function iterInnerHeights(i, childNode) {
- trHeight = Math.max(trHeight, $(childNode).outerHeight());
- }
-
- // Reveal one level <tr> at a time and stop when we find one out of bounds
- for (i = 0; i < trEls.length; i++) {
- trEl = trEls.eq(i).removeClass('fc-limited'); // reset to original state (reveal)
-
- // with rowspans>1 and IE8, trEl.outerHeight() would return the height of the largest cell,
- // so instead, find the tallest inner content element.
- trHeight = 0;
- trEl.find('> td > :first-child').each(iterInnerHeights);
-
- if (trEl.position().top + trHeight > rowHeight) {
- return i;
- }
- }
-
- return false; // should not limit at all
- },
-
-
- // Limits the given grid row to the maximum number of levels and injects "more" links if necessary.
- // `row` is the row number.
- // `levelLimit` is a number for the maximum (inclusive) number of levels allowed.
- limitRow: function(row, levelLimit) {
- var _this = this;
- var rowStruct = this.rowStructs[row];
- var moreNodes = []; // array of "more" <a> links and <td> DOM nodes
- var col = 0; // col #, left-to-right (not chronologically)
- var levelSegs; // array of segment objects in the last allowable level, ordered left-to-right
- var cellMatrix; // a matrix (by level, then column) of all <td> jQuery elements in the row
- var limitedNodes; // array of temporarily hidden level <tr> and segment <td> DOM nodes
- var i, seg;
- var segsBelow; // array of segment objects below `seg` in the current `col`
- var totalSegsBelow; // total number of segments below `seg` in any of the columns `seg` occupies
- var colSegsBelow; // array of segment arrays, below seg, one for each column (offset from segs's first column)
- var td, rowspan;
- var segMoreNodes; // array of "more" <td> cells that will stand-in for the current seg's cell
- var j;
- var moreTd, moreWrap, moreLink;
-
- // Iterates through empty level cells and places "more" links inside if need be
- function emptyCellsUntil(endCol) { // goes from current `col` to `endCol`
- while (col < endCol) {
- segsBelow = _this.getCellSegs(row, col, levelLimit);
- if (segsBelow.length) {
- td = cellMatrix[levelLimit - 1][col];
- moreLink = _this.renderMoreLink(row, col, segsBelow);
- moreWrap = $('<div/>').append(moreLink);
- td.append(moreWrap);
- moreNodes.push(moreWrap[0]);
- }
- col++;
- }
- }
-
- if (levelLimit && levelLimit < rowStruct.segLevels.length) { // is it actually over the limit?
- levelSegs = rowStruct.segLevels[levelLimit - 1];
- cellMatrix = rowStruct.cellMatrix;
-
- limitedNodes = rowStruct.tbodyEl.children().slice(levelLimit) // get level <tr> elements past the limit
- .addClass('fc-limited').get(); // hide elements and get a simple DOM-nodes array
-
- // iterate though segments in the last allowable level
- for (i = 0; i < levelSegs.length; i++) {
- seg = levelSegs[i];
- emptyCellsUntil(seg.leftCol); // process empty cells before the segment
-
- // determine *all* segments below `seg` that occupy the same columns
- colSegsBelow = [];
- totalSegsBelow = 0;
- while (col <= seg.rightCol) {
- segsBelow = this.getCellSegs(row, col, levelLimit);
- colSegsBelow.push(segsBelow);
- totalSegsBelow += segsBelow.length;
- col++;
- }
-
- if (totalSegsBelow) { // do we need to replace this segment with one or many "more" links?
- td = cellMatrix[levelLimit - 1][seg.leftCol]; // the segment's parent cell
- rowspan = td.attr('rowspan') || 1;
- segMoreNodes = [];
-
- // make a replacement <td> for each column the segment occupies. will be one for each colspan
- for (j = 0; j < colSegsBelow.length; j++) {
- moreTd = $('<td class="fc-more-cell"/>').attr('rowspan', rowspan);
- segsBelow = colSegsBelow[j];
- moreLink = this.renderMoreLink(
- row,
- seg.leftCol + j,
- [ seg ].concat(segsBelow) // count seg as hidden too
- );
- moreWrap = $('<div/>').append(moreLink);
- moreTd.append(moreWrap);
- segMoreNodes.push(moreTd[0]);
- moreNodes.push(moreTd[0]);
- }
-
- td.addClass('fc-limited').after($(segMoreNodes)); // hide original <td> and inject replacements
- limitedNodes.push(td[0]);
- }
- }
-
- emptyCellsUntil(this.colCnt); // finish off the level
- rowStruct.moreEls = $(moreNodes); // for easy undoing later
- rowStruct.limitedEls = $(limitedNodes); // for easy undoing later
- }
- },
-
-
- // Reveals all levels and removes all "more"-related elements for a grid's row.
- // `row` is a row number.
- unlimitRow: function(row) {
- var rowStruct = this.rowStructs[row];
-
- if (rowStruct.moreEls) {
- rowStruct.moreEls.remove();
- rowStruct.moreEls = null;
- }
-
- if (rowStruct.limitedEls) {
- rowStruct.limitedEls.removeClass('fc-limited');
- rowStruct.limitedEls = null;
- }
- },
-
-
- // Renders an <a> element that represents hidden event element for a cell.
- // Responsible for attaching click handler as well.
- renderMoreLink: function(row, col, hiddenSegs) {
- var _this = this;
- var view = this.view;
-
- return $('<a class="fc-more"/>')
- .text(
- this.getMoreLinkText(hiddenSegs.length)
- )
- .on('click', function(ev) {
- var clickOption = view.opt('eventLimitClick');
- var date = _this.getCellDate(row, col);
- var moreEl = $(this);
- var dayEl = _this.getCellEl(row, col);
- var allSegs = _this.getCellSegs(row, col);
-
- // rescope the segments to be within the cell's date
- var reslicedAllSegs = _this.resliceDaySegs(allSegs, date);
- var reslicedHiddenSegs = _this.resliceDaySegs(hiddenSegs, date);
-
- if (typeof clickOption === 'function') {
- // the returned value can be an atomic option
- clickOption = view.trigger('eventLimitClick', null, {
- date: date,
- dayEl: dayEl,
- moreEl: moreEl,
- segs: reslicedAllSegs,
- hiddenSegs: reslicedHiddenSegs
- }, ev);
- }
-
- if (clickOption === 'popover') {
- _this.showSegPopover(row, col, moreEl, reslicedAllSegs);
- }
- else if (typeof clickOption === 'string') { // a view name
- view.calendar.zoomTo(date, clickOption);
- }
- });
- },
-
-
- // Reveals the popover that displays all events within a cell
- showSegPopover: function(row, col, moreLink, segs) {
- var _this = this;
- var view = this.view;
- var moreWrap = moreLink.parent(); // the <div> wrapper around the <a>
- var topEl; // the element we want to match the top coordinate of
- var options;
-
- if (this.rowCnt == 1) {
- topEl = view.el; // will cause the popover to cover any sort of header
- }
- else {
- topEl = this.rowEls.eq(row); // will align with top of row
- }
-
- options = {
- className: 'fc-more-popover',
- content: this.renderSegPopoverContent(row, col, segs),
- parentEl: this.el,
- top: topEl.offset().top,
- autoHide: true, // when the user clicks elsewhere, hide the popover
- viewportConstrain: view.opt('popoverViewportConstrain'),
- hide: function() {
- // kill everything when the popover is hidden
- _this.segPopover.removeElement();
- _this.segPopover = null;
- _this.popoverSegs = null;
- }
- };
-
- // Determine horizontal coordinate.
- // We use the moreWrap instead of the <td> to avoid border confusion.
- if (this.isRTL) {
- options.right = moreWrap.offset().left + moreWrap.outerWidth() + 1; // +1 to be over cell border
- }
- else {
- options.left = moreWrap.offset().left - 1; // -1 to be over cell border
- }
-
- this.segPopover = new Popover(options);
- this.segPopover.show();
- },
-
-
- // Builds the inner DOM contents of the segment popover
- renderSegPopoverContent: function(row, col, segs) {
- var view = this.view;
- var isTheme = view.opt('theme');
- var title = this.getCellDate(row, col).format(view.opt('dayPopoverFormat'));
- var content = $(
- '<div class="fc-header ' + view.widgetHeaderClass + '">' +
- '<span class="fc-close ' +
- (isTheme ? 'ui-icon ui-icon-closethick' : 'fc-icon fc-icon-x') +
- '"></span>' +
- '<span class="fc-title">' +
- htmlEscape(title) +
- '</span>' +
- '<div class="fc-clear"/>' +
- '</div>' +
- '<div class="fc-body ' + view.widgetContentClass + '">' +
- '<div class="fc-event-container"></div>' +
- '</div>'
- );
- var segContainer = content.find('.fc-event-container');
- var i;
-
- // render each seg's `el` and only return the visible segs
- segs = this.renderFgSegEls(segs, true); // disableResizing=true
- this.popoverSegs = segs;
-
- for (i = 0; i < segs.length; i++) {
-
- // because segments in the popover are not part of a grid coordinate system, provide a hint to any
- // grids that want to do drag-n-drop about which cell it came from
- this.prepareHits();
- segs[i].hit = this.getCellHit(row, col);
- this.releaseHits();
-
- segContainer.append(segs[i].el);
- }
-
- return content;
- },
-
-
- // Given the events within an array of segment objects, reslice them to be in a single day
- resliceDaySegs: function(segs, dayDate) {
-
- // build an array of the original events
- var events = $.map(segs, function(seg) {
- return seg.event;
- });
-
- var dayStart = dayDate.clone();
- var dayEnd = dayStart.clone().add(1, 'days');
- var dayRange = { start: dayStart, end: dayEnd };
-
- // slice the events with a custom slicing function
- segs = this.eventsToSegs(
- events,
- function(range) {
- var seg = intersectRanges(range, dayRange); // undefind if no intersection
- return seg ? [ seg ] : []; // must return an array of segments
- }
- );
-
- // force an order because eventsToSegs doesn't guarantee one
- this.sortEventSegs(segs);
-
- return segs;
- },
-
-
- // Generates the text that should be inside a "more" link, given the number of events it represents
- getMoreLinkText: function(num) {
- var opt = this.view.opt('eventLimitText');
-
- if (typeof opt === 'function') {
- return opt(num);
- }
- else {
- return '+' + num + ' ' + opt;
- }
- },
-
-
- // Returns segments within a given cell.
- // If `startLevel` is specified, returns only events including and below that level. Otherwise returns all segs.
- getCellSegs: function(row, col, startLevel) {
- var segMatrix = this.rowStructs[row].segMatrix;
- var level = startLevel || 0;
- var segs = [];
- var seg;
-
- while (level < segMatrix.length) {
- seg = segMatrix[level][col];
- if (seg) {
- segs.push(seg);
- }
- level++;
- }
-
- return segs;
- }
-
-});
-
-;;
-
-/* A component that renders one or more columns of vertical time slots
-----------------------------------------------------------------------------------------------------------------------*/
-// We mixin DayTable, even though there is only a single row of days
-
-var TimeGrid = FC.TimeGrid = Grid.extend(DayTableMixin, {
-
- slotDuration: null, // duration of a "slot", a distinct time segment on given day, visualized by lines
- snapDuration: null, // granularity of time for dragging and selecting
- snapsPerSlot: null,
- minTime: null, // Duration object that denotes the first visible time of any given day
- maxTime: null, // Duration object that denotes the exclusive visible end time of any given day
- labelFormat: null, // formatting string for times running along vertical axis
- labelInterval: null, // duration of how often a label should be displayed for a slot
-
- colEls: null, // cells elements in the day-row background
- slatContainerEl: null, // div that wraps all the slat rows
- slatEls: null, // elements running horizontally across all columns
- nowIndicatorEls: null,
-
- colCoordCache: null,
- slatCoordCache: null,
-
-
- constructor: function() {
- Grid.apply(this, arguments); // call the super-constructor
-
- this.processOptions();
- },
-
-
- // Renders the time grid into `this.el`, which should already be assigned.
- // Relies on the view's colCnt. In the future, this component should probably be self-sufficient.
- renderDates: function() {
- this.el.html(this.renderHtml());
- this.colEls = this.el.find('.fc-day');
- this.slatContainerEl = this.el.find('.fc-slats');
- this.slatEls = this.slatContainerEl.find('tr');
-
- this.colCoordCache = new CoordCache({
- els: this.colEls,
- isHorizontal: true
- });
- this.slatCoordCache = new CoordCache({
- els: this.slatEls,
- isVertical: true
- });
-
- this.renderContentSkeleton();
- },
-
-
- // Renders the basic HTML skeleton for the grid
- renderHtml: function() {
- return '' +
- '<div class="fc-bg">' +
- '<table>' +
- this.renderBgTrHtml(0) + // row=0
- '</table>' +
- '</div>' +
- '<div class="fc-slats">' +
- '<table>' +
- this.renderSlatRowHtml() +
- '</table>' +
- '</div>';
- },
-
-
- // Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
- renderSlatRowHtml: function() {
- var view = this.view;
- var isRTL = this.isRTL;
- var html = '';
- var slotTime = moment.duration(+this.minTime); // wish there was .clone() for durations
- var slotDate; // will be on the view's first day, but we only care about its time
- var isLabeled;
- var axisHtml;
-
- // Calculate the time for each slot
- while (slotTime < this.maxTime) {
- slotDate = this.start.clone().time(slotTime);
- isLabeled = isInt(divideDurationByDuration(slotTime, this.labelInterval));
-
- axisHtml =
- '<td class="fc-axis fc-time ' + view.widgetContentClass + '" ' + view.axisStyleAttr() + '>' +
- (isLabeled ?
- '<span>' + // for matchCellWidths
- htmlEscape(slotDate.format(this.labelFormat)) +
- '</span>' :
- ''
- ) +
- '</td>';
-
- html +=
- '<tr data-time="' + slotDate.format('HH:mm:ss') + '"' +
- (isLabeled ? '' : ' class="fc-minor"') +
- '>' +
- (!isRTL ? axisHtml : '') +
- '<td class="' + view.widgetContentClass + '"/>' +
- (isRTL ? axisHtml : '') +
- "</tr>";
-
- slotTime.add(this.slotDuration);
- }
-
- return html;
- },
-
-
- /* Options
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Parses various options into properties of this object
- processOptions: function() {
- var view = this.view;
- var slotDuration = view.opt('slotDuration');
- var snapDuration = view.opt('snapDuration');
- var input;
-
- slotDuration = moment.duration(slotDuration);
- snapDuration = snapDuration ? moment.duration(snapDuration) : slotDuration;
-
- this.slotDuration = slotDuration;
- this.snapDuration = snapDuration;
- this.snapsPerSlot = slotDuration / snapDuration; // TODO: ensure an integer multiple?
-
- this.minResizeDuration = snapDuration; // hack
-
- this.minTime = moment.duration(view.opt('minTime'));
- this.maxTime = moment.duration(view.opt('maxTime'));
-
- // might be an array value (for TimelineView).
- // if so, getting the most granular entry (the last one probably).
- input = view.opt('slotLabelFormat');
- if ($.isArray(input)) {
- input = input[input.length - 1];
- }
-
- this.labelFormat =
- input ||
- view.opt('axisFormat') || // deprecated
- view.opt('smallTimeFormat'); // the computed default
-
- input = view.opt('slotLabelInterval');
- this.labelInterval = input ?
- moment.duration(input) :
- this.computeLabelInterval(slotDuration);
- },
-
-
- // Computes an automatic value for slotLabelInterval
- computeLabelInterval: function(slotDuration) {
- var i;
- var labelInterval;
- var slotsPerLabel;
-
- // find the smallest stock label interval that results in more than one slots-per-label
- for (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) {
- labelInterval = moment.duration(AGENDA_STOCK_SUB_DURATIONS[i]);
- slotsPerLabel = divideDurationByDuration(labelInterval, slotDuration);
- if (isInt(slotsPerLabel) && slotsPerLabel > 1) {
- return labelInterval;
- }
- }
-
- return moment.duration(slotDuration); // fall back. clone
- },
-
-
- // Computes a default event time formatting string if `timeFormat` is not explicitly defined
- computeEventTimeFormat: function() {
- return this.view.opt('noMeridiemTimeFormat'); // like "6:30" (no AM/PM)
- },
-
-
- // Computes a default `displayEventEnd` value if one is not expliclty defined
- computeDisplayEventEnd: function() {
- return true;
- },
-
-
- /* Hit System
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- prepareHits: function() {
- this.colCoordCache.build();
- this.slatCoordCache.build();
- },
-
-
- releaseHits: function() {
- this.colCoordCache.clear();
- // NOTE: don't clear slatCoordCache because we rely on it for computeTimeTop
- },
-
-
- queryHit: function(leftOffset, topOffset) {
- var snapsPerSlot = this.snapsPerSlot;
- var colCoordCache = this.colCoordCache;
- var slatCoordCache = this.slatCoordCache;
- var colIndex = colCoordCache.getHorizontalIndex(leftOffset);
- var slatIndex = slatCoordCache.getVerticalIndex(topOffset);
-
- if (colIndex != null && slatIndex != null) {
- var slatTop = slatCoordCache.getTopOffset(slatIndex);
- var slatHeight = slatCoordCache.getHeight(slatIndex);
- var partial = (topOffset - slatTop) / slatHeight; // floating point number between 0 and 1
- var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
- var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
- var snapTop = slatTop + (localSnapIndex / snapsPerSlot) * slatHeight;
- var snapBottom = slatTop + ((localSnapIndex + 1) / snapsPerSlot) * slatHeight;
-
- return {
- col: colIndex,
- snap: snapIndex,
- component: this, // needed unfortunately :(
- left: colCoordCache.getLeftOffset(colIndex),
- right: colCoordCache.getRightOffset(colIndex),
- top: snapTop,
- bottom: snapBottom
- };
- }
- },
-
-
- getHitSpan: function(hit) {
- var start = this.getCellDate(0, hit.col); // row=0
- var time = this.computeSnapTime(hit.snap); // pass in the snap-index
- var end;
-
- start.time(time);
- end = start.clone().add(this.snapDuration);
-
- return { start: start, end: end };
- },
-
-
- getHitEl: function(hit) {
- return this.colEls.eq(hit.col);
- },
-
-
- /* Dates
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- rangeUpdated: function() {
- this.updateDayTable();
- },
-
-
- // Given a row number of the grid, representing a "snap", returns a time (Duration) from its start-of-day
- computeSnapTime: function(snapIndex) {
- return moment.duration(this.minTime + this.snapDuration * snapIndex);
- },
-
-
- // Slices up the given span (unzoned start/end with other misc data) into an array of segments
- spanToSegs: function(span) {
- var segs = this.sliceRangeByTimes(span);
- var i;
-
- for (i = 0; i < segs.length; i++) {
- if (this.isRTL) {
- segs[i].col = this.daysPerRow - 1 - segs[i].dayIndex;
- }
- else {
- segs[i].col = segs[i].dayIndex;
- }
- }
-
- return segs;
- },
-
-
- sliceRangeByTimes: function(range) {
- var segs = [];
- var seg;
- var dayIndex;
- var dayDate;
- var dayRange;
-
- for (dayIndex = 0; dayIndex < this.daysPerRow; dayIndex++) {
- dayDate = this.dayDates[dayIndex].clone(); // TODO: better API for this?
- dayRange = {
- start: dayDate.clone().time(this.minTime),
- end: dayDate.clone().time(this.maxTime)
- };
- seg = intersectRanges(range, dayRange); // both will be ambig timezone
- if (seg) {
- seg.dayIndex = dayIndex;
- segs.push(seg);
- }
- }
-
- return segs;
- },
-
-
- /* Coordinates
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- updateSize: function(isResize) { // NOT a standard Grid method
- this.slatCoordCache.build();
-
- if (isResize) {
- this.updateSegVerticals(
- [].concat(this.fgSegs || [], this.bgSegs || [], this.businessSegs || [])
- );
- }
- },
-
-
- getTotalSlatHeight: function() {
- return this.slatContainerEl.outerHeight();
- },
-
-
- // Computes the top coordinate, relative to the bounds of the grid, of the given date.
- // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.
- computeDateTop: function(date, startOfDayDate) {
- return this.computeTimeTop(
- moment.duration(
- date - startOfDayDate.clone().stripTime()
- )
- );
- },
-
-
- // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
- computeTimeTop: function(time) {
- var len = this.slatEls.length;
- var slatCoverage = (time - this.minTime) / this.slotDuration; // floating-point value of # of slots covered
- var slatIndex;
- var slatRemainder;
-
- // compute a floating-point number for how many slats should be progressed through.
- // from 0 to number of slats (inclusive)
- // constrained because minTime/maxTime might be customized.
- slatCoverage = Math.max(0, slatCoverage);
- slatCoverage = Math.min(len, slatCoverage);
-
- // an integer index of the furthest whole slat
- // from 0 to number slats (*exclusive*, so len-1)
- slatIndex = Math.floor(slatCoverage);
- slatIndex = Math.min(slatIndex, len - 1);
-
- // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
- // could be 1.0 if slatCoverage is covering *all* the slots
- slatRemainder = slatCoverage - slatIndex;
-
- return this.slatCoordCache.getTopPosition(slatIndex) +
- this.slatCoordCache.getHeight(slatIndex) * slatRemainder;
- },
-
-
-
- /* Event Drag Visualization
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders a visual indication of an event being dragged over the specified date(s).
- // A returned value of `true` signals that a mock "helper" event has been rendered.
- renderDrag: function(eventLocation, seg) {
-
- if (seg) { // if there is event information for this drag, render a helper event
-
- // returns mock event elements
- // signal that a helper has been rendered
- return this.renderEventLocationHelper(eventLocation, seg);
- }
- else {
- // otherwise, just render a highlight
- this.renderHighlight(this.eventToSpan(eventLocation));
- }
- },
-
-
- // Unrenders any visual indication of an event being dragged
- unrenderDrag: function() {
- this.unrenderHelper();
- this.unrenderHighlight();
- },
-
-
- /* Event Resize Visualization
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders a visual indication of an event being resized
- renderEventResize: function(eventLocation, seg) {
- return this.renderEventLocationHelper(eventLocation, seg); // returns mock event elements
- },
-
-
- // Unrenders any visual indication of an event being resized
- unrenderEventResize: function() {
- this.unrenderHelper();
- },
-
-
- /* Event Helper
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders a mock "helper" event. `sourceSeg` is the original segment object and might be null (an external drag)
- renderHelper: function(event, sourceSeg) {
- return this.renderHelperSegs(this.eventToSegs(event), sourceSeg); // returns mock event elements
- },
-
-
- // Unrenders any mock helper event
- unrenderHelper: function() {
- this.unrenderHelperSegs();
- },
-
-
- /* Business Hours
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- renderBusinessHours: function() {
- var events = this.view.calendar.getBusinessHoursEvents();
- var segs = this.eventsToSegs(events);
-
- this.renderBusinessSegs(segs);
- },
-
-
- unrenderBusinessHours: function() {
- this.unrenderBusinessSegs();
- },
-
-
- /* Now Indicator
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- getNowIndicatorUnit: function() {
- return 'minute'; // will refresh on the minute
- },
-
-
- renderNowIndicator: function(date) {
- // seg system might be overkill, but it handles scenario where line needs to be rendered
- // more than once because of columns with the same date (resources columns for example)
- var segs = this.spanToSegs({ start: date, end: date });
- var top = this.computeDateTop(date, date);
- var nodes = [];
- var i;
-
- // render lines within the columns
- for (i = 0; i < segs.length; i++) {
- nodes.push($('<div class="fc-now-indicator fc-now-indicator-line"></div>')
- .css('top', top)
- .appendTo(this.colContainerEls.eq(segs[i].col))[0]);
- }
-
- // render an arrow over the axis
- if (segs.length > 0) { // is the current time in view?
- nodes.push($('<div class="fc-now-indicator fc-now-indicator-arrow"></div>')
- .css('top', top)
- .appendTo(this.el.find('.fc-content-skeleton'))[0]);
- }
-
- this.nowIndicatorEls = $(nodes);
- },
-
-
- unrenderNowIndicator: function() {
- if (this.nowIndicatorEls) {
- this.nowIndicatorEls.remove();
- this.nowIndicatorEls = null;
- }
- },
-
-
- /* Selection
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight.
- renderSelection: function(span) {
- if (this.view.opt('selectHelper')) { // this setting signals that a mock helper event should be rendered
-
- // normally acceps an eventLocation, span has a start/end, which is good enough
- this.renderEventLocationHelper(span);
- }
- else {
- this.renderHighlight(span);
- }
- },
-
-
- // Unrenders any visual indication of a selection
- unrenderSelection: function() {
- this.unrenderHelper();
- this.unrenderHighlight();
- },
-
-
- /* Highlight
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- renderHighlight: function(span) {
- this.renderHighlightSegs(this.spanToSegs(span));
- },
-
-
- unrenderHighlight: function() {
- this.unrenderHighlightSegs();
- }
-
-});
-
-;;
-
-/* Methods for rendering SEGMENTS, pieces of content that live on the view
- ( this file is no longer just for events )
-----------------------------------------------------------------------------------------------------------------------*/
-
-TimeGrid.mixin({
-
- colContainerEls: null, // containers for each column
-
- // inner-containers for each column where different types of segs live
- fgContainerEls: null,
- bgContainerEls: null,
- helperContainerEls: null,
- highlightContainerEls: null,
- businessContainerEls: null,
-
- // arrays of different types of displayed segments
- fgSegs: null,
- bgSegs: null,
- helperSegs: null,
- highlightSegs: null,
- businessSegs: null,
-
-
- // Renders the DOM that the view's content will live in
- renderContentSkeleton: function() {
- var cellHtml = '';
- var i;
- var skeletonEl;
-
- for (i = 0; i < this.colCnt; i++) {
- cellHtml +=
- '<td>' +
- '<div class="fc-content-col">' +
- '<div class="fc-event-container fc-helper-container"></div>' +
- '<div class="fc-event-container"></div>' +
- '<div class="fc-highlight-container"></div>' +
- '<div class="fc-bgevent-container"></div>' +
- '<div class="fc-business-container"></div>' +
- '</div>' +
- '</td>';
- }
-
- skeletonEl = $(
- '<div class="fc-content-skeleton">' +
- '<table>' +
- '<tr>' + cellHtml + '</tr>' +
- '</table>' +
- '</div>'
- );
-
- this.colContainerEls = skeletonEl.find('.fc-content-col');
- this.helperContainerEls = skeletonEl.find('.fc-helper-container');
- this.fgContainerEls = skeletonEl.find('.fc-event-container:not(.fc-helper-container)');
- this.bgContainerEls = skeletonEl.find('.fc-bgevent-container');
- this.highlightContainerEls = skeletonEl.find('.fc-highlight-container');
- this.businessContainerEls = skeletonEl.find('.fc-business-container');
-
- this.bookendCells(skeletonEl.find('tr')); // TODO: do this on string level
- this.el.append(skeletonEl);
- },
-
-
- /* Foreground Events
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- renderFgSegs: function(segs) {
- segs = this.renderFgSegsIntoContainers(segs, this.fgContainerEls);
- this.fgSegs = segs;
- return segs; // needed for Grid::renderEvents
- },
-
-
- unrenderFgSegs: function() {
- this.unrenderNamedSegs('fgSegs');
- },
-
-
- /* Foreground Helper Events
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- renderHelperSegs: function(segs, sourceSeg) {
- var helperEls = [];
- var i, seg;
- var sourceEl;
-
- segs = this.renderFgSegsIntoContainers(segs, this.helperContainerEls);
-
- // Try to make the segment that is in the same row as sourceSeg look the same
- for (i = 0; i < segs.length; i++) {
- seg = segs[i];
- if (sourceSeg && sourceSeg.col === seg.col) {
- sourceEl = sourceSeg.el;
- seg.el.css({
- left: sourceEl.css('left'),
- right: sourceEl.css('right'),
- 'margin-left': sourceEl.css('margin-left'),
- 'margin-right': sourceEl.css('margin-right')
- });
- }
- helperEls.push(seg.el[0]);
- }
-
- this.helperSegs = segs;
-
- return $(helperEls); // must return rendered helpers
- },
-
-
- unrenderHelperSegs: function() {
- this.unrenderNamedSegs('helperSegs');
- },
-
-
- /* Background Events
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- renderBgSegs: function(segs) {
- segs = this.renderFillSegEls('bgEvent', segs); // TODO: old fill system
- this.updateSegVerticals(segs);
- this.attachSegsByCol(this.groupSegsByCol(segs), this.bgContainerEls);
- this.bgSegs = segs;
- return segs; // needed for Grid::renderEvents
- },
-
-
- unrenderBgSegs: function() {
- this.unrenderNamedSegs('bgSegs');
- },
-
-
- /* Highlight
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- renderHighlightSegs: function(segs) {
- segs = this.renderFillSegEls('highlight', segs); // TODO: old fill system
- this.updateSegVerticals(segs);
- this.attachSegsByCol(this.groupSegsByCol(segs), this.highlightContainerEls);
- this.highlightSegs = segs;
- },
-
-
- unrenderHighlightSegs: function() {
- this.unrenderNamedSegs('highlightSegs');
- },
-
-
- /* Business Hours
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- renderBusinessSegs: function(segs) {
- segs = this.renderFillSegEls('businessHours', segs); // TODO: old fill system
- this.updateSegVerticals(segs);
- this.attachSegsByCol(this.groupSegsByCol(segs), this.businessContainerEls);
- this.businessSegs = segs;
- },
-
-
- unrenderBusinessSegs: function() {
- this.unrenderNamedSegs('businessSegs');
- },
-
-
- /* Seg Rendering Utils
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col
- groupSegsByCol: function(segs) {
- var segsByCol = [];
- var i;
-
- for (i = 0; i < this.colCnt; i++) {
- segsByCol.push([]);
- }
-
- for (i = 0; i < segs.length; i++) {
- segsByCol[segs[i].col].push(segs[i]);
- }
-
- return segsByCol;
- },
-
-
- // Given segments grouped by column, insert the segments' elements into a parallel array of container
- // elements, each living within a column.
- attachSegsByCol: function(segsByCol, containerEls) {
- var col;
- var segs;
- var i;
-
- for (col = 0; col < this.colCnt; col++) { // iterate each column grouping
- segs = segsByCol[col];
-
- for (i = 0; i < segs.length; i++) {
- containerEls.eq(col).append(segs[i].el);
- }
- }
- },
-
-
- // Given the name of a property of `this` object, assumed to be an array of segments,
- // loops through each segment and removes from DOM. Will null-out the property afterwards.
- unrenderNamedSegs: function(propName) {
- var segs = this[propName];
- var i;
-
- if (segs) {
- for (i = 0; i < segs.length; i++) {
- segs[i].el.remove();
- }
- this[propName] = null;
- }
- },
-
-
-
- /* Foreground Event Rendering Utils
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Given an array of foreground segments, render a DOM element for each, computes position,
- // and attaches to the column inner-container elements.
- renderFgSegsIntoContainers: function(segs, containerEls) {
- var segsByCol;
- var col;
-
- segs = this.renderFgSegEls(segs); // will call fgSegHtml
- segsByCol = this.groupSegsByCol(segs);
-
- for (col = 0; col < this.colCnt; col++) {
- this.updateFgSegCoords(segsByCol[col]);
- }
-
- this.attachSegsByCol(segsByCol, containerEls);
-
- return segs;
- },
-
-
- // Renders the HTML for a single event segment's default rendering
- fgSegHtml: function(seg, disableResizing) {
- var view = this.view;
- var event = seg.event;
- var isDraggable = view.isEventDraggable(event);
- var isResizableFromStart = !disableResizing && seg.isStart && view.isEventResizableFromStart(event);
- var isResizableFromEnd = !disableResizing && seg.isEnd && view.isEventResizableFromEnd(event);
- var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd);
- var skinCss = cssToStr(this.getSegSkinCss(seg));
- var timeText;
- var fullTimeText; // more verbose time text. for the print stylesheet
- var startTimeText; // just the start time text
-
- classes.unshift('fc-time-grid-event', 'fc-v-event');
-
- if (view.isMultiDayEvent(event)) { // if the event appears to span more than one day...
- // Don't display time text on segments that run entirely through a day.
- // That would appear as midnight-midnight and would look dumb.
- // Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am)
- if (seg.isStart || seg.isEnd) {
- timeText = this.getEventTimeText(seg);
- fullTimeText = this.getEventTimeText(seg, 'LT');
- startTimeText = this.getEventTimeText(seg, null, false); // displayEnd=false
- }
- } else {
- // Display the normal time text for the *event's* times
- timeText = this.getEventTimeText(event);
- fullTimeText = this.getEventTimeText(event, 'LT');
- startTimeText = this.getEventTimeText(event, null, false); // displayEnd=false
- }
-
- return '<a class="' + classes.join(' ') + '"' +
- (event.url ?
- ' href="' + htmlEscape(event.url) + '"' :
- ''
- ) +
- (skinCss ?
- ' style="' + skinCss + '"' :
- ''
- ) +
- '>' +
- '<div class="fc-content">' +
- (timeText ?
- '<div class="fc-time"' +
- ' data-start="' + htmlEscape(startTimeText) + '"' +
- ' data-full="' + htmlEscape(fullTimeText) + '"' +
- '>' +
- '<span>' + htmlEscape(timeText) + '</span>' +
- '</div>' :
- ''
- ) +
- (event.title ?
- '<div class="fc-title">' +
- htmlEscape(event.title) +
- '</div>' :
- ''
- ) +
- '</div>' +
- '<div class="fc-bg"/>' +
- /* TODO: write CSS for this
- (isResizableFromStart ?
- '<div class="fc-resizer fc-start-resizer" />' :
- ''
- ) +
- */
- (isResizableFromEnd ?
- '<div class="fc-resizer fc-end-resizer" />' :
- ''
- ) +
- '</a>';
- },
-
-
- /* Seg Position Utils
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Refreshes the CSS top/bottom coordinates for each segment element.
- // Works when called after initial render, after a window resize/zoom for example.
- updateSegVerticals: function(segs) {
- this.computeSegVerticals(segs);
- this.assignSegVerticals(segs);
- },
-
-
- // For each segment in an array, computes and assigns its top and bottom properties
- computeSegVerticals: function(segs) {
- var i, seg;
-
- for (i = 0; i < segs.length; i++) {
- seg = segs[i];
- seg.top = this.computeDateTop(seg.start, seg.start);
- seg.bottom = this.computeDateTop(seg.end, seg.start);
- }
- },
-
-
- // Given segments that already have their top/bottom properties computed, applies those values to
- // the segments' elements.
- assignSegVerticals: function(segs) {
- var i, seg;
-
- for (i = 0; i < segs.length; i++) {
- seg = segs[i];
- seg.el.css(this.generateSegVerticalCss(seg));
- }
- },
-
-
- // Generates an object with CSS properties for the top/bottom coordinates of a segment element
- generateSegVerticalCss: function(seg) {
- return {
- top: seg.top,
- bottom: -seg.bottom // flipped because needs to be space beyond bottom edge of event container
- };
- },
-
-
- /* Foreground Event Positioning Utils
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Given segments that are assumed to all live in the *same column*,
- // compute their verical/horizontal coordinates and assign to their elements.
- updateFgSegCoords: function(segs) {
- this.computeSegVerticals(segs); // horizontals relies on this
- this.computeFgSegHorizontals(segs); // compute horizontal coordinates, z-index's, and reorder the array
- this.assignSegVerticals(segs);
- this.assignFgSegHorizontals(segs);
- },
-
-
- // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
- // NOTE: Also reorders the given array by date!
- computeFgSegHorizontals: function(segs) {
- var levels;
- var level0;
- var i;
-
- this.sortEventSegs(segs); // order by certain criteria
- levels = buildSlotSegLevels(segs);
- computeForwardSlotSegs(levels);
-
- if ((level0 = levels[0])) {
-
- for (i = 0; i < level0.length; i++) {
- computeSlotSegPressures(level0[i]);
- }
-
- for (i = 0; i < level0.length; i++) {
- this.computeFgSegForwardBack(level0[i], 0, 0);
- }
- }
- },
-
-
- // Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range
- // from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to "left" and
- // seg.forwardCoord maps to "right" (via percentage). Vice-versa if the calendar is right-to-left.
- //
- // The segment might be part of a "series", which means consecutive segments with the same pressure
- // who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of
- // segments behind this one in the current series, and `seriesBackwardCoord` is the starting
- // coordinate of the first segment in the series.
- computeFgSegForwardBack: function(seg, seriesBackwardPressure, seriesBackwardCoord) {
- var forwardSegs = seg.forwardSegs;
- var i;
-
- if (seg.forwardCoord === undefined) { // not already computed
-
- if (!forwardSegs.length) {
-
- // if there are no forward segments, this segment should butt up against the edge
- seg.forwardCoord = 1;
- }
- else {
-
- // sort highest pressure first
- this.sortForwardSegs(forwardSegs);
-
- // this segment's forwardCoord will be calculated from the backwardCoord of the
- // highest-pressure forward segment.
- this.computeFgSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);
- seg.forwardCoord = forwardSegs[0].backwardCoord;
- }
-
- // calculate the backwardCoord from the forwardCoord. consider the series
- seg.backwardCoord = seg.forwardCoord -
- (seg.forwardCoord - seriesBackwardCoord) / // available width for series
- (seriesBackwardPressure + 1); // # of segments in the series
-
- // use this segment's coordinates to computed the coordinates of the less-pressurized
- // forward segments
- for (i=0; i<forwardSegs.length; i++) {
- this.computeFgSegForwardBack(forwardSegs[i], 0, seg.forwardCoord);
- }
- }
- },
-
-
- sortForwardSegs: function(forwardSegs) {
- forwardSegs.sort(proxy(this, 'compareForwardSegs'));
- },
-
-
- // A cmp function for determining which forward segment to rely on more when computing coordinates.
- compareForwardSegs: function(seg1, seg2) {
- // put higher-pressure first
- return seg2.forwardPressure - seg1.forwardPressure ||
- // put segments that are closer to initial edge first (and favor ones with no coords yet)
- (seg1.backwardCoord || 0) - (seg2.backwardCoord || 0) ||
- // do normal sorting...
- this.compareEventSegs(seg1, seg2);
- },
-
-
- // Given foreground event segments that have already had their position coordinates computed,
- // assigns position-related CSS values to their elements.
- assignFgSegHorizontals: function(segs) {
- var i, seg;
-
- for (i = 0; i < segs.length; i++) {
- seg = segs[i];
- seg.el.css(this.generateFgSegHorizontalCss(seg));
-
- // if the height is short, add a className for alternate styling
- if (seg.bottom - seg.top < 30) {
- seg.el.addClass('fc-short');
- }
- }
- },
-
-
- // Generates an object with CSS properties/values that should be applied to an event segment element.
- // Contains important positioning-related properties that should be applied to any event element, customized or not.
- generateFgSegHorizontalCss: function(seg) {
- var shouldOverlap = this.view.opt('slotEventOverlap');
- var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point
- var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point
- var props = this.generateSegVerticalCss(seg); // get top/bottom first
- var left; // amount of space from left edge, a fraction of the total width
- var right; // amount of space from right edge, a fraction of the total width
-
- if (shouldOverlap) {
- // double the width, but don't go beyond the maximum forward coordinate (1.0)
- forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2);
- }
-
- if (this.isRTL) {
- left = 1 - forwardCoord;
- right = backwardCoord;
- }
- else {
- left = backwardCoord;
- right = 1 - forwardCoord;
- }
-
- props.zIndex = seg.level + 1; // convert from 0-base to 1-based
- props.left = left * 100 + '%';
- props.right = right * 100 + '%';
-
- if (shouldOverlap && seg.forwardPressure) {
- // add padding to the edge so that forward stacked events don't cover the resizer's icon
- props[this.isRTL ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
- }
-
- return props;
- }
-
-});
-
-
-// Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
-// left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.
-function buildSlotSegLevels(segs) {
- var levels = [];
- var i, seg;
- var j;
-
- for (i=0; i<segs.length; i++) {
- seg = segs[i];
-
- // go through all the levels and stop on the first level where there are no collisions
- for (j=0; j<levels.length; j++) {
- if (!computeSlotSegCollisions(seg, levels[j]).length) {
- break;
- }
- }
-
- seg.level = j;
-
- (levels[j] || (levels[j] = [])).push(seg);
- }
-
- return levels;
-}
-
-
-// For every segment, figure out the other segments that are in subsequent
-// levels that also occupy the same vertical space. Accumulate in seg.forwardSegs
-function computeForwardSlotSegs(levels) {
- var i, level;
- var j, seg;
- var k;
-
- for (i=0; i<levels.length; i++) {
- level = levels[i];
-
- for (j=0; j<level.length; j++) {
- seg = level[j];
-
- seg.forwardSegs = [];
- for (k=i+1; k<levels.length; k++) {
- computeSlotSegCollisions(seg, levels[k], seg.forwardSegs);
- }
- }
- }
-}
-
-
-// Figure out which path forward (via seg.forwardSegs) results in the longest path until
-// the furthest edge is reached. The number of segments in this path will be seg.forwardPressure
-function computeSlotSegPressures(seg) {
- var forwardSegs = seg.forwardSegs;
- var forwardPressure = 0;
- var i, forwardSeg;
-
- if (seg.forwardPressure === undefined) { // not already computed
-
- for (i=0; i<forwardSegs.length; i++) {
- forwardSeg = forwardSegs[i];
-
- // figure out the child's maximum forward path
- computeSlotSegPressures(forwardSeg);
-
- // either use the existing maximum, or use the child's forward pressure
- // plus one (for the forwardSeg itself)
- forwardPressure = Math.max(
- forwardPressure,
- 1 + forwardSeg.forwardPressure
- );
- }
-
- seg.forwardPressure = forwardPressure;
- }
-}
-
-
-// Find all the segments in `otherSegs` that vertically collide with `seg`.
-// Append into an optionally-supplied `results` array and return.
-function computeSlotSegCollisions(seg, otherSegs, results) {
- results = results || [];
-
- for (var i=0; i<otherSegs.length; i++) {
- if (isSlotSegCollision(seg, otherSegs[i])) {
- results.push(otherSegs[i]);
- }
- }
-
- return results;
-}
-
-
-// Do these segments occupy the same vertical space?
-function isSlotSegCollision(seg1, seg2) {
- return seg1.bottom > seg2.top && seg1.top < seg2.bottom;
-}
-
-;;
-
-/* An abstract class from which other views inherit from
-----------------------------------------------------------------------------------------------------------------------*/
-
-var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
-
- type: null, // subclass' view name (string)
- name: null, // deprecated. use `type` instead
- title: null, // the text that will be displayed in the header's title
-
- calendar: null, // owner Calendar object
- options: null, // hash containing all options. already merged with view-specific-options
- el: null, // the view's containing element. set by Calendar
-
- displaying: null, // a promise representing the state of rendering. null if no render requested
- isSkeletonRendered: false,
- isEventsRendered: false,
-
- // range the view is actually displaying (moments)
- start: null,
- end: null, // exclusive
-
- // range the view is formally responsible for (moments)
- // may be different from start/end. for example, a month view might have 1st-31st, excluding padded dates
- intervalStart: null,
- intervalEnd: null, // exclusive
- intervalDuration: null,
- intervalUnit: null, // name of largest unit being displayed, like "month" or "week"
-
- isRTL: false,
- isSelected: false, // boolean whether a range of time is user-selected or not
- selectedEvent: null,
-
- eventOrderSpecs: null, // criteria for ordering events when they have same date/time
-
- // classNames styled by jqui themes
- widgetHeaderClass: null,
- widgetContentClass: null,
- highlightStateClass: null,
-
- // for date utils, computed from options
- nextDayThreshold: null,
- isHiddenDayHash: null,
-
- // now indicator
- isNowIndicatorRendered: null,
- initialNowDate: null, // result first getNow call
- initialNowQueriedMs: null, // ms time the getNow was called
- nowIndicatorTimeoutID: null, // for refresh timing of now indicator
- nowIndicatorIntervalID: null, // "
-
-
- constructor: function(calendar, type, options, intervalDuration) {
-
- this.calendar = calendar;
- this.type = this.name = type; // .name is deprecated
- this.options = options;
- this.intervalDuration = intervalDuration || moment.duration(1, 'day');
-
- this.nextDayThreshold = moment.duration(this.opt('nextDayThreshold'));
- this.initThemingProps();
- this.initHiddenDays();
- this.isRTL = this.opt('isRTL');
-
- this.eventOrderSpecs = parseFieldSpecs(this.opt('eventOrder'));
-
- this.initialize();
- },
-
-
- // A good place for subclasses to initialize member variables
- initialize: function() {
- // subclasses can implement
- },
-
-
- // Retrieves an option with the given name
- opt: function(name) {
- return this.options[name];
- },
-
-
- // Triggers handlers that are view-related. Modifies args before passing to calendar.
- trigger: function(name, thisObj) { // arguments beyond thisObj are passed along
- var calendar = this.calendar;
-
- return calendar.trigger.apply(
- calendar,
- [name, thisObj || this].concat(
- Array.prototype.slice.call(arguments, 2), // arguments beyond thisObj
- [ this ] // always make the last argument a reference to the view. TODO: deprecate
- )
- );
- },
-
-
- /* Dates
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Updates all internal dates to center around the given current unzoned date.
- setDate: function(date) {
- this.setRange(this.computeRange(date));
- },
-
-
- // Updates all internal dates for displaying the given unzoned range.
- setRange: function(range) {
- $.extend(this, range); // assigns every property to this object's member variables
- this.updateTitle();
- },
-
-
- // Given a single current unzoned date, produce information about what range to display.
- // Subclasses can override. Must return all properties.
- computeRange: function(date) {
- var intervalUnit = computeIntervalUnit(this.intervalDuration);
- var intervalStart = date.clone().startOf(intervalUnit);
- var intervalEnd = intervalStart.clone().add(this.intervalDuration);
- var start, end;
-
- // normalize the range's time-ambiguity
- if (/year|month|week|day/.test(intervalUnit)) { // whole-days?
- intervalStart.stripTime();
- intervalEnd.stripTime();
- }
- else { // needs to have a time?
- if (!intervalStart.hasTime()) {
- intervalStart = this.calendar.time(0); // give 00:00 time
- }
- if (!intervalEnd.hasTime()) {
- intervalEnd = this.calendar.time(0); // give 00:00 time
- }
- }
-
- start = intervalStart.clone();
- start = this.skipHiddenDays(start);
- end = intervalEnd.clone();
- end = this.skipHiddenDays(end, -1, true); // exclusively move backwards
-
- return {
- intervalUnit: intervalUnit,
- intervalStart: intervalStart,
- intervalEnd: intervalEnd,
- start: start,
- end: end
- };
- },
-
-
- // Computes the new date when the user hits the prev button, given the current date
- computePrevDate: function(date) {
- return this.massageCurrentDate(
- date.clone().startOf(this.intervalUnit).subtract(this.intervalDuration), -1
- );
- },
-
-
- // Computes the new date when the user hits the next button, given the current date
- computeNextDate: function(date) {
- return this.massageCurrentDate(
- date.clone().startOf(this.intervalUnit).add(this.intervalDuration)
- );
- },
-
-
- // Given an arbitrarily calculated current date of the calendar, returns a date that is ensured to be completely
- // visible. `direction` is optional and indicates which direction the current date was being
- // incremented or decremented (1 or -1).
- massageCurrentDate: function(date, direction) {
- if (this.intervalDuration.as('days') <= 1) { // if the view displays a single day or smaller
- if (this.isHiddenDay(date)) {
- date = this.skipHiddenDays(date, direction);
- date.startOf('day');
- }
- }
-
- return date;
- },
-
-
- /* Title and Date Formatting
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Sets the view's title property to the most updated computed value
- updateTitle: function() {
- this.title = this.computeTitle();
- },
-
-
- // Computes what the title at the top of the calendar should be for this view
- computeTitle: function() {
- return this.formatRange(
- {
- // in case intervalStart/End has a time, make sure timezone is correct
- start: this.calendar.applyTimezone(this.intervalStart),
- end: this.calendar.applyTimezone(this.intervalEnd)
- },
- this.opt('titleFormat') || this.computeTitleFormat(),
- this.opt('titleRangeSeparator')
- );
- },
-
-
- // Generates the format string that should be used to generate the title for the current date range.
- // Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.
- computeTitleFormat: function() {
- if (this.intervalUnit == 'year') {
- return 'YYYY';
- }
- else if (this.intervalUnit == 'month') {
- return this.opt('monthYearFormat'); // like "September 2014"
- }
- else if (this.intervalDuration.as('days') > 1) {
- return 'll'; // multi-day range. shorter, like "Sep 9 - 10 2014"
- }
- else {
- return 'LL'; // one day. longer, like "September 9 2014"
- }
- },
-
-
- // Utility for formatting a range. Accepts a range object, formatting string, and optional separator.
- // Displays all-day ranges naturally, with an inclusive end. Takes the current isRTL into account.
- // The timezones of the dates within `range` will be respected.
- formatRange: function(range, formatStr, separator) {
- var end = range.end;
-
- if (!end.hasTime()) { // all-day?
- end = end.clone().subtract(1); // convert to inclusive. last ms of previous day
- }
-
- return formatRange(range.start, end, formatStr, separator, this.opt('isRTL'));
- },
-
-
- /* Rendering
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Sets the container element that the view should render inside of.
- // Does other DOM-related initializations.
- setElement: function(el) {
- this.el = el;
- this.bindGlobalHandlers();
- },
-
-
- // Removes the view's container element from the DOM, clearing any content beforehand.
- // Undoes any other DOM-related attachments.
- removeElement: function() {
- this.clear(); // clears all content
-
- // clean up the skeleton
- if (this.isSkeletonRendered) {
- this.unrenderSkeleton();
- this.isSkeletonRendered = false;
- }
-
- this.unbindGlobalHandlers();
-
- this.el.remove();
-
- // NOTE: don't null-out this.el in case the View was destroyed within an API callback.
- // We don't null-out the View's other jQuery element references upon destroy,
- // so we shouldn't kill this.el either.
- },
-
-
- // Does everything necessary to display the view centered around the given unzoned date.
- // Does every type of rendering EXCEPT rendering events.
- // Is asychronous and returns a promise.
- display: function(date) {
- var _this = this;
- var scrollState = null;
-
- if (this.displaying) {
- scrollState = this.queryScroll();
- }
-
- this.calendar.freezeContentHeight();
-
- return this.clear().then(function() { // clear the content first (async)
- return (
- _this.displaying =
- $.when(_this.displayView(date)) // displayView might return a promise
- .then(function() {
- _this.forceScroll(_this.computeInitialScroll(scrollState));
- _this.calendar.unfreezeContentHeight();
- _this.triggerRender();
- })
- );
- });
- },
-
-
- // Does everything necessary to clear the content of the view.
- // Clears dates and events. Does not clear the skeleton.
- // Is asychronous and returns a promise.
- clear: function() {
- var _this = this;
- var displaying = this.displaying;
-
- if (displaying) { // previously displayed, or in the process of being displayed?
- return displaying.then(function() { // wait for the display to finish
- _this.displaying = null;
- _this.clearEvents();
- return _this.clearView(); // might return a promise. chain it
- });
- }
- else {
- return $.when(); // an immediately-resolved promise
- }
- },
-
-
- // Displays the view's non-event content, such as date-related content or anything required by events.
- // Renders the view's non-content skeleton if necessary.
- // Can be asynchronous and return a promise.
- displayView: function(date) {
- if (!this.isSkeletonRendered) {
- this.renderSkeleton();
- this.isSkeletonRendered = true;
- }
- if (date) {
- this.setDate(date);
- }
- if (this.render) {
- this.render(); // TODO: deprecate
- }
- this.renderDates();
- this.updateSize();
- this.renderBusinessHours(); // might need coordinates, so should go after updateSize()
- this.startNowIndicator();
- },
-
-
- // Unrenders the view content that was rendered in displayView.
- // Can be asynchronous and return a promise.
- clearView: function() {
- this.unselect();
- this.stopNowIndicator();
- this.triggerUnrender();
- this.unrenderBusinessHours();
- this.unrenderDates();
- if (this.destroy) {
- this.destroy(); // TODO: deprecate
- }
- },
-
-
- // Renders the basic structure of the view before any content is rendered
- renderSkeleton: function() {
- // subclasses should implement
- },
-
-
- // Unrenders the basic structure of the view
- unrenderSkeleton: function() {
- // subclasses should implement
- },
-
-
- // Renders the view's date-related content.
- // Assumes setRange has already been called and the skeleton has already been rendered.
- renderDates: function() {
- // subclasses should implement
- },
-
-
- // Unrenders the view's date-related content
- unrenderDates: function() {
- // subclasses should override
- },
-
-
- // Signals that the view's content has been rendered
- triggerRender: function() {
- this.trigger('viewRender', this, this, this.el);
- },
-
-
- // Signals that the view's content is about to be unrendered
- triggerUnrender: function() {
- this.trigger('viewDestroy', this, this, this.el);
- },
-
-
- // Binds DOM handlers to elements that reside outside the view container, such as the document
- bindGlobalHandlers: function() {
- this.listenTo($(document), 'mousedown', this.handleDocumentMousedown);
- this.listenTo($(document), 'touchstart', this.processUnselect);
- },
-
-
- // Unbinds DOM handlers from elements that reside outside the view container
- unbindGlobalHandlers: function() {
- this.stopListeningTo($(document));
- },
-
-
- // Initializes internal variables related to theming
- initThemingProps: function() {
- var tm = this.opt('theme') ? 'ui' : 'fc';
-
- this.widgetHeaderClass = tm + '-widget-header';
- this.widgetContentClass = tm + '-widget-content';
- this.highlightStateClass = tm + '-state-highlight';
- },
-
-
- /* Business Hours
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders business-hours onto the view. Assumes updateSize has already been called.
- renderBusinessHours: function() {
- // subclasses should implement
- },
-
-
- // Unrenders previously-rendered business-hours
- unrenderBusinessHours: function() {
- // subclasses should implement
- },
-
-
- /* Now Indicator
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Immediately render the current time indicator and begins re-rendering it at an interval,
- // which is defined by this.getNowIndicatorUnit().
- // TODO: somehow do this for the current whole day's background too
- startNowIndicator: function() {
- var _this = this;
- var unit;
- var update;
- var delay; // ms wait value
-
- if (this.opt('nowIndicator')) {
- unit = this.getNowIndicatorUnit();
- if (unit) {
- update = proxy(this, 'updateNowIndicator'); // bind to `this`
-
- this.initialNowDate = this.calendar.getNow();
- this.initialNowQueriedMs = +new Date();
- this.renderNowIndicator(this.initialNowDate);
- this.isNowIndicatorRendered = true;
-
- // wait until the beginning of the next interval
- delay = this.initialNowDate.clone().startOf(unit).add(1, unit) - this.initialNowDate;
- this.nowIndicatorTimeoutID = setTimeout(function() {
- _this.nowIndicatorTimeoutID = null;
- update();
- delay = +moment.duration(1, unit);
- delay = Math.max(100, delay); // prevent too frequent
- _this.nowIndicatorIntervalID = setInterval(update, delay); // update every interval
- }, delay);
- }
- }
- },
-
-
- // rerenders the now indicator, computing the new current time from the amount of time that has passed
- // since the initial getNow call.
- updateNowIndicator: function() {
- if (this.isNowIndicatorRendered) {
- this.unrenderNowIndicator();
- this.renderNowIndicator(
- this.initialNowDate.clone().add(new Date() - this.initialNowQueriedMs) // add ms
- );
- }
- },
-
-
- // Immediately unrenders the view's current time indicator and stops any re-rendering timers.
- // Won't cause side effects if indicator isn't rendered.
- stopNowIndicator: function() {
- if (this.isNowIndicatorRendered) {
-
- if (this.nowIndicatorTimeoutID) {
- clearTimeout(this.nowIndicatorTimeoutID);
- this.nowIndicatorTimeoutID = null;
- }
- if (this.nowIndicatorIntervalID) {
- clearTimeout(this.nowIndicatorIntervalID);
- this.nowIndicatorIntervalID = null;
- }
-
- this.unrenderNowIndicator();
- this.isNowIndicatorRendered = false;
- }
- },
-
-
- // Returns a string unit, like 'second' or 'minute' that defined how often the current time indicator
- // should be refreshed. If something falsy is returned, no time indicator is rendered at all.
- getNowIndicatorUnit: function() {
- // subclasses should implement
- },
-
-
- // Renders a current time indicator at the given datetime
- renderNowIndicator: function(date) {
- // subclasses should implement
- },
-
-
- // Undoes the rendering actions from renderNowIndicator
- unrenderNowIndicator: function() {
- // subclasses should implement
- },
-
-
- /* Dimensions
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Refreshes anything dependant upon sizing of the container element of the grid
- updateSize: function(isResize) {
- var scrollState;
-
- if (isResize) {
- scrollState = this.queryScroll();
- }
-
- this.updateHeight(isResize);
- this.updateWidth(isResize);
- this.updateNowIndicator();
-
- if (isResize) {
- this.setScroll(scrollState);
- }
- },
-
-
- // Refreshes the horizontal dimensions of the calendar
- updateWidth: function(isResize) {
- // subclasses should implement
- },
-
-
- // Refreshes the vertical dimensions of the calendar
- updateHeight: function(isResize) {
- var calendar = this.calendar; // we poll the calendar for height information
-
- this.setHeight(
- calendar.getSuggestedViewHeight(),
- calendar.isHeightAuto()
- );
- },
-
-
- // Updates the vertical dimensions of the calendar to the specified height.
- // if `isAuto` is set to true, height becomes merely a suggestion and the view should use its "natural" height.
- setHeight: function(height, isAuto) {
- // subclasses should implement
- },
-
-
- /* Scroller
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Computes the initial pre-configured scroll state prior to allowing the user to change it.
- // Given the scroll state from the previous rendering. If first time rendering, given null.
- computeInitialScroll: function(previousScrollState) {
- return 0;
- },
-
-
- // Retrieves the view's current natural scroll state. Can return an arbitrary format.
- queryScroll: function() {
- // subclasses must implement
- },
-
-
- // Sets the view's scroll state. Will accept the same format computeInitialScroll and queryScroll produce.
- setScroll: function(scrollState) {
- // subclasses must implement
- },
-
-
- // Sets the scroll state, making sure to overcome any predefined scroll value the browser has in mind
- forceScroll: function(scrollState) {
- var _this = this;
-
- this.setScroll(scrollState);
- setTimeout(function() {
- _this.setScroll(scrollState);
- }, 0);
- },
-
-
- /* Event Elements / Segments
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Does everything necessary to display the given events onto the current view
- displayEvents: function(events) {
- var scrollState = this.queryScroll();
-
- this.clearEvents();
- this.renderEvents(events);
- this.isEventsRendered = true;
- this.setScroll(scrollState);
- this.triggerEventRender();
- },
-
-
- // Does everything necessary to clear the view's currently-rendered events
- clearEvents: function() {
- var scrollState;
-
- if (this.isEventsRendered) {
-
- // TODO: optimize: if we know this is part of a displayEvents call, don't queryScroll/setScroll
- scrollState = this.queryScroll();
-
- this.triggerEventUnrender();
- if (this.destroyEvents) {
- this.destroyEvents(); // TODO: deprecate
- }
- this.unrenderEvents();
- this.setScroll(scrollState);
- this.isEventsRendered = false;
- }
- },
-
-
- // Renders the events onto the view.
- renderEvents: function(events) {
- // subclasses should implement
- },
-
-
- // Removes event elements from the view.
- unrenderEvents: function() {
- // subclasses should implement
- },
-
-
- // Signals that all events have been rendered
- triggerEventRender: function() {
- this.renderedEventSegEach(function(seg) {
- this.trigger('eventAfterRender', seg.event, seg.event, seg.el);
- });
- this.trigger('eventAfterAllRender');
- },
-
-
- // Signals that all event elements are about to be removed
- triggerEventUnrender: function() {
- this.renderedEventSegEach(function(seg) {
- this.trigger('eventDestroy', seg.event, seg.event, seg.el);
- });
- },
-
-
- // Given an event and the default element used for rendering, returns the element that should actually be used.
- // Basically runs events and elements through the eventRender hook.
- resolveEventEl: function(event, el) {
- var custom = this.trigger('eventRender', event, event, el);
-
- if (custom === false) { // means don't render at all
- el = null;
- }
- else if (custom && custom !== true) {
- el = $(custom);
- }
-
- return el;
- },
-
-
- // Hides all rendered event segments linked to the given event
- showEvent: function(event) {
- this.renderedEventSegEach(function(seg) {
- seg.el.css('visibility', '');
- }, event);
- },
-
-
- // Shows all rendered event segments linked to the given event
- hideEvent: function(event) {
- this.renderedEventSegEach(function(seg) {
- seg.el.css('visibility', 'hidden');
- }, event);
- },
-
-
- // Iterates through event segments that have been rendered (have an el). Goes through all by default.
- // If the optional `event` argument is specified, only iterates through segments linked to that event.
- // The `this` value of the callback function will be the view.
- renderedEventSegEach: function(func, event) {
- var segs = this.getEventSegs();
- var i;
-
- for (i = 0; i < segs.length; i++) {
- if (!event || segs[i].event._id === event._id) {
- if (segs[i].el) {
- func.call(this, segs[i]);
- }
- }
- }
- },
-
-
- // Retrieves all the rendered segment objects for the view
- getEventSegs: function() {
- // subclasses must implement
- return [];
- },
-
-
- /* Event Drag-n-Drop
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Computes if the given event is allowed to be dragged by the user
- isEventDraggable: function(event) {
- var source = event.source || {};
-
- return firstDefined(
- event.startEditable,
- source.startEditable,
- this.opt('eventStartEditable'),
- event.editable,
- source.editable,
- this.opt('editable')
- );
- },
-
-
- // Must be called when an event in the view is dropped onto new location.
- // `dropLocation` is an object that contains the new zoned start/end/allDay values for the event.
- reportEventDrop: function(event, dropLocation, largeUnit, el, ev) {
- var calendar = this.calendar;
- var mutateResult = calendar.mutateEvent(event, dropLocation, largeUnit);
- var undoFunc = function() {
- mutateResult.undo();
- calendar.reportEventChange();
- };
-
- this.triggerEventDrop(event, mutateResult.dateDelta, undoFunc, el, ev);
- calendar.reportEventChange(); // will rerender events
- },
-
-
- // Triggers event-drop handlers that have subscribed via the API
- triggerEventDrop: function(event, dateDelta, undoFunc, el, ev) {
- this.trigger('eventDrop', el[0], event, dateDelta, undoFunc, ev, {}); // {} = jqui dummy
- },
-
-
- /* External Element Drag-n-Drop
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Must be called when an external element, via jQuery UI, has been dropped onto the calendar.
- // `meta` is the parsed data that has been embedded into the dragging event.
- // `dropLocation` is an object that contains the new zoned start/end/allDay values for the event.
- reportExternalDrop: function(meta, dropLocation, el, ev, ui) {
- var eventProps = meta.eventProps;
- var eventInput;
- var event;
-
- // Try to build an event object and render it. TODO: decouple the two
- if (eventProps) {
- eventInput = $.extend({}, eventProps, dropLocation);
- event = this.calendar.renderEvent(eventInput, meta.stick)[0]; // renderEvent returns an array
- }
-
- this.triggerExternalDrop(event, dropLocation, el, ev, ui);
- },
-
-
- // Triggers external-drop handlers that have subscribed via the API
- triggerExternalDrop: function(event, dropLocation, el, ev, ui) {
-
- // trigger 'drop' regardless of whether element represents an event
- this.trigger('drop', el[0], dropLocation.start, ev, ui);
-
- if (event) {
- this.trigger('eventReceive', null, event); // signal an external event landed
- }
- },
-
-
- /* Drag-n-Drop Rendering (for both events and external elements)
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders a visual indication of a event or external-element drag over the given drop zone.
- // If an external-element, seg will be `null`.
- // Must return elements used for any mock events.
- renderDrag: function(dropLocation, seg) {
- // subclasses must implement
- },
-
-
- // Unrenders a visual indication of an event or external-element being dragged.
- unrenderDrag: function() {
- // subclasses must implement
- },
-
-
- /* Event Resizing
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Computes if the given event is allowed to be resized from its starting edge
- isEventResizableFromStart: function(event) {
- return this.opt('eventResizableFromStart') && this.isEventResizable(event);
- },
-
-
- // Computes if the given event is allowed to be resized from its ending edge
- isEventResizableFromEnd: function(event) {
- return this.isEventResizable(event);
- },
-
-
- // Computes if the given event is allowed to be resized by the user at all
- isEventResizable: function(event) {
- var source = event.source || {};
-
- return firstDefined(
- event.durationEditable,
- source.durationEditable,
- this.opt('eventDurationEditable'),
- event.editable,
- source.editable,
- this.opt('editable')
- );
- },
-
-
- // Must be called when an event in the view has been resized to a new length
- reportEventResize: function(event, resizeLocation, largeUnit, el, ev) {
- var calendar = this.calendar;
- var mutateResult = calendar.mutateEvent(event, resizeLocation, largeUnit);
- var undoFunc = function() {
- mutateResult.undo();
- calendar.reportEventChange();
- };
-
- this.triggerEventResize(event, mutateResult.durationDelta, undoFunc, el, ev);
- calendar.reportEventChange(); // will rerender events
- },
-
-
- // Triggers event-resize handlers that have subscribed via the API
- triggerEventResize: function(event, durationDelta, undoFunc, el, ev) {
- this.trigger('eventResize', el[0], event, durationDelta, undoFunc, ev, {}); // {} = jqui dummy
- },
-
-
- /* Selection (time range)
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Selects a date span on the view. `start` and `end` are both Moments.
- // `ev` is the native mouse event that begin the interaction.
- select: function(span, ev) {
- this.unselect(ev);
- this.renderSelection(span);
- this.reportSelection(span, ev);
- },
-
-
- // Renders a visual indication of the selection
- renderSelection: function(span) {
- // subclasses should implement
- },
-
-
- // Called when a new selection is made. Updates internal state and triggers handlers.
- reportSelection: function(span, ev) {
- this.isSelected = true;
- this.triggerSelect(span, ev);
- },
-
-
- // Triggers handlers to 'select'
- triggerSelect: function(span, ev) {
- this.trigger(
- 'select',
- null,
- this.calendar.applyTimezone(span.start), // convert to calendar's tz for external API
- this.calendar.applyTimezone(span.end), // "
- ev
- );
- },
-
-
- // Undoes a selection. updates in the internal state and triggers handlers.
- // `ev` is the native mouse event that began the interaction.
- unselect: function(ev) {
- if (this.isSelected) {
- this.isSelected = false;
- if (this.destroySelection) {
- this.destroySelection(); // TODO: deprecate
- }
- this.unrenderSelection();
- this.trigger('unselect', null, ev);
- }
- },
-
-
- // Unrenders a visual indication of selection
- unrenderSelection: function() {
- // subclasses should implement
- },
-
-
- /* Event Selection
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- selectEvent: function(event) {
- if (!this.selectedEvent || this.selectedEvent !== event) {
- this.unselectEvent();
- this.renderedEventSegEach(function(seg) {
- seg.el.addClass('fc-selected');
- }, event);
- this.selectedEvent = event;
- }
- },
-
-
- unselectEvent: function() {
- if (this.selectedEvent) {
- this.renderedEventSegEach(function(seg) {
- seg.el.removeClass('fc-selected');
- }, this.selectedEvent);
- this.selectedEvent = null;
- }
- },
-
-
- isEventSelected: function(event) {
- // event references might change on refetchEvents(), while selectedEvent doesn't,
- // so compare IDs
- return this.selectedEvent && this.selectedEvent._id === event._id;
- },
-
-
- /* Mouse / Touch Unselecting (time range & event unselection)
- ------------------------------------------------------------------------------------------------------------------*/
- // TODO: move consistently to down/start or up/end?
- // TODO: don't kill previous selection if touch scrolling
-
-
- handleDocumentMousedown: function(ev) {
- if (isPrimaryMouseButton(ev)) {
- this.processUnselect(ev);
- }
- },
-
-
- processUnselect: function(ev) {
- this.processRangeUnselect(ev);
- this.processEventUnselect(ev);
- },
-
-
- processRangeUnselect: function(ev) {
- var ignore;
-
- // is there a time-range selection?
- if (this.isSelected && this.opt('unselectAuto')) {
- // only unselect if the clicked element is not identical to or inside of an 'unselectCancel' element
- ignore = this.opt('unselectCancel');
- if (!ignore || !$(ev.target).closest(ignore).length) {
- this.unselect(ev);
- }
- }
- },
-
-
- processEventUnselect: function(ev) {
- if (this.selectedEvent) {
- if (!$(ev.target).closest('.fc-selected').length) {
- this.unselectEvent();
- }
- }
- },
-
-
- /* Day Click
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Triggers handlers to 'dayClick'
- // Span has start/end of the clicked area. Only the start is useful.
- triggerDayClick: function(span, dayEl, ev) {
- this.trigger(
- 'dayClick',
- dayEl,
- this.calendar.applyTimezone(span.start), // convert to calendar's timezone for external API
- ev
- );
- },
-
-
- /* Date Utils
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Initializes internal variables related to calculating hidden days-of-week
- initHiddenDays: function() {
- var hiddenDays = this.opt('hiddenDays') || []; // array of day-of-week indices that are hidden
- var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)
- var dayCnt = 0;
- var i;
-
- if (this.opt('weekends') === false) {
- hiddenDays.push(0, 6); // 0=sunday, 6=saturday
- }
-
- for (i = 0; i < 7; i++) {
- if (
- !(isHiddenDayHash[i] = $.inArray(i, hiddenDays) !== -1)
- ) {
- dayCnt++;
- }
- }
-
- if (!dayCnt) {
- throw 'invalid hiddenDays'; // all days were hidden? bad.
- }
-
- this.isHiddenDayHash = isHiddenDayHash;
- },
-
-
- // Is the current day hidden?
- // `day` is a day-of-week index (0-6), or a Moment
- isHiddenDay: function(day) {
- if (moment.isMoment(day)) {
- day = day.day();
- }
- return this.isHiddenDayHash[day];
- },
-
-
- // Incrementing the current day until it is no longer a hidden day, returning a copy.
- // If the initial value of `date` is not a hidden day, don't do anything.
- // Pass `isExclusive` as `true` if you are dealing with an end date.
- // `inc` defaults to `1` (increment one day forward each time)
- skipHiddenDays: function(date, inc, isExclusive) {
- var out = date.clone();
- inc = inc || 1;
- while (
- this.isHiddenDayHash[(out.day() + (isExclusive ? inc : 0) + 7) % 7]
- ) {
- out.add(inc, 'days');
- }
- return out;
- },
-
-
- // Returns the date range of the full days the given range visually appears to occupy.
- // Returns a new range object.
- computeDayRange: function(range) {
- var startDay = range.start.clone().stripTime(); // the beginning of the day the range starts
- var end = range.end;
- var endDay = null;
- var endTimeMS;
-
- if (end) {
- endDay = end.clone().stripTime(); // the beginning of the day the range exclusively ends
- endTimeMS = +end.time(); // # of milliseconds into `endDay`
-
- // If the end time is actually inclusively part of the next day and is equal to or
- // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.
- // Otherwise, leaving it as inclusive will cause it to exclude `endDay`.
- if (endTimeMS && endTimeMS >= this.nextDayThreshold) {
- endDay.add(1, 'days');
- }
- }
-
- // If no end was specified, or if it is within `startDay` but not past nextDayThreshold,
- // assign the default duration of one day.
- if (!end || endDay <= startDay) {
- endDay = startDay.clone().add(1, 'days');
- }
-
- return { start: startDay, end: endDay };
- },
-
-
- // Does the given event visually appear to occupy more than one day?
- isMultiDayEvent: function(event) {
- var range = this.computeDayRange(event); // event is range-ish
-
- return range.end.diff(range.start, 'days') > 1;
- }
-
-});
-
-;;
-
-/*
-Embodies a div that has potential scrollbars
-*/
-var Scroller = FC.Scroller = Class.extend({
-
- el: null, // the guaranteed outer element
- scrollEl: null, // the element with the scrollbars
- overflowX: null,
- overflowY: null,
-
-
- constructor: function(options) {
- options = options || {};
- this.overflowX = options.overflowX || options.overflow || 'auto';
- this.overflowY = options.overflowY || options.overflow || 'auto';
- },
-
-
- render: function() {
- this.el = this.renderEl();
- this.applyOverflow();
- },
-
-
- renderEl: function() {
- return (this.scrollEl = $('<div class="fc-scroller"></div>'));
- },
-
-
- // sets to natural height, unlocks overflow
- clear: function() {
- this.setHeight('auto');
- this.applyOverflow();
- },
-
-
- destroy: function() {
- this.el.remove();
- },
-
-
- // Overflow
- // -----------------------------------------------------------------------------------------------------------------
-
-
- applyOverflow: function() {
- this.scrollEl.css({
- 'overflow-x': this.overflowX,
- 'overflow-y': this.overflowY
- });
- },
-
-
- // Causes any 'auto' overflow values to resolves to 'scroll' or 'hidden'.
- // Useful for preserving scrollbar widths regardless of future resizes.
- // Can pass in scrollbarWidths for optimization.
- lockOverflow: function(scrollbarWidths) {
- var overflowX = this.overflowX;
- var overflowY = this.overflowY;
-
- scrollbarWidths = scrollbarWidths || this.getScrollbarWidths();
-
- if (overflowX === 'auto') {
- overflowX = (
- scrollbarWidths.top || scrollbarWidths.bottom || // horizontal scrollbars?
- // OR scrolling pane with massless scrollbars?
- this.scrollEl[0].scrollWidth - 1 > this.scrollEl[0].clientWidth
- // subtract 1 because of IE off-by-one issue
- ) ? 'scroll' : 'hidden';
- }
-
- if (overflowY === 'auto') {
- overflowY = (
- scrollbarWidths.left || scrollbarWidths.right || // vertical scrollbars?
- // OR scrolling pane with massless scrollbars?
- this.scrollEl[0].scrollHeight - 1 > this.scrollEl[0].clientHeight
- // subtract 1 because of IE off-by-one issue
- ) ? 'scroll' : 'hidden';
- }
-
- this.scrollEl.css({ 'overflow-x': overflowX, 'overflow-y': overflowY });
- },
-
-
- // Getters / Setters
- // -----------------------------------------------------------------------------------------------------------------
-
-
- setHeight: function(height) {
- this.scrollEl.height(height);
- },
-
-
- getScrollTop: function() {
- return this.scrollEl.scrollTop();
- },
-
-
- setScrollTop: function(top) {
- this.scrollEl.scrollTop(top);
- },
-
-
- getClientWidth: function() {
- return this.scrollEl[0].clientWidth;
- },
-
-
- getClientHeight: function() {
- return this.scrollEl[0].clientHeight;
- },
-
-
- getScrollbarWidths: function() {
- return getScrollbarWidths(this.scrollEl);
- }
-
-});
-
-;;
-
-var Calendar = FC.Calendar = Class.extend({
-
- dirDefaults: null, // option defaults related to LTR or RTL
- langDefaults: null, // option defaults related to current locale
- overrides: null, // option overrides given to the fullCalendar constructor
- options: null, // all defaults combined with overrides
- viewSpecCache: null, // cache of view definitions
- view: null, // current View object
- header: null,
- loadingLevel: 0, // number of simultaneous loading tasks
-
-
- // a lot of this class' OOP logic is scoped within this constructor function,
- // but in the future, write individual methods on the prototype.
- constructor: Calendar_constructor,
-
-
- // Subclasses can override this for initialization logic after the constructor has been called
- initialize: function() {
- },
-
-
- // Initializes `this.options` and other important options-related objects
- initOptions: function(overrides) {
- var lang, langDefaults;
- var isRTL, dirDefaults;
-
- // converts legacy options into non-legacy ones.
- // in the future, when this is removed, don't use `overrides` reference. make a copy.
- overrides = massageOverrides(overrides);
-
- lang = overrides.lang;
- langDefaults = langOptionHash[lang];
- if (!langDefaults) {
- lang = Calendar.defaults.lang;
- langDefaults = langOptionHash[lang] || {};
- }
-
- isRTL = firstDefined(
- overrides.isRTL,
- langDefaults.isRTL,
- Calendar.defaults.isRTL
- );
- dirDefaults = isRTL ? Calendar.rtlDefaults : {};
-
- this.dirDefaults = dirDefaults;
- this.langDefaults = langDefaults;
- this.overrides = overrides;
- this.options = mergeOptions([ // merge defaults and overrides. lowest to highest precedence
- Calendar.defaults, // global defaults
- dirDefaults,
- langDefaults,
- overrides
- ]);
- populateInstanceComputableOptions(this.options);
-
- this.viewSpecCache = {}; // somewhat unrelated
- },
-
-
- // Gets information about how to create a view. Will use a cache.
- getViewSpec: function(viewType) {
- var cache = this.viewSpecCache;
-
- return cache[viewType] || (cache[viewType] = this.buildViewSpec(viewType));
- },
-
-
- // Given a duration singular unit, like "week" or "day", finds a matching view spec.
- // Preference is given to views that have corresponding buttons.
- getUnitViewSpec: function(unit) {
- var viewTypes;
- var i;
- var spec;
-
- if ($.inArray(unit, intervalUnits) != -1) {
-
- // put views that have buttons first. there will be duplicates, but oh well
- viewTypes = this.header.getViewsWithButtons();
- $.each(FC.views, function(viewType) { // all views
- viewTypes.push(viewType);
- });
-
- for (i = 0; i < viewTypes.length; i++) {
- spec = this.getViewSpec(viewTypes[i]);
- if (spec) {
- if (spec.singleUnit == unit) {
- return spec;
- }
- }
- }
- }
- },
-
-
- // Builds an object with information on how to create a given view
- buildViewSpec: function(requestedViewType) {
- var viewOverrides = this.overrides.views || {};
- var specChain = []; // for the view. lowest to highest priority
- var defaultsChain = []; // for the view. lowest to highest priority
- var overridesChain = []; // for the view. lowest to highest priority
- var viewType = requestedViewType;
- var spec; // for the view
- var overrides; // for the view
- var duration;
- var unit;
-
- // iterate from the specific view definition to a more general one until we hit an actual View class
- while (viewType) {
- spec = fcViews[viewType];
- overrides = viewOverrides[viewType];
- viewType = null; // clear. might repopulate for another iteration
-
- if (typeof spec === 'function') { // TODO: deprecate
- spec = { 'class': spec };
- }
-
- if (spec) {
- specChain.unshift(spec);
- defaultsChain.unshift(spec.defaults || {});
- duration = duration || spec.duration;
- viewType = viewType || spec.type;
- }
-
- if (overrides) {
- overridesChain.unshift(overrides); // view-specific option hashes have options at zero-level
- duration = duration || overrides.duration;
- viewType = viewType || overrides.type;
- }
- }
-
- spec = mergeProps(specChain);
- spec.type = requestedViewType;
- if (!spec['class']) {
- return false;
- }
-
- if (duration) {
- duration = moment.duration(duration);
- if (duration.valueOf()) { // valid?
- spec.duration = duration;
- unit = computeIntervalUnit(duration);
-
- // view is a single-unit duration, like "week" or "day"
- // incorporate options for this. lowest priority
- if (duration.as(unit) === 1) {
- spec.singleUnit = unit;
- overridesChain.unshift(viewOverrides[unit] || {});
- }
- }
- }
-
- spec.defaults = mergeOptions(defaultsChain);
- spec.overrides = mergeOptions(overridesChain);
-
- this.buildViewSpecOptions(spec);
- this.buildViewSpecButtonText(spec, requestedViewType);
-
- return spec;
- },
-
-
- // Builds and assigns a view spec's options object from its already-assigned defaults and overrides
- buildViewSpecOptions: function(spec) {
- spec.options = mergeOptions([ // lowest to highest priority
- Calendar.defaults, // global defaults
- spec.defaults, // view's defaults (from ViewSubclass.defaults)
- this.dirDefaults,
- this.langDefaults, // locale and dir take precedence over view's defaults!
- this.overrides, // calendar's overrides (options given to constructor)
- spec.overrides // view's overrides (view-specific options)
- ]);
- populateInstanceComputableOptions(spec.options);
- },
-
-
- // Computes and assigns a view spec's buttonText-related options
- buildViewSpecButtonText: function(spec, requestedViewType) {
-
- // given an options object with a possible `buttonText` hash, lookup the buttonText for the
- // requested view, falling back to a generic unit entry like "week" or "day"
- function queryButtonText(options) {
- var buttonText = options.buttonText || {};
- return buttonText[requestedViewType] ||
- (spec.singleUnit ? buttonText[spec.singleUnit] : null);
- }
-
- // highest to lowest priority
- spec.buttonTextOverride =
- queryButtonText(this.overrides) || // constructor-specified buttonText lookup hash takes precedence
- spec.overrides.buttonText; // `buttonText` for view-specific options is a string
-
- // highest to lowest priority. mirrors buildViewSpecOptions
- spec.buttonTextDefault =
- queryButtonText(this.langDefaults) ||
- queryButtonText(this.dirDefaults) ||
- spec.defaults.buttonText || // a single string. from ViewSubclass.defaults
- queryButtonText(Calendar.defaults) ||
- (spec.duration ? this.humanizeDuration(spec.duration) : null) || // like "3 days"
- requestedViewType; // fall back to given view name
- },
-
-
- // Given a view name for a custom view or a standard view, creates a ready-to-go View object
- instantiateView: function(viewType) {
- var spec = this.getViewSpec(viewType);
-
- return new spec['class'](this, viewType, spec.options, spec.duration);
- },
-
-
- // Returns a boolean about whether the view is okay to instantiate at some point
- isValidViewType: function(viewType) {
- return Boolean(this.getViewSpec(viewType));
- },
-
-
- // Should be called when any type of async data fetching begins
- pushLoading: function() {
- if (!(this.loadingLevel++)) {
- this.trigger('loading', null, true, this.view);
- }
- },
-
-
- // Should be called when any type of async data fetching completes
- popLoading: function() {
- if (!(--this.loadingLevel)) {
- this.trigger('loading', null, false, this.view);
- }
- },
-
-
- // Given arguments to the select method in the API, returns a span (unzoned start/end and other info)
- buildSelectSpan: function(zonedStartInput, zonedEndInput) {
- var start = this.moment(zonedStartInput).stripZone();
- var end;
-
- if (zonedEndInput) {
- end = this.moment(zonedEndInput).stripZone();
- }
- else if (start.hasTime()) {
- end = start.clone().add(this.defaultTimedEventDuration);
- }
- else {
- end = start.clone().add(this.defaultAllDayEventDuration);
- }
-
- return { start: start, end: end };
- }
-
-});
-
-
-Calendar.mixin(EmitterMixin);
-
-
-function Calendar_constructor(element, overrides) {
- var t = this;
-
-
- t.initOptions(overrides || {});
- var options = this.options;
-
-
- // Exports
- // -----------------------------------------------------------------------------------
-
- t.render = render;
- t.destroy = destroy;
- t.refetchEvents = refetchEvents;
- t.reportEvents = reportEvents;
- t.reportEventChange = reportEventChange;
- t.rerenderEvents = renderEvents; // `renderEvents` serves as a rerender. an API method
- t.changeView = renderView; // `renderView` will switch to another view
- t.select = select;
- t.unselect = unselect;
- t.prev = prev;
- t.next = next;
- t.prevYear = prevYear;
- t.nextYear = nextYear;
- t.today = today;
- t.gotoDate = gotoDate;
- t.incrementDate = incrementDate;
- t.zoomTo = zoomTo;
- t.getDate = getDate;
- t.getCalendar = getCalendar;
- t.getView = getView;
- t.option = option;
- t.trigger = trigger;
-
-
-
- // Language-data Internals
- // -----------------------------------------------------------------------------------
- // Apply overrides to the current language's data
-
-
- var localeData = createObject( // make a cheap copy
- getMomentLocaleData(options.lang) // will fall back to en
- );
-
- if (options.monthNames) {
- localeData._months = options.monthNames;
- }
- if (options.monthNamesShort) {
- localeData._monthsShort = options.monthNamesShort;
- }
- if (options.dayNames) {
- localeData._weekdays = options.dayNames;
- }
- if (options.dayNamesShort) {
- localeData._weekdaysShort = options.dayNamesShort;
- }
- if (options.firstDay != null) {
- var _week = createObject(localeData._week); // _week: { dow: # }
- _week.dow = options.firstDay;
- localeData._week = _week;
- }
-
- // assign a normalized value, to be used by our .week() moment extension
- localeData._fullCalendar_weekCalc = (function(weekCalc) {
- if (typeof weekCalc === 'function') {
- return weekCalc;
- }
- else if (weekCalc === 'local') {
- return weekCalc;
- }
- else if (weekCalc === 'iso' || weekCalc === 'ISO') {
- return 'ISO';
- }
- })(options.weekNumberCalculation);
-
-
-
- // Calendar-specific Date Utilities
- // -----------------------------------------------------------------------------------
-
-
- t.defaultAllDayEventDuration = moment.duration(options.defaultAllDayEventDuration);
- t.defaultTimedEventDuration = moment.duration(options.defaultTimedEventDuration);
-
-
- // Builds a moment using the settings of the current calendar: timezone and language.
- // Accepts anything the vanilla moment() constructor accepts.
- t.moment = function() {
- var mom;
-
- if (options.timezone === 'local') {
- mom = FC.moment.apply(null, arguments);
-
- // Force the moment to be local, because FC.moment doesn't guarantee it.
- if (mom.hasTime()) { // don't give ambiguously-timed moments a local zone
- mom.local();
- }
- }
- else if (options.timezone === 'UTC') {
- mom = FC.moment.utc.apply(null, arguments); // process as UTC
- }
- else {
- mom = FC.moment.parseZone.apply(null, arguments); // let the input decide the zone
- }
-
- if ('_locale' in mom) { // moment 2.8 and above
- mom._locale = localeData;
- }
- else { // pre-moment-2.8
- mom._lang = localeData;
- }
-
- return mom;
- };
-
-
- // Returns a boolean about whether or not the calendar knows how to calculate
- // the timezone offset of arbitrary dates in the current timezone.
- t.getIsAmbigTimezone = function() {
- return options.timezone !== 'local' && options.timezone !== 'UTC';
- };
-
-
- // Returns a copy of the given date in the current timezone. Has no effect on dates without times.
- t.applyTimezone = function(date) {
- if (!date.hasTime()) {
- return date.clone();
- }
-
- var zonedDate = t.moment(date.toArray());
- var timeAdjust = date.time() - zonedDate.time();
- var adjustedZonedDate;
-
- // Safari sometimes has problems with this coersion when near DST. Adjust if necessary. (bug #2396)
- if (timeAdjust) { // is the time result different than expected?
- adjustedZonedDate = zonedDate.clone().add(timeAdjust); // add milliseconds
- if (date.time() - adjustedZonedDate.time() === 0) { // does it match perfectly now?
- zonedDate = adjustedZonedDate;
- }
- }
-
- return zonedDate;
- };
-
-
- // Returns a moment for the current date, as defined by the client's computer or from the `now` option.
- // Will return an moment with an ambiguous timezone.
- t.getNow = function() {
- var now = options.now;
- if (typeof now === 'function') {
- now = now();
- }
- return t.moment(now).stripZone();
- };
-
-
- // Get an event's normalized end date. If not present, calculate it from the defaults.
- t.getEventEnd = function(event) {
- if (event.end) {
- return event.end.clone();
- }
- else {
- return t.getDefaultEventEnd(event.allDay, event.start);
- }
- };
-
-
- // Given an event's allDay status and start date, return what its fallback end date should be.
- // TODO: rename to computeDefaultEventEnd
- t.getDefaultEventEnd = function(allDay, zonedStart) {
- var end = zonedStart.clone();
-
- if (allDay) {
- end.stripTime().add(t.defaultAllDayEventDuration);
- }
- else {
- end.add(t.defaultTimedEventDuration);
- }
-
- if (t.getIsAmbigTimezone()) {
- end.stripZone(); // we don't know what the tzo should be
- }
-
- return end;
- };
-
-
- // Produces a human-readable string for the given duration.
- // Side-effect: changes the locale of the given duration.
- t.humanizeDuration = function(duration) {
- return (duration.locale || duration.lang).call(duration, options.lang) // works moment-pre-2.8
- .humanize();
- };
-
-
-
- // Imports
- // -----------------------------------------------------------------------------------
-
-
- EventManager.call(t, options);
- var isFetchNeeded = t.isFetchNeeded;
- var fetchEvents = t.fetchEvents;
-
-
-
- // Locals
- // -----------------------------------------------------------------------------------
-
-
- var _element = element[0];
- var header;
- var headerElement;
- var content;
- var tm; // for making theme classes
- var currentView; // NOTE: keep this in sync with this.view
- var viewsByType = {}; // holds all instantiated view instances, current or not
- var suggestedViewHeight;
- var windowResizeProxy; // wraps the windowResize function
- var ignoreWindowResize = 0;
- var events = [];
- var date; // unzoned
-
-
-
- // Main Rendering
- // -----------------------------------------------------------------------------------
-
-
- // compute the initial ambig-timezone date
- if (options.defaultDate != null) {
- date = t.moment(options.defaultDate).stripZone();
- }
- else {
- date = t.getNow(); // getNow already returns unzoned
- }
-
-
- function render() {
- if (!content) {
- initialRender();
- }
- else if (elementVisible()) {
- // mainly for the public API
- calcSize();
- renderView();
- }
- }
-
-
- function initialRender() {
- tm = options.theme ? 'ui' : 'fc';
- element.addClass('fc');
-
- if (options.isRTL) {
- element.addClass('fc-rtl');
- }
- else {
- element.addClass('fc-ltr');
- }
-
- if (options.theme) {
- element.addClass('ui-widget');
- }
- else {
- element.addClass('fc-unthemed');
- }
-
- content = $("<div class='fc-view-container'/>").prependTo(element);
-
- header = t.header = new Header(t, options);
- headerElement = header.render();
- if (headerElement) {
- element.prepend(headerElement);
- }
-
- renderView(options.defaultView);
-
- if (options.handleWindowResize) {
- windowResizeProxy = debounce(windowResize, options.windowResizeDelay); // prevents rapid calls
- $(window).resize(windowResizeProxy);
- }
- }
-
-
- function destroy() {
-
- if (currentView) {
- currentView.removeElement();
-
- // NOTE: don't null-out currentView/t.view in case API methods are called after destroy.
- // It is still the "current" view, just not rendered.
- }
-
- header.removeElement();
- content.remove();
- element.removeClass('fc fc-ltr fc-rtl fc-unthemed ui-widget');
-
- if (windowResizeProxy) {
- $(window).unbind('resize', windowResizeProxy);
- }
- }
-
-
- function elementVisible() {
- return element.is(':visible');
- }
-
-
-
- // View Rendering
- // -----------------------------------------------------------------------------------
-
-
- // Renders a view because of a date change, view-type change, or for the first time.
- // If not given a viewType, keep the current view but render different dates.
- function renderView(viewType) {
- ignoreWindowResize++;
-
- // if viewType is changing, remove the old view's rendering
- if (currentView && viewType && currentView.type !== viewType) {
- header.deactivateButton(currentView.type);
- freezeContentHeight(); // prevent a scroll jump when view element is removed
- currentView.removeElement();
- currentView = t.view = null;
- }
-
- // if viewType changed, or the view was never created, create a fresh view
- if (!currentView && viewType) {
- currentView = t.view =
- viewsByType[viewType] ||
- (viewsByType[viewType] = t.instantiateView(viewType));
-
- currentView.setElement(
- $("<div class='fc-view fc-" + viewType + "-view' />").appendTo(content)
- );
- header.activateButton(viewType);
- }
-
- if (currentView) {
-
- // in case the view should render a period of time that is completely hidden
- date = currentView.massageCurrentDate(date);
-
- // render or rerender the view
- if (
- !currentView.displaying ||
- !date.isWithin(currentView.intervalStart, currentView.intervalEnd) // implicit date window change
- ) {
- if (elementVisible()) {
-
- currentView.display(date); // will call freezeContentHeight
- unfreezeContentHeight(); // immediately unfreeze regardless of whether display is async
-
- // need to do this after View::render, so dates are calculated
- updateHeaderTitle();
- updateTodayButton();
-
- getAndRenderEvents();
- }
- }
- }
-
- unfreezeContentHeight(); // undo any lone freezeContentHeight calls
- ignoreWindowResize--;
- }
-
-
-
- // Resizing
- // -----------------------------------------------------------------------------------
-
-
- t.getSuggestedViewHeight = function() {
- if (suggestedViewHeight === undefined) {
- calcSize();
- }
- return suggestedViewHeight;
- };
-
-
- t.isHeightAuto = function() {
- return options.contentHeight === 'auto' || options.height === 'auto';
- };
-
-
- function updateSize(shouldRecalc) {
- if (elementVisible()) {
-
- if (shouldRecalc) {
- _calcSize();
- }
-
- ignoreWindowResize++;
- currentView.updateSize(true); // isResize=true. will poll getSuggestedViewHeight() and isHeightAuto()
- ignoreWindowResize--;
-
- return true; // signal success
- }
- }
-
-
- function calcSize() {
- if (elementVisible()) {
- _calcSize();
- }
- }
-
-
- function _calcSize() { // assumes elementVisible
- if (typeof options.contentHeight === 'number') { // exists and not 'auto'
- suggestedViewHeight = options.contentHeight;
- }
- else if (typeof options.height === 'number') { // exists and not 'auto'
- suggestedViewHeight = options.height - (headerElement ? headerElement.outerHeight(true) : 0);
- }
- else {
- suggestedViewHeight = Math.round(content.width() / Math.max(options.aspectRatio, .5));
- }
- }
-
-
- function windowResize(ev) {
- if (
- !ignoreWindowResize &&
- ev.target === window && // so we don't process jqui "resize" events that have bubbled up
- currentView.start // view has already been rendered
- ) {
- if (updateSize(true)) {
- currentView.trigger('windowResize', _element);
- }
- }
- }
-
-
-
- /* Event Fetching/Rendering
- -----------------------------------------------------------------------------*/
- // TODO: going forward, most of this stuff should be directly handled by the view
-
-
- function refetchEvents() { // can be called as an API method
- destroyEvents(); // so that events are cleared before user starts waiting for AJAX
- fetchAndRenderEvents();
- }
-
-
- function renderEvents() { // destroys old events if previously rendered
- if (elementVisible()) {
- freezeContentHeight();
- currentView.displayEvents(events);
- unfreezeContentHeight();
- }
- }
-
-
- function destroyEvents() {
- freezeContentHeight();
- currentView.clearEvents();
- unfreezeContentHeight();
- }
-
-
- function getAndRenderEvents() {
- if (!options.lazyFetching || isFetchNeeded(currentView.start, currentView.end)) {
- fetchAndRenderEvents();
- }
- else {
- renderEvents();
- }
- }
-
-
- function fetchAndRenderEvents() {
- fetchEvents(currentView.start, currentView.end);
- // ... will call reportEvents
- // ... which will call renderEvents
- }
-
-
- // called when event data arrives
- function reportEvents(_events) {
- events = _events;
- renderEvents();
- }
-
-
- // called when a single event's data has been changed
- function reportEventChange() {
- renderEvents();
- }
-
-
-
- /* Header Updating
- -----------------------------------------------------------------------------*/
-
-
- function updateHeaderTitle() {
- header.updateTitle(currentView.title);
- }
-
-
- function updateTodayButton() {
- var now = t.getNow();
- if (now.isWithin(currentView.intervalStart, currentView.intervalEnd)) {
- header.disableButton('today');
- }
- else {
- header.enableButton('today');
- }
- }
-
-
-
- /* Selection
- -----------------------------------------------------------------------------*/
-
-
- // this public method receives start/end dates in any format, with any timezone
- function select(zonedStartInput, zonedEndInput) {
- currentView.select(
- t.buildSelectSpan.apply(t, arguments)
- );
- }
-
-
- function unselect() { // safe to be called before renderView
- if (currentView) {
- currentView.unselect();
- }
- }
-
-
-
- /* Date
- -----------------------------------------------------------------------------*/
-
-
- function prev() {
- date = currentView.computePrevDate(date);
- renderView();
- }
-
-
- function next() {
- date = currentView.computeNextDate(date);
- renderView();
- }
-
-
- function prevYear() {
- date.add(-1, 'years');
- renderView();
- }
-
-
- function nextYear() {
- date.add(1, 'years');
- renderView();
- }
-
-
- function today() {
- date = t.getNow();
- renderView();
- }
-
-
- function gotoDate(zonedDateInput) {
- date = t.moment(zonedDateInput).stripZone();
- renderView();
- }
-
-
- function incrementDate(delta) {
- date.add(moment.duration(delta));
- renderView();
- }
-
-
- // Forces navigation to a view for the given date.
- // `viewType` can be a specific view name or a generic one like "week" or "day".
- function zoomTo(newDate, viewType) {
- var spec;
-
- viewType = viewType || 'day'; // day is default zoom
- spec = t.getViewSpec(viewType) || t.getUnitViewSpec(viewType);
-
- date = newDate.clone();
- renderView(spec ? spec.type : null);
- }
-
-
- // for external API
- function getDate() {
- return t.applyTimezone(date); // infuse the calendar's timezone
- }
-
-
-
- /* Height "Freezing"
- -----------------------------------------------------------------------------*/
- // TODO: move this into the view
-
- t.freezeContentHeight = freezeContentHeight;
- t.unfreezeContentHeight = unfreezeContentHeight;
-
-
- function freezeContentHeight() {
- content.css({
- width: '100%',
- height: content.height(),
- overflow: 'hidden'
- });
- }
-
-
- function unfreezeContentHeight() {
- content.css({
- width: '',
- height: '',
- overflow: ''
- });
- }
-
-
-
- /* Misc
- -----------------------------------------------------------------------------*/
-
-
- function getCalendar() {
- return t;
- }
-
-
- function getView() {
- return currentView;
- }
-
-
- function option(name, value) {
- if (value === undefined) {
- return options[name];
- }
- if (name == 'height' || name == 'contentHeight' || name == 'aspectRatio') {
- options[name] = value;
- updateSize(true); // true = allow recalculation of height
- }
- }
-
-
- function trigger(name, thisObj) { // overrides the Emitter's trigger method :(
- var args = Array.prototype.slice.call(arguments, 2);
-
- thisObj = thisObj || _element;
- this.triggerWith(name, thisObj, args); // Emitter's method
-
- if (options[name]) {
- return options[name].apply(thisObj, args);
- }
- }
-
- t.initialize();
-}
-
-;;
-
-Calendar.defaults = {
-
- titleRangeSeparator: ' \u2014 ', // emphasized dash
- monthYearFormat: 'MMMM YYYY', // required for en. other languages rely on datepicker computable option
-
- defaultTimedEventDuration: '02:00:00',
- defaultAllDayEventDuration: { days: 1 },
- forceEventDuration: false,
- nextDayThreshold: '09:00:00', // 9am
-
- // display
- defaultView: 'month',
- aspectRatio: 1.35,
- header: {
- left: 'title',
- center: '',
- right: 'today prev,next'
- },
- weekends: true,
- weekNumbers: false,
-
- weekNumberTitle: 'W',
- weekNumberCalculation: 'local',
-
- //editable: false,
-
- //nowIndicator: false,
-
- scrollTime: '06:00:00',
-
- // event ajax
- lazyFetching: true,
- startParam: 'start',
- endParam: 'end',
- timezoneParam: 'timezone',
-
- timezone: false,
-
- //allDayDefault: undefined,
-
- // locale
- isRTL: false,
- buttonText: {
- prev: "prev",
- next: "next",
- prevYear: "prev year",
- nextYear: "next year",
- year: 'year', // TODO: locale files need to specify this
- today: 'today',
- month: 'month',
- week: 'week',
- day: 'day'
- },
-
- buttonIcons: {
- prev: 'left-single-arrow',
- next: 'right-single-arrow',
- prevYear: 'left-double-arrow',
- nextYear: 'right-double-arrow'
- },
-
- // jquery-ui theming
- theme: false,
- themeButtonIcons: {
- prev: 'circle-triangle-w',
- next: 'circle-triangle-e',
- prevYear: 'seek-prev',
- nextYear: 'seek-next'
- },
-
- //eventResizableFromStart: false,
- dragOpacity: .75,
- dragRevertDuration: 500,
- dragScroll: true,
-
- //selectable: false,
- unselectAuto: true,
-
- dropAccept: '*',
-
- eventOrder: 'title',
-
- eventLimit: false,
- eventLimitText: 'more',
- eventLimitClick: 'popover',
- dayPopoverFormat: 'LL',
-
- handleWindowResize: true,
- windowResizeDelay: 200, // milliseconds before an updateSize happens
-
- longPressDelay: 1000
-
-};
-
-
-Calendar.englishDefaults = { // used by lang.js
- dayPopoverFormat: 'dddd, MMMM D'
-};
-
-
-Calendar.rtlDefaults = { // right-to-left defaults
- header: { // TODO: smarter solution (first/center/last ?)
- left: 'next,prev today',
- center: '',
- right: 'title'
- },
- buttonIcons: {
- prev: 'right-single-arrow',
- next: 'left-single-arrow',
- prevYear: 'right-double-arrow',
- nextYear: 'left-double-arrow'
- },
- themeButtonIcons: {
- prev: 'circle-triangle-e',
- next: 'circle-triangle-w',
- nextYear: 'seek-prev',
- prevYear: 'seek-next'
- }
-};
-
-;;
-
-var langOptionHash = FC.langs = {}; // initialize and expose
-
-
-// TODO: document the structure and ordering of a FullCalendar lang file
-// TODO: rename everything "lang" to "locale", like what the moment project did
-
-
-// Initialize jQuery UI datepicker translations while using some of the translations
-// Will set this as the default language for datepicker.
-FC.datepickerLang = function(langCode, dpLangCode, dpOptions) {
-
- // get the FullCalendar internal option hash for this language. create if necessary
- var fcOptions = langOptionHash[langCode] || (langOptionHash[langCode] = {});
-
- // transfer some simple options from datepicker to fc
- fcOptions.isRTL = dpOptions.isRTL;
- fcOptions.weekNumberTitle = dpOptions.weekHeader;
-
- // compute some more complex options from datepicker
- $.each(dpComputableOptions, function(name, func) {
- fcOptions[name] = func(dpOptions);
- });
-
- // is jQuery UI Datepicker is on the page?
- if ($.datepicker) {
-
- // Register the language data.
- // FullCalendar and MomentJS use language codes like "pt-br" but Datepicker
- // does it like "pt-BR" or if it doesn't have the language, maybe just "pt".
- // Make an alias so the language can be referenced either way.
- $.datepicker.regional[dpLangCode] =
- $.datepicker.regional[langCode] = // alias
- dpOptions;
-
- // Alias 'en' to the default language data. Do this every time.
- $.datepicker.regional.en = $.datepicker.regional[''];
-
- // Set as Datepicker's global defaults.
- $.datepicker.setDefaults(dpOptions);
- }
-};
-
-
-// Sets FullCalendar-specific translations. Will set the language as the global default.
-FC.lang = function(langCode, newFcOptions) {
- var fcOptions;
- var momOptions;
-
- // get the FullCalendar internal option hash for this language. create if necessary
- fcOptions = langOptionHash[langCode] || (langOptionHash[langCode] = {});
-
- // provided new options for this language? merge them in
- if (newFcOptions) {
- fcOptions = langOptionHash[langCode] = mergeOptions([ fcOptions, newFcOptions ]);
- }
-
- // compute language options that weren't defined.
- // always do this. newFcOptions can be undefined when initializing from i18n file,
- // so no way to tell if this is an initialization or a default-setting.
- momOptions = getMomentLocaleData(langCode); // will fall back to en
- $.each(momComputableOptions, function(name, func) {
- if (fcOptions[name] == null) {
- fcOptions[name] = func(momOptions, fcOptions);
- }
- });
-
- // set it as the default language for FullCalendar
- Calendar.defaults.lang = langCode;
-};
-
-
-// NOTE: can't guarantee any of these computations will run because not every language has datepicker
-// configs, so make sure there are English fallbacks for these in the defaults file.
-var dpComputableOptions = {
-
- buttonText: function(dpOptions) {
- return {
- // the translations sometimes wrongly contain HTML entities
- prev: stripHtmlEntities(dpOptions.prevText),
- next: stripHtmlEntities(dpOptions.nextText),
- today: stripHtmlEntities(dpOptions.currentText)
- };
- },
-
- // Produces format strings like "MMMM YYYY" -> "September 2014"
- monthYearFormat: function(dpOptions) {
- return dpOptions.showMonthAfterYear ?
- 'YYYY[' + dpOptions.yearSuffix + '] MMMM' :
- 'MMMM YYYY[' + dpOptions.yearSuffix + ']';
- }
-
-};
-
-var momComputableOptions = {
-
- // Produces format strings like "ddd M/D" -> "Fri 9/15"
- dayOfMonthFormat: function(momOptions, fcOptions) {
- var format = momOptions.longDateFormat('l'); // for the format like "M/D/YYYY"
-
- // strip the year off the edge, as well as other misc non-whitespace chars
- format = format.replace(/^Y+[^\w\s]*|[^\w\s]*Y+$/g, '');
-
- if (fcOptions.isRTL) {
- format += ' ddd'; // for RTL, add day-of-week to end
- }
- else {
- format = 'ddd ' + format; // for LTR, add day-of-week to beginning
- }
- return format;
- },
-
- // Produces format strings like "h:mma" -> "6:00pm"
- mediumTimeFormat: function(momOptions) { // can't be called `timeFormat` because collides with option
- return momOptions.longDateFormat('LT')
- .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
- },
-
- // Produces format strings like "h(:mm)a" -> "6pm" / "6:30pm"
- smallTimeFormat: function(momOptions) {
- return momOptions.longDateFormat('LT')
- .replace(':mm', '(:mm)')
- .replace(/(\Wmm)$/, '($1)') // like above, but for foreign langs
- .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
- },
-
- // Produces format strings like "h(:mm)t" -> "6p" / "6:30p"
- extraSmallTimeFormat: function(momOptions) {
- return momOptions.longDateFormat('LT')
- .replace(':mm', '(:mm)')
- .replace(/(\Wmm)$/, '($1)') // like above, but for foreign langs
- .replace(/\s*a$/i, 't'); // convert to AM/PM/am/pm to lowercase one-letter. remove any spaces beforehand
- },
-
- // Produces format strings like "ha" / "H" -> "6pm" / "18"
- hourFormat: function(momOptions) {
- return momOptions.longDateFormat('LT')
- .replace(':mm', '')
- .replace(/(\Wmm)$/, '') // like above, but for foreign langs
- .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
- },
-
- // Produces format strings like "h:mm" -> "6:30" (with no AM/PM)
- noMeridiemTimeFormat: function(momOptions) {
- return momOptions.longDateFormat('LT')
- .replace(/\s*a$/i, ''); // remove trailing AM/PM
- }
-
-};
-
-
-// options that should be computed off live calendar options (considers override options)
-// TODO: best place for this? related to lang?
-// TODO: flipping text based on isRTL is a bad idea because the CSS `direction` might want to handle it
-var instanceComputableOptions = {
-
- // Produces format strings for results like "Mo 16"
- smallDayDateFormat: function(options) {
- return options.isRTL ?
- 'D dd' :
- 'dd D';
- },
-
- // Produces format strings for results like "Wk 5"
- weekFormat: function(options) {
- return options.isRTL ?
- 'w[ ' + options.weekNumberTitle + ']' :
- '[' + options.weekNumberTitle + ' ]w';
- },
-
- // Produces format strings for results like "Wk5"
- smallWeekFormat: function(options) {
- return options.isRTL ?
- 'w[' + options.weekNumberTitle + ']' :
- '[' + options.weekNumberTitle + ']w';
- }
-
-};
-
-function populateInstanceComputableOptions(options) {
- $.each(instanceComputableOptions, function(name, func) {
- if (options[name] == null) {
- options[name] = func(options);
- }
- });
-}
-
-
-// Returns moment's internal locale data. If doesn't exist, returns English.
-// Works with moment-pre-2.8
-function getMomentLocaleData(langCode) {
- var func = moment.localeData || moment.langData;
- return func.call(moment, langCode) ||
- func.call(moment, 'en'); // the newer localData could return null, so fall back to en
-}
-
-
-// Initialize English by forcing computation of moment-derived options.
-// Also, sets it as the default.
-FC.lang('en', Calendar.englishDefaults);
-
-;;
-
-/* Top toolbar area with buttons and title
-----------------------------------------------------------------------------------------------------------------------*/
-// TODO: rename all header-related things to "toolbar"
-
-function Header(calendar, options) {
- var t = this;
-
- // exports
- t.render = render;
- t.removeElement = removeElement;
- t.updateTitle = updateTitle;
- t.activateButton = activateButton;
- t.deactivateButton = deactivateButton;
- t.disableButton = disableButton;
- t.enableButton = enableButton;
- t.getViewsWithButtons = getViewsWithButtons;
-
- // locals
- var el = $();
- var viewsWithButtons = [];
- var tm;
-
-
- function render() {
- var sections = options.header;
-
- tm = options.theme ? 'ui' : 'fc';
-
- if (sections) {
- el = $("<div class='fc-toolbar'/>")
- .append(renderSection('left'))
- .append(renderSection('right'))
- .append(renderSection('center'))
- .append('<div class="fc-clear"/>');
-
- return el;
- }
- }
-
-
- function removeElement() {
- el.remove();
- el = $();
- }
-
-
- function renderSection(position) {
- var sectionEl = $('<div class="fc-' + position + '"/>');
- var buttonStr = options.header[position];
-
- if (buttonStr) {
- $.each(buttonStr.split(' '), function(i) {
- var groupChildren = $();
- var isOnlyButtons = true;
- var groupEl;
-
- $.each(this.split(','), function(j, buttonName) {
- var customButtonProps;
- var viewSpec;
- var buttonClick;
- var overrideText; // text explicitly set by calendar's constructor options. overcomes icons
- var defaultText;
- var themeIcon;
- var normalIcon;
- var innerHtml;
- var classes;
- var button; // the element
-
- if (buttonName == 'title') {
- groupChildren = groupChildren.add($('<h2>&nbsp;</h2>')); // we always want it to take up height
- isOnlyButtons = false;
- }
- else {
- if ((customButtonProps = (calendar.options.customButtons || {})[buttonName])) {
- buttonClick = function(ev) {
- if (customButtonProps.click) {
- customButtonProps.click.call(button[0], ev);
- }
- };
- overrideText = ''; // icons will override text
- defaultText = customButtonProps.text;
- }
- else if ((viewSpec = calendar.getViewSpec(buttonName))) {
- buttonClick = function() {
- calendar.changeView(buttonName);
- };
- viewsWithButtons.push(buttonName);
- overrideText = viewSpec.buttonTextOverride;
- defaultText = viewSpec.buttonTextDefault;
- }
- else if (calendar[buttonName]) { // a calendar method
- buttonClick = function() {
- calendar[buttonName]();
- };
- overrideText = (calendar.overrides.buttonText || {})[buttonName];
- defaultText = options.buttonText[buttonName]; // everything else is considered default
- }
-
- if (buttonClick) {
-
- themeIcon =
- customButtonProps ?
- customButtonProps.themeIcon :
- options.themeButtonIcons[buttonName];
-
- normalIcon =
- customButtonProps ?
- customButtonProps.icon :
- options.buttonIcons[buttonName];
-
- if (overrideText) {
- innerHtml = htmlEscape(overrideText);
- }
- else if (themeIcon && options.theme) {
- innerHtml = "<span class='ui-icon ui-icon-" + themeIcon + "'></span>";
- }
- else if (normalIcon && !options.theme) {
- innerHtml = "<span class='fc-icon fc-icon-" + normalIcon + "'></span>";
- }
- else {
- innerHtml = htmlEscape(defaultText);
- }
-
- classes = [
- 'fc-' + buttonName + '-button',
- tm + '-button',
- tm + '-state-default'
- ];
-
- button = $( // type="button" so that it doesn't submit a form
- '<button type="button" class="' + classes.join(' ') + '">' +
- innerHtml +
- '</button>'
- )
- .click(function(ev) {
- // don't process clicks for disabled buttons
- if (!button.hasClass(tm + '-state-disabled')) {
-
- buttonClick(ev);
-
- // after the click action, if the button becomes the "active" tab, or disabled,
- // it should never have a hover class, so remove it now.
- if (
- button.hasClass(tm + '-state-active') ||
- button.hasClass(tm + '-state-disabled')
- ) {
- button.removeClass(tm + '-state-hover');
- }
- }
- })
- .mousedown(function() {
- // the *down* effect (mouse pressed in).
- // only on buttons that are not the "active" tab, or disabled
- button
- .not('.' + tm + '-state-active')
- .not('.' + tm + '-state-disabled')
- .addClass(tm + '-state-down');
- })
- .mouseup(function() {
- // undo the *down* effect
- button.removeClass(tm + '-state-down');
- })
- .hover(
- function() {
- // the *hover* effect.
- // only on buttons that are not the "active" tab, or disabled
- button
- .not('.' + tm + '-state-active')
- .not('.' + tm + '-state-disabled')
- .addClass(tm + '-state-hover');
- },
- function() {
- // undo the *hover* effect
- button
- .removeClass(tm + '-state-hover')
- .removeClass(tm + '-state-down'); // if mouseleave happens before mouseup
- }
- );
-
- groupChildren = groupChildren.add(button);
- }
- }
- });
-
- if (isOnlyButtons) {
- groupChildren
- .first().addClass(tm + '-corner-left').end()
- .last().addClass(tm + '-corner-right').end();
- }
-
- if (groupChildren.length > 1) {
- groupEl = $('<div/>');
- if (isOnlyButtons) {
- groupEl.addClass('fc-button-group');
- }
- groupEl.append(groupChildren);
- sectionEl.append(groupEl);
- }
- else {
- sectionEl.append(groupChildren); // 1 or 0 children
- }
- });
- }
-
- return sectionEl;
- }
-
-
- function updateTitle(text) {
- el.find('h2').text(text);
- }
-
-
- function activateButton(buttonName) {
- el.find('.fc-' + buttonName + '-button')
- .addClass(tm + '-state-active');
- }
-
-
- function deactivateButton(buttonName) {
- el.find('.fc-' + buttonName + '-button')
- .removeClass(tm + '-state-active');
- }
-
-
- function disableButton(buttonName) {
- el.find('.fc-' + buttonName + '-button')
- .attr('disabled', 'disabled')
- .addClass(tm + '-state-disabled');
- }
-
-
- function enableButton(buttonName) {
- el.find('.fc-' + buttonName + '-button')
- .removeAttr('disabled')
- .removeClass(tm + '-state-disabled');
- }
-
-
- function getViewsWithButtons() {
- return viewsWithButtons;
- }
-
-}
-
-;;
-
-FC.sourceNormalizers = [];
-FC.sourceFetchers = [];
-
-var ajaxDefaults = {
- dataType: 'json',
- cache: false
-};
-
-var eventGUID = 1;
-
-
-function EventManager(options) { // assumed to be a calendar
- var t = this;
-
-
- // exports
- t.isFetchNeeded = isFetchNeeded;
- t.fetchEvents = fetchEvents;
- t.addEventSource = addEventSource;
- t.removeEventSource = removeEventSource;
- t.updateEvent = updateEvent;
- t.renderEvent = renderEvent;
- t.removeEvents = removeEvents;
- t.clientEvents = clientEvents;
- t.mutateEvent = mutateEvent;
- t.normalizeEventDates = normalizeEventDates;
- t.normalizeEventTimes = normalizeEventTimes;
-
-
- // imports
- var reportEvents = t.reportEvents;
-
-
- // locals
- var stickySource = { events: [] };
- var sources = [ stickySource ];
- var rangeStart, rangeEnd;
- var currentFetchID = 0;
- var pendingSourceCnt = 0;
- var cache = []; // holds events that have already been expanded
-
-
- $.each(
- (options.events ? [ options.events ] : []).concat(options.eventSources || []),
- function(i, sourceInput) {
- var source = buildEventSource(sourceInput);
- if (source) {
- sources.push(source);
- }
- }
- );
-
-
-
- /* Fetching
- -----------------------------------------------------------------------------*/
-
-
- // start and end are assumed to be unzoned
- function isFetchNeeded(start, end) {
- return !rangeStart || // nothing has been fetched yet?
- start < rangeStart || end > rangeEnd; // is part of the new range outside of the old range?
- }
-
-
- function fetchEvents(start, end) {
- rangeStart = start;
- rangeEnd = end;
- cache = [];
- var fetchID = ++currentFetchID;
- var len = sources.length;
- pendingSourceCnt = len;
- for (var i=0; i<len; i++) {
- fetchEventSource(sources[i], fetchID);
- }
- }
-
-
- function fetchEventSource(source, fetchID) {
- _fetchEventSource(source, function(eventInputs) {
- var isArraySource = $.isArray(source.events);
- var i, eventInput;
- var abstractEvent;
-
- if (fetchID == currentFetchID) {
-
- if (eventInputs) {
- for (i = 0; i < eventInputs.length; i++) {
- eventInput = eventInputs[i];
-
- if (isArraySource) { // array sources have already been convert to Event Objects
- abstractEvent = eventInput;
- }
- else {
- abstractEvent = buildEventFromInput(eventInput, source);
- }
-
- if (abstractEvent) { // not false (an invalid event)
- cache.push.apply(
- cache,
- expandEvent(abstractEvent) // add individual expanded events to the cache
- );
- }
- }
- }
-
- pendingSourceCnt--;
- if (!pendingSourceCnt) {
- reportEvents(cache);
- }
- }
- });
- }
-
-
- function _fetchEventSource(source, callback) {
- var i;
- var fetchers = FC.sourceFetchers;
- var res;
-
- for (i=0; i<fetchers.length; i++) {
- res = fetchers[i].call(
- t, // this, the Calendar object
- source,
- rangeStart.clone(),
- rangeEnd.clone(),
- options.timezone,
- callback
- );
-
- if (res === true) {
- // the fetcher is in charge. made its own async request
- return;
- }
- else if (typeof res == 'object') {
- // the fetcher returned a new source. process it
- _fetchEventSource(res, callback);
- return;
- }
- }
-
- var events = source.events;
- if (events) {
- if ($.isFunction(events)) {
- t.pushLoading();
- events.call(
- t, // this, the Calendar object
- rangeStart.clone(),
- rangeEnd.clone(),
- options.timezone,
- function(events) {
- callback(events);
- t.popLoading();
- }
- );
- }
- else if ($.isArray(events)) {
- callback(events);
- }
- else {
- callback();
- }
- }else{
- var url = source.url;
- if (url) {
- var success = source.success;
- var error = source.error;
- var complete = source.complete;
-
- // retrieve any outbound GET/POST $.ajax data from the options
- var customData;
- if ($.isFunction(source.data)) {
- // supplied as a function that returns a key/value object
- customData = source.data();
- }
- else {
- // supplied as a straight key/value object
- customData = source.data;
- }
-
- // use a copy of the custom data so we can modify the parameters
- // and not affect the passed-in object.
- var data = $.extend({}, customData || {});
-
- var startParam = firstDefined(source.startParam, options.startParam);
- var endParam = firstDefined(source.endParam, options.endParam);
- var timezoneParam = firstDefined(source.timezoneParam, options.timezoneParam);
-
- if (startParam) {
- data[startParam] = rangeStart.format();
- }
- if (endParam) {
- data[endParam] = rangeEnd.format();
- }
- if (options.timezone && options.timezone != 'local') {
- data[timezoneParam] = options.timezone;
- }
-
- t.pushLoading();
- $.ajax($.extend({}, ajaxDefaults, source, {
- data: data,
- success: function(events) {
- events = events || [];
- var res = applyAll(success, this, arguments);
- if ($.isArray(res)) {
- events = res;
- }
- callback(events);
- },
- error: function() {
- applyAll(error, this, arguments);
- callback();
- },
- complete: function() {
- applyAll(complete, this, arguments);
- t.popLoading();
- }
- }));
- }else{
- callback();
- }
- }
- }
-
-
-
- /* Sources
- -----------------------------------------------------------------------------*/
-
-
- function addEventSource(sourceInput) {
- var source = buildEventSource(sourceInput);
- if (source) {
- sources.push(source);
- pendingSourceCnt++;
- fetchEventSource(source, currentFetchID); // will eventually call reportEvents
- }
- }
-
-
- function buildEventSource(sourceInput) { // will return undefined if invalid source
- var normalizers = FC.sourceNormalizers;
- var source;
- var i;
-
- if ($.isFunction(sourceInput) || $.isArray(sourceInput)) {
- source = { events: sourceInput };
- }
- else if (typeof sourceInput === 'string') {
- source = { url: sourceInput };
- }
- else if (typeof sourceInput === 'object') {
- source = $.extend({}, sourceInput); // shallow copy
- }
-
- if (source) {
-
- // TODO: repeat code, same code for event classNames
- if (source.className) {
- if (typeof source.className === 'string') {
- source.className = source.className.split(/\s+/);
- }
- // otherwise, assumed to be an array
- }
- else {
- source.className = [];
- }
-
- // for array sources, we convert to standard Event Objects up front
- if ($.isArray(source.events)) {
- source.origArray = source.events; // for removeEventSource
- source.events = $.map(source.events, function(eventInput) {
- return buildEventFromInput(eventInput, source);
- });
- }
-
- for (i=0; i<normalizers.length; i++) {
- normalizers[i].call(t, source);
- }
-
- return source;
- }
- }
-
-
- function removeEventSource(source) {
- sources = $.grep(sources, function(src) {
- return !isSourcesEqual(src, source);
- });
- // remove all client events from that source
- cache = $.grep(cache, function(e) {
- return !isSourcesEqual(e.source, source);
- });
- reportEvents(cache);
- }
-
-
- function isSourcesEqual(source1, source2) {
- return source1 && source2 && getSourcePrimitive(source1) == getSourcePrimitive(source2);
- }
-
-
- function getSourcePrimitive(source) {
- return (
- (typeof source === 'object') ? // a normalized event source?
- (source.origArray || source.googleCalendarId || source.url || source.events) : // get the primitive
- null
- ) ||
- source; // the given argument *is* the primitive
- }
-
-
-
- /* Manipulation
- -----------------------------------------------------------------------------*/
-
-
- // Only ever called from the externally-facing API
- function updateEvent(event) {
-
- // massage start/end values, even if date string values
- event.start = t.moment(event.start);
- if (event.end) {
- event.end = t.moment(event.end);
- }
- else {
- event.end = null;
- }
-
- mutateEvent(event, getMiscEventProps(event)); // will handle start/end/allDay normalization
- reportEvents(cache); // reports event modifications (so we can redraw)
- }
-
-
- // Returns a hash of misc event properties that should be copied over to related events.
- function getMiscEventProps(event) {
- var props = {};
-
- $.each(event, function(name, val) {
- if (isMiscEventPropName(name)) {
- if (val !== undefined && isAtomic(val)) { // a defined non-object
- props[name] = val;
- }
- }
- });
-
- return props;
- }
-
- // non-date-related, non-id-related, non-secret
- function isMiscEventPropName(name) {
- return !/^_|^(id|allDay|start|end)$/.test(name);
- }
-
-
- // returns the expanded events that were created
- function renderEvent(eventInput, stick) {
- var abstractEvent = buildEventFromInput(eventInput);
- var events;
- var i, event;
-
- if (abstractEvent) { // not false (a valid input)
- events = expandEvent(abstractEvent);
-
- for (i = 0; i < events.length; i++) {
- event = events[i];
-
- if (!event.source) {
- if (stick) {
- stickySource.events.push(event);
- event.source = stickySource;
- }
- cache.push(event);
- }
- }
-
- reportEvents(cache);
-
- return events;
- }
-
- return [];
- }
-
-
- function removeEvents(filter) {
- var eventID;
- var i;
-
- if (filter == null) { // null or undefined. remove all events
- filter = function() { return true; }; // will always match
- }
- else if (!$.isFunction(filter)) { // an event ID
- eventID = filter + '';
- filter = function(event) {
- return event._id == eventID;
- };
- }
-
- // Purge event(s) from our local cache
- cache = $.grep(cache, filter, true); // inverse=true
-
- // Remove events from array sources.
- // This works because they have been converted to official Event Objects up front.
- // (and as a result, event._id has been calculated).
- for (i=0; i<sources.length; i++) {
- if ($.isArray(sources[i].events)) {
- sources[i].events = $.grep(sources[i].events, filter, true);
- }
- }
-
- reportEvents(cache);
- }
-
-
- function clientEvents(filter) {
- if ($.isFunction(filter)) {
- return $.grep(cache, filter);
- }
- else if (filter != null) { // not null, not undefined. an event ID
- filter += '';
- return $.grep(cache, function(e) {
- return e._id == filter;
- });
- }
- return cache; // else, return all
- }
-
-
-
- /* Event Normalization
- -----------------------------------------------------------------------------*/
-
-
- // Given a raw object with key/value properties, returns an "abstract" Event object.
- // An "abstract" event is an event that, if recurring, will not have been expanded yet.
- // Will return `false` when input is invalid.
- // `source` is optional
- function buildEventFromInput(input, source) {
- var out = {};
- var start, end;
- var allDay;
-
- if (options.eventDataTransform) {
- input = options.eventDataTransform(input);
- }
- if (source && source.eventDataTransform) {
- input = source.eventDataTransform(input);
- }
-
- // Copy all properties over to the resulting object.
- // The special-case properties will be copied over afterwards.
- $.extend(out, input);
-
- if (source) {
- out.source = source;
- }
-
- out._id = input._id || (input.id === undefined ? '_fc' + eventGUID++ : input.id + '');
-
- if (input.className) {
- if (typeof input.className == 'string') {
- out.className = input.className.split(/\s+/);
- }
- else { // assumed to be an array
- out.className = input.className;
- }
- }
- else {
- out.className = [];
- }
-
- start = input.start || input.date; // "date" is an alias for "start"
- end = input.end;
-
- // parse as a time (Duration) if applicable
- if (isTimeString(start)) {
- start = moment.duration(start);
- }
- if (isTimeString(end)) {
- end = moment.duration(end);
- }
-
- if (input.dow || moment.isDuration(start) || moment.isDuration(end)) {
-
- // the event is "abstract" (recurring) so don't calculate exact start/end dates just yet
- out.start = start ? moment.duration(start) : null; // will be a Duration or null
- out.end = end ? moment.duration(end) : null; // will be a Duration or null
- out._recurring = true; // our internal marker
- }
- else {
-
- if (start) {
- start = t.moment(start);
- if (!start.isValid()) {
- return false;
- }
- }
-
- if (end) {
- end = t.moment(end);
- if (!end.isValid()) {
- end = null; // let defaults take over
- }
- }
-
- allDay = input.allDay;
- if (allDay === undefined) { // still undefined? fallback to default
- allDay = firstDefined(
- source ? source.allDayDefault : undefined,
- options.allDayDefault
- );
- // still undefined? normalizeEventDates will calculate it
- }
-
- assignDatesToEvent(start, end, allDay, out);
- }
-
- return out;
- }
-
-
- // Normalizes and assigns the given dates to the given partially-formed event object.
- // NOTE: mutates the given start/end moments. does not make a copy.
- function assignDatesToEvent(start, end, allDay, event) {
- event.start = start;
- event.end = end;
- event.allDay = allDay;
- normalizeEventDates(event);
- backupEventDates(event);
- }
-
-
- // Ensures proper values for allDay/start/end. Accepts an Event object, or a plain object with event-ish properties.
- // NOTE: Will modify the given object.
- function normalizeEventDates(eventProps) {
-
- normalizeEventTimes(eventProps);
-
- if (eventProps.end && !eventProps.end.isAfter(eventProps.start)) {
- eventProps.end = null;
- }
-
- if (!eventProps.end) {
- if (options.forceEventDuration) {
- eventProps.end = t.getDefaultEventEnd(eventProps.allDay, eventProps.start);
- }
- else {
- eventProps.end = null;
- }
- }
- }
-
-
- // Ensures the allDay property exists and the timeliness of the start/end dates are consistent
- function normalizeEventTimes(eventProps) {
- if (eventProps.allDay == null) {
- eventProps.allDay = !(eventProps.start.hasTime() || (eventProps.end && eventProps.end.hasTime()));
- }
-
- if (eventProps.allDay) {
- eventProps.start.stripTime();
- if (eventProps.end) {
- // TODO: consider nextDayThreshold here? If so, will require a lot of testing and adjustment
- eventProps.end.stripTime();
- }
- }
- else {
- if (!eventProps.start.hasTime()) {
- eventProps.start = t.applyTimezone(eventProps.start.time(0)); // will assign a 00:00 time
- }
- if (eventProps.end && !eventProps.end.hasTime()) {
- eventProps.end = t.applyTimezone(eventProps.end.time(0)); // will assign a 00:00 time
- }
- }
- }
-
-
- // If the given event is a recurring event, break it down into an array of individual instances.
- // If not a recurring event, return an array with the single original event.
- // If given a falsy input (probably because of a failed buildEventFromInput call), returns an empty array.
- // HACK: can override the recurring window by providing custom rangeStart/rangeEnd (for businessHours).
- function expandEvent(abstractEvent, _rangeStart, _rangeEnd) {
- var events = [];
- var dowHash;
- var dow;
- var i;
- var date;
- var startTime, endTime;
- var start, end;
- var event;
-
- _rangeStart = _rangeStart || rangeStart;
- _rangeEnd = _rangeEnd || rangeEnd;
-
- if (abstractEvent) {
- if (abstractEvent._recurring) {
-
- // make a boolean hash as to whether the event occurs on each day-of-week
- if ((dow = abstractEvent.dow)) {
- dowHash = {};
- for (i = 0; i < dow.length; i++) {
- dowHash[dow[i]] = true;
- }
- }
-
- // iterate through every day in the current range
- date = _rangeStart.clone().stripTime(); // holds the date of the current day
- while (date.isBefore(_rangeEnd)) {
-
- if (!dowHash || dowHash[date.day()]) { // if everyday, or this particular day-of-week
-
- startTime = abstractEvent.start; // the stored start and end properties are times (Durations)
- endTime = abstractEvent.end; // "
- start = date.clone();
- end = null;
-
- if (startTime) {
- start = start.time(startTime);
- }
- if (endTime) {
- end = date.clone().time(endTime);
- }
-
- event = $.extend({}, abstractEvent); // make a copy of the original
- assignDatesToEvent(
- start, end,
- !startTime && !endTime, // allDay?
- event
- );
- events.push(event);
- }
-
- date.add(1, 'days');
- }
- }
- else {
- events.push(abstractEvent); // return the original event. will be a one-item array
- }
- }
-
- return events;
- }
-
-
-
- /* Event Modification Math
- -----------------------------------------------------------------------------------------*/
-
-
- // Modifies an event and all related events by applying the given properties.
- // Special date-diffing logic is used for manipulation of dates.
- // If `props` does not contain start/end dates, the updated values are assumed to be the event's current start/end.
- // All date comparisons are done against the event's pristine _start and _end dates.
- // Returns an object with delta information and a function to undo all operations.
- // For making computations in a granularity greater than day/time, specify largeUnit.
- // NOTE: The given `newProps` might be mutated for normalization purposes.
- function mutateEvent(event, newProps, largeUnit) {
- var miscProps = {};
- var oldProps;
- var clearEnd;
- var startDelta;
- var endDelta;
- var durationDelta;
- var undoFunc;
-
- // diffs the dates in the appropriate way, returning a duration
- function diffDates(date1, date0) { // date1 - date0
- if (largeUnit) {
- return diffByUnit(date1, date0, largeUnit);
- }
- else if (newProps.allDay) {
- return diffDay(date1, date0);
- }
- else {
- return diffDayTime(date1, date0);
- }
- }
-
- newProps = newProps || {};
-
- // normalize new date-related properties
- if (!newProps.start) {
- newProps.start = event.start.clone();
- }
- if (newProps.end === undefined) {
- newProps.end = event.end ? event.end.clone() : null;
- }
- if (newProps.allDay == null) { // is null or undefined?
- newProps.allDay = event.allDay;
- }
- normalizeEventDates(newProps);
-
- // create normalized versions of the original props to compare against
- // need a real end value, for diffing
- oldProps = {
- start: event._start.clone(),
- end: event._end ? event._end.clone() : t.getDefaultEventEnd(event._allDay, event._start),
- allDay: newProps.allDay // normalize the dates in the same regard as the new properties
- };
- normalizeEventDates(oldProps);
-
- // need to clear the end date if explicitly changed to null
- clearEnd = event._end !== null && newProps.end === null;
-
- // compute the delta for moving the start date
- startDelta = diffDates(newProps.start, oldProps.start);
-
- // compute the delta for moving the end date
- if (newProps.end) {
- endDelta = diffDates(newProps.end, oldProps.end);
- durationDelta = endDelta.subtract(startDelta);
- }
- else {
- durationDelta = null;
- }
-
- // gather all non-date-related properties
- $.each(newProps, function(name, val) {
- if (isMiscEventPropName(name)) {
- if (val !== undefined) {
- miscProps[name] = val;
- }
- }
- });
-
- // apply the operations to the event and all related events
- undoFunc = mutateEvents(
- clientEvents(event._id), // get events with this ID
- clearEnd,
- newProps.allDay,
- startDelta,
- durationDelta,
- miscProps
- );
-
- return {
- dateDelta: startDelta,
- durationDelta: durationDelta,
- undo: undoFunc
- };
- }
-
-
- // Modifies an array of events in the following ways (operations are in order):
- // - clear the event's `end`
- // - convert the event to allDay
- // - add `dateDelta` to the start and end
- // - add `durationDelta` to the event's duration
- // - assign `miscProps` to the event
- //
- // Returns a function that can be called to undo all the operations.
- //
- // TODO: don't use so many closures. possible memory issues when lots of events with same ID.
- //
- function mutateEvents(events, clearEnd, allDay, dateDelta, durationDelta, miscProps) {
- var isAmbigTimezone = t.getIsAmbigTimezone();
- var undoFunctions = [];
-
- // normalize zero-length deltas to be null
- if (dateDelta && !dateDelta.valueOf()) { dateDelta = null; }
- if (durationDelta && !durationDelta.valueOf()) { durationDelta = null; }
-
- $.each(events, function(i, event) {
- var oldProps;
- var newProps;
-
- // build an object holding all the old values, both date-related and misc.
- // for the undo function.
- oldProps = {
- start: event.start.clone(),
- end: event.end ? event.end.clone() : null,
- allDay: event.allDay
- };
- $.each(miscProps, function(name) {
- oldProps[name] = event[name];
- });
-
- // new date-related properties. work off the original date snapshot.
- // ok to use references because they will be thrown away when backupEventDates is called.
- newProps = {
- start: event._start,
- end: event._end,
- allDay: allDay // normalize the dates in the same regard as the new properties
- };
- normalizeEventDates(newProps); // massages start/end/allDay
-
- // strip or ensure the end date
- if (clearEnd) {
- newProps.end = null;
- }
- else if (durationDelta && !newProps.end) { // the duration translation requires an end date
- newProps.end = t.getDefaultEventEnd(newProps.allDay, newProps.start);
- }
-
- if (dateDelta) {
- newProps.start.add(dateDelta);
- if (newProps.end) {
- newProps.end.add(dateDelta);
- }
- }
-
- if (durationDelta) {
- newProps.end.add(durationDelta); // end already ensured above
- }
-
- // if the dates have changed, and we know it is impossible to recompute the
- // timezone offsets, strip the zone.
- if (
- isAmbigTimezone &&
- !newProps.allDay &&
- (dateDelta || durationDelta)
- ) {
- newProps.start.stripZone();
- if (newProps.end) {
- newProps.end.stripZone();
- }
- }
-
- $.extend(event, miscProps, newProps); // copy over misc props, then date-related props
- backupEventDates(event); // regenerate internal _start/_end/_allDay
-
- undoFunctions.push(function() {
- $.extend(event, oldProps);
- backupEventDates(event); // regenerate internal _start/_end/_allDay
- });
- });
-
- return function() {
- for (var i = 0; i < undoFunctions.length; i++) {
- undoFunctions[i]();
- }
- };
- }
-
-
- /* Business Hours
- -----------------------------------------------------------------------------------------*/
-
- t.getBusinessHoursEvents = getBusinessHoursEvents;
-
-
- // Returns an array of events as to when the business hours occur in the given view.
- // Abuse of our event system :(
- function getBusinessHoursEvents(wholeDay) {
- var optionVal = options.businessHours;
- var defaultVal = {
- className: 'fc-nonbusiness',
- start: '09:00',
- end: '17:00',
- dow: [ 1, 2, 3, 4, 5 ], // monday - friday
- rendering: 'inverse-background'
- };
- var view = t.getView();
- var eventInput;
-
- if (optionVal) { // `true` (which means "use the defaults") or an override object
- eventInput = $.extend(
- {}, // copy to a new object in either case
- defaultVal,
- typeof optionVal === 'object' ? optionVal : {} // override the defaults
- );
- }
-
- if (eventInput) {
-
- // if a whole-day series is requested, clear the start/end times
- if (wholeDay) {
- eventInput.start = null;
- eventInput.end = null;
- }
-
- return expandEvent(
- buildEventFromInput(eventInput),
- view.start,
- view.end
- );
- }
-
- return [];
- }
-
-
- /* Overlapping / Constraining
- -----------------------------------------------------------------------------------------*/
-
- t.isEventSpanAllowed = isEventSpanAllowed;
- t.isExternalSpanAllowed = isExternalSpanAllowed;
- t.isSelectionSpanAllowed = isSelectionSpanAllowed;
-
-
- // Determines if the given event can be relocated to the given span (unzoned start/end with other misc data)
- function isEventSpanAllowed(span, event) {
- var source = event.source || {};
- var constraint = firstDefined(
- event.constraint,
- source.constraint,
- options.eventConstraint
- );
- var overlap = firstDefined(
- event.overlap,
- source.overlap,
- options.eventOverlap
- );
- return isSpanAllowed(span, constraint, overlap, event);
- }
-
-
- // Determines if an external event can be relocated to the given span (unzoned start/end with other misc data)
- function isExternalSpanAllowed(eventSpan, eventLocation, eventProps) {
- var eventInput;
- var event;
-
- // note: very similar logic is in View's reportExternalDrop
- if (eventProps) {
- eventInput = $.extend({}, eventProps, eventLocation);
- event = expandEvent(buildEventFromInput(eventInput))[0];
- }
-
- if (event) {
- return isEventSpanAllowed(eventSpan, event);
- }
- else { // treat it as a selection
-
- return isSelectionSpanAllowed(eventSpan);
- }
- }
-
-
- // Determines the given span (unzoned start/end with other misc data) can be selected.
- function isSelectionSpanAllowed(span) {
- return isSpanAllowed(span, options.selectConstraint, options.selectOverlap);
- }
-
-
- // Returns true if the given span (caused by an event drop/resize or a selection) is allowed to exist
- // according to the constraint/overlap settings.
- // `event` is not required if checking a selection.
- function isSpanAllowed(span, constraint, overlap, event) {
- var constraintEvents;
- var anyContainment;
- var peerEvents;
- var i, peerEvent;
- var peerOverlap;
-
- // the range must be fully contained by at least one of produced constraint events
- if (constraint != null) {
-
- // not treated as an event! intermediate data structure
- // TODO: use ranges in the future
- constraintEvents = constraintToEvents(constraint);
-
- anyContainment = false;
- for (i = 0; i < constraintEvents.length; i++) {
- if (eventContainsRange(constraintEvents[i], span)) {
- anyContainment = true;
- break;
- }
- }
-
- if (!anyContainment) {
- return false;
- }
- }
-
- peerEvents = t.getPeerEvents(span, event);
-
- for (i = 0; i < peerEvents.length; i++) {
- peerEvent = peerEvents[i];
-
- // there needs to be an actual intersection before disallowing anything
- if (eventIntersectsRange(peerEvent, span)) {
-
- // evaluate overlap for the given range and short-circuit if necessary
- if (overlap === false) {
- return false;
- }
- // if the event's overlap is a test function, pass the peer event in question as the first param
- else if (typeof overlap === 'function' && !overlap(peerEvent, event)) {
- return false;
- }
-
- // if we are computing if the given range is allowable for an event, consider the other event's
- // EventObject-specific or Source-specific `overlap` property
- if (event) {
- peerOverlap = firstDefined(
- peerEvent.overlap,
- (peerEvent.source || {}).overlap
- // we already considered the global `eventOverlap`
- );
- if (peerOverlap === false) {
- return false;
- }
- // if the peer event's overlap is a test function, pass the subject event as the first param
- if (typeof peerOverlap === 'function' && !peerOverlap(event, peerEvent)) {
- return false;
- }
- }
- }
- }
-
- return true;
- }
-
-
- // Given an event input from the API, produces an array of event objects. Possible event inputs:
- // 'businessHours'
- // An event ID (number or string)
- // An object with specific start/end dates or a recurring event (like what businessHours accepts)
- function constraintToEvents(constraintInput) {
-
- if (constraintInput === 'businessHours') {
- return getBusinessHoursEvents();
- }
-
- if (typeof constraintInput === 'object') {
- return expandEvent(buildEventFromInput(constraintInput));
- }
-
- return clientEvents(constraintInput); // probably an ID
- }
-
-
- // Does the event's date range fully contain the given range?
- // start/end already assumed to have stripped zones :(
- function eventContainsRange(event, range) {
- var eventStart = event.start.clone().stripZone();
- var eventEnd = t.getEventEnd(event).stripZone();
-
- return range.start >= eventStart && range.end <= eventEnd;
- }
-
-
- // Does the event's date range intersect with the given range?
- // start/end already assumed to have stripped zones :(
- function eventIntersectsRange(event, range) {
- var eventStart = event.start.clone().stripZone();
- var eventEnd = t.getEventEnd(event).stripZone();
-
- return range.start < eventEnd && range.end > eventStart;
- }
-
-
- t.getEventCache = function() {
- return cache;
- };
-
-}
-
-
-// Returns a list of events that the given event should be compared against when being considered for a move to
-// the specified span. Attached to the Calendar's prototype because EventManager is a mixin for a Calendar.
-Calendar.prototype.getPeerEvents = function(span, event) {
- var cache = this.getEventCache();
- var peerEvents = [];
- var i, otherEvent;
-
- for (i = 0; i < cache.length; i++) {
- otherEvent = cache[i];
- if (
- !event ||
- event._id !== otherEvent._id // don't compare the event to itself or other related [repeating] events
- ) {
- peerEvents.push(otherEvent);
- }
- }
-
- return peerEvents;
-};
-
-
-// updates the "backup" properties, which are preserved in order to compute diffs later on.
-function backupEventDates(event) {
- event._allDay = event.allDay;
- event._start = event.start.clone();
- event._end = event.end ? event.end.clone() : null;
-}
-
-;;
-
-/* An abstract class for the "basic" views, as well as month view. Renders one or more rows of day cells.
-----------------------------------------------------------------------------------------------------------------------*/
-// It is a manager for a DayGrid subcomponent, which does most of the heavy lifting.
-// It is responsible for managing width/height.
-
-var BasicView = FC.BasicView = View.extend({
-
- scroller: null,
-
- dayGridClass: DayGrid, // class the dayGrid will be instantiated from (overridable by subclasses)
- dayGrid: null, // the main subcomponent that does most of the heavy lifting
-
- dayNumbersVisible: false, // display day numbers on each day cell?
- weekNumbersVisible: false, // display week numbers along the side?
-
- weekNumberWidth: null, // width of all the week-number cells running down the side
-
- headContainerEl: null, // div that hold's the dayGrid's rendered date header
- headRowEl: null, // the fake row element of the day-of-week header
-
-
- initialize: function() {
- this.dayGrid = this.instantiateDayGrid();
-
- this.scroller = new Scroller({
- overflowX: 'hidden',
- overflowY: 'auto'
- });
- },
-
-
- // Generates the DayGrid object this view needs. Draws from this.dayGridClass
- instantiateDayGrid: function() {
- // generate a subclass on the fly with BasicView-specific behavior
- // TODO: cache this subclass
- var subclass = this.dayGridClass.extend(basicDayGridMethods);
-
- return new subclass(this);
- },
-
-
- // Sets the display range and computes all necessary dates
- setRange: function(range) {
- View.prototype.setRange.call(this, range); // call the super-method
-
- this.dayGrid.breakOnWeeks = /year|month|week/.test(this.intervalUnit); // do before setRange
- this.dayGrid.setRange(range);
- },
-
-
- // Compute the value to feed into setRange. Overrides superclass.
- computeRange: function(date) {
- var range = View.prototype.computeRange.call(this, date); // get value from the super-method
-
- // year and month views should be aligned with weeks. this is already done for week
- if (/year|month/.test(range.intervalUnit)) {
- range.start.startOf('week');
- range.start = this.skipHiddenDays(range.start);
-
- // make end-of-week if not already
- if (range.end.weekday()) {
- range.end.add(1, 'week').startOf('week');
- range.end = this.skipHiddenDays(range.end, -1, true); // exclusively move backwards
- }
- }
-
- return range;
- },
-
-
- // Renders the view into `this.el`, which should already be assigned
- renderDates: function() {
-
- this.dayNumbersVisible = this.dayGrid.rowCnt > 1; // TODO: make grid responsible
- this.weekNumbersVisible = this.opt('weekNumbers');
- this.dayGrid.numbersVisible = this.dayNumbersVisible || this.weekNumbersVisible;
-
- this.el.addClass('fc-basic-view').html(this.renderSkeletonHtml());
- this.renderHead();
-
- this.scroller.render();
- var dayGridContainerEl = this.scroller.el.addClass('fc-day-grid-container');
- var dayGridEl = $('<div class="fc-day-grid" />').appendTo(dayGridContainerEl);
- this.el.find('.fc-body > tr > td').append(dayGridContainerEl);
-
- this.dayGrid.setElement(dayGridEl);
- this.dayGrid.renderDates(this.hasRigidRows());
- },
-
-
- // render the day-of-week headers
- renderHead: function() {
- this.headContainerEl =
- this.el.find('.fc-head-container')
- .html(this.dayGrid.renderHeadHtml());
- this.headRowEl = this.headContainerEl.find('.fc-row');
- },
-
-
- // Unrenders the content of the view. Since we haven't separated skeleton rendering from date rendering,
- // always completely kill the dayGrid's rendering.
- unrenderDates: function() {
- this.dayGrid.unrenderDates();
- this.dayGrid.removeElement();
- this.scroller.destroy();
- },
-
-
- renderBusinessHours: function() {
- this.dayGrid.renderBusinessHours();
- },
-
-
- // Builds the HTML skeleton for the view.
- // The day-grid component will render inside of a container defined by this HTML.
- renderSkeletonHtml: function() {
- return '' +
- '<table>' +
- '<thead class="fc-head">' +
- '<tr>' +
- '<td class="fc-head-container ' + this.widgetHeaderClass + '"></td>' +
- '</tr>' +
- '</thead>' +
- '<tbody class="fc-body">' +
- '<tr>' +
- '<td class="' + this.widgetContentClass + '"></td>' +
- '</tr>' +
- '</tbody>' +
- '</table>';
- },
-
-
- // Generates an HTML attribute string for setting the width of the week number column, if it is known
- weekNumberStyleAttr: function() {
- if (this.weekNumberWidth !== null) {
- return 'style="width:' + this.weekNumberWidth + 'px"';
- }
- return '';
- },
-
-
- // Determines whether each row should have a constant height
- hasRigidRows: function() {
- var eventLimit = this.opt('eventLimit');
- return eventLimit && typeof eventLimit !== 'number';
- },
-
-
- /* Dimensions
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Refreshes the horizontal dimensions of the view
- updateWidth: function() {
- if (this.weekNumbersVisible) {
- // Make sure all week number cells running down the side have the same width.
- // Record the width for cells created later.
- this.weekNumberWidth = matchCellWidths(
- this.el.find('.fc-week-number')
- );
- }
- },
-
-
- // Adjusts the vertical dimensions of the view to the specified values
- setHeight: function(totalHeight, isAuto) {
- var eventLimit = this.opt('eventLimit');
- var scrollerHeight;
- var scrollbarWidths;
-
- // reset all heights to be natural
- this.scroller.clear();
- uncompensateScroll(this.headRowEl);
-
- this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed
-
- // is the event limit a constant level number?
- if (eventLimit && typeof eventLimit === 'number') {
- this.dayGrid.limitRows(eventLimit); // limit the levels first so the height can redistribute after
- }
-
- // distribute the height to the rows
- // (totalHeight is a "recommended" value if isAuto)
- scrollerHeight = this.computeScrollerHeight(totalHeight);
- this.setGridHeight(scrollerHeight, isAuto);
-
- // is the event limit dynamically calculated?
- if (eventLimit && typeof eventLimit !== 'number') {
- this.dayGrid.limitRows(eventLimit); // limit the levels after the grid's row heights have been set
- }
-
- if (!isAuto) { // should we force dimensions of the scroll container?
-
- this.scroller.setHeight(scrollerHeight);
- scrollbarWidths = this.scroller.getScrollbarWidths();
-
- if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars?
-
- compensateScroll(this.headRowEl, scrollbarWidths);
-
- // doing the scrollbar compensation might have created text overflow which created more height. redo
- scrollerHeight = this.computeScrollerHeight(totalHeight);
- this.scroller.setHeight(scrollerHeight);
- }
-
- // guarantees the same scrollbar widths
- this.scroller.lockOverflow(scrollbarWidths);
- }
- },
-
-
- // given a desired total height of the view, returns what the height of the scroller should be
- computeScrollerHeight: function(totalHeight) {
- return totalHeight -
- subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
- },
-
-
- // Sets the height of just the DayGrid component in this view
- setGridHeight: function(height, isAuto) {
- if (isAuto) {
- undistributeHeight(this.dayGrid.rowEls); // let the rows be their natural height with no expanding
- }
- else {
- distributeHeight(this.dayGrid.rowEls, height, true); // true = compensate for height-hogging rows
- }
- },
-
-
- /* Scroll
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- queryScroll: function() {
- return this.scroller.getScrollTop();
- },
-
-
- setScroll: function(top) {
- this.scroller.setScrollTop(top);
- },
-
-
- /* Hit Areas
- ------------------------------------------------------------------------------------------------------------------*/
- // forward all hit-related method calls to dayGrid
-
-
- prepareHits: function() {
- this.dayGrid.prepareHits();
- },
-
-
- releaseHits: function() {
- this.dayGrid.releaseHits();
- },
-
-
- queryHit: function(left, top) {
- return this.dayGrid.queryHit(left, top);
- },
-
-
- getHitSpan: function(hit) {
- return this.dayGrid.getHitSpan(hit);
- },
-
-
- getHitEl: function(hit) {
- return this.dayGrid.getHitEl(hit);
- },
-
-
- /* Events
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders the given events onto the view and populates the segments array
- renderEvents: function(events) {
- this.dayGrid.renderEvents(events);
-
- this.updateHeight(); // must compensate for events that overflow the row
- },
-
-
- // Retrieves all segment objects that are rendered in the view
- getEventSegs: function() {
- return this.dayGrid.getEventSegs();
- },
-
-
- // Unrenders all event elements and clears internal segment data
- unrenderEvents: function() {
- this.dayGrid.unrenderEvents();
-
- // we DON'T need to call updateHeight() because:
- // A) a renderEvents() call always happens after this, which will eventually call updateHeight()
- // B) in IE8, this causes a flash whenever events are rerendered
- },
-
-
- /* Dragging (for both events and external elements)
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // A returned value of `true` signals that a mock "helper" event has been rendered.
- renderDrag: function(dropLocation, seg) {
- return this.dayGrid.renderDrag(dropLocation, seg);
- },
-
-
- unrenderDrag: function() {
- this.dayGrid.unrenderDrag();
- },
-
-
- /* Selection
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders a visual indication of a selection
- renderSelection: function(span) {
- this.dayGrid.renderSelection(span);
- },
-
-
- // Unrenders a visual indications of a selection
- unrenderSelection: function() {
- this.dayGrid.unrenderSelection();
- }
-
-});
-
-
-// Methods that will customize the rendering behavior of the BasicView's dayGrid
-var basicDayGridMethods = {
-
-
- // Generates the HTML that will go before the day-of week header cells
- renderHeadIntroHtml: function() {
- var view = this.view;
-
- if (view.weekNumbersVisible) {
- return '' +
- '<th class="fc-week-number ' + view.widgetHeaderClass + '" ' + view.weekNumberStyleAttr() + '>' +
- '<span>' + // needed for matchCellWidths
- htmlEscape(view.opt('weekNumberTitle')) +
- '</span>' +
- '</th>';
- }
-
- return '';
- },
-
-
- // Generates the HTML that will go before content-skeleton cells that display the day/week numbers
- renderNumberIntroHtml: function(row) {
- var view = this.view;
-
- if (view.weekNumbersVisible) {
- return '' +
- '<td class="fc-week-number" ' + view.weekNumberStyleAttr() + '>' +
- '<span>' + // needed for matchCellWidths
- this.getCellDate(row, 0).format('w') +
- '</span>' +
- '</td>';
- }
-
- return '';
- },
-
-
- // Generates the HTML that goes before the day bg cells for each day-row
- renderBgIntroHtml: function() {
- var view = this.view;
-
- if (view.weekNumbersVisible) {
- return '<td class="fc-week-number ' + view.widgetContentClass + '" ' +
- view.weekNumberStyleAttr() + '></td>';
- }
-
- return '';
- },
-
-
- // Generates the HTML that goes before every other type of row generated by DayGrid.
- // Affects helper-skeleton and highlight-skeleton rows.
- renderIntroHtml: function() {
- var view = this.view;
-
- if (view.weekNumbersVisible) {
- return '<td class="fc-week-number" ' + view.weekNumberStyleAttr() + '></td>';
- }
-
- return '';
- }
-
-};
-
-;;
-
-/* A month view with day cells running in rows (one-per-week) and columns
-----------------------------------------------------------------------------------------------------------------------*/
-
-var MonthView = FC.MonthView = BasicView.extend({
-
- // Produces information about what range to display
- computeRange: function(date) {
- var range = BasicView.prototype.computeRange.call(this, date); // get value from super-method
- var rowCnt;
-
- // ensure 6 weeks
- if (this.isFixedWeeks()) {
- rowCnt = Math.ceil(range.end.diff(range.start, 'weeks', true)); // could be partial weeks due to hiddenDays
- range.end.add(6 - rowCnt, 'weeks');
- }
-
- return range;
- },
-
-
- // Overrides the default BasicView behavior to have special multi-week auto-height logic
- setGridHeight: function(height, isAuto) {
-
- isAuto = isAuto || this.opt('weekMode') === 'variable'; // LEGACY: weekMode is deprecated
-
- // if auto, make the height of each row the height that it would be if there were 6 weeks
- if (isAuto) {
- height *= this.rowCnt / 6;
- }
-
- distributeHeight(this.dayGrid.rowEls, height, !isAuto); // if auto, don't compensate for height-hogging rows
- },
-
-
- isFixedWeeks: function() {
- var weekMode = this.opt('weekMode'); // LEGACY: weekMode is deprecated
- if (weekMode) {
- return weekMode === 'fixed'; // if any other type of weekMode, assume NOT fixed
- }
-
- return this.opt('fixedWeekCount');
- }
-
-});
-
-;;
-
-fcViews.basic = {
- 'class': BasicView
-};
-
-fcViews.basicDay = {
- type: 'basic',
- duration: { days: 1 }
-};
-
-fcViews.basicWeek = {
- type: 'basic',
- duration: { weeks: 1 }
-};
-
-fcViews.month = {
- 'class': MonthView,
- duration: { months: 1 }, // important for prev/next
- defaults: {
- fixedWeekCount: true
- }
-};
-;;
-
-/* An abstract class for all agenda-related views. Displays one more columns with time slots running vertically.
-----------------------------------------------------------------------------------------------------------------------*/
-// Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on).
-// Responsible for managing width/height.
-
-var AgendaView = FC.AgendaView = View.extend({
-
- scroller: null,
-
- timeGridClass: TimeGrid, // class used to instantiate the timeGrid. subclasses can override
- timeGrid: null, // the main time-grid subcomponent of this view
-
- dayGridClass: DayGrid, // class used to instantiate the dayGrid. subclasses can override
- dayGrid: null, // the "all-day" subcomponent. if all-day is turned off, this will be null
-
- axisWidth: null, // the width of the time axis running down the side
-
- headContainerEl: null, // div that hold's the timeGrid's rendered date header
- noScrollRowEls: null, // set of fake row elements that must compensate when scroller has scrollbars
-
- // when the time-grid isn't tall enough to occupy the given height, we render an <hr> underneath
- bottomRuleEl: null,
-
-
- initialize: function() {
- this.timeGrid = this.instantiateTimeGrid();
-
- if (this.opt('allDaySlot')) { // should we display the "all-day" area?
- this.dayGrid = this.instantiateDayGrid(); // the all-day subcomponent of this view
- }
-
- this.scroller = new Scroller({
- overflowX: 'hidden',
- overflowY: 'auto'
- });
- },
-
-
- // Instantiates the TimeGrid object this view needs. Draws from this.timeGridClass
- instantiateTimeGrid: function() {
- var subclass = this.timeGridClass.extend(agendaTimeGridMethods);
-
- return new subclass(this);
- },
-
-
- // Instantiates the DayGrid object this view might need. Draws from this.dayGridClass
- instantiateDayGrid: function() {
- var subclass = this.dayGridClass.extend(agendaDayGridMethods);
-
- return new subclass(this);
- },
-
-
- /* Rendering
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Sets the display range and computes all necessary dates
- setRange: function(range) {
- View.prototype.setRange.call(this, range); // call the super-method
-
- this.timeGrid.setRange(range);
- if (this.dayGrid) {
- this.dayGrid.setRange(range);
- }
- },
-
-
- // Renders the view into `this.el`, which has already been assigned
- renderDates: function() {
-
- this.el.addClass('fc-agenda-view').html(this.renderSkeletonHtml());
- this.renderHead();
-
- this.scroller.render();
- var timeGridWrapEl = this.scroller.el.addClass('fc-time-grid-container');
- var timeGridEl = $('<div class="fc-time-grid" />').appendTo(timeGridWrapEl);
- this.el.find('.fc-body > tr > td').append(timeGridWrapEl);
-
- this.timeGrid.setElement(timeGridEl);
- this.timeGrid.renderDates();
-
- // the <hr> that sometimes displays under the time-grid
- this.bottomRuleEl = $('<hr class="fc-divider ' + this.widgetHeaderClass + '"/>')
- .appendTo(this.timeGrid.el); // inject it into the time-grid
-
- if (this.dayGrid) {
- this.dayGrid.setElement(this.el.find('.fc-day-grid'));
- this.dayGrid.renderDates();
-
- // have the day-grid extend it's coordinate area over the <hr> dividing the two grids
- this.dayGrid.bottomCoordPadding = this.dayGrid.el.next('hr').outerHeight();
- }
-
- this.noScrollRowEls = this.el.find('.fc-row:not(.fc-scroller *)'); // fake rows not within the scroller
- },
-
-
- // render the day-of-week headers
- renderHead: function() {
- this.headContainerEl =
- this.el.find('.fc-head-container')
- .html(this.timeGrid.renderHeadHtml());
- },
-
-
- // Unrenders the content of the view. Since we haven't separated skeleton rendering from date rendering,
- // always completely kill each grid's rendering.
- unrenderDates: function() {
- this.timeGrid.unrenderDates();
- this.timeGrid.removeElement();
-
- if (this.dayGrid) {
- this.dayGrid.unrenderDates();
- this.dayGrid.removeElement();
- }
-
- this.scroller.destroy();
- },
-
-
- // Builds the HTML skeleton for the view.
- // The day-grid and time-grid components will render inside containers defined by this HTML.
- renderSkeletonHtml: function() {
- return '' +
- '<table>' +
- '<thead class="fc-head">' +
- '<tr>' +
- '<td class="fc-head-container ' + this.widgetHeaderClass + '"></td>' +
- '</tr>' +
- '</thead>' +
- '<tbody class="fc-body">' +
- '<tr>' +
- '<td class="' + this.widgetContentClass + '">' +
- (this.dayGrid ?
- '<div class="fc-day-grid"/>' +
- '<hr class="fc-divider ' + this.widgetHeaderClass + '"/>' :
- ''
- ) +
- '</td>' +
- '</tr>' +
- '</tbody>' +
- '</table>';
- },
-
-
- // Generates an HTML attribute string for setting the width of the axis, if it is known
- axisStyleAttr: function() {
- if (this.axisWidth !== null) {
- return 'style="width:' + this.axisWidth + 'px"';
- }
- return '';
- },
-
-
- /* Business Hours
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- renderBusinessHours: function() {
- this.timeGrid.renderBusinessHours();
-
- if (this.dayGrid) {
- this.dayGrid.renderBusinessHours();
- }
- },
-
-
- unrenderBusinessHours: function() {
- this.timeGrid.unrenderBusinessHours();
-
- if (this.dayGrid) {
- this.dayGrid.unrenderBusinessHours();
- }
- },
-
-
- /* Now Indicator
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- getNowIndicatorUnit: function() {
- return this.timeGrid.getNowIndicatorUnit();
- },
-
-
- renderNowIndicator: function(date) {
- this.timeGrid.renderNowIndicator(date);
- },
-
-
- unrenderNowIndicator: function() {
- this.timeGrid.unrenderNowIndicator();
- },
-
-
- /* Dimensions
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- updateSize: function(isResize) {
- this.timeGrid.updateSize(isResize);
-
- View.prototype.updateSize.call(this, isResize); // call the super-method
- },
-
-
- // Refreshes the horizontal dimensions of the view
- updateWidth: function() {
- // make all axis cells line up, and record the width so newly created axis cells will have it
- this.axisWidth = matchCellWidths(this.el.find('.fc-axis'));
- },
-
-
- // Adjusts the vertical dimensions of the view to the specified values
- setHeight: function(totalHeight, isAuto) {
- var eventLimit;
- var scrollerHeight;
- var scrollbarWidths;
-
- // reset all dimensions back to the original state
- this.bottomRuleEl.hide(); // .show() will be called later if this <hr> is necessary
- this.scroller.clear(); // sets height to 'auto' and clears overflow
- uncompensateScroll(this.noScrollRowEls);
-
- // limit number of events in the all-day area
- if (this.dayGrid) {
- this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed
-
- eventLimit = this.opt('eventLimit');
- if (eventLimit && typeof eventLimit !== 'number') {
- eventLimit = AGENDA_ALL_DAY_EVENT_LIMIT; // make sure "auto" goes to a real number
- }
- if (eventLimit) {
- this.dayGrid.limitRows(eventLimit);
- }
- }
-
- if (!isAuto) { // should we force dimensions of the scroll container?
-
- scrollerHeight = this.computeScrollerHeight(totalHeight);
- this.scroller.setHeight(scrollerHeight);
- scrollbarWidths = this.scroller.getScrollbarWidths();
-
- if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars?
-
- // make the all-day and header rows lines up
- compensateScroll(this.noScrollRowEls, scrollbarWidths);
-
- // the scrollbar compensation might have changed text flow, which might affect height, so recalculate
- // and reapply the desired height to the scroller.
- scrollerHeight = this.computeScrollerHeight(totalHeight);
- this.scroller.setHeight(scrollerHeight);
- }
-
- // guarantees the same scrollbar widths
- this.scroller.lockOverflow(scrollbarWidths);
-
- // if there's any space below the slats, show the horizontal rule.
- // this won't cause any new overflow, because lockOverflow already called.
- if (this.timeGrid.getTotalSlatHeight() < scrollerHeight) {
- this.bottomRuleEl.show();
- }
- }
- },
-
-
- // given a desired total height of the view, returns what the height of the scroller should be
- computeScrollerHeight: function(totalHeight) {
- return totalHeight -
- subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
- },
-
-
- /* Scroll
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Computes the initial pre-configured scroll state prior to allowing the user to change it
- computeInitialScroll: function() {
- var scrollTime = moment.duration(this.opt('scrollTime'));
- var top = this.timeGrid.computeTimeTop(scrollTime);
-
- // zoom can give weird floating-point values. rather scroll a little bit further
- top = Math.ceil(top);
-
- if (top) {
- top++; // to overcome top border that slots beyond the first have. looks better
- }
-
- return top;
- },
-
-
- queryScroll: function() {
- return this.scroller.getScrollTop();
- },
-
-
- setScroll: function(top) {
- this.scroller.setScrollTop(top);
- },
-
-
- /* Hit Areas
- ------------------------------------------------------------------------------------------------------------------*/
- // forward all hit-related method calls to the grids (dayGrid might not be defined)
-
-
- prepareHits: function() {
- this.timeGrid.prepareHits();
- if (this.dayGrid) {
- this.dayGrid.prepareHits();
- }
- },
-
-
- releaseHits: function() {
- this.timeGrid.releaseHits();
- if (this.dayGrid) {
- this.dayGrid.releaseHits();
- }
- },
-
-
- queryHit: function(left, top) {
- var hit = this.timeGrid.queryHit(left, top);
-
- if (!hit && this.dayGrid) {
- hit = this.dayGrid.queryHit(left, top);
- }
-
- return hit;
- },
-
-
- getHitSpan: function(hit) {
- // TODO: hit.component is set as a hack to identify where the hit came from
- return hit.component.getHitSpan(hit);
- },
-
-
- getHitEl: function(hit) {
- // TODO: hit.component is set as a hack to identify where the hit came from
- return hit.component.getHitEl(hit);
- },
-
-
- /* Events
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders events onto the view and populates the View's segment array
- renderEvents: function(events) {
- var dayEvents = [];
- var timedEvents = [];
- var daySegs = [];
- var timedSegs;
- var i;
-
- // separate the events into all-day and timed
- for (i = 0; i < events.length; i++) {
- if (events[i].allDay) {
- dayEvents.push(events[i]);
- }
- else {
- timedEvents.push(events[i]);
- }
- }
-
- // render the events in the subcomponents
- timedSegs = this.timeGrid.renderEvents(timedEvents);
- if (this.dayGrid) {
- daySegs = this.dayGrid.renderEvents(dayEvents);
- }
-
- // the all-day area is flexible and might have a lot of events, so shift the height
- this.updateHeight();
- },
-
-
- // Retrieves all segment objects that are rendered in the view
- getEventSegs: function() {
- return this.timeGrid.getEventSegs().concat(
- this.dayGrid ? this.dayGrid.getEventSegs() : []
- );
- },
-
-
- // Unrenders all event elements and clears internal segment data
- unrenderEvents: function() {
-
- // unrender the events in the subcomponents
- this.timeGrid.unrenderEvents();
- if (this.dayGrid) {
- this.dayGrid.unrenderEvents();
- }
-
- // we DON'T need to call updateHeight() because:
- // A) a renderEvents() call always happens after this, which will eventually call updateHeight()
- // B) in IE8, this causes a flash whenever events are rerendered
- },
-
-
- /* Dragging (for events and external elements)
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // A returned value of `true` signals that a mock "helper" event has been rendered.
- renderDrag: function(dropLocation, seg) {
- if (dropLocation.start.hasTime()) {
- return this.timeGrid.renderDrag(dropLocation, seg);
- }
- else if (this.dayGrid) {
- return this.dayGrid.renderDrag(dropLocation, seg);
- }
- },
-
-
- unrenderDrag: function() {
- this.timeGrid.unrenderDrag();
- if (this.dayGrid) {
- this.dayGrid.unrenderDrag();
- }
- },
-
-
- /* Selection
- ------------------------------------------------------------------------------------------------------------------*/
-
-
- // Renders a visual indication of a selection
- renderSelection: function(span) {
- if (span.start.hasTime() || span.end.hasTime()) {
- this.timeGrid.renderSelection(span);
- }
- else if (this.dayGrid) {
- this.dayGrid.renderSelection(span);
- }
- },
-
-
- // Unrenders a visual indications of a selection
- unrenderSelection: function() {
- this.timeGrid.unrenderSelection();
- if (this.dayGrid) {
- this.dayGrid.unrenderSelection();
- }
- }
-
-});
-
-
-// Methods that will customize the rendering behavior of the AgendaView's timeGrid
-// TODO: move into TimeGrid
-var agendaTimeGridMethods = {
-
-
- // Generates the HTML that will go before the day-of week header cells
- renderHeadIntroHtml: function() {
- var view = this.view;
- var weekText;
-
- if (view.opt('weekNumbers')) {
- weekText = this.start.format(view.opt('smallWeekFormat'));
-
- return '' +
- '<th class="fc-axis fc-week-number ' + view.widgetHeaderClass + '" ' + view.axisStyleAttr() + '>' +
- '<span>' + // needed for matchCellWidths
- htmlEscape(weekText) +
- '</span>' +
- '</th>';
- }
- else {
- return '<th class="fc-axis ' + view.widgetHeaderClass + '" ' + view.axisStyleAttr() + '></th>';
- }
- },
-
-
- // Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column.
- renderBgIntroHtml: function() {
- var view = this.view;
-
- return '<td class="fc-axis ' + view.widgetContentClass + '" ' + view.axisStyleAttr() + '></td>';
- },
-
-
- // Generates the HTML that goes before all other types of cells.
- // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid.
- renderIntroHtml: function() {
- var view = this.view;
-
- return '<td class="fc-axis" ' + view.axisStyleAttr() + '></td>';
- }
-
-};
-
-
-// Methods that will customize the rendering behavior of the AgendaView's dayGrid
-var agendaDayGridMethods = {
-
-
- // Generates the HTML that goes before the all-day cells
- renderBgIntroHtml: function() {
- var view = this.view;
-
- return '' +
- '<td class="fc-axis ' + view.widgetContentClass + '" ' + view.axisStyleAttr() + '>' +
- '<span>' + // needed for matchCellWidths
- (view.opt('allDayHtml') || htmlEscape(view.opt('allDayText'))) +
- '</span>' +
- '</td>';
- },
-
-
- // Generates the HTML that goes before all other types of cells.
- // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid.
- renderIntroHtml: function() {
- var view = this.view;
-
- return '<td class="fc-axis" ' + view.axisStyleAttr() + '></td>';
- }
-
-};
-
-;;
-
-var AGENDA_ALL_DAY_EVENT_LIMIT = 5;
-
-// potential nice values for the slot-duration and interval-duration
-// from largest to smallest
-var AGENDA_STOCK_SUB_DURATIONS = [
- { hours: 1 },
- { minutes: 30 },
- { minutes: 15 },
- { seconds: 30 },
- { seconds: 15 }
-];
-
-fcViews.agenda = {
- 'class': AgendaView,
- defaults: {
- allDaySlot: true,
- allDayText: 'all-day',
- slotDuration: '00:30:00',
- minTime: '00:00:00',
- maxTime: '24:00:00',
- slotEventOverlap: true // a bad name. confused with overlap/constraint system
- }
-};
-
-fcViews.agendaDay = {
- type: 'agenda',
- duration: { days: 1 }
-};
-
-fcViews.agendaWeek = {
- type: 'agenda',
- duration: { weeks: 1 }
-};
-;;
-
-return FC; // export for Node/CommonJS
-}); \ No newline at end of file
diff --git a/tools/infra-dashboard/js/fullcalendar.min.js b/tools/infra-dashboard/js/fullcalendar.min.js
deleted file mode 100644
index de0babcf..00000000
--- a/tools/infra-dashboard/js/fullcalendar.min.js
+++ /dev/null
@@ -1,9 +0,0 @@
-/*!
- * FullCalendar v2.7.2
- * Docs & License: http://fullcalendar.io/
- * (c) 2016 Adam Shaw
- */
-!function(a){"function"==typeof define&&define.amd?define(["jquery","moment"],a):"object"==typeof exports?module.exports=a(require("jquery"),require("moment")):a(jQuery,moment)}(function(a,b){function c(a){return W(a,Xa)}function d(b){var c,d={views:b.views||{}};return a.each(b,function(b,e){"views"!=b&&(a.isPlainObject(e)&&!/(time|duration|interval)$/i.test(b)&&-1==a.inArray(b,Xa)?(c=null,a.each(e,function(a,e){/^(month|week|day|default|basic(Week|Day)?|agenda(Week|Day)?)$/.test(a)?(d.views[a]||(d.views[a]={}),d.views[a][b]=e):(c||(c={}),c[a]=e)}),c&&(d[b]=c)):d[b]=e)}),d}function e(a,b){b.left&&a.css({"border-left-width":1,"margin-left":b.left-1}),b.right&&a.css({"border-right-width":1,"margin-right":b.right-1})}function f(a){a.css({"margin-left":"","margin-right":"","border-left-width":"","border-right-width":""})}function g(){a("body").addClass("fc-not-allowed")}function h(){a("body").removeClass("fc-not-allowed")}function i(b,c,d){var e=Math.floor(c/b.length),f=Math.floor(c-e*(b.length-1)),g=[],h=[],i=[],k=0;j(b),b.each(function(c,d){var j=c===b.length-1?f:e,l=a(d).outerHeight(!0);j>l?(g.push(d),h.push(l),i.push(a(d).height())):k+=l}),d&&(c-=k,e=Math.floor(c/g.length),f=Math.floor(c-e*(g.length-1))),a(g).each(function(b,c){var d=b===g.length-1?f:e,j=h[b],k=i[b],l=d-(j-k);d>j&&a(c).height(l)})}function j(a){a.height("")}function k(b){var c=0;return b.find("> span").each(function(b,d){var e=a(d).outerWidth();e>c&&(c=e)}),c++,b.width(c),c}function l(a,b){var c,d=a.add(b);return d.css({position:"relative",left:-1}),c=a.outerHeight()-b.outerHeight(),d.css({position:"",left:""}),c}function m(b){var c=b.css("position"),d=b.parents().filter(function(){var b=a(this);return/(auto|scroll)/.test(b.css("overflow")+b.css("overflow-y")+b.css("overflow-x"))}).eq(0);return"fixed"!==c&&d.length?d:a(b[0].ownerDocument||document)}function n(a,b){var c=a.offset(),d=c.left-(b?b.left:0),e=c.top-(b?b.top:0);return{left:d,right:d+a.outerWidth(),top:e,bottom:e+a.outerHeight()}}function o(a,b){var c=a.offset(),d=q(a),e=c.left+t(a,"border-left-width")+d.left-(b?b.left:0),f=c.top+t(a,"border-top-width")+d.top-(b?b.top:0);return{left:e,right:e+a[0].clientWidth,top:f,bottom:f+a[0].clientHeight}}function p(a,b){var c=a.offset(),d=c.left+t(a,"border-left-width")+t(a,"padding-left")-(b?b.left:0),e=c.top+t(a,"border-top-width")+t(a,"padding-top")-(b?b.top:0);return{left:d,right:d+a.width(),top:e,bottom:e+a.height()}}function q(a){var b=a.innerWidth()-a[0].clientWidth,c={left:0,right:0,top:0,bottom:a.innerHeight()-a[0].clientHeight};return r()&&"rtl"==a.css("direction")?c.left=b:c.right=b,c}function r(){return null===Ya&&(Ya=s()),Ya}function s(){var b=a("<div><div/></div>").css({position:"absolute",top:-1e3,left:0,border:0,padding:0,overflow:"scroll",direction:"rtl"}).appendTo("body"),c=b.children(),d=c.offset().left>b.offset().left;return b.remove(),d}function t(a,b){return parseFloat(a.css(b))||0}function u(a){return 1==a.which&&!a.ctrlKey}function v(a){if(void 0!==a.pageX)return a.pageX;var b=a.originalEvent.touches;return b?b[0].pageX:void 0}function w(a){if(void 0!==a.pageY)return a.pageY;var b=a.originalEvent.touches;return b?b[0].pageY:void 0}function x(a){return/^touch/.test(a.type)}function y(a){a.addClass("fc-unselectable").on("selectstart",z)}function z(a){a.preventDefault()}function A(a){return window.addEventListener?(window.addEventListener("scroll",a,!0),!0):!1}function B(a){return window.removeEventListener?(window.removeEventListener("scroll",a,!0),!0):!1}function C(a,b){var c={left:Math.max(a.left,b.left),right:Math.min(a.right,b.right),top:Math.max(a.top,b.top),bottom:Math.min(a.bottom,b.bottom)};return c.left<c.right&&c.top<c.bottom?c:!1}function D(a,b){return{left:Math.min(Math.max(a.left,b.left),b.right),top:Math.min(Math.max(a.top,b.top),b.bottom)}}function E(a){return{left:(a.left+a.right)/2,top:(a.top+a.bottom)/2}}function F(a,b){return{left:a.left-b.left,top:a.top-b.top}}function G(b){var c,d,e=[],f=[];for("string"==typeof b?f=b.split(/\s*,\s*/):"function"==typeof b?f=[b]:a.isArray(b)&&(f=b),c=0;c<f.length;c++)d=f[c],"string"==typeof d?e.push("-"==d.charAt(0)?{field:d.substring(1),order:-1}:{field:d,order:1}):"function"==typeof d&&e.push({func:d});return e}function H(a,b,c){var d,e;for(d=0;d<c.length;d++)if(e=I(a,b,c[d]))return e;return 0}function I(a,b,c){return c.func?c.func(a,b):J(a[c.field],b[c.field])*(c.order||1)}function J(b,c){return b||c?null==c?-1:null==b?1:"string"===a.type(b)||"string"===a.type(c)?String(b).localeCompare(String(c)):b-c:0}function K(a,b){var c,d,e,f,g=a.start,h=a.end,i=b.start,j=b.end;return h>i&&j>g?(g>=i?(c=g.clone(),e=!0):(c=i.clone(),e=!1),j>=h?(d=h.clone(),f=!0):(d=j.clone(),f=!1),{start:c,end:d,isStart:e,isEnd:f}):void 0}function L(a,c){return b.duration({days:a.clone().stripTime().diff(c.clone().stripTime(),"days"),ms:a.time()-c.time()})}function M(a,c){return b.duration({days:a.clone().stripTime().diff(c.clone().stripTime(),"days")})}function N(a,c,d){return b.duration(Math.round(a.diff(c,d,!0)),d)}function O(a,b){var c,d,e;for(c=0;c<$a.length&&(d=$a[c],e=P(d,a,b),!(e>=1&&ha(e)));c++);return d}function P(a,c,d){return null!=d?d.diff(c,a,!0):b.isDuration(c)?c.as(a):c.end.diff(c.start,a,!0)}function Q(a,b,c){var d;return T(c)?(b-a)/c:(d=c.asMonths(),Math.abs(d)>=1&&ha(d)?b.diff(a,"months",!0)/d:b.diff(a,"days",!0)/c.asDays())}function R(a,b){var c,d;return T(a)||T(b)?a/b:(c=a.asMonths(),d=b.asMonths(),Math.abs(c)>=1&&ha(c)&&Math.abs(d)>=1&&ha(d)?c/d:a.asDays()/b.asDays())}function S(a,c){var d;return T(a)?b.duration(a*c):(d=a.asMonths(),Math.abs(d)>=1&&ha(d)?b.duration({months:d*c}):b.duration({days:a.asDays()*c}))}function T(a){return Boolean(a.hours()||a.minutes()||a.seconds()||a.milliseconds())}function U(a){return"[object Date]"===Object.prototype.toString.call(a)||a instanceof Date}function V(a){return/^\d+\:\d+(?:\:\d+\.?(?:\d{3})?)?$/.test(a)}function W(a,b){var c,d,e,f,g,h,i={};if(b)for(c=0;c<b.length;c++){for(d=b[c],e=[],f=a.length-1;f>=0;f--)if(g=a[f][d],"object"==typeof g)e.unshift(g);else if(void 0!==g){i[d]=g;break}e.length&&(i[d]=W(e))}for(c=a.length-1;c>=0;c--){h=a[c];for(d in h)d in i||(i[d]=h[d])}return i}function X(a){var b=function(){};return b.prototype=a,new b}function Y(a,b){for(var c in a)$(a,c)&&(b[c]=a[c])}function Z(a,b){var c,d,e=["constructor","toString","valueOf"];for(c=0;c<e.length;c++)d=e[c],a[d]!==Object.prototype[d]&&(b[d]=a[d])}function $(a,b){return cb.call(a,b)}function _(b){return/undefined|null|boolean|number|string/.test(a.type(b))}function aa(b,c,d){if(a.isFunction(b)&&(b=[b]),b){var e,f;for(e=0;e<b.length;e++)f=b[e].apply(c,d)||f;return f}}function ba(){for(var a=0;a<arguments.length;a++)if(void 0!==arguments[a])return arguments[a]}function ca(a){return(a+"").replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/'/g,"&#039;").replace(/"/g,"&quot;").replace(/\n/g,"<br />")}function da(a){return a.replace(/&.*?;/g,"")}function ea(b){var c=[];return a.each(b,function(a,b){null!=b&&c.push(a+":"+b)}),c.join(";")}function fa(a){return a.charAt(0).toUpperCase()+a.slice(1)}function ga(a,b){return a-b}function ha(a){return a%1===0}function ia(a,b){var c=a[b];return function(){return c.apply(a,arguments)}}function ja(a,b,c){var d,e,f,g,h,i=function(){var j=+new Date-g;b>j?d=setTimeout(i,b-j):(d=null,c||(h=a.apply(f,e),f=e=null))};return function(){f=this,e=arguments,g=+new Date;var j=c&&!d;return d||(d=setTimeout(i,b)),j&&(h=a.apply(f,e),f=e=null),h}}function ka(c,d,e){var f,g,h,i,j=c[0],k=1==c.length&&"string"==typeof j;return b.isMoment(j)?(i=b.apply(null,c),ma(j,i)):U(j)||void 0===j?i=b.apply(null,c):(f=!1,g=!1,k?db.test(j)?(j+="-01",c=[j],f=!0,g=!0):(h=eb.exec(j))&&(f=!h[5],g=!0):a.isArray(j)&&(g=!0),i=d||f?b.utc.apply(b,c):b.apply(null,c),f?(i._ambigTime=!0,i._ambigZone=!0):e&&(g?i._ambigZone=!0:k&&(i.utcOffset?i.utcOffset(j):i.zone(j)))),i._fullCalendar=!0,i}function la(a,c){var d,e,f=!1,g=!1,h=a.length,i=[];for(d=0;h>d;d++)e=a[d],b.isMoment(e)||(e=Va.moment.parseZone(e)),f=f||e._ambigTime,g=g||e._ambigZone,i.push(e);for(d=0;h>d;d++)e=i[d],c||!f||e._ambigTime?g&&!e._ambigZone&&(i[d]=e.clone().stripZone()):i[d]=e.clone().stripTime();return i}function ma(a,b){a._ambigTime?b._ambigTime=!0:b._ambigTime&&(b._ambigTime=!1),a._ambigZone?b._ambigZone=!0:b._ambigZone&&(b._ambigZone=!1)}function na(a,b){a.year(b[0]||0).month(b[1]||0).date(b[2]||0).hours(b[3]||0).minutes(b[4]||0).seconds(b[5]||0).milliseconds(b[6]||0)}function oa(a,b){return gb.format.call(a,b)}function pa(a,b){return qa(a,va(b))}function qa(a,b){var c,d="";for(c=0;c<b.length;c++)d+=ra(a,b[c]);return d}function ra(a,b){var c,d;return"string"==typeof b?b:(c=b.token)?hb[c]?hb[c](a):oa(a,c):b.maybe&&(d=qa(a,b.maybe),d.match(/[1-9]/))?d:""}function sa(a,b,c,d,e){var f;return a=Va.moment.parseZone(a),b=Va.moment.parseZone(b),f=(a.localeData||a.lang).call(a),c=f.longDateFormat(c)||c,d=d||" - ",ta(a,b,va(c),d,e)}function ta(a,b,c,d,e){var f,g,h,i,j=a.clone().stripZone(),k=b.clone().stripZone(),l="",m="",n="",o="",p="";for(g=0;g<c.length&&(f=ua(a,b,j,k,c[g]),f!==!1);g++)l+=f;for(h=c.length-1;h>g&&(f=ua(a,b,j,k,c[h]),f!==!1);h--)m=f+m;for(i=g;h>=i;i++)n+=ra(a,c[i]),o+=ra(b,c[i]);return(n||o)&&(p=e?o+d+n:n+d+o),l+p+m}function ua(a,b,c,d,e){var f,g;return"string"==typeof e?e:(f=e.token)&&(g=ib[f.charAt(0)],g&&c.isSame(d,g))?oa(a,f):!1}function va(a){return a in jb?jb[a]:jb[a]=wa(a)}function wa(a){for(var b,c=[],d=/\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g;b=d.exec(a);)b[1]?c.push(b[1]):b[2]?c.push({maybe:wa(b[2])}):b[3]?c.push({token:b[3]}):b[5]&&c.push(b[5]);return c}function xa(){}function ya(a,b){var c;return $(b,"constructor")&&(c=b.constructor),"function"!=typeof c&&(c=b.constructor=function(){a.apply(this,arguments)}),c.prototype=X(a.prototype),Y(b,c.prototype),Z(b,c.prototype),Y(a,c),c}function za(a,b){Y(b,a.prototype)}function Aa(a,b){return a||b?a&&b?a.component===b.component&&Ba(a,b)&&Ba(b,a):!1:!0}function Ba(a,b){for(var c in a)if(!/^(component|left|right|top|bottom)$/.test(c)&&a[c]!==b[c])return!1;return!0}function Ca(a){var b=Ea(a);return"background"===b||"inverse-background"===b}function Da(a){return"inverse-background"===Ea(a)}function Ea(a){return ba((a.source||{}).rendering,a.rendering)}function Fa(a){var b,c,d={};for(b=0;b<a.length;b++)c=a[b],(d[c._id]||(d[c._id]=[])).push(c);return d}function Ga(a,b){return a.start-b.start}function Ha(c){var d,e,f,g,h=Va.dataAttrPrefix;return h&&(h+="-"),d=c.data(h+"event")||null,d&&(d="object"==typeof d?a.extend({},d):{},e=d.start,null==e&&(e=d.time),f=d.duration,g=d.stick,delete d.start,delete d.time,delete d.duration,delete d.stick),null==e&&(e=c.data(h+"start")),null==e&&(e=c.data(h+"time")),null==f&&(f=c.data(h+"duration")),null==g&&(g=c.data(h+"stick")),e=null!=e?b.duration(e):null,f=null!=f?b.duration(f):null,g=Boolean(g),{eventProps:d,startTime:e,duration:f,stick:g}}function Ia(a,b){var c,d;for(c=0;c<b.length;c++)if(d=b[c],d.leftCol<=a.rightCol&&d.rightCol>=a.leftCol)return!0;return!1}function Ja(a,b){return a.leftCol-b.leftCol}function Ka(a){var b,c,d,e=[];for(b=0;b<a.length;b++){for(c=a[b],d=0;d<e.length&&Na(c,e[d]).length;d++);c.level=d,(e[d]||(e[d]=[])).push(c)}return e}function La(a){var b,c,d,e,f;for(b=0;b<a.length;b++)for(c=a[b],d=0;d<c.length;d++)for(e=c[d],e.forwardSegs=[],f=b+1;f<a.length;f++)Na(e,a[f],e.forwardSegs)}function Ma(a){var b,c,d=a.forwardSegs,e=0;if(void 0===a.forwardPressure){for(b=0;b<d.length;b++)c=d[b],Ma(c),e=Math.max(e,1+c.forwardPressure);a.forwardPressure=e}}function Na(a,b,c){c=c||[];for(var d=0;d<b.length;d++)Oa(a,b[d])&&c.push(b[d]);return c}function Oa(a,b){return a.bottom>b.top&&a.top<b.bottom}function Pa(c,d){function e(){T?h()&&(k(),i()):f()}function f(){U=O.theme?"ui":"fc",c.addClass("fc"),O.isRTL?c.addClass("fc-rtl"):c.addClass("fc-ltr"),O.theme?c.addClass("ui-widget"):c.addClass("fc-unthemed"),T=a("<div class='fc-view-container'/>").prependTo(c),R=N.header=new Sa(N,O),S=R.render(),S&&c.prepend(S),i(O.defaultView),O.handleWindowResize&&(Y=ja(m,O.windowResizeDelay),a(window).resize(Y))}function g(){V&&V.removeElement(),R.removeElement(),T.remove(),c.removeClass("fc fc-ltr fc-rtl fc-unthemed ui-widget"),Y&&a(window).unbind("resize",Y)}function h(){return c.is(":visible")}function i(b){ca++,V&&b&&V.type!==b&&(R.deactivateButton(V.type),H(),V.removeElement(),V=N.view=null),!V&&b&&(V=N.view=ba[b]||(ba[b]=N.instantiateView(b)),V.setElement(a("<div class='fc-view fc-"+b+"-view' />").appendTo(T)),R.activateButton(b)),V&&(Z=V.massageCurrentDate(Z),V.displaying&&Z.isWithin(V.intervalStart,V.intervalEnd)||h()&&(V.display(Z),I(),u(),v(),q())),I(),ca--}function j(a){return h()?(a&&l(),ca++,V.updateSize(!0),ca--,!0):void 0}function k(){h()&&l()}function l(){W="number"==typeof O.contentHeight?O.contentHeight:"number"==typeof O.height?O.height-(S?S.outerHeight(!0):0):Math.round(T.width()/Math.max(O.aspectRatio,.5))}function m(a){!ca&&a.target===window&&V.start&&j(!0)&&V.trigger("windowResize",aa)}function n(){p(),r()}function o(){h()&&(H(),V.displayEvents(da),I())}function p(){H(),V.clearEvents(),I()}function q(){!O.lazyFetching||$(V.start,V.end)?r():o()}function r(){_(V.start,V.end)}function s(a){da=a,o()}function t(){o()}function u(){R.updateTitle(V.title)}function v(){var a=N.getNow();a.isWithin(V.intervalStart,V.intervalEnd)?R.disableButton("today"):R.enableButton("today")}function w(a,b){V.select(N.buildSelectSpan.apply(N,arguments))}function x(){V&&V.unselect()}function y(){Z=V.computePrevDate(Z),i()}function z(){Z=V.computeNextDate(Z),i()}function A(){Z.add(-1,"years"),i()}function B(){Z.add(1,"years"),i()}function C(){Z=N.getNow(),i()}function D(a){Z=N.moment(a).stripZone(),i()}function E(a){Z.add(b.duration(a)),i()}function F(a,b){var c;b=b||"day",c=N.getViewSpec(b)||N.getUnitViewSpec(b),Z=a.clone(),i(c?c.type:null)}function G(){return N.applyTimezone(Z)}function H(){T.css({width:"100%",height:T.height(),overflow:"hidden"})}function I(){T.css({width:"",height:"",overflow:""})}function J(){return N}function K(){return V}function L(a,b){return void 0===b?O[a]:void("height"!=a&&"contentHeight"!=a&&"aspectRatio"!=a||(O[a]=b,j(!0)))}function M(a,b){var c=Array.prototype.slice.call(arguments,2);return b=b||aa,this.triggerWith(a,b,c),O[a]?O[a].apply(b,c):void 0}var N=this;N.initOptions(d||{});var O=this.options;N.render=e,N.destroy=g,N.refetchEvents=n,N.reportEvents=s,N.reportEventChange=t,N.rerenderEvents=o,N.changeView=i,N.select=w,N.unselect=x,N.prev=y,N.next=z,N.prevYear=A,N.nextYear=B,N.today=C,N.gotoDate=D,N.incrementDate=E,N.zoomTo=F,N.getDate=G,N.getCalendar=J,N.getView=K,N.option=L,N.trigger=M;var P=X(Ra(O.lang));if(O.monthNames&&(P._months=O.monthNames),O.monthNamesShort&&(P._monthsShort=O.monthNamesShort),O.dayNames&&(P._weekdays=O.dayNames),O.dayNamesShort&&(P._weekdaysShort=O.dayNamesShort),null!=O.firstDay){var Q=X(P._week);Q.dow=O.firstDay,P._week=Q}P._fullCalendar_weekCalc=function(a){return"function"==typeof a?a:"local"===a?a:"iso"===a||"ISO"===a?"ISO":void 0}(O.weekNumberCalculation),N.defaultAllDayEventDuration=b.duration(O.defaultAllDayEventDuration),N.defaultTimedEventDuration=b.duration(O.defaultTimedEventDuration),N.moment=function(){var a;return"local"===O.timezone?(a=Va.moment.apply(null,arguments),a.hasTime()&&a.local()):a="UTC"===O.timezone?Va.moment.utc.apply(null,arguments):Va.moment.parseZone.apply(null,arguments),"_locale"in a?a._locale=P:a._lang=P,a},N.getIsAmbigTimezone=function(){return"local"!==O.timezone&&"UTC"!==O.timezone},N.applyTimezone=function(a){if(!a.hasTime())return a.clone();var b,c=N.moment(a.toArray()),d=a.time()-c.time();return d&&(b=c.clone().add(d),a.time()-b.time()===0&&(c=b)),c},N.getNow=function(){var a=O.now;return"function"==typeof a&&(a=a()),N.moment(a).stripZone()},N.getEventEnd=function(a){return a.end?a.end.clone():N.getDefaultEventEnd(a.allDay,a.start)},N.getDefaultEventEnd=function(a,b){var c=b.clone();return a?c.stripTime().add(N.defaultAllDayEventDuration):c.add(N.defaultTimedEventDuration),N.getIsAmbigTimezone()&&c.stripZone(),c},N.humanizeDuration=function(a){return(a.locale||a.lang).call(a,O.lang).humanize()},Ta.call(N,O);var R,S,T,U,V,W,Y,Z,$=N.isFetchNeeded,_=N.fetchEvents,aa=c[0],ba={},ca=0,da=[];Z=null!=O.defaultDate?N.moment(O.defaultDate).stripZone():N.getNow(),N.getSuggestedViewHeight=function(){return void 0===W&&k(),W},N.isHeightAuto=function(){return"auto"===O.contentHeight||"auto"===O.height},N.freezeContentHeight=H,N.unfreezeContentHeight=I,N.initialize()}function Qa(b){a.each(Cb,function(a,c){null==b[a]&&(b[a]=c(b))})}function Ra(a){var c=b.localeData||b.langData;return c.call(b,a)||c.call(b,"en")}function Sa(b,c){function d(){var b=c.header;return n=c.theme?"ui":"fc",b?o=a("<div class='fc-toolbar'/>").append(f("left")).append(f("right")).append(f("center")).append('<div class="fc-clear"/>'):void 0}function e(){o.remove(),o=a()}function f(d){var e=a('<div class="fc-'+d+'"/>'),f=c.header[d];return f&&a.each(f.split(" "),function(d){var f,g=a(),h=!0;a.each(this.split(","),function(d,e){var f,i,j,k,l,m,o,q,r,s;"title"==e?(g=g.add(a("<h2>&nbsp;</h2>")),h=!1):((f=(b.options.customButtons||{})[e])?(j=function(a){f.click&&f.click.call(s[0],a)},k="",l=f.text):(i=b.getViewSpec(e))?(j=function(){b.changeView(e)},p.push(e),k=i.buttonTextOverride,l=i.buttonTextDefault):b[e]&&(j=function(){b[e]()},k=(b.overrides.buttonText||{})[e],l=c.buttonText[e]),j&&(m=f?f.themeIcon:c.themeButtonIcons[e],o=f?f.icon:c.buttonIcons[e],q=k?ca(k):m&&c.theme?"<span class='ui-icon ui-icon-"+m+"'></span>":o&&!c.theme?"<span class='fc-icon fc-icon-"+o+"'></span>":ca(l),r=["fc-"+e+"-button",n+"-button",n+"-state-default"],s=a('<button type="button" class="'+r.join(" ")+'">'+q+"</button>").click(function(a){s.hasClass(n+"-state-disabled")||(j(a),(s.hasClass(n+"-state-active")||s.hasClass(n+"-state-disabled"))&&s.removeClass(n+"-state-hover"))}).mousedown(function(){s.not("."+n+"-state-active").not("."+n+"-state-disabled").addClass(n+"-state-down")}).mouseup(function(){s.removeClass(n+"-state-down")}).hover(function(){s.not("."+n+"-state-active").not("."+n+"-state-disabled").addClass(n+"-state-hover")},function(){s.removeClass(n+"-state-hover").removeClass(n+"-state-down")}),g=g.add(s)))}),h&&g.first().addClass(n+"-corner-left").end().last().addClass(n+"-corner-right").end(),g.length>1?(f=a("<div/>"),h&&f.addClass("fc-button-group"),f.append(g),e.append(f)):e.append(g)}),e}function g(a){o.find("h2").text(a)}function h(a){o.find(".fc-"+a+"-button").addClass(n+"-state-active")}function i(a){o.find(".fc-"+a+"-button").removeClass(n+"-state-active")}function j(a){o.find(".fc-"+a+"-button").attr("disabled","disabled").addClass(n+"-state-disabled")}function k(a){o.find(".fc-"+a+"-button").removeAttr("disabled").removeClass(n+"-state-disabled")}function l(){return p}var m=this;m.render=d,m.removeElement=e,m.updateTitle=g,m.activateButton=h,m.deactivateButton=i,m.disableButton=j,m.enableButton=k,m.getViewsWithButtons=l;var n,o=a(),p=[]}function Ta(c){function d(a,b){return!I||I>a||b>J}function e(a,b){I=a,J=b,S=[];var c=++Q,d=P.length;R=d;for(var e=0;d>e;e++)f(P[e],c)}function f(b,c){g(b,function(d){var e,f,g,h=a.isArray(b.events);if(c==Q){if(d)for(e=0;e<d.length;e++)f=d[e],g=h?f:s(f,b),g&&S.push.apply(S,w(g));R--,R||K(S)}})}function g(b,d){var e,f,h=Va.sourceFetchers;for(e=0;e<h.length;e++){if(f=h[e].call(H,b,I.clone(),J.clone(),c.timezone,d),f===!0)return;if("object"==typeof f)return void g(f,d)}var i=b.events;if(i)a.isFunction(i)?(H.pushLoading(),i.call(H,I.clone(),J.clone(),c.timezone,function(a){d(a),H.popLoading()})):a.isArray(i)?d(i):d();else{var j=b.url;if(j){var k,l=b.success,m=b.error,n=b.complete;k=a.isFunction(b.data)?b.data():b.data;var o=a.extend({},k||{}),p=ba(b.startParam,c.startParam),q=ba(b.endParam,c.endParam),r=ba(b.timezoneParam,c.timezoneParam);p&&(o[p]=I.format()),q&&(o[q]=J.format()),c.timezone&&"local"!=c.timezone&&(o[r]=c.timezone),H.pushLoading(),a.ajax(a.extend({},Db,b,{data:o,success:function(b){b=b||[];var c=aa(l,this,arguments);a.isArray(c)&&(b=c),d(b)},error:function(){aa(m,this,arguments),d()},complete:function(){aa(n,this,arguments),H.popLoading()}}))}else d()}}function h(a){var b=i(a);b&&(P.push(b),R++,f(b,Q))}function i(b){var c,d,e=Va.sourceNormalizers;if(a.isFunction(b)||a.isArray(b)?c={events:b}:"string"==typeof b?c={url:b}:"object"==typeof b&&(c=a.extend({},b)),c){for(c.className?"string"==typeof c.className&&(c.className=c.className.split(/\s+/)):c.className=[],a.isArray(c.events)&&(c.origArray=c.events,c.events=a.map(c.events,function(a){return s(a,c)})),d=0;d<e.length;d++)e[d].call(H,c);return c}}function j(b){P=a.grep(P,function(a){return!k(a,b)}),S=a.grep(S,function(a){return!k(a.source,b)}),K(S)}function k(a,b){return a&&b&&l(a)==l(b)}function l(a){return("object"==typeof a?a.origArray||a.googleCalendarId||a.url||a.events:null)||a}function m(a){a.start=H.moment(a.start),a.end?a.end=H.moment(a.end):a.end=null,x(a,n(a)),K(S)}function n(b){var c={};return a.each(b,function(a,b){o(a)&&void 0!==b&&_(b)&&(c[a]=b)}),c}function o(a){return!/^_|^(id|allDay|start|end)$/.test(a)}function p(a,b){var c,d,e,f=s(a);if(f){for(c=w(f),d=0;d<c.length;d++)e=c[d],e.source||(b&&(O.events.push(e),e.source=O),S.push(e));return K(S),c}return[]}function q(b){var c,d;for(null==b?b=function(){return!0}:a.isFunction(b)||(c=b+"",b=function(a){return a._id==c}),S=a.grep(S,b,!0),d=0;d<P.length;d++)a.isArray(P[d].events)&&(P[d].events=a.grep(P[d].events,b,!0));K(S)}function r(b){return a.isFunction(b)?a.grep(S,b):null!=b?(b+="",a.grep(S,function(a){return a._id==b})):S}function s(d,e){var f,g,h,i={};if(c.eventDataTransform&&(d=c.eventDataTransform(d)),e&&e.eventDataTransform&&(d=e.eventDataTransform(d)),a.extend(i,d),e&&(i.source=e),i._id=d._id||(void 0===d.id?"_fc"+Eb++:d.id+""),d.className?"string"==typeof d.className?i.className=d.className.split(/\s+/):i.className=d.className:i.className=[],f=d.start||d.date,g=d.end,V(f)&&(f=b.duration(f)),V(g)&&(g=b.duration(g)),d.dow||b.isDuration(f)||b.isDuration(g))i.start=f?b.duration(f):null,i.end=g?b.duration(g):null,i._recurring=!0;else{if(f&&(f=H.moment(f),!f.isValid()))return!1;g&&(g=H.moment(g),g.isValid()||(g=null)),h=d.allDay,void 0===h&&(h=ba(e?e.allDayDefault:void 0,c.allDayDefault)),t(f,g,h,i)}return i}function t(a,b,c,d){d.start=a,d.end=b,d.allDay=c,u(d),Ua(d)}function u(a){v(a),a.end&&!a.end.isAfter(a.start)&&(a.end=null),a.end||(c.forceEventDuration?a.end=H.getDefaultEventEnd(a.allDay,a.start):a.end=null)}function v(a){null==a.allDay&&(a.allDay=!(a.start.hasTime()||a.end&&a.end.hasTime())),a.allDay?(a.start.stripTime(),a.end&&a.end.stripTime()):(a.start.hasTime()||(a.start=H.applyTimezone(a.start.time(0))),a.end&&!a.end.hasTime()&&(a.end=H.applyTimezone(a.end.time(0))))}function w(b,c,d){var e,f,g,h,i,j,k,l,m,n=[];if(c=c||I,d=d||J,b)if(b._recurring){if(f=b.dow)for(e={},g=0;g<f.length;g++)e[f[g]]=!0;for(h=c.clone().stripTime();h.isBefore(d);)e&&!e[h.day()]||(i=b.start,j=b.end,k=h.clone(),l=null,i&&(k=k.time(i)),j&&(l=h.clone().time(j)),m=a.extend({},b),t(k,l,!i&&!j,m),n.push(m)),h.add(1,"days")}else n.push(b);return n}function x(b,c,d){function e(a,b){return d?N(a,b,d):c.allDay?M(a,b):L(a,b)}var f,g,h,i,j,k,l={};return c=c||{},c.start||(c.start=b.start.clone()),void 0===c.end&&(c.end=b.end?b.end.clone():null),null==c.allDay&&(c.allDay=b.allDay),u(c),f={start:b._start.clone(),end:b._end?b._end.clone():H.getDefaultEventEnd(b._allDay,b._start),allDay:c.allDay},u(f),g=null!==b._end&&null===c.end,h=e(c.start,f.start),c.end?(i=e(c.end,f.end),j=i.subtract(h)):j=null,a.each(c,function(a,b){o(a)&&void 0!==b&&(l[a]=b)}),k=y(r(b._id),g,c.allDay,h,j,l),{dateDelta:h,durationDelta:j,undo:k}}function y(b,c,d,e,f,g){var h=H.getIsAmbigTimezone(),i=[];return e&&!e.valueOf()&&(e=null),f&&!f.valueOf()&&(f=null),a.each(b,function(b,j){var k,l;k={start:j.start.clone(),end:j.end?j.end.clone():null,allDay:j.allDay},a.each(g,function(a){k[a]=j[a]}),l={start:j._start,end:j._end,allDay:d},u(l),c?l.end=null:f&&!l.end&&(l.end=H.getDefaultEventEnd(l.allDay,l.start)),e&&(l.start.add(e),l.end&&l.end.add(e)),f&&l.end.add(f),h&&!l.allDay&&(e||f)&&(l.start.stripZone(),l.end&&l.end.stripZone()),a.extend(j,g,l),Ua(j),i.push(function(){a.extend(j,k),Ua(j)})}),function(){for(var a=0;a<i.length;a++)i[a]()}}function z(b){var d,e=c.businessHours,f={className:"fc-nonbusiness",start:"09:00",end:"17:00",dow:[1,2,3,4,5],rendering:"inverse-background"},g=H.getView();return e&&(d=a.extend({},f,"object"==typeof e?e:{})),d?(b&&(d.start=null,d.end=null),w(s(d),g.start,g.end)):[]}function A(a,b){var d=b.source||{},e=ba(b.constraint,d.constraint,c.eventConstraint),f=ba(b.overlap,d.overlap,c.eventOverlap);return D(a,e,f,b)}function B(b,c,d){var e,f;return d&&(e=a.extend({},d,c),f=w(s(e))[0]),f?A(b,f):C(b)}function C(a){return D(a,c.selectConstraint,c.selectOverlap)}function D(a,b,c,d){var e,f,g,h,i,j;if(null!=b){for(e=E(b),f=!1,h=0;h<e.length;h++)if(F(e[h],a)){f=!0;break}if(!f)return!1}for(g=H.getPeerEvents(a,d),h=0;h<g.length;h++)if(i=g[h],G(i,a)){if(c===!1)return!1;if("function"==typeof c&&!c(i,d))return!1;if(d){if(j=ba(i.overlap,(i.source||{}).overlap),j===!1)return!1;if("function"==typeof j&&!j(d,i))return!1}}return!0}function E(a){return"businessHours"===a?z():"object"==typeof a?w(s(a)):r(a)}function F(a,b){var c=a.start.clone().stripZone(),d=H.getEventEnd(a).stripZone();return b.start>=c&&b.end<=d}function G(a,b){var c=a.start.clone().stripZone(),d=H.getEventEnd(a).stripZone();return b.start<d&&b.end>c}var H=this;H.isFetchNeeded=d,H.fetchEvents=e,H.addEventSource=h,H.removeEventSource=j,H.updateEvent=m,H.renderEvent=p,H.removeEvents=q,H.clientEvents=r,H.mutateEvent=x,H.normalizeEventDates=u,H.normalizeEventTimes=v;var I,J,K=H.reportEvents,O={events:[]},P=[O],Q=0,R=0,S=[];a.each((c.events?[c.events]:[]).concat(c.eventSources||[]),function(a,b){var c=i(b);c&&P.push(c)}),H.getBusinessHoursEvents=z,H.isEventSpanAllowed=A,H.isExternalSpanAllowed=B,H.isSelectionSpanAllowed=C,H.getEventCache=function(){return S}}function Ua(a){a._allDay=a.allDay,a._start=a.start.clone(),a._end=a.end?a.end.clone():null}var Va=a.fullCalendar={version:"2.7.2",internalApiVersion:3},Wa=Va.views={};a.fn.fullCalendar=function(b){var c=Array.prototype.slice.call(arguments,1),d=this;return this.each(function(e,f){var g,h=a(f),i=h.data("fullCalendar");"string"==typeof b?i&&a.isFunction(i[b])&&(g=i[b].apply(i,c),e||(d=g),"destroy"===b&&h.removeData("fullCalendar")):i||(i=new yb(h,b),h.data("fullCalendar",i),i.render())}),d};var Xa=["header","buttonText","buttonIcons","themeButtonIcons"];Va.intersectRanges=K,Va.applyAll=aa,Va.debounce=ja,Va.isInt=ha,Va.htmlEscape=ca,Va.cssToStr=ea,Va.proxy=ia,Va.capitaliseFirstLetter=fa,Va.getOuterRect=n,Va.getClientRect=o,Va.getContentRect=p,Va.getScrollbarWidths=q;var Ya=null;Va.preventDefault=z,Va.intersectRects=C,Va.parseFieldSpecs=G,Va.compareByFieldSpecs=H,Va.compareByFieldSpec=I,Va.flexibleCompare=J,Va.computeIntervalUnit=O,Va.divideRangeByDuration=Q,Va.divideDurationByDuration=R,Va.multiplyDuration=S,Va.durationHasTime=T;var Za=["sun","mon","tue","wed","thu","fri","sat"],$a=["year","month","week","day","hour","minute","second","millisecond"];Va.log=function(){var a=window.console;return a&&a.log?a.log.apply(a,arguments):void 0},Va.warn=function(){var a=window.console;return a&&a.warn?a.warn.apply(a,arguments):Va.log.apply(Va,arguments)};var _a,ab,bb,cb={}.hasOwnProperty,db=/^\s*\d{4}-\d\d$/,eb=/^\s*\d{4}-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?)?$/,fb=b.fn,gb=a.extend({},fb);Va.moment=function(){return ka(arguments)},Va.moment.utc=function(){var a=ka(arguments,!0);return a.hasTime()&&a.utc(),a},Va.moment.parseZone=function(){return ka(arguments,!0,!0)},fb.clone=function(){var a=gb.clone.apply(this,arguments);return ma(this,a),this._fullCalendar&&(a._fullCalendar=!0),a},fb.week=fb.weeks=function(a){var b=(this._locale||this._lang)._fullCalendar_weekCalc;return null==a&&"function"==typeof b?b(this):"ISO"===b?gb.isoWeek.apply(this,arguments):gb.week.apply(this,arguments)},fb.time=function(a){if(!this._fullCalendar)return gb.time.apply(this,arguments);if(null==a)return b.duration({hours:this.hours(),minutes:this.minutes(),seconds:this.seconds(),milliseconds:this.milliseconds()});this._ambigTime=!1,b.isDuration(a)||b.isMoment(a)||(a=b.duration(a));var c=0;return b.isDuration(a)&&(c=24*Math.floor(a.asDays())),this.hours(c+a.hours()).minutes(a.minutes()).seconds(a.seconds()).milliseconds(a.milliseconds())},fb.stripTime=function(){var a;return this._ambigTime||(a=this.toArray(),this.utc(),ab(this,a.slice(0,3)),this._ambigTime=!0,this._ambigZone=!0),this},fb.hasTime=function(){return!this._ambigTime},fb.stripZone=function(){var a,b;return this._ambigZone||(a=this.toArray(),b=this._ambigTime,this.utc(),ab(this,a),this._ambigTime=b||!1,this._ambigZone=!0),this},fb.hasZone=function(){return!this._ambigZone},fb.local=function(){var a=this.toArray(),b=this._ambigZone;return gb.local.apply(this,arguments),this._ambigTime=!1,this._ambigZone=!1,b&&bb(this,a),this},fb.utc=function(){return gb.utc.apply(this,arguments),this._ambigTime=!1,this._ambigZone=!1,this},a.each(["zone","utcOffset"],function(a,b){gb[b]&&(fb[b]=function(a){return null!=a&&(this._ambigTime=!1,this._ambigZone=!1),gb[b].apply(this,arguments)})}),fb.format=function(){return this._fullCalendar&&arguments[0]?pa(this,arguments[0]):this._ambigTime?oa(this,"YYYY-MM-DD"):this._ambigZone?oa(this,"YYYY-MM-DD[T]HH:mm:ss"):gb.format.apply(this,arguments)},fb.toISOString=function(){return this._ambigTime?oa(this,"YYYY-MM-DD"):this._ambigZone?oa(this,"YYYY-MM-DD[T]HH:mm:ss"):gb.toISOString.apply(this,arguments)},fb.isWithin=function(a,b){var c=la([this,a,b]);return c[0]>=c[1]&&c[0]<c[2]},fb.isSame=function(a,b){var c;return this._fullCalendar?b?(c=la([this,a],!0),gb.isSame.call(c[0],c[1],b)):(a=Va.moment.parseZone(a),gb.isSame.call(this,a)&&Boolean(this._ambigTime)===Boolean(a._ambigTime)&&Boolean(this._ambigZone)===Boolean(a._ambigZone)):gb.isSame.apply(this,arguments)},a.each(["isBefore","isAfter"],function(a,b){fb[b]=function(a,c){var d;return this._fullCalendar?(d=la([this,a]),gb[b].call(d[0],d[1],c)):gb[b].apply(this,arguments)}}),_a="_d"in b()&&"updateOffset"in b,ab=_a?function(a,c){a._d.setTime(Date.UTC.apply(Date,c)),b.updateOffset(a,!1)}:na,bb=_a?function(a,c){a._d.setTime(+new Date(c[0]||0,c[1]||0,c[2]||0,c[3]||0,c[4]||0,c[5]||0,c[6]||0)),b.updateOffset(a,!1)}:na;var hb={t:function(a){return oa(a,"a").charAt(0)},T:function(a){return oa(a,"A").charAt(0)}};Va.formatRange=sa;var ib={Y:"year",M:"month",D:"day",d:"day",A:"second",a:"second",T:"second",t:"second",H:"second",h:"second",m:"second",s:"second"},jb={};Va.Class=xa,xa.extend=function(){var a,b,c=arguments.length;for(a=0;c>a;a++)b=arguments[a],c-1>a&&za(this,b);return ya(this,b||{})},xa.mixin=function(a){za(this,a)};var kb=Va.EmitterMixin={callbackHash:null,on:function(a,b){return this.loopCallbacks(a,"add",[b]),this},off:function(a,b){return this.loopCallbacks(a,"remove",[b]),this},trigger:function(a){var b=Array.prototype.slice.call(arguments,1);return this.triggerWith(a,this,b),this},triggerWith:function(a,b,c){return this.loopCallbacks(a,"fireWith",[b,c]),this},loopCallbacks:function(a,b,c){var d,e,f,g=a.split(".");for(d=0;d<g.length;d++)e=g[d],e&&(f=this.ensureCallbackObj((d?".":"")+e),f[b].apply(f,c))},ensureCallbackObj:function(b){return this.callbackHash||(this.callbackHash={}),this.callbackHash[b]||(this.callbackHash[b]=a.Callbacks()),this.callbackHash[b]}},lb=Va.ListenerMixin=function(){var b=0,c={listenerId:null,listenTo:function(b,c,d){if("object"==typeof c)for(var e in c)c.hasOwnProperty(e)&&this.listenTo(b,e,c[e]);else"string"==typeof c&&b.on(c+"."+this.getListenerNamespace(),a.proxy(d,this))},stopListeningTo:function(a,b){a.off((b||"")+"."+this.getListenerNamespace())},getListenerNamespace:function(){return null==this.listenerId&&(this.listenerId=b++),"_listener"+this.listenerId}};return c}(),mb={isIgnoringMouse:!1,delayUnignoreMouse:null,
-initMouseIgnoring:function(a){this.delayUnignoreMouse=ja(ia(this,"unignoreMouse"),a||1e3)},tempIgnoreMouse:function(){this.isIgnoringMouse=!0,this.delayUnignoreMouse()},unignoreMouse:function(){this.isIgnoringMouse=!1}},nb=xa.extend(lb,{isHidden:!0,options:null,el:null,margin:10,constructor:function(a){this.options=a||{}},show:function(){this.isHidden&&(this.el||this.render(),this.el.show(),this.position(),this.isHidden=!1,this.trigger("show"))},hide:function(){this.isHidden||(this.el.hide(),this.isHidden=!0,this.trigger("hide"))},render:function(){var b=this,c=this.options;this.el=a('<div class="fc-popover"/>').addClass(c.className||"").css({top:0,left:0}).append(c.content).appendTo(c.parentEl),this.el.on("click",".fc-close",function(){b.hide()}),c.autoHide&&this.listenTo(a(document),"mousedown",this.documentMousedown)},documentMousedown:function(b){this.el&&!a(b.target).closest(this.el).length&&this.hide()},removeElement:function(){this.hide(),this.el&&(this.el.remove(),this.el=null),this.stopListeningTo(a(document),"mousedown")},position:function(){var b,c,d,e,f,g=this.options,h=this.el.offsetParent().offset(),i=this.el.outerWidth(),j=this.el.outerHeight(),k=a(window),l=m(this.el);e=g.top||0,f=void 0!==g.left?g.left:void 0!==g.right?g.right-i:0,l.is(window)||l.is(document)?(l=k,b=0,c=0):(d=l.offset(),b=d.top,c=d.left),b+=k.scrollTop(),c+=k.scrollLeft(),g.viewportConstrain!==!1&&(e=Math.min(e,b+l.outerHeight()-j-this.margin),e=Math.max(e,b+this.margin),f=Math.min(f,c+l.outerWidth()-i-this.margin),f=Math.max(f,c+this.margin)),this.el.css({top:e-h.top,left:f-h.left})},trigger:function(a){this.options[a]&&this.options[a].apply(this,Array.prototype.slice.call(arguments,1))}}),ob=Va.CoordCache=xa.extend({els:null,forcedOffsetParentEl:null,origin:null,boundingRect:null,isHorizontal:!1,isVertical:!1,lefts:null,rights:null,tops:null,bottoms:null,constructor:function(b){this.els=a(b.els),this.isHorizontal=b.isHorizontal,this.isVertical=b.isVertical,this.forcedOffsetParentEl=b.offsetParent?a(b.offsetParent):null},build:function(){var a=this.forcedOffsetParentEl||this.els.eq(0).offsetParent();this.origin=a.offset(),this.boundingRect=this.queryBoundingRect(),this.isHorizontal&&this.buildElHorizontals(),this.isVertical&&this.buildElVerticals()},clear:function(){this.origin=null,this.boundingRect=null,this.lefts=null,this.rights=null,this.tops=null,this.bottoms=null},ensureBuilt:function(){this.origin||this.build()},queryBoundingRect:function(){var a=m(this.els.eq(0));return a.is(document)?void 0:o(a)},buildElHorizontals:function(){var b=[],c=[];this.els.each(function(d,e){var f=a(e),g=f.offset().left,h=f.outerWidth();b.push(g),c.push(g+h)}),this.lefts=b,this.rights=c},buildElVerticals:function(){var b=[],c=[];this.els.each(function(d,e){var f=a(e),g=f.offset().top,h=f.outerHeight();b.push(g),c.push(g+h)}),this.tops=b,this.bottoms=c},getHorizontalIndex:function(a){this.ensureBuilt();var b,c=this.boundingRect,d=this.lefts,e=this.rights,f=d.length;if(!c||a>=c.left&&a<c.right)for(b=0;f>b;b++)if(a>=d[b]&&a<e[b])return b},getVerticalIndex:function(a){this.ensureBuilt();var b,c=this.boundingRect,d=this.tops,e=this.bottoms,f=d.length;if(!c||a>=c.top&&a<c.bottom)for(b=0;f>b;b++)if(a>=d[b]&&a<e[b])return b},getLeftOffset:function(a){return this.ensureBuilt(),this.lefts[a]},getLeftPosition:function(a){return this.ensureBuilt(),this.lefts[a]-this.origin.left},getRightOffset:function(a){return this.ensureBuilt(),this.rights[a]},getRightPosition:function(a){return this.ensureBuilt(),this.rights[a]-this.origin.left},getWidth:function(a){return this.ensureBuilt(),this.rights[a]-this.lefts[a]},getTopOffset:function(a){return this.ensureBuilt(),this.tops[a]},getTopPosition:function(a){return this.ensureBuilt(),this.tops[a]-this.origin.top},getBottomOffset:function(a){return this.ensureBuilt(),this.bottoms[a]},getBottomPosition:function(a){return this.ensureBuilt(),this.bottoms[a]-this.origin.top},getHeight:function(a){return this.ensureBuilt(),this.bottoms[a]-this.tops[a]}}),pb=Va.DragListener=xa.extend(lb,mb,{options:null,subjectEl:null,subjectHref:null,originX:null,originY:null,scrollEl:null,isInteracting:!1,isDistanceSurpassed:!1,isDelayEnded:!1,isDragging:!1,isTouch:!1,delay:null,delayTimeoutId:null,minDistance:null,handleTouchScrollProxy:null,constructor:function(a){this.options=a||{},this.handleTouchScrollProxy=ia(this,"handleTouchScroll"),this.initMouseIgnoring(500)},startInteraction:function(b,c){var d=x(b);if("mousedown"===b.type){if(this.isIgnoringMouse)return;if(!u(b))return;b.preventDefault()}this.isInteracting||(c=c||{},this.delay=ba(c.delay,this.options.delay,0),this.minDistance=ba(c.distance,this.options.distance,0),this.subjectEl=this.options.subjectEl,this.isInteracting=!0,this.isTouch=d,this.isDelayEnded=!1,this.isDistanceSurpassed=!1,this.originX=v(b),this.originY=w(b),this.scrollEl=m(a(b.target)),this.bindHandlers(),this.initAutoScroll(),this.handleInteractionStart(b),this.startDelay(b),this.minDistance||this.handleDistanceSurpassed(b))},handleInteractionStart:function(a){this.trigger("interactionStart",a)},endInteraction:function(a,b){this.isInteracting&&(this.endDrag(a),this.delayTimeoutId&&(clearTimeout(this.delayTimeoutId),this.delayTimeoutId=null),this.destroyAutoScroll(),this.unbindHandlers(),this.isInteracting=!1,this.handleInteractionEnd(a,b),this.isTouch&&this.tempIgnoreMouse())},handleInteractionEnd:function(a,b){this.trigger("interactionEnd",a,b||!1)},bindHandlers:function(){var b=this,c=1;this.isTouch?(this.listenTo(a(document),{touchmove:this.handleTouchMove,touchend:this.endInteraction,touchcancel:this.endInteraction,touchstart:function(a){c?c--:b.endInteraction(a,!0)}}),!A(this.handleTouchScrollProxy)&&this.scrollEl&&this.listenTo(this.scrollEl,"scroll",this.handleTouchScroll)):this.listenTo(a(document),{mousemove:this.handleMouseMove,mouseup:this.endInteraction}),this.listenTo(a(document),{selectstart:z,contextmenu:z})},unbindHandlers:function(){this.stopListeningTo(a(document)),B(this.handleTouchScrollProxy),this.scrollEl&&this.stopListeningTo(this.scrollEl,"scroll")},startDrag:function(a,b){this.startInteraction(a,b),this.isDragging||(this.isDragging=!0,this.handleDragStart(a))},handleDragStart:function(a){this.trigger("dragStart",a),this.initHrefHack()},handleMove:function(a){var b,c=v(a)-this.originX,d=w(a)-this.originY,e=this.minDistance;this.isDistanceSurpassed||(b=c*c+d*d,b>=e*e&&this.handleDistanceSurpassed(a)),this.isDragging&&this.handleDrag(c,d,a)},handleDrag:function(a,b,c){this.trigger("drag",a,b,c),this.updateAutoScroll(c)},endDrag:function(a){this.isDragging&&(this.isDragging=!1,this.handleDragEnd(a))},handleDragEnd:function(a){this.trigger("dragEnd",a),this.destroyHrefHack()},startDelay:function(a){var b=this;this.delay?this.delayTimeoutId=setTimeout(function(){b.handleDelayEnd(a)},this.delay):this.handleDelayEnd(a)},handleDelayEnd:function(a){this.isDelayEnded=!0,this.isDistanceSurpassed&&this.startDrag(a)},handleDistanceSurpassed:function(a){this.isDistanceSurpassed=!0,this.isDelayEnded&&this.startDrag(a)},handleTouchMove:function(a){this.isDragging&&a.preventDefault(),this.handleMove(a)},handleMouseMove:function(a){this.handleMove(a)},handleTouchScroll:function(a){this.isDragging||this.endInteraction(a,!0)},initHrefHack:function(){var a=this.subjectEl;(this.subjectHref=a?a.attr("href"):null)&&a.removeAttr("href")},destroyHrefHack:function(){var a=this.subjectEl,b=this.subjectHref;setTimeout(function(){b&&a.attr("href",b)},0)},trigger:function(a){this.options[a]&&this.options[a].apply(this,Array.prototype.slice.call(arguments,1)),this["_"+a]&&this["_"+a].apply(this,Array.prototype.slice.call(arguments,1))}});pb.mixin({isAutoScroll:!1,scrollBounds:null,scrollTopVel:null,scrollLeftVel:null,scrollIntervalId:null,scrollSensitivity:30,scrollSpeed:200,scrollIntervalMs:50,initAutoScroll:function(){var a=this.scrollEl;this.isAutoScroll=this.options.scroll&&a&&!a.is(window)&&!a.is(document),this.isAutoScroll&&this.listenTo(a,"scroll",ja(this.handleDebouncedScroll,100))},destroyAutoScroll:function(){this.endAutoScroll(),this.isAutoScroll&&this.stopListeningTo(this.scrollEl,"scroll")},computeScrollBounds:function(){this.isAutoScroll&&(this.scrollBounds=n(this.scrollEl))},updateAutoScroll:function(a){var b,c,d,e,f=this.scrollSensitivity,g=this.scrollBounds,h=0,i=0;g&&(b=(f-(w(a)-g.top))/f,c=(f-(g.bottom-w(a)))/f,d=(f-(v(a)-g.left))/f,e=(f-(g.right-v(a)))/f,b>=0&&1>=b?h=b*this.scrollSpeed*-1:c>=0&&1>=c&&(h=c*this.scrollSpeed),d>=0&&1>=d?i=d*this.scrollSpeed*-1:e>=0&&1>=e&&(i=e*this.scrollSpeed)),this.setScrollVel(h,i)},setScrollVel:function(a,b){this.scrollTopVel=a,this.scrollLeftVel=b,this.constrainScrollVel(),!this.scrollTopVel&&!this.scrollLeftVel||this.scrollIntervalId||(this.scrollIntervalId=setInterval(ia(this,"scrollIntervalFunc"),this.scrollIntervalMs))},constrainScrollVel:function(){var a=this.scrollEl;this.scrollTopVel<0?a.scrollTop()<=0&&(this.scrollTopVel=0):this.scrollTopVel>0&&a.scrollTop()+a[0].clientHeight>=a[0].scrollHeight&&(this.scrollTopVel=0),this.scrollLeftVel<0?a.scrollLeft()<=0&&(this.scrollLeftVel=0):this.scrollLeftVel>0&&a.scrollLeft()+a[0].clientWidth>=a[0].scrollWidth&&(this.scrollLeftVel=0)},scrollIntervalFunc:function(){var a=this.scrollEl,b=this.scrollIntervalMs/1e3;this.scrollTopVel&&a.scrollTop(a.scrollTop()+this.scrollTopVel*b),this.scrollLeftVel&&a.scrollLeft(a.scrollLeft()+this.scrollLeftVel*b),this.constrainScrollVel(),this.scrollTopVel||this.scrollLeftVel||this.endAutoScroll()},endAutoScroll:function(){this.scrollIntervalId&&(clearInterval(this.scrollIntervalId),this.scrollIntervalId=null,this.handleScrollEnd())},handleDebouncedScroll:function(){this.scrollIntervalId||this.handleScrollEnd()},handleScrollEnd:function(){}});var qb=pb.extend({component:null,origHit:null,hit:null,coordAdjust:null,constructor:function(a,b){pb.call(this,b),this.component=a},handleInteractionStart:function(a){var b,c,d,e=this.subjectEl;this.computeCoords(),a?(c={left:v(a),top:w(a)},d=c,e&&(b=n(e),d=D(d,b)),this.origHit=this.queryHit(d.left,d.top),e&&this.options.subjectCenter&&(this.origHit&&(b=C(this.origHit,b)||b),d=E(b)),this.coordAdjust=F(d,c)):(this.origHit=null,this.coordAdjust=null),pb.prototype.handleInteractionStart.apply(this,arguments)},computeCoords:function(){this.component.prepareHits(),this.computeScrollBounds()},handleDragStart:function(a){var b;pb.prototype.handleDragStart.apply(this,arguments),b=this.queryHit(v(a),w(a)),b&&this.handleHitOver(b)},handleDrag:function(a,b,c){var d;pb.prototype.handleDrag.apply(this,arguments),d=this.queryHit(v(c),w(c)),Aa(d,this.hit)||(this.hit&&this.handleHitOut(),d&&this.handleHitOver(d))},handleDragEnd:function(){this.handleHitDone(),pb.prototype.handleDragEnd.apply(this,arguments)},handleHitOver:function(a){var b=Aa(a,this.origHit);this.hit=a,this.trigger("hitOver",this.hit,b,this.origHit)},handleHitOut:function(){this.hit&&(this.trigger("hitOut",this.hit),this.handleHitDone(),this.hit=null)},handleHitDone:function(){this.hit&&this.trigger("hitDone",this.hit)},handleInteractionEnd:function(){pb.prototype.handleInteractionEnd.apply(this,arguments),this.origHit=null,this.hit=null,this.component.releaseHits()},handleScrollEnd:function(){pb.prototype.handleScrollEnd.apply(this,arguments),this.computeCoords()},queryHit:function(a,b){return this.coordAdjust&&(a+=this.coordAdjust.left,b+=this.coordAdjust.top),this.component.queryHit(a,b)}}),rb=xa.extend(lb,{options:null,sourceEl:null,el:null,parentEl:null,top0:null,left0:null,y0:null,x0:null,topDelta:null,leftDelta:null,isFollowing:!1,isHidden:!1,isAnimating:!1,constructor:function(b,c){this.options=c=c||{},this.sourceEl=b,this.parentEl=c.parentEl?a(c.parentEl):b.parent()},start:function(b){this.isFollowing||(this.isFollowing=!0,this.y0=w(b),this.x0=v(b),this.topDelta=0,this.leftDelta=0,this.isHidden||this.updatePosition(),x(b)?this.listenTo(a(document),"touchmove",this.handleMove):this.listenTo(a(document),"mousemove",this.handleMove))},stop:function(b,c){function d(){this.isAnimating=!1,e.removeElement(),this.top0=this.left0=null,c&&c()}var e=this,f=this.options.revertDuration;this.isFollowing&&!this.isAnimating&&(this.isFollowing=!1,this.stopListeningTo(a(document)),b&&f&&!this.isHidden?(this.isAnimating=!0,this.el.animate({top:this.top0,left:this.left0},{duration:f,complete:d})):d())},getEl:function(){var a=this.el;return a||(this.sourceEl.width(),a=this.el=this.sourceEl.clone().addClass(this.options.additionalClass||"").css({position:"absolute",visibility:"",display:this.isHidden?"none":"",margin:0,right:"auto",bottom:"auto",width:this.sourceEl.width(),height:this.sourceEl.height(),opacity:this.options.opacity||"",zIndex:this.options.zIndex}),a.addClass("fc-unselectable"),a.appendTo(this.parentEl)),a},removeElement:function(){this.el&&(this.el.remove(),this.el=null)},updatePosition:function(){var a,b;this.getEl(),null===this.top0&&(this.sourceEl.width(),a=this.sourceEl.offset(),b=this.el.offsetParent().offset(),this.top0=a.top-b.top,this.left0=a.left-b.left),this.el.css({top:this.top0+this.topDelta,left:this.left0+this.leftDelta})},handleMove:function(a){this.topDelta=w(a)-this.y0,this.leftDelta=v(a)-this.x0,this.isHidden||this.updatePosition()},hide:function(){this.isHidden||(this.isHidden=!0,this.el&&this.el.hide())},show:function(){this.isHidden&&(this.isHidden=!1,this.updatePosition(),this.getEl().show())}}),sb=Va.Grid=xa.extend(lb,mb,{view:null,isRTL:null,start:null,end:null,el:null,elsByFill:null,eventTimeFormat:null,displayEventTime:null,displayEventEnd:null,minResizeDuration:null,largeUnit:null,dayDragListener:null,segDragListener:null,segResizeListener:null,externalDragListener:null,constructor:function(a){this.view=a,this.isRTL=a.opt("isRTL"),this.elsByFill={},this.dayDragListener=this.buildDayDragListener(),this.initMouseIgnoring()},computeEventTimeFormat:function(){return this.view.opt("smallTimeFormat")},computeDisplayEventTime:function(){return!0},computeDisplayEventEnd:function(){return!0},setRange:function(a){this.start=a.start.clone(),this.end=a.end.clone(),this.rangeUpdated(),this.processRangeOptions()},rangeUpdated:function(){},processRangeOptions:function(){var a,b,c=this.view;this.eventTimeFormat=c.opt("eventTimeFormat")||c.opt("timeFormat")||this.computeEventTimeFormat(),a=c.opt("displayEventTime"),null==a&&(a=this.computeDisplayEventTime()),b=c.opt("displayEventEnd"),null==b&&(b=this.computeDisplayEventEnd()),this.displayEventTime=a,this.displayEventEnd=b},spanToSegs:function(a){},diffDates:function(a,b){return this.largeUnit?N(a,b,this.largeUnit):L(a,b)},prepareHits:function(){},releaseHits:function(){},queryHit:function(a,b){},getHitSpan:function(a){},getHitEl:function(a){},setElement:function(a){this.el=a,y(a),this.bindDayHandler("touchstart",this.dayTouchStart),this.bindDayHandler("mousedown",this.dayMousedown),this.bindSegHandlers(),this.bindGlobalHandlers()},bindDayHandler:function(b,c){var d=this;this.el.on(b,function(b){return a(b.target).is(".fc-event-container *, .fc-more")||a(b.target).closest(".fc-popover").length?void 0:c.call(d,b)})},removeElement:function(){this.unbindGlobalHandlers(),this.clearDragListeners(),this.el.remove()},renderSkeleton:function(){},renderDates:function(){},unrenderDates:function(){},bindGlobalHandlers:function(){this.listenTo(a(document),{dragstart:this.externalDragStart,sortstart:this.externalDragStart})},unbindGlobalHandlers:function(){this.stopListeningTo(a(document))},dayMousedown:function(a){this.isIgnoringMouse||this.dayDragListener.startInteraction(a,{})},dayTouchStart:function(a){var b=this.view;(b.isSelected||b.selectedEvent)&&this.tempIgnoreMouse(),this.dayDragListener.startInteraction(a,{delay:this.view.opt("longPressDelay")})},buildDayDragListener:function(){var a,b,c=this,d=this.view,e=d.opt("selectable"),f=new qb(this,{scroll:d.opt("dragScroll"),interactionStart:function(){a=f.origHit},dragStart:function(){d.unselect()},hitOver:function(d,f,h){h&&(f||(a=null),e&&(b=c.computeSelection(c.getHitSpan(h),c.getHitSpan(d)),b?c.renderSelection(b):b===!1&&g()))},hitOut:function(){a=null,b=null,c.unrenderSelection(),h()},interactionEnd:function(e,f){f||(a&&!c.isIgnoringMouse&&d.triggerDayClick(c.getHitSpan(a),c.getHitEl(a),e),b&&d.reportSelection(b,e),h())}});return f},clearDragListeners:function(){this.dayDragListener.endInteraction(),this.segDragListener&&this.segDragListener.endInteraction(),this.segResizeListener&&this.segResizeListener.endInteraction(),this.externalDragListener&&this.externalDragListener.endInteraction()},renderEventLocationHelper:function(a,b){var c=this.fabricateHelperEvent(a,b);return this.renderHelper(c,b)},fabricateHelperEvent:function(a,b){var c=b?X(b.event):{};return c.start=a.start.clone(),c.end=a.end?a.end.clone():null,c.allDay=null,this.view.calendar.normalizeEventDates(c),c.className=(c.className||[]).concat("fc-helper"),b||(c.editable=!1),c},renderHelper:function(a,b){},unrenderHelper:function(){},renderSelection:function(a){this.renderHighlight(a)},unrenderSelection:function(){this.unrenderHighlight()},computeSelection:function(a,b){var c=this.computeSelectionSpan(a,b);return c&&!this.view.calendar.isSelectionSpanAllowed(c)?!1:c},computeSelectionSpan:function(a,b){var c=[a.start,a.end,b.start,b.end];return c.sort(ga),{start:c[0].clone(),end:c[3].clone()}},renderHighlight:function(a){this.renderFill("highlight",this.spanToSegs(a))},unrenderHighlight:function(){this.unrenderFill("highlight")},highlightSegClasses:function(){return["fc-highlight"]},renderBusinessHours:function(){},unrenderBusinessHours:function(){},getNowIndicatorUnit:function(){},renderNowIndicator:function(a){},unrenderNowIndicator:function(){},renderFill:function(a,b){},unrenderFill:function(a){var b=this.elsByFill[a];b&&(b.remove(),delete this.elsByFill[a])},renderFillSegEls:function(b,c){var d,e=this,f=this[b+"SegEl"],g="",h=[];if(c.length){for(d=0;d<c.length;d++)g+=this.fillSegHtml(b,c[d]);a(g).each(function(b,d){var g=c[b],i=a(d);f&&(i=f.call(e,g,i)),i&&(i=a(i),i.is(e.fillSegTag)&&(g.el=i,h.push(g)))})}return h},fillSegTag:"div",fillSegHtml:function(a,b){var c=this[a+"SegClasses"],d=this[a+"SegCss"],e=c?c.call(this,b):[],f=ea(d?d.call(this,b):{});return"<"+this.fillSegTag+(e.length?' class="'+e.join(" ")+'"':"")+(f?' style="'+f+'"':"")+" />"},getDayClasses:function(a){var b=this.view,c=b.calendar.getNow(),d=["fc-"+Za[a.day()]];return 1==b.intervalDuration.as("months")&&a.month()!=b.intervalStart.month()&&d.push("fc-other-month"),a.isSame(c,"day")?d.push("fc-today",b.highlightStateClass):c>a?d.push("fc-past"):d.push("fc-future"),d}});sb.mixin({mousedOverSeg:null,isDraggingSeg:!1,isResizingSeg:!1,isDraggingExternal:!1,segs:null,renderEvents:function(a){var b,c=[],d=[];for(b=0;b<a.length;b++)(Ca(a[b])?c:d).push(a[b]);this.segs=[].concat(this.renderBgEvents(c),this.renderFgEvents(d))},renderBgEvents:function(a){var b=this.eventsToSegs(a);return this.renderBgSegs(b)||b},renderFgEvents:function(a){var b=this.eventsToSegs(a);return this.renderFgSegs(b)||b},unrenderEvents:function(){this.handleSegMouseout(),this.clearDragListeners(),this.unrenderFgSegs(),this.unrenderBgSegs(),this.segs=null},getEventSegs:function(){return this.segs||[]},renderFgSegs:function(a){},unrenderFgSegs:function(){},renderFgSegEls:function(b,c){var d,e=this.view,f="",g=[];if(b.length){for(d=0;d<b.length;d++)f+=this.fgSegHtml(b[d],c);a(f).each(function(c,d){var f=b[c],h=e.resolveEventEl(f.event,a(d));h&&(h.data("fc-seg",f),f.el=h,g.push(f))})}return g},fgSegHtml:function(a,b){},renderBgSegs:function(a){return this.renderFill("bgEvent",a)},unrenderBgSegs:function(){this.unrenderFill("bgEvent")},bgEventSegEl:function(a,b){return this.view.resolveEventEl(a.event,b)},bgEventSegClasses:function(a){var b=a.event,c=b.source||{};return["fc-bgevent"].concat(b.className,c.className||[])},bgEventSegCss:function(a){return{"background-color":this.getSegSkinCss(a)["background-color"]}},businessHoursSegClasses:function(a){return["fc-nonbusiness","fc-bgevent"]},bindSegHandlers:function(){this.bindSegHandler("touchstart",this.handleSegTouchStart),this.bindSegHandler("touchend",this.handleSegTouchEnd),this.bindSegHandler("mouseenter",this.handleSegMouseover),this.bindSegHandler("mouseleave",this.handleSegMouseout),this.bindSegHandler("mousedown",this.handleSegMousedown),this.bindSegHandler("click",this.handleSegClick)},bindSegHandler:function(b,c){var d=this;this.el.on(b,".fc-event-container > *",function(b){var e=a(this).data("fc-seg");return!e||d.isDraggingSeg||d.isResizingSeg?void 0:c.call(d,e,b)})},handleSegClick:function(a,b){return this.view.trigger("eventClick",a.el[0],a.event,b)},handleSegMouseover:function(a,b){this.isIgnoringMouse||this.mousedOverSeg||(this.mousedOverSeg=a,a.el.addClass("fc-allow-mouse-resize"),this.view.trigger("eventMouseover",a.el[0],a.event,b))},handleSegMouseout:function(a,b){b=b||{},this.mousedOverSeg&&(a=a||this.mousedOverSeg,this.mousedOverSeg=null,a.el.removeClass("fc-allow-mouse-resize"),this.view.trigger("eventMouseout",a.el[0],a.event,b))},handleSegMousedown:function(a,b){var c=this.startSegResize(a,b,{distance:5});!c&&this.view.isEventDraggable(a.event)&&this.buildSegDragListener(a).startInteraction(b,{distance:5})},handleSegTouchStart:function(a,b){var c,d=this.view,e=a.event,f=d.isEventSelected(e),g=d.isEventDraggable(e),h=d.isEventResizable(e),i=!1;f&&h&&(i=this.startSegResize(a,b)),i||!g&&!h||(c=g?this.buildSegDragListener(a):this.buildSegSelectListener(a),c.startInteraction(b,{delay:f?0:this.view.opt("longPressDelay")})),this.tempIgnoreMouse()},handleSegTouchEnd:function(a,b){this.tempIgnoreMouse()},startSegResize:function(b,c,d){return a(c.target).is(".fc-resizer")?(this.buildSegResizeListener(b,a(c.target).is(".fc-start-resizer")).startInteraction(c,d),!0):!1},buildSegDragListener:function(a){var b,c,d,e=this,f=this.view,i=f.calendar,j=a.el,k=a.event;if(this.segDragListener)return this.segDragListener;var l=this.segDragListener=new qb(f,{scroll:f.opt("dragScroll"),subjectEl:j,subjectCenter:!0,interactionStart:function(d){b=!1,c=new rb(a.el,{additionalClass:"fc-dragging",parentEl:f.el,opacity:l.isTouch?null:f.opt("dragOpacity"),revertDuration:f.opt("dragRevertDuration"),zIndex:2}),c.hide(),c.start(d)},dragStart:function(c){l.isTouch&&!f.isEventSelected(k)&&f.selectEvent(k),b=!0,e.handleSegMouseout(a,c),e.segDragStart(a,c),f.hideEvent(k)},hitOver:function(b,h,j){var m;a.hit&&(j=a.hit),d=e.computeEventDrop(j.component.getHitSpan(j),b.component.getHitSpan(b),k),d&&!i.isEventSpanAllowed(e.eventToSpan(d),k)&&(g(),d=null),d&&(m=f.renderDrag(d,a))?(m.addClass("fc-dragging"),l.isTouch||e.applyDragOpacity(m),c.hide()):c.show(),h&&(d=null)},hitOut:function(){f.unrenderDrag(),c.show(),d=null},hitDone:function(){h()},interactionEnd:function(g){c.stop(!d,function(){b&&(f.unrenderDrag(),f.showEvent(k),e.segDragStop(a,g)),d&&f.reportEventDrop(k,d,this.largeUnit,j,g)}),e.segDragListener=null}});return l},buildSegSelectListener:function(a){var b=this,c=this.view,d=a.event;if(this.segDragListener)return this.segDragListener;var e=this.segDragListener=new pb({dragStart:function(a){e.isTouch&&!c.isEventSelected(d)&&c.selectEvent(d)},interactionEnd:function(a){b.segDragListener=null}});return e},segDragStart:function(a,b){this.isDraggingSeg=!0,this.view.trigger("eventDragStart",a.el[0],a.event,b,{})},segDragStop:function(a,b){this.isDraggingSeg=!1,this.view.trigger("eventDragStop",a.el[0],a.event,b,{})},computeEventDrop:function(a,b,c){var d,e,f=this.view.calendar,g=a.start,h=b.start;return g.hasTime()===h.hasTime()?(d=this.diffDates(h,g),c.allDay&&T(d)?(e={start:c.start.clone(),end:f.getEventEnd(c),allDay:!1},f.normalizeEventTimes(e)):e={start:c.start.clone(),end:c.end?c.end.clone():null,allDay:c.allDay},e.start.add(d),e.end&&e.end.add(d)):e={start:h.clone(),end:null,allDay:!h.hasTime()},e},applyDragOpacity:function(a){var b=this.view.opt("dragOpacity");null!=b&&a.each(function(a,c){c.style.opacity=b})},externalDragStart:function(b,c){var d,e,f=this.view;f.opt("droppable")&&(d=a((c?c.item:null)||b.target),e=f.opt("dropAccept"),(a.isFunction(e)?e.call(d[0],d):d.is(e))&&(this.isDraggingExternal||this.listenToExternalDrag(d,b,c)))},listenToExternalDrag:function(a,b,c){var d,e=this,f=this.view.calendar,i=Ha(a),j=e.externalDragListener=new qb(this,{interactionStart:function(){e.isDraggingExternal=!0},hitOver:function(a){d=e.computeExternalDrop(a.component.getHitSpan(a),i),d&&!f.isExternalSpanAllowed(e.eventToSpan(d),d,i.eventProps)&&(g(),d=null),d&&e.renderDrag(d)},hitOut:function(){d=null},hitDone:function(){h(),e.unrenderDrag()},interactionEnd:function(b){d&&e.view.reportExternalDrop(i,d,a,b,c),e.isDraggingExternal=!1,e.externalDragListener=null}});j.startDrag(b)},computeExternalDrop:function(a,b){var c=this.view.calendar,d={start:c.applyTimezone(a.start),end:null};return b.startTime&&!d.start.hasTime()&&d.start.time(b.startTime),b.duration&&(d.end=d.start.clone().add(b.duration)),d},renderDrag:function(a,b){},unrenderDrag:function(){},buildSegResizeListener:function(a,b){var c,d,e=this,f=this.view,i=f.calendar,j=a.el,k=a.event,l=i.getEventEnd(k),m=this.segResizeListener=new qb(this,{scroll:f.opt("dragScroll"),subjectEl:j,interactionStart:function(){c=!1},dragStart:function(b){c=!0,e.handleSegMouseout(a,b),e.segResizeStart(a,b)},hitOver:function(c,h,j){var m=e.getHitSpan(j),n=e.getHitSpan(c);d=b?e.computeEventStartResize(m,n,k):e.computeEventEndResize(m,n,k),d&&(i.isEventSpanAllowed(e.eventToSpan(d),k)?d.start.isSame(k.start)&&d.end.isSame(l)&&(d=null):(g(),d=null)),d&&(f.hideEvent(k),e.renderEventResize(d,a))},hitOut:function(){d=null},hitDone:function(){e.unrenderEventResize(),f.showEvent(k),h()},interactionEnd:function(b){c&&e.segResizeStop(a,b),d&&f.reportEventResize(k,d,this.largeUnit,j,b),e.segResizeListener=null}});return m},segResizeStart:function(a,b){this.isResizingSeg=!0,this.view.trigger("eventResizeStart",a.el[0],a.event,b,{})},segResizeStop:function(a,b){this.isResizingSeg=!1,this.view.trigger("eventResizeStop",a.el[0],a.event,b,{})},computeEventStartResize:function(a,b,c){return this.computeEventResize("start",a,b,c)},computeEventEndResize:function(a,b,c){return this.computeEventResize("end",a,b,c)},computeEventResize:function(a,b,c,d){var e,f,g=this.view.calendar,h=this.diffDates(c[a],b[a]);return e={start:d.start.clone(),end:g.getEventEnd(d),allDay:d.allDay},e.allDay&&T(h)&&(e.allDay=!1,g.normalizeEventTimes(e)),e[a].add(h),e.start.isBefore(e.end)||(f=this.minResizeDuration||(d.allDay?g.defaultAllDayEventDuration:g.defaultTimedEventDuration),"start"==a?e.start=e.end.clone().subtract(f):e.end=e.start.clone().add(f)),e},renderEventResize:function(a,b){},unrenderEventResize:function(){},getEventTimeText:function(a,b,c){return null==b&&(b=this.eventTimeFormat),null==c&&(c=this.displayEventEnd),this.displayEventTime&&a.start.hasTime()?c&&a.end?this.view.formatRange(a,b):a.start.format(b):""},getSegClasses:function(a,b,c){var d=this.view,e=a.event,f=["fc-event",a.isStart?"fc-start":"fc-not-start",a.isEnd?"fc-end":"fc-not-end"].concat(e.className,e.source?e.source.className:[]);return b&&f.push("fc-draggable"),c&&f.push("fc-resizable"),d.isEventSelected(e)&&f.push("fc-selected"),f},getSegSkinCss:function(a){var b=a.event,c=this.view,d=b.source||{},e=b.color,f=d.color,g=c.opt("eventColor");return{"background-color":b.backgroundColor||e||d.backgroundColor||f||c.opt("eventBackgroundColor")||g,"border-color":b.borderColor||e||d.borderColor||f||c.opt("eventBorderColor")||g,color:b.textColor||d.textColor||c.opt("eventTextColor")}},eventToSegs:function(a){return this.eventsToSegs([a])},eventToSpan:function(a){return this.eventToSpans(a)[0]},eventToSpans:function(a){var b=this.eventToRange(a);return this.eventRangeToSpans(b,a)},eventsToSegs:function(b,c){var d=this,e=Fa(b),f=[];return a.each(e,function(a,b){var e,g=[];for(e=0;e<b.length;e++)g.push(d.eventToRange(b[e]));if(Da(b[0]))for(g=d.invertRanges(g),e=0;e<g.length;e++)f.push.apply(f,d.eventRangeToSegs(g[e],b[0],c));else for(e=0;e<g.length;e++)f.push.apply(f,d.eventRangeToSegs(g[e],b[e],c))}),f},eventToRange:function(a){return{start:a.start.clone().stripZone(),end:(a.end?a.end.clone():this.view.calendar.getDefaultEventEnd(null!=a.allDay?a.allDay:!a.start.hasTime(),a.start)).stripZone()}},eventRangeToSegs:function(a,b,c){var d,e=this.eventRangeToSpans(a,b),f=[];for(d=0;d<e.length;d++)f.push.apply(f,this.eventSpanToSegs(e[d],b,c));return f},eventRangeToSpans:function(b,c){return[a.extend({},b)]},eventSpanToSegs:function(a,b,c){var d,e,f=c?c(a):this.spanToSegs(a);for(d=0;d<f.length;d++)e=f[d],e.event=b,e.eventStartMS=+a.start,e.eventDurationMS=a.end-a.start;return f},invertRanges:function(a){var b,c,d=this.view,e=d.start.clone(),f=d.end.clone(),g=[],h=e;for(a.sort(Ga),b=0;b<a.length;b++)c=a[b],c.start>h&&g.push({start:h,end:c.start}),h=c.end;return f>h&&g.push({start:h,end:f}),g},sortEventSegs:function(a){a.sort(ia(this,"compareEventSegs"))},compareEventSegs:function(a,b){return a.eventStartMS-b.eventStartMS||b.eventDurationMS-a.eventDurationMS||b.event.allDay-a.event.allDay||H(a.event,b.event,this.view.eventOrderSpecs)}}),Va.isBgEvent=Ca,Va.dataAttrPrefix="";var tb=Va.DayTableMixin={breakOnWeeks:!1,dayDates:null,dayIndices:null,daysPerRow:null,rowCnt:null,colCnt:null,colHeadFormat:null,updateDayTable:function(){for(var a,b,c,d=this.view,e=this.start.clone(),f=-1,g=[],h=[];e.isBefore(this.end);)d.isHiddenDay(e)?g.push(f+.5):(f++,g.push(f),h.push(e.clone())),e.add(1,"days");if(this.breakOnWeeks){for(b=h[0].day(),a=1;a<h.length&&h[a].day()!=b;a++);c=Math.ceil(h.length/a)}else c=1,a=h.length;this.dayDates=h,this.dayIndices=g,this.daysPerRow=a,this.rowCnt=c,this.updateDayTableCols()},updateDayTableCols:function(){this.colCnt=this.computeColCnt(),this.colHeadFormat=this.view.opt("columnFormat")||this.computeColHeadFormat()},computeColCnt:function(){return this.daysPerRow},getCellDate:function(a,b){return this.dayDates[this.getCellDayIndex(a,b)].clone()},getCellRange:function(a,b){var c=this.getCellDate(a,b),d=c.clone().add(1,"days");return{start:c,end:d}},getCellDayIndex:function(a,b){return a*this.daysPerRow+this.getColDayIndex(b)},getColDayIndex:function(a){return this.isRTL?this.colCnt-1-a:a},getDateDayIndex:function(a){var b=this.dayIndices,c=a.diff(this.start,"days");return 0>c?b[0]-1:c>=b.length?b[b.length-1]+1:b[c]},computeColHeadFormat:function(){return this.rowCnt>1||this.colCnt>10?"ddd":this.colCnt>1?this.view.opt("dayOfMonthFormat"):"dddd"},sliceRangeByRow:function(a){var b,c,d,e,f,g=this.daysPerRow,h=this.view.computeDayRange(a),i=this.getDateDayIndex(h.start),j=this.getDateDayIndex(h.end.clone().subtract(1,"days")),k=[];for(b=0;b<this.rowCnt;b++)c=b*g,d=c+g-1,e=Math.max(i,c),f=Math.min(j,d),e=Math.ceil(e),f=Math.floor(f),f>=e&&k.push({row:b,firstRowDayIndex:e-c,lastRowDayIndex:f-c,isStart:e===i,isEnd:f===j});return k},sliceRangeByDay:function(a){var b,c,d,e,f,g,h=this.daysPerRow,i=this.view.computeDayRange(a),j=this.getDateDayIndex(i.start),k=this.getDateDayIndex(i.end.clone().subtract(1,"days")),l=[];for(b=0;b<this.rowCnt;b++)for(c=b*h,d=c+h-1,e=c;d>=e;e++)f=Math.max(j,e),g=Math.min(k,e),f=Math.ceil(f),g=Math.floor(g),g>=f&&l.push({row:b,firstRowDayIndex:f-c,lastRowDayIndex:g-c,isStart:f===j,isEnd:g===k});return l},renderHeadHtml:function(){var a=this.view;return'<div class="fc-row '+a.widgetHeaderClass+'"><table><thead>'+this.renderHeadTrHtml()+"</thead></table></div>"},renderHeadIntroHtml:function(){return this.renderIntroHtml()},renderHeadTrHtml:function(){return"<tr>"+(this.isRTL?"":this.renderHeadIntroHtml())+this.renderHeadDateCellsHtml()+(this.isRTL?this.renderHeadIntroHtml():"")+"</tr>"},renderHeadDateCellsHtml:function(){var a,b,c=[];for(a=0;a<this.colCnt;a++)b=this.getCellDate(0,a),c.push(this.renderHeadDateCellHtml(b));return c.join("")},renderHeadDateCellHtml:function(a,b,c){var d=this.view;return'<th class="fc-day-header '+d.widgetHeaderClass+" fc-"+Za[a.day()]+'"'+(1==this.rowCnt?' data-date="'+a.format("YYYY-MM-DD")+'"':"")+(b>1?' colspan="'+b+'"':"")+(c?" "+c:"")+">"+ca(a.format(this.colHeadFormat))+"</th>";
-},renderBgTrHtml:function(a){return"<tr>"+(this.isRTL?"":this.renderBgIntroHtml(a))+this.renderBgCellsHtml(a)+(this.isRTL?this.renderBgIntroHtml(a):"")+"</tr>"},renderBgIntroHtml:function(a){return this.renderIntroHtml()},renderBgCellsHtml:function(a){var b,c,d=[];for(b=0;b<this.colCnt;b++)c=this.getCellDate(a,b),d.push(this.renderBgCellHtml(c));return d.join("")},renderBgCellHtml:function(a,b){var c=this.view,d=this.getDayClasses(a);return d.unshift("fc-day",c.widgetContentClass),'<td class="'+d.join(" ")+'" data-date="'+a.format("YYYY-MM-DD")+'"'+(b?" "+b:"")+"></td>"},renderIntroHtml:function(){},bookendCells:function(a){var b=this.renderIntroHtml();b&&(this.isRTL?a.append(b):a.prepend(b))}},ub=Va.DayGrid=sb.extend(tb,{numbersVisible:!1,bottomCoordPadding:0,rowEls:null,cellEls:null,helperEls:null,rowCoordCache:null,colCoordCache:null,renderDates:function(a){var b,c,d=this.view,e=this.rowCnt,f=this.colCnt,g="";for(b=0;e>b;b++)g+=this.renderDayRowHtml(b,a);for(this.el.html(g),this.rowEls=this.el.find(".fc-row"),this.cellEls=this.el.find(".fc-day"),this.rowCoordCache=new ob({els:this.rowEls,isVertical:!0}),this.colCoordCache=new ob({els:this.cellEls.slice(0,this.colCnt),isHorizontal:!0}),b=0;e>b;b++)for(c=0;f>c;c++)d.trigger("dayRender",null,this.getCellDate(b,c),this.getCellEl(b,c))},unrenderDates:function(){this.removeSegPopover()},renderBusinessHours:function(){var a=this.view.calendar.getBusinessHoursEvents(!0),b=this.eventsToSegs(a);this.renderFill("businessHours",b,"bgevent")},renderDayRowHtml:function(a,b){var c=this.view,d=["fc-row","fc-week",c.widgetContentClass];return b&&d.push("fc-rigid"),'<div class="'+d.join(" ")+'"><div class="fc-bg"><table>'+this.renderBgTrHtml(a)+'</table></div><div class="fc-content-skeleton"><table>'+(this.numbersVisible?"<thead>"+this.renderNumberTrHtml(a)+"</thead>":"")+"</table></div></div>"},renderNumberTrHtml:function(a){return"<tr>"+(this.isRTL?"":this.renderNumberIntroHtml(a))+this.renderNumberCellsHtml(a)+(this.isRTL?this.renderNumberIntroHtml(a):"")+"</tr>"},renderNumberIntroHtml:function(a){return this.renderIntroHtml()},renderNumberCellsHtml:function(a){var b,c,d=[];for(b=0;b<this.colCnt;b++)c=this.getCellDate(a,b),d.push(this.renderNumberCellHtml(c));return d.join("")},renderNumberCellHtml:function(a){var b;return this.view.dayNumbersVisible?(b=this.getDayClasses(a),b.unshift("fc-day-number"),'<td class="'+b.join(" ")+'" data-date="'+a.format()+'">'+a.date()+"</td>"):"<td/>"},computeEventTimeFormat:function(){return this.view.opt("extraSmallTimeFormat")},computeDisplayEventEnd:function(){return 1==this.colCnt},rangeUpdated:function(){this.updateDayTable()},spanToSegs:function(a){var b,c,d=this.sliceRangeByRow(a);for(b=0;b<d.length;b++)c=d[b],this.isRTL?(c.leftCol=this.daysPerRow-1-c.lastRowDayIndex,c.rightCol=this.daysPerRow-1-c.firstRowDayIndex):(c.leftCol=c.firstRowDayIndex,c.rightCol=c.lastRowDayIndex);return d},prepareHits:function(){this.colCoordCache.build(),this.rowCoordCache.build(),this.rowCoordCache.bottoms[this.rowCnt-1]+=this.bottomCoordPadding},releaseHits:function(){this.colCoordCache.clear(),this.rowCoordCache.clear()},queryHit:function(a,b){var c=this.colCoordCache.getHorizontalIndex(a),d=this.rowCoordCache.getVerticalIndex(b);return null!=d&&null!=c?this.getCellHit(d,c):void 0},getHitSpan:function(a){return this.getCellRange(a.row,a.col)},getHitEl:function(a){return this.getCellEl(a.row,a.col)},getCellHit:function(a,b){return{row:a,col:b,component:this,left:this.colCoordCache.getLeftOffset(b),right:this.colCoordCache.getRightOffset(b),top:this.rowCoordCache.getTopOffset(a),bottom:this.rowCoordCache.getBottomOffset(a)}},getCellEl:function(a,b){return this.cellEls.eq(a*this.colCnt+b)},renderDrag:function(a,b){return this.renderHighlight(this.eventToSpan(a)),b&&!b.el.closest(this.el).length?this.renderEventLocationHelper(a,b):void 0},unrenderDrag:function(){this.unrenderHighlight(),this.unrenderHelper()},renderEventResize:function(a,b){return this.renderHighlight(this.eventToSpan(a)),this.renderEventLocationHelper(a,b)},unrenderEventResize:function(){this.unrenderHighlight(),this.unrenderHelper()},renderHelper:function(b,c){var d,e=[],f=this.eventToSegs(b);return f=this.renderFgSegEls(f),d=this.renderSegRows(f),this.rowEls.each(function(b,f){var g,h=a(f),i=a('<div class="fc-helper-skeleton"><table/></div>');g=c&&c.row===b?c.el.position().top:h.find(".fc-content-skeleton tbody").position().top,i.css("top",g).find("table").append(d[b].tbodyEl),h.append(i),e.push(i[0])}),this.helperEls=a(e)},unrenderHelper:function(){this.helperEls&&(this.helperEls.remove(),this.helperEls=null)},fillSegTag:"td",renderFill:function(b,c,d){var e,f,g,h=[];for(c=this.renderFillSegEls(b,c),e=0;e<c.length;e++)f=c[e],g=this.renderFillRow(b,f,d),this.rowEls.eq(f.row).append(g),h.push(g[0]);return this.elsByFill[b]=a(h),c},renderFillRow:function(b,c,d){var e,f,g=this.colCnt,h=c.leftCol,i=c.rightCol+1;return d=d||b.toLowerCase(),e=a('<div class="fc-'+d+'-skeleton"><table><tr/></table></div>'),f=e.find("tr"),h>0&&f.append('<td colspan="'+h+'"/>'),f.append(c.el.attr("colspan",i-h)),g>i&&f.append('<td colspan="'+(g-i)+'"/>'),this.bookendCells(f),e}});ub.mixin({rowStructs:null,unrenderEvents:function(){this.removeSegPopover(),sb.prototype.unrenderEvents.apply(this,arguments)},getEventSegs:function(){return sb.prototype.getEventSegs.call(this).concat(this.popoverSegs||[])},renderBgSegs:function(b){var c=a.grep(b,function(a){return a.event.allDay});return sb.prototype.renderBgSegs.call(this,c)},renderFgSegs:function(b){var c;return b=this.renderFgSegEls(b),c=this.rowStructs=this.renderSegRows(b),this.rowEls.each(function(b,d){a(d).find(".fc-content-skeleton > table").append(c[b].tbodyEl)}),b},unrenderFgSegs:function(){for(var a,b=this.rowStructs||[];a=b.pop();)a.tbodyEl.remove();this.rowStructs=null},renderSegRows:function(a){var b,c,d=[];for(b=this.groupSegRows(a),c=0;c<b.length;c++)d.push(this.renderSegRow(c,b[c]));return d},fgSegHtml:function(a,b){var c,d,e=this.view,f=a.event,g=e.isEventDraggable(f),h=!b&&f.allDay&&a.isStart&&e.isEventResizableFromStart(f),i=!b&&f.allDay&&a.isEnd&&e.isEventResizableFromEnd(f),j=this.getSegClasses(a,g,h||i),k=ea(this.getSegSkinCss(a)),l="";return j.unshift("fc-day-grid-event","fc-h-event"),a.isStart&&(c=this.getEventTimeText(f),c&&(l='<span class="fc-time">'+ca(c)+"</span>")),d='<span class="fc-title">'+(ca(f.title||"")||"&nbsp;")+"</span>",'<a class="'+j.join(" ")+'"'+(f.url?' href="'+ca(f.url)+'"':"")+(k?' style="'+k+'"':"")+'><div class="fc-content">'+(this.isRTL?d+" "+l:l+" "+d)+"</div>"+(h?'<div class="fc-resizer fc-start-resizer" />':"")+(i?'<div class="fc-resizer fc-end-resizer" />':"")+"</a>"},renderSegRow:function(b,c){function d(b){for(;b>g;)k=(r[e-1]||[])[g],k?k.attr("rowspan",parseInt(k.attr("rowspan")||1,10)+1):(k=a("<td/>"),h.append(k)),q[e][g]=k,r[e][g]=k,g++}var e,f,g,h,i,j,k,l=this.colCnt,m=this.buildSegLevels(c),n=Math.max(1,m.length),o=a("<tbody/>"),p=[],q=[],r=[];for(e=0;n>e;e++){if(f=m[e],g=0,h=a("<tr/>"),p.push([]),q.push([]),r.push([]),f)for(i=0;i<f.length;i++){for(j=f[i],d(j.leftCol),k=a('<td class="fc-event-container"/>').append(j.el),j.leftCol!=j.rightCol?k.attr("colspan",j.rightCol-j.leftCol+1):r[e][g]=k;g<=j.rightCol;)q[e][g]=k,p[e][g]=j,g++;h.append(k)}d(l),this.bookendCells(h),o.append(h)}return{row:b,tbodyEl:o,cellMatrix:q,segMatrix:p,segLevels:m,segs:c}},buildSegLevels:function(a){var b,c,d,e=[];for(this.sortEventSegs(a),b=0;b<a.length;b++){for(c=a[b],d=0;d<e.length&&Ia(c,e[d]);d++);c.level=d,(e[d]||(e[d]=[])).push(c)}for(d=0;d<e.length;d++)e[d].sort(Ja);return e},groupSegRows:function(a){var b,c=[];for(b=0;b<this.rowCnt;b++)c.push([]);for(b=0;b<a.length;b++)c[a[b].row].push(a[b]);return c}}),ub.mixin({segPopover:null,popoverSegs:null,removeSegPopover:function(){this.segPopover&&this.segPopover.hide()},limitRows:function(a){var b,c,d=this.rowStructs||[];for(b=0;b<d.length;b++)this.unlimitRow(b),c=a?"number"==typeof a?a:this.computeRowLevelLimit(b):!1,c!==!1&&this.limitRow(b,c)},computeRowLevelLimit:function(b){function c(b,c){f=Math.max(f,a(c).outerHeight())}var d,e,f,g=this.rowEls.eq(b),h=g.height(),i=this.rowStructs[b].tbodyEl.children();for(d=0;d<i.length;d++)if(e=i.eq(d).removeClass("fc-limited"),f=0,e.find("> td > :first-child").each(c),e.position().top+f>h)return d;return!1},limitRow:function(b,c){function d(d){for(;d>w;)j=t.getCellSegs(b,w,c),j.length&&(m=f[c-1][w],s=t.renderMoreLink(b,w,j),r=a("<div/>").append(s),m.append(r),v.push(r[0])),w++}var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t=this,u=this.rowStructs[b],v=[],w=0;if(c&&c<u.segLevels.length){for(e=u.segLevels[c-1],f=u.cellMatrix,g=u.tbodyEl.children().slice(c).addClass("fc-limited").get(),h=0;h<e.length;h++){for(i=e[h],d(i.leftCol),l=[],k=0;w<=i.rightCol;)j=this.getCellSegs(b,w,c),l.push(j),k+=j.length,w++;if(k){for(m=f[c-1][i.leftCol],n=m.attr("rowspan")||1,o=[],p=0;p<l.length;p++)q=a('<td class="fc-more-cell"/>').attr("rowspan",n),j=l[p],s=this.renderMoreLink(b,i.leftCol+p,[i].concat(j)),r=a("<div/>").append(s),q.append(r),o.push(q[0]),v.push(q[0]);m.addClass("fc-limited").after(a(o)),g.push(m[0])}}d(this.colCnt),u.moreEls=a(v),u.limitedEls=a(g)}},unlimitRow:function(a){var b=this.rowStructs[a];b.moreEls&&(b.moreEls.remove(),b.moreEls=null),b.limitedEls&&(b.limitedEls.removeClass("fc-limited"),b.limitedEls=null)},renderMoreLink:function(b,c,d){var e=this,f=this.view;return a('<a class="fc-more"/>').text(this.getMoreLinkText(d.length)).on("click",function(g){var h=f.opt("eventLimitClick"),i=e.getCellDate(b,c),j=a(this),k=e.getCellEl(b,c),l=e.getCellSegs(b,c),m=e.resliceDaySegs(l,i),n=e.resliceDaySegs(d,i);"function"==typeof h&&(h=f.trigger("eventLimitClick",null,{date:i,dayEl:k,moreEl:j,segs:m,hiddenSegs:n},g)),"popover"===h?e.showSegPopover(b,c,j,m):"string"==typeof h&&f.calendar.zoomTo(i,h)})},showSegPopover:function(a,b,c,d){var e,f,g=this,h=this.view,i=c.parent();e=1==this.rowCnt?h.el:this.rowEls.eq(a),f={className:"fc-more-popover",content:this.renderSegPopoverContent(a,b,d),parentEl:this.el,top:e.offset().top,autoHide:!0,viewportConstrain:h.opt("popoverViewportConstrain"),hide:function(){g.segPopover.removeElement(),g.segPopover=null,g.popoverSegs=null}},this.isRTL?f.right=i.offset().left+i.outerWidth()+1:f.left=i.offset().left-1,this.segPopover=new nb(f),this.segPopover.show()},renderSegPopoverContent:function(b,c,d){var e,f=this.view,g=f.opt("theme"),h=this.getCellDate(b,c).format(f.opt("dayPopoverFormat")),i=a('<div class="fc-header '+f.widgetHeaderClass+'"><span class="fc-close '+(g?"ui-icon ui-icon-closethick":"fc-icon fc-icon-x")+'"></span><span class="fc-title">'+ca(h)+'</span><div class="fc-clear"/></div><div class="fc-body '+f.widgetContentClass+'"><div class="fc-event-container"></div></div>'),j=i.find(".fc-event-container");for(d=this.renderFgSegEls(d,!0),this.popoverSegs=d,e=0;e<d.length;e++)this.prepareHits(),d[e].hit=this.getCellHit(b,c),this.releaseHits(),j.append(d[e].el);return i},resliceDaySegs:function(b,c){var d=a.map(b,function(a){return a.event}),e=c.clone(),f=e.clone().add(1,"days"),g={start:e,end:f};return b=this.eventsToSegs(d,function(a){var b=K(a,g);return b?[b]:[]}),this.sortEventSegs(b),b},getMoreLinkText:function(a){var b=this.view.opt("eventLimitText");return"function"==typeof b?b(a):"+"+a+" "+b},getCellSegs:function(a,b,c){for(var d,e=this.rowStructs[a].segMatrix,f=c||0,g=[];f<e.length;)d=e[f][b],d&&g.push(d),f++;return g}});var vb=Va.TimeGrid=sb.extend(tb,{slotDuration:null,snapDuration:null,snapsPerSlot:null,minTime:null,maxTime:null,labelFormat:null,labelInterval:null,colEls:null,slatContainerEl:null,slatEls:null,nowIndicatorEls:null,colCoordCache:null,slatCoordCache:null,constructor:function(){sb.apply(this,arguments),this.processOptions()},renderDates:function(){this.el.html(this.renderHtml()),this.colEls=this.el.find(".fc-day"),this.slatContainerEl=this.el.find(".fc-slats"),this.slatEls=this.slatContainerEl.find("tr"),this.colCoordCache=new ob({els:this.colEls,isHorizontal:!0}),this.slatCoordCache=new ob({els:this.slatEls,isVertical:!0}),this.renderContentSkeleton()},renderHtml:function(){return'<div class="fc-bg"><table>'+this.renderBgTrHtml(0)+'</table></div><div class="fc-slats"><table>'+this.renderSlatRowHtml()+"</table></div>"},renderSlatRowHtml:function(){for(var a,c,d,e=this.view,f=this.isRTL,g="",h=b.duration(+this.minTime);h<this.maxTime;)a=this.start.clone().time(h),c=ha(R(h,this.labelInterval)),d='<td class="fc-axis fc-time '+e.widgetContentClass+'" '+e.axisStyleAttr()+">"+(c?"<span>"+ca(a.format(this.labelFormat))+"</span>":"")+"</td>",g+='<tr data-time="'+a.format("HH:mm:ss")+'"'+(c?"":' class="fc-minor"')+">"+(f?"":d)+'<td class="'+e.widgetContentClass+'"/>'+(f?d:"")+"</tr>",h.add(this.slotDuration);return g},processOptions:function(){var c,d=this.view,e=d.opt("slotDuration"),f=d.opt("snapDuration");e=b.duration(e),f=f?b.duration(f):e,this.slotDuration=e,this.snapDuration=f,this.snapsPerSlot=e/f,this.minResizeDuration=f,this.minTime=b.duration(d.opt("minTime")),this.maxTime=b.duration(d.opt("maxTime")),c=d.opt("slotLabelFormat"),a.isArray(c)&&(c=c[c.length-1]),this.labelFormat=c||d.opt("axisFormat")||d.opt("smallTimeFormat"),c=d.opt("slotLabelInterval"),this.labelInterval=c?b.duration(c):this.computeLabelInterval(e)},computeLabelInterval:function(a){var c,d,e;for(c=Mb.length-1;c>=0;c--)if(d=b.duration(Mb[c]),e=R(d,a),ha(e)&&e>1)return d;return b.duration(a)},computeEventTimeFormat:function(){return this.view.opt("noMeridiemTimeFormat")},computeDisplayEventEnd:function(){return!0},prepareHits:function(){this.colCoordCache.build(),this.slatCoordCache.build()},releaseHits:function(){this.colCoordCache.clear()},queryHit:function(a,b){var c=this.snapsPerSlot,d=this.colCoordCache,e=this.slatCoordCache,f=d.getHorizontalIndex(a),g=e.getVerticalIndex(b);if(null!=f&&null!=g){var h=e.getTopOffset(g),i=e.getHeight(g),j=(b-h)/i,k=Math.floor(j*c),l=g*c+k,m=h+k/c*i,n=h+(k+1)/c*i;return{col:f,snap:l,component:this,left:d.getLeftOffset(f),right:d.getRightOffset(f),top:m,bottom:n}}},getHitSpan:function(a){var b,c=this.getCellDate(0,a.col),d=this.computeSnapTime(a.snap);return c.time(d),b=c.clone().add(this.snapDuration),{start:c,end:b}},getHitEl:function(a){return this.colEls.eq(a.col)},rangeUpdated:function(){this.updateDayTable()},computeSnapTime:function(a){return b.duration(this.minTime+this.snapDuration*a)},spanToSegs:function(a){var b,c=this.sliceRangeByTimes(a);for(b=0;b<c.length;b++)this.isRTL?c[b].col=this.daysPerRow-1-c[b].dayIndex:c[b].col=c[b].dayIndex;return c},sliceRangeByTimes:function(a){var b,c,d,e,f=[];for(c=0;c<this.daysPerRow;c++)d=this.dayDates[c].clone(),e={start:d.clone().time(this.minTime),end:d.clone().time(this.maxTime)},b=K(a,e),b&&(b.dayIndex=c,f.push(b));return f},updateSize:function(a){this.slatCoordCache.build(),a&&this.updateSegVerticals([].concat(this.fgSegs||[],this.bgSegs||[],this.businessSegs||[]))},getTotalSlatHeight:function(){return this.slatContainerEl.outerHeight()},computeDateTop:function(a,c){return this.computeTimeTop(b.duration(a-c.clone().stripTime()))},computeTimeTop:function(a){var b,c,d=this.slatEls.length,e=(a-this.minTime)/this.slotDuration;return e=Math.max(0,e),e=Math.min(d,e),b=Math.floor(e),b=Math.min(b,d-1),c=e-b,this.slatCoordCache.getTopPosition(b)+this.slatCoordCache.getHeight(b)*c},renderDrag:function(a,b){return b?this.renderEventLocationHelper(a,b):void this.renderHighlight(this.eventToSpan(a))},unrenderDrag:function(){this.unrenderHelper(),this.unrenderHighlight()},renderEventResize:function(a,b){return this.renderEventLocationHelper(a,b)},unrenderEventResize:function(){this.unrenderHelper()},renderHelper:function(a,b){return this.renderHelperSegs(this.eventToSegs(a),b)},unrenderHelper:function(){this.unrenderHelperSegs()},renderBusinessHours:function(){var a=this.view.calendar.getBusinessHoursEvents(),b=this.eventsToSegs(a);this.renderBusinessSegs(b)},unrenderBusinessHours:function(){this.unrenderBusinessSegs()},getNowIndicatorUnit:function(){return"minute"},renderNowIndicator:function(b){var c,d=this.spanToSegs({start:b,end:b}),e=this.computeDateTop(b,b),f=[];for(c=0;c<d.length;c++)f.push(a('<div class="fc-now-indicator fc-now-indicator-line"></div>').css("top",e).appendTo(this.colContainerEls.eq(d[c].col))[0]);d.length>0&&f.push(a('<div class="fc-now-indicator fc-now-indicator-arrow"></div>').css("top",e).appendTo(this.el.find(".fc-content-skeleton"))[0]),this.nowIndicatorEls=a(f)},unrenderNowIndicator:function(){this.nowIndicatorEls&&(this.nowIndicatorEls.remove(),this.nowIndicatorEls=null)},renderSelection:function(a){this.view.opt("selectHelper")?this.renderEventLocationHelper(a):this.renderHighlight(a)},unrenderSelection:function(){this.unrenderHelper(),this.unrenderHighlight()},renderHighlight:function(a){this.renderHighlightSegs(this.spanToSegs(a))},unrenderHighlight:function(){this.unrenderHighlightSegs()}});vb.mixin({colContainerEls:null,fgContainerEls:null,bgContainerEls:null,helperContainerEls:null,highlightContainerEls:null,businessContainerEls:null,fgSegs:null,bgSegs:null,helperSegs:null,highlightSegs:null,businessSegs:null,renderContentSkeleton:function(){var b,c,d="";for(b=0;b<this.colCnt;b++)d+='<td><div class="fc-content-col"><div class="fc-event-container fc-helper-container"></div><div class="fc-event-container"></div><div class="fc-highlight-container"></div><div class="fc-bgevent-container"></div><div class="fc-business-container"></div></div></td>';c=a('<div class="fc-content-skeleton"><table><tr>'+d+"</tr></table></div>"),this.colContainerEls=c.find(".fc-content-col"),this.helperContainerEls=c.find(".fc-helper-container"),this.fgContainerEls=c.find(".fc-event-container:not(.fc-helper-container)"),this.bgContainerEls=c.find(".fc-bgevent-container"),this.highlightContainerEls=c.find(".fc-highlight-container"),this.businessContainerEls=c.find(".fc-business-container"),this.bookendCells(c.find("tr")),this.el.append(c)},renderFgSegs:function(a){return a=this.renderFgSegsIntoContainers(a,this.fgContainerEls),this.fgSegs=a,a},unrenderFgSegs:function(){this.unrenderNamedSegs("fgSegs")},renderHelperSegs:function(b,c){var d,e,f,g=[];for(b=this.renderFgSegsIntoContainers(b,this.helperContainerEls),d=0;d<b.length;d++)e=b[d],c&&c.col===e.col&&(f=c.el,e.el.css({left:f.css("left"),right:f.css("right"),"margin-left":f.css("margin-left"),"margin-right":f.css("margin-right")})),g.push(e.el[0]);return this.helperSegs=b,a(g)},unrenderHelperSegs:function(){this.unrenderNamedSegs("helperSegs")},renderBgSegs:function(a){return a=this.renderFillSegEls("bgEvent",a),this.updateSegVerticals(a),this.attachSegsByCol(this.groupSegsByCol(a),this.bgContainerEls),this.bgSegs=a,a},unrenderBgSegs:function(){this.unrenderNamedSegs("bgSegs")},renderHighlightSegs:function(a){a=this.renderFillSegEls("highlight",a),this.updateSegVerticals(a),this.attachSegsByCol(this.groupSegsByCol(a),this.highlightContainerEls),this.highlightSegs=a},unrenderHighlightSegs:function(){this.unrenderNamedSegs("highlightSegs")},renderBusinessSegs:function(a){a=this.renderFillSegEls("businessHours",a),this.updateSegVerticals(a),this.attachSegsByCol(this.groupSegsByCol(a),this.businessContainerEls),this.businessSegs=a},unrenderBusinessSegs:function(){this.unrenderNamedSegs("businessSegs")},groupSegsByCol:function(a){var b,c=[];for(b=0;b<this.colCnt;b++)c.push([]);for(b=0;b<a.length;b++)c[a[b].col].push(a[b]);return c},attachSegsByCol:function(a,b){var c,d,e;for(c=0;c<this.colCnt;c++)for(d=a[c],e=0;e<d.length;e++)b.eq(c).append(d[e].el)},unrenderNamedSegs:function(a){var b,c=this[a];if(c){for(b=0;b<c.length;b++)c[b].el.remove();this[a]=null}},renderFgSegsIntoContainers:function(a,b){var c,d;for(a=this.renderFgSegEls(a),c=this.groupSegsByCol(a),d=0;d<this.colCnt;d++)this.updateFgSegCoords(c[d]);return this.attachSegsByCol(c,b),a},fgSegHtml:function(a,b){var c,d,e,f=this.view,g=a.event,h=f.isEventDraggable(g),i=!b&&a.isStart&&f.isEventResizableFromStart(g),j=!b&&a.isEnd&&f.isEventResizableFromEnd(g),k=this.getSegClasses(a,h,i||j),l=ea(this.getSegSkinCss(a));return k.unshift("fc-time-grid-event","fc-v-event"),f.isMultiDayEvent(g)?(a.isStart||a.isEnd)&&(c=this.getEventTimeText(a),d=this.getEventTimeText(a,"LT"),e=this.getEventTimeText(a,null,!1)):(c=this.getEventTimeText(g),d=this.getEventTimeText(g,"LT"),e=this.getEventTimeText(g,null,!1)),'<a class="'+k.join(" ")+'"'+(g.url?' href="'+ca(g.url)+'"':"")+(l?' style="'+l+'"':"")+'><div class="fc-content">'+(c?'<div class="fc-time" data-start="'+ca(e)+'" data-full="'+ca(d)+'"><span>'+ca(c)+"</span></div>":"")+(g.title?'<div class="fc-title">'+ca(g.title)+"</div>":"")+'</div><div class="fc-bg"/>'+(j?'<div class="fc-resizer fc-end-resizer" />':"")+"</a>"},updateSegVerticals:function(a){this.computeSegVerticals(a),this.assignSegVerticals(a)},computeSegVerticals:function(a){var b,c;for(b=0;b<a.length;b++)c=a[b],c.top=this.computeDateTop(c.start,c.start),c.bottom=this.computeDateTop(c.end,c.start)},assignSegVerticals:function(a){var b,c;for(b=0;b<a.length;b++)c=a[b],c.el.css(this.generateSegVerticalCss(c))},generateSegVerticalCss:function(a){return{top:a.top,bottom:-a.bottom}},updateFgSegCoords:function(a){this.computeSegVerticals(a),this.computeFgSegHorizontals(a),this.assignSegVerticals(a),this.assignFgSegHorizontals(a)},computeFgSegHorizontals:function(a){var b,c,d;if(this.sortEventSegs(a),b=Ka(a),La(b),c=b[0]){for(d=0;d<c.length;d++)Ma(c[d]);for(d=0;d<c.length;d++)this.computeFgSegForwardBack(c[d],0,0)}},computeFgSegForwardBack:function(a,b,c){var d,e=a.forwardSegs;if(void 0===a.forwardCoord)for(e.length?(this.sortForwardSegs(e),this.computeFgSegForwardBack(e[0],b+1,c),a.forwardCoord=e[0].backwardCoord):a.forwardCoord=1,a.backwardCoord=a.forwardCoord-(a.forwardCoord-c)/(b+1),d=0;d<e.length;d++)this.computeFgSegForwardBack(e[d],0,a.forwardCoord)},sortForwardSegs:function(a){a.sort(ia(this,"compareForwardSegs"))},compareForwardSegs:function(a,b){return b.forwardPressure-a.forwardPressure||(a.backwardCoord||0)-(b.backwardCoord||0)||this.compareEventSegs(a,b)},assignFgSegHorizontals:function(a){var b,c;for(b=0;b<a.length;b++)c=a[b],c.el.css(this.generateFgSegHorizontalCss(c)),c.bottom-c.top<30&&c.el.addClass("fc-short")},generateFgSegHorizontalCss:function(a){var b,c,d=this.view.opt("slotEventOverlap"),e=a.backwardCoord,f=a.forwardCoord,g=this.generateSegVerticalCss(a);return d&&(f=Math.min(1,e+2*(f-e))),this.isRTL?(b=1-f,c=e):(b=e,c=1-f),g.zIndex=a.level+1,g.left=100*b+"%",g.right=100*c+"%",d&&a.forwardPressure&&(g[this.isRTL?"marginLeft":"marginRight"]=20),g}});var wb=Va.View=xa.extend(kb,lb,{type:null,name:null,title:null,calendar:null,options:null,el:null,displaying:null,isSkeletonRendered:!1,isEventsRendered:!1,start:null,end:null,intervalStart:null,intervalEnd:null,intervalDuration:null,intervalUnit:null,isRTL:!1,isSelected:!1,selectedEvent:null,eventOrderSpecs:null,widgetHeaderClass:null,widgetContentClass:null,highlightStateClass:null,nextDayThreshold:null,isHiddenDayHash:null,isNowIndicatorRendered:null,initialNowDate:null,initialNowQueriedMs:null,nowIndicatorTimeoutID:null,nowIndicatorIntervalID:null,constructor:function(a,c,d,e){this.calendar=a,this.type=this.name=c,this.options=d,this.intervalDuration=e||b.duration(1,"day"),this.nextDayThreshold=b.duration(this.opt("nextDayThreshold")),this.initThemingProps(),this.initHiddenDays(),this.isRTL=this.opt("isRTL"),this.eventOrderSpecs=G(this.opt("eventOrder")),this.initialize()},initialize:function(){},opt:function(a){return this.options[a]},trigger:function(a,b){var c=this.calendar;return c.trigger.apply(c,[a,b||this].concat(Array.prototype.slice.call(arguments,2),[this]))},setDate:function(a){this.setRange(this.computeRange(a))},setRange:function(b){a.extend(this,b),this.updateTitle()},computeRange:function(a){var b,c,d=O(this.intervalDuration),e=a.clone().startOf(d),f=e.clone().add(this.intervalDuration);return/year|month|week|day/.test(d)?(e.stripTime(),f.stripTime()):(e.hasTime()||(e=this.calendar.time(0)),f.hasTime()||(f=this.calendar.time(0))),b=e.clone(),b=this.skipHiddenDays(b),c=f.clone(),c=this.skipHiddenDays(c,-1,!0),{intervalUnit:d,intervalStart:e,intervalEnd:f,start:b,end:c}},computePrevDate:function(a){return this.massageCurrentDate(a.clone().startOf(this.intervalUnit).subtract(this.intervalDuration),-1)},computeNextDate:function(a){return this.massageCurrentDate(a.clone().startOf(this.intervalUnit).add(this.intervalDuration))},massageCurrentDate:function(a,b){return this.intervalDuration.as("days")<=1&&this.isHiddenDay(a)&&(a=this.skipHiddenDays(a,b),a.startOf("day")),a},updateTitle:function(){this.title=this.computeTitle()},computeTitle:function(){return this.formatRange({start:this.calendar.applyTimezone(this.intervalStart),end:this.calendar.applyTimezone(this.intervalEnd)},this.opt("titleFormat")||this.computeTitleFormat(),this.opt("titleRangeSeparator"))},computeTitleFormat:function(){return"year"==this.intervalUnit?"YYYY":"month"==this.intervalUnit?this.opt("monthYearFormat"):this.intervalDuration.as("days")>1?"ll":"LL"},formatRange:function(a,b,c){var d=a.end;return d.hasTime()||(d=d.clone().subtract(1)),sa(a.start,d,b,c,this.opt("isRTL"))},setElement:function(a){this.el=a,this.bindGlobalHandlers()},removeElement:function(){this.clear(),this.isSkeletonRendered&&(this.unrenderSkeleton(),this.isSkeletonRendered=!1),this.unbindGlobalHandlers(),this.el.remove()},display:function(b){var c=this,d=null;return this.displaying&&(d=this.queryScroll()),this.calendar.freezeContentHeight(),this.clear().then(function(){return c.displaying=a.when(c.displayView(b)).then(function(){c.forceScroll(c.computeInitialScroll(d)),c.calendar.unfreezeContentHeight(),c.triggerRender()})})},clear:function(){var b=this,c=this.displaying;return c?c.then(function(){return b.displaying=null,b.clearEvents(),b.clearView()}):a.when()},displayView:function(a){this.isSkeletonRendered||(this.renderSkeleton(),this.isSkeletonRendered=!0),a&&this.setDate(a),this.render&&this.render(),this.renderDates(),this.updateSize(),this.renderBusinessHours(),this.startNowIndicator()},clearView:function(){this.unselect(),this.stopNowIndicator(),this.triggerUnrender(),this.unrenderBusinessHours(),this.unrenderDates(),this.destroy&&this.destroy()},renderSkeleton:function(){},unrenderSkeleton:function(){},renderDates:function(){},unrenderDates:function(){},triggerRender:function(){this.trigger("viewRender",this,this,this.el)},triggerUnrender:function(){this.trigger("viewDestroy",this,this,this.el)},bindGlobalHandlers:function(){this.listenTo(a(document),"mousedown",this.handleDocumentMousedown),this.listenTo(a(document),"touchstart",this.processUnselect)},unbindGlobalHandlers:function(){this.stopListeningTo(a(document))},initThemingProps:function(){var a=this.opt("theme")?"ui":"fc";this.widgetHeaderClass=a+"-widget-header",this.widgetContentClass=a+"-widget-content",this.highlightStateClass=a+"-state-highlight"},renderBusinessHours:function(){},unrenderBusinessHours:function(){},startNowIndicator:function(){var a,c,d,e=this;this.opt("nowIndicator")&&(a=this.getNowIndicatorUnit(),a&&(c=ia(this,"updateNowIndicator"),this.initialNowDate=this.calendar.getNow(),this.initialNowQueriedMs=+new Date,this.renderNowIndicator(this.initialNowDate),this.isNowIndicatorRendered=!0,d=this.initialNowDate.clone().startOf(a).add(1,a)-this.initialNowDate,this.nowIndicatorTimeoutID=setTimeout(function(){e.nowIndicatorTimeoutID=null,c(),d=+b.duration(1,a),d=Math.max(100,d),e.nowIndicatorIntervalID=setInterval(c,d)},d)))},updateNowIndicator:function(){this.isNowIndicatorRendered&&(this.unrenderNowIndicator(),this.renderNowIndicator(this.initialNowDate.clone().add(new Date-this.initialNowQueriedMs)))},stopNowIndicator:function(){this.isNowIndicatorRendered&&(this.nowIndicatorTimeoutID&&(clearTimeout(this.nowIndicatorTimeoutID),this.nowIndicatorTimeoutID=null),this.nowIndicatorIntervalID&&(clearTimeout(this.nowIndicatorIntervalID),this.nowIndicatorIntervalID=null),this.unrenderNowIndicator(),this.isNowIndicatorRendered=!1)},getNowIndicatorUnit:function(){},renderNowIndicator:function(a){},unrenderNowIndicator:function(){},updateSize:function(a){var b;a&&(b=this.queryScroll()),this.updateHeight(a),this.updateWidth(a),this.updateNowIndicator(),a&&this.setScroll(b)},updateWidth:function(a){},updateHeight:function(a){var b=this.calendar;this.setHeight(b.getSuggestedViewHeight(),b.isHeightAuto())},setHeight:function(a,b){},computeInitialScroll:function(a){return 0},queryScroll:function(){},setScroll:function(a){},forceScroll:function(a){var b=this;this.setScroll(a),setTimeout(function(){b.setScroll(a)},0)},displayEvents:function(a){var b=this.queryScroll();this.clearEvents(),this.renderEvents(a),this.isEventsRendered=!0,this.setScroll(b),this.triggerEventRender()},clearEvents:function(){var a;this.isEventsRendered&&(a=this.queryScroll(),this.triggerEventUnrender(),this.destroyEvents&&this.destroyEvents(),this.unrenderEvents(),this.setScroll(a),this.isEventsRendered=!1)},renderEvents:function(a){},unrenderEvents:function(){},triggerEventRender:function(){this.renderedEventSegEach(function(a){this.trigger("eventAfterRender",a.event,a.event,a.el)}),this.trigger("eventAfterAllRender")},triggerEventUnrender:function(){this.renderedEventSegEach(function(a){this.trigger("eventDestroy",a.event,a.event,a.el)})},resolveEventEl:function(b,c){var d=this.trigger("eventRender",b,b,c);return d===!1?c=null:d&&d!==!0&&(c=a(d)),c},showEvent:function(a){this.renderedEventSegEach(function(a){a.el.css("visibility","")},a)},hideEvent:function(a){this.renderedEventSegEach(function(a){a.el.css("visibility","hidden")},a)},renderedEventSegEach:function(a,b){var c,d=this.getEventSegs();for(c=0;c<d.length;c++)b&&d[c].event._id!==b._id||d[c].el&&a.call(this,d[c])},getEventSegs:function(){return[]},isEventDraggable:function(a){var b=a.source||{};return ba(a.startEditable,b.startEditable,this.opt("eventStartEditable"),a.editable,b.editable,this.opt("editable"))},reportEventDrop:function(a,b,c,d,e){var f=this.calendar,g=f.mutateEvent(a,b,c),h=function(){g.undo(),f.reportEventChange()};this.triggerEventDrop(a,g.dateDelta,h,d,e),f.reportEventChange()},triggerEventDrop:function(a,b,c,d,e){this.trigger("eventDrop",d[0],a,b,c,e,{})},reportExternalDrop:function(b,c,d,e,f){var g,h,i=b.eventProps;i&&(g=a.extend({},i,c),h=this.calendar.renderEvent(g,b.stick)[0]),this.triggerExternalDrop(h,c,d,e,f)},triggerExternalDrop:function(a,b,c,d,e){this.trigger("drop",c[0],b.start,d,e),a&&this.trigger("eventReceive",null,a)},renderDrag:function(a,b){},unrenderDrag:function(){},isEventResizableFromStart:function(a){return this.opt("eventResizableFromStart")&&this.isEventResizable(a)},isEventResizableFromEnd:function(a){return this.isEventResizable(a)},isEventResizable:function(a){var b=a.source||{};return ba(a.durationEditable,b.durationEditable,this.opt("eventDurationEditable"),a.editable,b.editable,this.opt("editable"))},reportEventResize:function(a,b,c,d,e){var f=this.calendar,g=f.mutateEvent(a,b,c),h=function(){g.undo(),f.reportEventChange()};this.triggerEventResize(a,g.durationDelta,h,d,e),f.reportEventChange()},triggerEventResize:function(a,b,c,d,e){this.trigger("eventResize",d[0],a,b,c,e,{})},select:function(a,b){this.unselect(b),this.renderSelection(a),this.reportSelection(a,b)},renderSelection:function(a){},reportSelection:function(a,b){this.isSelected=!0,this.triggerSelect(a,b)},triggerSelect:function(a,b){this.trigger("select",null,this.calendar.applyTimezone(a.start),this.calendar.applyTimezone(a.end),b)},unselect:function(a){this.isSelected&&(this.isSelected=!1,this.destroySelection&&this.destroySelection(),this.unrenderSelection(),this.trigger("unselect",null,a))},unrenderSelection:function(){},selectEvent:function(a){this.selectedEvent&&this.selectedEvent===a||(this.unselectEvent(),this.renderedEventSegEach(function(a){a.el.addClass("fc-selected")},a),this.selectedEvent=a)},unselectEvent:function(){this.selectedEvent&&(this.renderedEventSegEach(function(a){a.el.removeClass("fc-selected");
-},this.selectedEvent),this.selectedEvent=null)},isEventSelected:function(a){return this.selectedEvent&&this.selectedEvent._id===a._id},handleDocumentMousedown:function(a){u(a)&&this.processUnselect(a)},processUnselect:function(a){this.processRangeUnselect(a),this.processEventUnselect(a)},processRangeUnselect:function(b){var c;this.isSelected&&this.opt("unselectAuto")&&(c=this.opt("unselectCancel"),c&&a(b.target).closest(c).length||this.unselect(b))},processEventUnselect:function(b){this.selectedEvent&&(a(b.target).closest(".fc-selected").length||this.unselectEvent())},triggerDayClick:function(a,b,c){this.trigger("dayClick",b,this.calendar.applyTimezone(a.start),c)},initHiddenDays:function(){var b,c=this.opt("hiddenDays")||[],d=[],e=0;for(this.opt("weekends")===!1&&c.push(0,6),b=0;7>b;b++)(d[b]=-1!==a.inArray(b,c))||e++;if(!e)throw"invalid hiddenDays";this.isHiddenDayHash=d},isHiddenDay:function(a){return b.isMoment(a)&&(a=a.day()),this.isHiddenDayHash[a]},skipHiddenDays:function(a,b,c){var d=a.clone();for(b=b||1;this.isHiddenDayHash[(d.day()+(c?b:0)+7)%7];)d.add(b,"days");return d},computeDayRange:function(a){var b,c=a.start.clone().stripTime(),d=a.end,e=null;return d&&(e=d.clone().stripTime(),b=+d.time(),b&&b>=this.nextDayThreshold&&e.add(1,"days")),(!d||c>=e)&&(e=c.clone().add(1,"days")),{start:c,end:e}},isMultiDayEvent:function(a){var b=this.computeDayRange(a);return b.end.diff(b.start,"days")>1}}),xb=Va.Scroller=xa.extend({el:null,scrollEl:null,overflowX:null,overflowY:null,constructor:function(a){a=a||{},this.overflowX=a.overflowX||a.overflow||"auto",this.overflowY=a.overflowY||a.overflow||"auto"},render:function(){this.el=this.renderEl(),this.applyOverflow()},renderEl:function(){return this.scrollEl=a('<div class="fc-scroller"></div>')},clear:function(){this.setHeight("auto"),this.applyOverflow()},destroy:function(){this.el.remove()},applyOverflow:function(){this.scrollEl.css({"overflow-x":this.overflowX,"overflow-y":this.overflowY})},lockOverflow:function(a){var b=this.overflowX,c=this.overflowY;a=a||this.getScrollbarWidths(),"auto"===b&&(b=a.top||a.bottom||this.scrollEl[0].scrollWidth-1>this.scrollEl[0].clientWidth?"scroll":"hidden"),"auto"===c&&(c=a.left||a.right||this.scrollEl[0].scrollHeight-1>this.scrollEl[0].clientHeight?"scroll":"hidden"),this.scrollEl.css({"overflow-x":b,"overflow-y":c})},setHeight:function(a){this.scrollEl.height(a)},getScrollTop:function(){return this.scrollEl.scrollTop()},setScrollTop:function(a){this.scrollEl.scrollTop(a)},getClientWidth:function(){return this.scrollEl[0].clientWidth},getClientHeight:function(){return this.scrollEl[0].clientHeight},getScrollbarWidths:function(){return q(this.scrollEl)}}),yb=Va.Calendar=xa.extend({dirDefaults:null,langDefaults:null,overrides:null,options:null,viewSpecCache:null,view:null,header:null,loadingLevel:0,constructor:Pa,initialize:function(){},initOptions:function(a){var b,e,f,g;a=d(a),b=a.lang,e=zb[b],e||(b=yb.defaults.lang,e=zb[b]||{}),f=ba(a.isRTL,e.isRTL,yb.defaults.isRTL),g=f?yb.rtlDefaults:{},this.dirDefaults=g,this.langDefaults=e,this.overrides=a,this.options=c([yb.defaults,g,e,a]),Qa(this.options),this.viewSpecCache={}},getViewSpec:function(a){var b=this.viewSpecCache;return b[a]||(b[a]=this.buildViewSpec(a))},getUnitViewSpec:function(b){var c,d,e;if(-1!=a.inArray(b,$a))for(c=this.header.getViewsWithButtons(),a.each(Va.views,function(a){c.push(a)}),d=0;d<c.length;d++)if(e=this.getViewSpec(c[d]),e&&e.singleUnit==b)return e},buildViewSpec:function(a){for(var d,e,f,g,h=this.overrides.views||{},i=[],j=[],k=[],l=a;l;)d=Wa[l],e=h[l],l=null,"function"==typeof d&&(d={"class":d}),d&&(i.unshift(d),j.unshift(d.defaults||{}),f=f||d.duration,l=l||d.type),e&&(k.unshift(e),f=f||e.duration,l=l||e.type);return d=W(i),d.type=a,d["class"]?(f&&(f=b.duration(f),f.valueOf()&&(d.duration=f,g=O(f),1===f.as(g)&&(d.singleUnit=g,k.unshift(h[g]||{})))),d.defaults=c(j),d.overrides=c(k),this.buildViewSpecOptions(d),this.buildViewSpecButtonText(d,a),d):!1},buildViewSpecOptions:function(a){a.options=c([yb.defaults,a.defaults,this.dirDefaults,this.langDefaults,this.overrides,a.overrides]),Qa(a.options)},buildViewSpecButtonText:function(a,b){function c(c){var d=c.buttonText||{};return d[b]||(a.singleUnit?d[a.singleUnit]:null)}a.buttonTextOverride=c(this.overrides)||a.overrides.buttonText,a.buttonTextDefault=c(this.langDefaults)||c(this.dirDefaults)||a.defaults.buttonText||c(yb.defaults)||(a.duration?this.humanizeDuration(a.duration):null)||b},instantiateView:function(a){var b=this.getViewSpec(a);return new b["class"](this,a,b.options,b.duration)},isValidViewType:function(a){return Boolean(this.getViewSpec(a))},pushLoading:function(){this.loadingLevel++||this.trigger("loading",null,!0,this.view)},popLoading:function(){--this.loadingLevel||this.trigger("loading",null,!1,this.view)},buildSelectSpan:function(a,b){var c,d=this.moment(a).stripZone();return c=b?this.moment(b).stripZone():d.hasTime()?d.clone().add(this.defaultTimedEventDuration):d.clone().add(this.defaultAllDayEventDuration),{start:d,end:c}}});yb.mixin(kb),yb.defaults={titleRangeSeparator:" — ",monthYearFormat:"MMMM YYYY",defaultTimedEventDuration:"02:00:00",defaultAllDayEventDuration:{days:1},forceEventDuration:!1,nextDayThreshold:"09:00:00",defaultView:"month",aspectRatio:1.35,header:{left:"title",center:"",right:"today prev,next"},weekends:!0,weekNumbers:!1,weekNumberTitle:"W",weekNumberCalculation:"local",scrollTime:"06:00:00",lazyFetching:!0,startParam:"start",endParam:"end",timezoneParam:"timezone",timezone:!1,isRTL:!1,buttonText:{prev:"prev",next:"next",prevYear:"prev year",nextYear:"next year",year:"year",today:"today",month:"month",week:"week",day:"day"},buttonIcons:{prev:"left-single-arrow",next:"right-single-arrow",prevYear:"left-double-arrow",nextYear:"right-double-arrow"},theme:!1,themeButtonIcons:{prev:"circle-triangle-w",next:"circle-triangle-e",prevYear:"seek-prev",nextYear:"seek-next"},dragOpacity:.75,dragRevertDuration:500,dragScroll:!0,unselectAuto:!0,dropAccept:"*",eventOrder:"title",eventLimit:!1,eventLimitText:"more",eventLimitClick:"popover",dayPopoverFormat:"LL",handleWindowResize:!0,windowResizeDelay:200,longPressDelay:1e3},yb.englishDefaults={dayPopoverFormat:"dddd, MMMM D"},yb.rtlDefaults={header:{left:"next,prev today",center:"",right:"title"},buttonIcons:{prev:"right-single-arrow",next:"left-single-arrow",prevYear:"right-double-arrow",nextYear:"left-double-arrow"},themeButtonIcons:{prev:"circle-triangle-e",next:"circle-triangle-w",nextYear:"seek-prev",prevYear:"seek-next"}};var zb=Va.langs={};Va.datepickerLang=function(b,c,d){var e=zb[b]||(zb[b]={});e.isRTL=d.isRTL,e.weekNumberTitle=d.weekHeader,a.each(Ab,function(a,b){e[a]=b(d)}),a.datepicker&&(a.datepicker.regional[c]=a.datepicker.regional[b]=d,a.datepicker.regional.en=a.datepicker.regional[""],a.datepicker.setDefaults(d))},Va.lang=function(b,d){var e,f;e=zb[b]||(zb[b]={}),d&&(e=zb[b]=c([e,d])),f=Ra(b),a.each(Bb,function(a,b){null==e[a]&&(e[a]=b(f,e))}),yb.defaults.lang=b};var Ab={buttonText:function(a){return{prev:da(a.prevText),next:da(a.nextText),today:da(a.currentText)}},monthYearFormat:function(a){return a.showMonthAfterYear?"YYYY["+a.yearSuffix+"] MMMM":"MMMM YYYY["+a.yearSuffix+"]"}},Bb={dayOfMonthFormat:function(a,b){var c=a.longDateFormat("l");return c=c.replace(/^Y+[^\w\s]*|[^\w\s]*Y+$/g,""),b.isRTL?c+=" ddd":c="ddd "+c,c},mediumTimeFormat:function(a){return a.longDateFormat("LT").replace(/\s*a$/i,"a")},smallTimeFormat:function(a){return a.longDateFormat("LT").replace(":mm","(:mm)").replace(/(\Wmm)$/,"($1)").replace(/\s*a$/i,"a")},extraSmallTimeFormat:function(a){return a.longDateFormat("LT").replace(":mm","(:mm)").replace(/(\Wmm)$/,"($1)").replace(/\s*a$/i,"t")},hourFormat:function(a){return a.longDateFormat("LT").replace(":mm","").replace(/(\Wmm)$/,"").replace(/\s*a$/i,"a")},noMeridiemTimeFormat:function(a){return a.longDateFormat("LT").replace(/\s*a$/i,"")}},Cb={smallDayDateFormat:function(a){return a.isRTL?"D dd":"dd D"},weekFormat:function(a){return a.isRTL?"w[ "+a.weekNumberTitle+"]":"["+a.weekNumberTitle+" ]w"},smallWeekFormat:function(a){return a.isRTL?"w["+a.weekNumberTitle+"]":"["+a.weekNumberTitle+"]w"}};Va.lang("en",yb.englishDefaults),Va.sourceNormalizers=[],Va.sourceFetchers=[];var Db={dataType:"json",cache:!1},Eb=1;yb.prototype.getPeerEvents=function(a,b){var c,d,e=this.getEventCache(),f=[];for(c=0;c<e.length;c++)d=e[c],b&&b._id===d._id||f.push(d);return f};var Fb=Va.BasicView=wb.extend({scroller:null,dayGridClass:ub,dayGrid:null,dayNumbersVisible:!1,weekNumbersVisible:!1,weekNumberWidth:null,headContainerEl:null,headRowEl:null,initialize:function(){this.dayGrid=this.instantiateDayGrid(),this.scroller=new xb({overflowX:"hidden",overflowY:"auto"})},instantiateDayGrid:function(){var a=this.dayGridClass.extend(Gb);return new a(this)},setRange:function(a){wb.prototype.setRange.call(this,a),this.dayGrid.breakOnWeeks=/year|month|week/.test(this.intervalUnit),this.dayGrid.setRange(a)},computeRange:function(a){var b=wb.prototype.computeRange.call(this,a);return/year|month/.test(b.intervalUnit)&&(b.start.startOf("week"),b.start=this.skipHiddenDays(b.start),b.end.weekday()&&(b.end.add(1,"week").startOf("week"),b.end=this.skipHiddenDays(b.end,-1,!0))),b},renderDates:function(){this.dayNumbersVisible=this.dayGrid.rowCnt>1,this.weekNumbersVisible=this.opt("weekNumbers"),this.dayGrid.numbersVisible=this.dayNumbersVisible||this.weekNumbersVisible,this.el.addClass("fc-basic-view").html(this.renderSkeletonHtml()),this.renderHead(),this.scroller.render();var b=this.scroller.el.addClass("fc-day-grid-container"),c=a('<div class="fc-day-grid" />').appendTo(b);this.el.find(".fc-body > tr > td").append(b),this.dayGrid.setElement(c),this.dayGrid.renderDates(this.hasRigidRows())},renderHead:function(){this.headContainerEl=this.el.find(".fc-head-container").html(this.dayGrid.renderHeadHtml()),this.headRowEl=this.headContainerEl.find(".fc-row")},unrenderDates:function(){this.dayGrid.unrenderDates(),this.dayGrid.removeElement(),this.scroller.destroy()},renderBusinessHours:function(){this.dayGrid.renderBusinessHours()},renderSkeletonHtml:function(){return'<table><thead class="fc-head"><tr><td class="fc-head-container '+this.widgetHeaderClass+'"></td></tr></thead><tbody class="fc-body"><tr><td class="'+this.widgetContentClass+'"></td></tr></tbody></table>'},weekNumberStyleAttr:function(){return null!==this.weekNumberWidth?'style="width:'+this.weekNumberWidth+'px"':""},hasRigidRows:function(){var a=this.opt("eventLimit");return a&&"number"!=typeof a},updateWidth:function(){this.weekNumbersVisible&&(this.weekNumberWidth=k(this.el.find(".fc-week-number")))},setHeight:function(a,b){var c,d,g=this.opt("eventLimit");this.scroller.clear(),f(this.headRowEl),this.dayGrid.removeSegPopover(),g&&"number"==typeof g&&this.dayGrid.limitRows(g),c=this.computeScrollerHeight(a),this.setGridHeight(c,b),g&&"number"!=typeof g&&this.dayGrid.limitRows(g),b||(this.scroller.setHeight(c),d=this.scroller.getScrollbarWidths(),(d.left||d.right)&&(e(this.headRowEl,d),c=this.computeScrollerHeight(a),this.scroller.setHeight(c)),this.scroller.lockOverflow(d))},computeScrollerHeight:function(a){return a-l(this.el,this.scroller.el)},setGridHeight:function(a,b){b?j(this.dayGrid.rowEls):i(this.dayGrid.rowEls,a,!0)},queryScroll:function(){return this.scroller.getScrollTop()},setScroll:function(a){this.scroller.setScrollTop(a)},prepareHits:function(){this.dayGrid.prepareHits()},releaseHits:function(){this.dayGrid.releaseHits()},queryHit:function(a,b){return this.dayGrid.queryHit(a,b)},getHitSpan:function(a){return this.dayGrid.getHitSpan(a)},getHitEl:function(a){return this.dayGrid.getHitEl(a)},renderEvents:function(a){this.dayGrid.renderEvents(a),this.updateHeight()},getEventSegs:function(){return this.dayGrid.getEventSegs()},unrenderEvents:function(){this.dayGrid.unrenderEvents()},renderDrag:function(a,b){return this.dayGrid.renderDrag(a,b)},unrenderDrag:function(){this.dayGrid.unrenderDrag()},renderSelection:function(a){this.dayGrid.renderSelection(a)},unrenderSelection:function(){this.dayGrid.unrenderSelection()}}),Gb={renderHeadIntroHtml:function(){var a=this.view;return a.weekNumbersVisible?'<th class="fc-week-number '+a.widgetHeaderClass+'" '+a.weekNumberStyleAttr()+"><span>"+ca(a.opt("weekNumberTitle"))+"</span></th>":""},renderNumberIntroHtml:function(a){var b=this.view;return b.weekNumbersVisible?'<td class="fc-week-number" '+b.weekNumberStyleAttr()+"><span>"+this.getCellDate(a,0).format("w")+"</span></td>":""},renderBgIntroHtml:function(){var a=this.view;return a.weekNumbersVisible?'<td class="fc-week-number '+a.widgetContentClass+'" '+a.weekNumberStyleAttr()+"></td>":""},renderIntroHtml:function(){var a=this.view;return a.weekNumbersVisible?'<td class="fc-week-number" '+a.weekNumberStyleAttr()+"></td>":""}},Hb=Va.MonthView=Fb.extend({computeRange:function(a){var b,c=Fb.prototype.computeRange.call(this,a);return this.isFixedWeeks()&&(b=Math.ceil(c.end.diff(c.start,"weeks",!0)),c.end.add(6-b,"weeks")),c},setGridHeight:function(a,b){b=b||"variable"===this.opt("weekMode"),b&&(a*=this.rowCnt/6),i(this.dayGrid.rowEls,a,!b)},isFixedWeeks:function(){var a=this.opt("weekMode");return a?"fixed"===a:this.opt("fixedWeekCount")}});Wa.basic={"class":Fb},Wa.basicDay={type:"basic",duration:{days:1}},Wa.basicWeek={type:"basic",duration:{weeks:1}},Wa.month={"class":Hb,duration:{months:1},defaults:{fixedWeekCount:!0}};var Ib=Va.AgendaView=wb.extend({scroller:null,timeGridClass:vb,timeGrid:null,dayGridClass:ub,dayGrid:null,axisWidth:null,headContainerEl:null,noScrollRowEls:null,bottomRuleEl:null,initialize:function(){this.timeGrid=this.instantiateTimeGrid(),this.opt("allDaySlot")&&(this.dayGrid=this.instantiateDayGrid()),this.scroller=new xb({overflowX:"hidden",overflowY:"auto"})},instantiateTimeGrid:function(){var a=this.timeGridClass.extend(Jb);return new a(this)},instantiateDayGrid:function(){var a=this.dayGridClass.extend(Kb);return new a(this)},setRange:function(a){wb.prototype.setRange.call(this,a),this.timeGrid.setRange(a),this.dayGrid&&this.dayGrid.setRange(a)},renderDates:function(){this.el.addClass("fc-agenda-view").html(this.renderSkeletonHtml()),this.renderHead(),this.scroller.render();var b=this.scroller.el.addClass("fc-time-grid-container"),c=a('<div class="fc-time-grid" />').appendTo(b);this.el.find(".fc-body > tr > td").append(b),this.timeGrid.setElement(c),this.timeGrid.renderDates(),this.bottomRuleEl=a('<hr class="fc-divider '+this.widgetHeaderClass+'"/>').appendTo(this.timeGrid.el),this.dayGrid&&(this.dayGrid.setElement(this.el.find(".fc-day-grid")),this.dayGrid.renderDates(),this.dayGrid.bottomCoordPadding=this.dayGrid.el.next("hr").outerHeight()),this.noScrollRowEls=this.el.find(".fc-row:not(.fc-scroller *)")},renderHead:function(){this.headContainerEl=this.el.find(".fc-head-container").html(this.timeGrid.renderHeadHtml())},unrenderDates:function(){this.timeGrid.unrenderDates(),this.timeGrid.removeElement(),this.dayGrid&&(this.dayGrid.unrenderDates(),this.dayGrid.removeElement()),this.scroller.destroy()},renderSkeletonHtml:function(){return'<table><thead class="fc-head"><tr><td class="fc-head-container '+this.widgetHeaderClass+'"></td></tr></thead><tbody class="fc-body"><tr><td class="'+this.widgetContentClass+'">'+(this.dayGrid?'<div class="fc-day-grid"/><hr class="fc-divider '+this.widgetHeaderClass+'"/>':"")+"</td></tr></tbody></table>"},axisStyleAttr:function(){return null!==this.axisWidth?'style="width:'+this.axisWidth+'px"':""},renderBusinessHours:function(){this.timeGrid.renderBusinessHours(),this.dayGrid&&this.dayGrid.renderBusinessHours()},unrenderBusinessHours:function(){this.timeGrid.unrenderBusinessHours(),this.dayGrid&&this.dayGrid.unrenderBusinessHours()},getNowIndicatorUnit:function(){return this.timeGrid.getNowIndicatorUnit()},renderNowIndicator:function(a){this.timeGrid.renderNowIndicator(a)},unrenderNowIndicator:function(){this.timeGrid.unrenderNowIndicator()},updateSize:function(a){this.timeGrid.updateSize(a),wb.prototype.updateSize.call(this,a)},updateWidth:function(){this.axisWidth=k(this.el.find(".fc-axis"))},setHeight:function(a,b){var c,d,g;this.bottomRuleEl.hide(),this.scroller.clear(),f(this.noScrollRowEls),this.dayGrid&&(this.dayGrid.removeSegPopover(),c=this.opt("eventLimit"),c&&"number"!=typeof c&&(c=Lb),c&&this.dayGrid.limitRows(c)),b||(d=this.computeScrollerHeight(a),this.scroller.setHeight(d),g=this.scroller.getScrollbarWidths(),(g.left||g.right)&&(e(this.noScrollRowEls,g),d=this.computeScrollerHeight(a),this.scroller.setHeight(d)),this.scroller.lockOverflow(g),this.timeGrid.getTotalSlatHeight()<d&&this.bottomRuleEl.show())},computeScrollerHeight:function(a){return a-l(this.el,this.scroller.el)},computeInitialScroll:function(){var a=b.duration(this.opt("scrollTime")),c=this.timeGrid.computeTimeTop(a);return c=Math.ceil(c),c&&c++,c},queryScroll:function(){return this.scroller.getScrollTop()},setScroll:function(a){this.scroller.setScrollTop(a)},prepareHits:function(){this.timeGrid.prepareHits(),this.dayGrid&&this.dayGrid.prepareHits()},releaseHits:function(){this.timeGrid.releaseHits(),this.dayGrid&&this.dayGrid.releaseHits()},queryHit:function(a,b){var c=this.timeGrid.queryHit(a,b);return!c&&this.dayGrid&&(c=this.dayGrid.queryHit(a,b)),c},getHitSpan:function(a){return a.component.getHitSpan(a)},getHitEl:function(a){return a.component.getHitEl(a)},renderEvents:function(a){var b,c,d=[],e=[],f=[];for(c=0;c<a.length;c++)a[c].allDay?d.push(a[c]):e.push(a[c]);b=this.timeGrid.renderEvents(e),this.dayGrid&&(f=this.dayGrid.renderEvents(d)),this.updateHeight()},getEventSegs:function(){return this.timeGrid.getEventSegs().concat(this.dayGrid?this.dayGrid.getEventSegs():[])},unrenderEvents:function(){this.timeGrid.unrenderEvents(),this.dayGrid&&this.dayGrid.unrenderEvents()},renderDrag:function(a,b){return a.start.hasTime()?this.timeGrid.renderDrag(a,b):this.dayGrid?this.dayGrid.renderDrag(a,b):void 0},unrenderDrag:function(){this.timeGrid.unrenderDrag(),this.dayGrid&&this.dayGrid.unrenderDrag()},renderSelection:function(a){a.start.hasTime()||a.end.hasTime()?this.timeGrid.renderSelection(a):this.dayGrid&&this.dayGrid.renderSelection(a)},unrenderSelection:function(){this.timeGrid.unrenderSelection(),this.dayGrid&&this.dayGrid.unrenderSelection()}}),Jb={renderHeadIntroHtml:function(){var a,b=this.view;return b.opt("weekNumbers")?(a=this.start.format(b.opt("smallWeekFormat")),'<th class="fc-axis fc-week-number '+b.widgetHeaderClass+'" '+b.axisStyleAttr()+"><span>"+ca(a)+"</span></th>"):'<th class="fc-axis '+b.widgetHeaderClass+'" '+b.axisStyleAttr()+"></th>"},renderBgIntroHtml:function(){var a=this.view;return'<td class="fc-axis '+a.widgetContentClass+'" '+a.axisStyleAttr()+"></td>"},renderIntroHtml:function(){var a=this.view;return'<td class="fc-axis" '+a.axisStyleAttr()+"></td>"}},Kb={renderBgIntroHtml:function(){var a=this.view;return'<td class="fc-axis '+a.widgetContentClass+'" '+a.axisStyleAttr()+"><span>"+(a.opt("allDayHtml")||ca(a.opt("allDayText")))+"</span></td>"},renderIntroHtml:function(){var a=this.view;return'<td class="fc-axis" '+a.axisStyleAttr()+"></td>"}},Lb=5,Mb=[{hours:1},{minutes:30},{minutes:15},{seconds:30},{seconds:15}];return Wa.agenda={"class":Ib,defaults:{allDaySlot:!0,allDayText:"all-day",slotDuration:"00:30:00",minTime:"00:00:00",maxTime:"24:00:00",slotEventOverlap:!0}},Wa.agendaDay={type:"agenda",duration:{days:1}},Wa.agendaWeek={type:"agenda",duration:{weeks:1}},Va}); \ No newline at end of file
diff --git a/tools/infra-dashboard/js/highslide-full.min.js b/tools/infra-dashboard/js/highslide-full.min.js
deleted file mode 100644
index 03c786f9..00000000
--- a/tools/infra-dashboard/js/highslide-full.min.js
+++ /dev/null
@@ -1,3315 +0,0 @@
-/******************************************************************************
-Name: Highslide JS
-Version: 4.1.8 (October 27 2009)
-Config: default +events +unobtrusive +imagemap +slideshow +positioning +transitions +viewport +thumbstrip +inline +ajax +iframe +flash
-Author: Torstein Hønsi
-Support: http://highslide.com/support
-
-Licence:
-Highslide JS is licensed under a Creative Commons Attribution-NonCommercial 2.5
-License (http://creativecommons.org/licenses/by-nc/2.5/).
-
-You are free:
- * to copy, distribute, display, and perform the work
- * to make derivative works
-
-Under the following conditions:
- * Attribution. You must attribute the work in the manner specified by the
- author or licensor.
- * Noncommercial. You may not use this work for commercial purposes.
-
-* For any reuse or distribution, you must make clear to others the license
- terms of this work.
-* Any of these conditions can be waived if you get permission from the
- copyright holder.
-
-Your fair use and other rights are in no way affected by the above.
-******************************************************************************/
-if (!hs) { var hs = {
-// Language strings
-lang : {
- cssDirection: 'ltr',
- loadingText : 'Loading...',
- loadingTitle : 'Click to cancel',
- focusTitle : 'Click to bring to front',
- fullExpandTitle : 'Expand to actual size (f)',
- creditsText : 'Powered by <i>Highslide JS</i>',
- creditsTitle : 'Go to the Highslide JS homepage',
- previousText : 'Previous',
- nextText : 'Next',
- moveText : 'Move',
- closeText : 'Close',
- closeTitle : 'Close (esc)',
- resizeTitle : 'Resize',
- playText : 'Play',
- playTitle : 'Play slideshow (spacebar)',
- pauseText : 'Pause',
- pauseTitle : 'Pause slideshow (spacebar)',
- previousTitle : 'Previous (arrow left)',
- nextTitle : 'Next (arrow right)',
- moveTitle : 'Move',
- fullExpandText : '1:1',
- number: 'Image %1 of %2',
- restoreTitle : 'Click to close image, click and drag to move. Use arrow keys for next and previous.'
-},
-// See http://highslide.com/ref for examples of settings
-graphicsDir : '../media/',
-expandCursor : 'zoomin.cur', // null disables
-restoreCursor : 'zoomout.cur', // null disables
-expandDuration : 250, // milliseconds
-restoreDuration : 250,
-marginLeft : 15,
-marginRight : 15,
-marginTop : 15,
-marginBottom : 15,
-zIndexCounter : 1001, // adjust to other absolutely positioned elements
-loadingOpacity : 0.75,
-allowMultipleInstances: true,
-numberOfImagesToPreload : 5,
-outlineWhileAnimating : 2, // 0 = never, 1 = always, 2 = HTML only
-outlineStartOffset : 3, // ends at 10
-padToMinWidth : false, // pad the popup width to make room for wide caption
-fullExpandPosition : 'bottom right',
-fullExpandOpacity : 1,
-showCredits : true, // you can set this to false if you want
-creditsHref : 'http://highslide.com/',
-creditsTarget : '_self',
-enableKeyListener : true,
-openerTagNames : ['a', 'area'], // Add more to allow slideshow indexing
-transitions : [],
-transitionDuration: 250,
-dimmingOpacity: 0, // Lightbox style dimming background
-dimmingDuration: 50, // 0 for instant dimming
-
-allowWidthReduction : false,
-allowHeightReduction : true,
-preserveContent : true, // Preserve changes made to the content and position of HTML popups.
-objectLoadTime : 'before', // Load iframes 'before' or 'after' expansion.
-cacheAjax : true, // Cache ajax popups for instant display. Can be overridden for each popup.
-anchor : 'auto', // where the image expands from
-align : 'auto', // position in the client (overrides anchor)
-targetX: null, // the id of a target element
-targetY: null,
-dragByHeading: true,
-minWidth: 200,
-minHeight: 200,
-allowSizeReduction: true, // allow the image to reduce to fit client size. If false, this overrides minWidth and minHeight
-outlineType : 'drop-shadow', // set null to disable outlines
-skin : {
- controls:
- '<div class="highslide-controls"><ul>'+
- '<li class="highslide-previous">'+
- '<a href="#" title="{hs.lang.previousTitle}">'+
- '<span>{hs.lang.previousText}</span></a>'+
- '</li>'+
- '<li class="highslide-play">'+
- '<a href="#" title="{hs.lang.playTitle}">'+
- '<span>{hs.lang.playText}</span></a>'+
- '</li>'+
- '<li class="highslide-pause">'+
- '<a href="#" title="{hs.lang.pauseTitle}">'+
- '<span>{hs.lang.pauseText}</span></a>'+
- '</li>'+
- '<li class="highslide-next">'+
- '<a href="#" title="{hs.lang.nextTitle}">'+
- '<span>{hs.lang.nextText}</span></a>'+
- '</li>'+
- '<li class="highslide-move">'+
- '<a href="#" title="{hs.lang.moveTitle}">'+
- '<span>{hs.lang.moveText}</span></a>'+
- '</li>'+
- '<li class="highslide-full-expand">'+
- '<a href="#" title="{hs.lang.fullExpandTitle}">'+
- '<span>{hs.lang.fullExpandText}</span></a>'+
- '</li>'+
- '<li class="highslide-close">'+
- '<a href="#" title="{hs.lang.closeTitle}" >'+
- '<span>{hs.lang.closeText}</span></a>'+
- '</li>'+
- '</ul></div>'
- ,
- contentWrapper:
- '<div class="highslide-header"><ul>'+
- '<li class="highslide-previous">'+
- '<a href="#" title="{hs.lang.previousTitle}" onclick="return hs.previous(this)">'+
- '<span>{hs.lang.previousText}</span></a>'+
- '</li>'+
- '<li class="highslide-next">'+
- '<a href="#" title="{hs.lang.nextTitle}" onclick="return hs.next(this)">'+
- '<span>{hs.lang.nextText}</span></a>'+
- '</li>'+
- '<li class="highslide-move">'+
- '<a href="#" title="{hs.lang.moveTitle}" onclick="return false">'+
- '<span>{hs.lang.moveText}</span></a>'+
- '</li>'+
- '<li class="highslide-close">'+
- '<a href="#" title="{hs.lang.closeTitle}" onclick="return hs.close(this)">'+
- '<span>{hs.lang.closeText}</span></a>'+
- '</li>'+
- '</ul></div>'+
- '<div class="highslide-body"></div>'+
- '<div class="highslide-footer"><div>'+
- '<span class="highslide-resize" title="{hs.lang.resizeTitle}"><span></span></span>'+
- '</div></div>'
-},
-// END OF YOUR SETTINGS
-
-
-// declare internal properties
-preloadTheseImages : [],
-continuePreloading: true,
-expanders : [],
-overrides : [
- 'allowSizeReduction',
- 'useBox',
- 'anchor',
- 'align',
- 'targetX',
- 'targetY',
- 'outlineType',
- 'outlineWhileAnimating',
- 'captionId',
- 'captionText',
- 'captionEval',
- 'captionOverlay',
- 'headingId',
- 'headingText',
- 'headingEval',
- 'headingOverlay',
- 'creditsPosition',
- 'dragByHeading',
- 'autoplay',
- 'numberPosition',
- 'transitions',
- 'dimmingOpacity',
-
- 'width',
- 'height',
-
- 'contentId',
- 'allowWidthReduction',
- 'allowHeightReduction',
- 'preserveContent',
- 'maincontentId',
- 'maincontentText',
- 'maincontentEval',
- 'objectType',
- 'cacheAjax',
- 'objectWidth',
- 'objectHeight',
- 'objectLoadTime',
- 'swfOptions',
- 'wrapperClassName',
- 'minWidth',
- 'minHeight',
- 'maxWidth',
- 'maxHeight',
- 'pageOrigin',
- 'slideshowGroup',
- 'easing',
- 'easingClose',
- 'fadeInOut',
- 'src'
-],
-overlays : [],
-idCounter : 0,
-oPos : {
- x: ['leftpanel', 'left', 'center', 'right', 'rightpanel'],
- y: ['above', 'top', 'middle', 'bottom', 'below']
-},
-mouse: {},
-headingOverlay: {},
-captionOverlay: {},
-swfOptions: { flashvars: {}, params: {}, attributes: {} },
-timers : [],
-
-slideshows : [],
-
-pendingOutlines : {},
-sleeping : [],
-preloadTheseAjax : [],
-cacheBindings : [],
-cachedGets : {},
-clones : {},
-onReady: [],
-uaVersion: /Trident\/4\.0/.test(navigator.userAgent) ? 8 :
- parseFloat((navigator.userAgent.toLowerCase().match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1]),
-ie : (document.all && !window.opera),
-safari : /Safari/.test(navigator.userAgent),
-geckoMac : /Macintosh.+rv:1\.[0-8].+Gecko/.test(navigator.userAgent),
-
-$ : function (id) {
- if (id) return document.getElementById(id);
-},
-
-push : function (arr, val) {
- arr[arr.length] = val;
-},
-
-createElement : function (tag, attribs, styles, parent, nopad) {
- var el = document.createElement(tag);
- if (attribs) hs.extend(el, attribs);
- if (nopad) hs.setStyles(el, {padding: 0, border: 'none', margin: 0});
- if (styles) hs.setStyles(el, styles);
- if (parent) parent.appendChild(el);
- return el;
-},
-
-extend : function (el, attribs) {
- for (var x in attribs) el[x] = attribs[x];
- return el;
-},
-
-setStyles : function (el, styles) {
- for (var x in styles) {
- if (hs.ie && x == 'opacity') {
- if (styles[x] > 0.99) el.style.removeAttribute('filter');
- else el.style.filter = 'alpha(opacity='+ (styles[x] * 100) +')';
- }
- else el.style[x] = styles[x];
- }
-},
-animate: function(el, prop, opt) {
- var start,
- end,
- unit;
- if (typeof opt != 'object' || opt === null) {
- var args = arguments;
- opt = {
- duration: args[2],
- easing: args[3],
- complete: args[4]
- };
- }
- if (typeof opt.duration != 'number') opt.duration = 250;
- opt.easing = Math[opt.easing] || Math.easeInQuad;
- opt.curAnim = hs.extend({}, prop);
- for (var name in prop) {
- var e = new hs.fx(el, opt , name );
-
- start = parseFloat(hs.css(el, name)) || 0;
- end = parseFloat(prop[name]);
- unit = name != 'opacity' ? 'px' : '';
-
- e.custom( start, end, unit );
- }
-},
-css: function(el, prop) {
- if (el.style[prop]) {
- return el.style[prop];
- } else if (document.defaultView) {
- return document.defaultView.getComputedStyle(el, null).getPropertyValue(prop);
-
- } else {
- if (prop == 'opacity') prop = 'filter';
- var val = el.currentStyle[prop.replace(/\-(\w)/g, function (a, b){ return b.toUpperCase(); })];
- if (prop == 'filter')
- val = val.replace(/alpha\(opacity=([0-9]+)\)/,
- function (a, b) { return b / 100 });
- return val === '' ? 1 : val;
- }
-},
-
-getPageSize : function () {
- var d = document, w = window, iebody = d.compatMode && d.compatMode != 'BackCompat'
- ? d.documentElement : d.body;
-
- var width = hs.ie ? iebody.clientWidth :
- (d.documentElement.clientWidth || self.innerWidth),
- height = hs.ie ? iebody.clientHeight : self.innerHeight;
-
- hs.page = {
- width: width,
- height: height,
- scrollLeft: hs.ie ? iebody.scrollLeft : pageXOffset,
- scrollTop: hs.ie ? iebody.scrollTop : pageYOffset
- };
- return hs.page;
-},
-
-getPosition : function(el) {
- if (/area/i.test(el.tagName)) {
- var imgs = document.getElementsByTagName('img');
- for (var i = 0; i < imgs.length; i++) {
- var u = imgs[i].useMap;
- if (u && u.replace(/^.*?#/, '') == el.parentNode.name) {
- el = imgs[i];
- break;
- }
- }
- }
- var p = { x: el.offsetLeft, y: el.offsetTop };
- while (el.offsetParent) {
- el = el.offsetParent;
- p.x += el.offsetLeft;
- p.y += el.offsetTop;
- if (el != document.body && el != document.documentElement) {
- p.x -= el.scrollLeft;
- p.y -= el.scrollTop;
- }
- }
- return p;
-},
-
-expand : function(a, params, custom, type) {
- if (!a) a = hs.createElement('a', null, { display: 'none' }, hs.container);
- if (typeof a.getParams == 'function') return params;
- if (type == 'html') {
- for (var i = 0; i < hs.sleeping.length; i++) {
- if (hs.sleeping[i] && hs.sleeping[i].a == a) {
- hs.sleeping[i].awake();
- hs.sleeping[i] = null;
- return false;
- }
- }
- hs.hasHtmlExpanders = true;
- }
- try {
- new hs.Expander(a, params, custom, type);
- return false;
- } catch (e) { return true; }
-},
-
-htmlExpand : function(a, params, custom) {
- return hs.expand(a, params, custom, 'html');
-},
-
-getSelfRendered : function() {
- return hs.createElement('div', {
- className: 'highslide-html-content',
- innerHTML: hs.replaceLang(hs.skin.contentWrapper)
- });
-},
-getElementByClass : function (el, tagName, className) {
- var els = el.getElementsByTagName(tagName);
- for (var i = 0; i < els.length; i++) {
- if ((new RegExp(className)).test(els[i].className)) {
- return els[i];
- }
- }
- return null;
-},
-replaceLang : function(s) {
- s = s.replace(/\s/g, ' ');
- var re = /{hs\.lang\.([^}]+)\}/g,
- matches = s.match(re),
- lang;
- if (matches) for (var i = 0; i < matches.length; i++) {
- lang = matches[i].replace(re, "$1");
- if (typeof hs.lang[lang] != 'undefined') s = s.replace(matches[i], hs.lang[lang]);
- }
- return s;
-},
-
-
-setClickEvents : function () {
- var els = document.getElementsByTagName('a');
- for (var i = 0; i < els.length; i++) {
- var type = hs.isUnobtrusiveAnchor(els[i]);
- if (type && !els[i].hsHasSetClick) {
- (function(){
- var t = type;
- if (hs.fireEvent(hs, 'onSetClickEvent', { element: els[i], type: t })) {
- els[i].onclick =(type == 'image') ?function() { return hs.expand(this) }:
- function() { return hs.htmlExpand(this, { objectType: t } );};
- }
- })();
- els[i].hsHasSetClick = true;
- }
- }
- hs.getAnchors();
-},
-isUnobtrusiveAnchor: function(el) {
- if (el.rel == 'highslide') return 'image';
- else if (el.rel == 'highslide-ajax') return 'ajax';
- else if (el.rel == 'highslide-iframe') return 'iframe';
- else if (el.rel == 'highslide-swf') return 'swf';
-},
-
-getCacheBinding : function (a) {
- for (var i = 0; i < hs.cacheBindings.length; i++) {
- if (hs.cacheBindings[i][0] == a) {
- var c = hs.cacheBindings[i][1];
- hs.cacheBindings[i][1] = c.cloneNode(1);
- return c;
- }
- }
- return null;
-},
-
-preloadAjax : function (e) {
- var arr = hs.getAnchors();
- for (var i = 0; i < arr.htmls.length; i++) {
- var a = arr.htmls[i];
- if (hs.getParam(a, 'objectType') == 'ajax' && hs.getParam(a, 'cacheAjax'))
- hs.push(hs.preloadTheseAjax, a);
- }
-
- hs.preloadAjaxElement(0);
-},
-
-preloadAjaxElement : function (i) {
- if (!hs.preloadTheseAjax[i]) return;
- var a = hs.preloadTheseAjax[i];
- var cache = hs.getNode(hs.getParam(a, 'contentId'));
- if (!cache) cache = hs.getSelfRendered();
- var ajax = new hs.Ajax(a, cache, 1);
- ajax.onError = function () { };
- ajax.onLoad = function () {
- hs.push(hs.cacheBindings, [a, cache]);
- hs.preloadAjaxElement(i + 1);
- };
- ajax.run();
-},
-
-focusTopmost : function() {
- var topZ = 0,
- topmostKey = -1,
- expanders = hs.expanders,
- exp,
- zIndex;
- for (var i = 0; i < expanders.length; i++) {
- exp = expanders[i];
- if (exp) {
- zIndex = exp.wrapper.style.zIndex;
- if (zIndex && zIndex > topZ) {
- topZ = zIndex;
- topmostKey = i;
- }
- }
- }
- if (topmostKey == -1) hs.focusKey = -1;
- else expanders[topmostKey].focus();
-},
-
-getParam : function (a, param) {
- a.getParams = a.onclick;
- var p = a.getParams ? a.getParams() : null;
- a.getParams = null;
-
- return (p && typeof p[param] != 'undefined') ? p[param] :
- (typeof hs[param] != 'undefined' ? hs[param] : null);
-},
-
-getSrc : function (a) {
- var src = hs.getParam(a, 'src');
- if (src) return src;
- return a.href;
-},
-
-getNode : function (id) {
- var node = hs.$(id), clone = hs.clones[id], a = {};
- if (!node && !clone) return null;
- if (!clone) {
- clone = node.cloneNode(true);
- clone.id = '';
- hs.clones[id] = clone;
- return node;
- } else {
- return clone.cloneNode(true);
- }
-},
-
-discardElement : function(d) {
- if (d) hs.garbageBin.appendChild(d);
- hs.garbageBin.innerHTML = '';
-},
-dim : function(exp) {
- if (!hs.dimmer) {
- hs.dimmer = hs.createElement ('div', {
- className: 'highslide-dimming highslide-viewport-size',
- owner: '',
- onclick: function() {
- if (hs.fireEvent(hs, 'onDimmerClick'))
-
- hs.close();
- }
- }, {
- visibility: 'visible',
- opacity: 0
- }, hs.container, true);
- }
-
- hs.dimmer.style.display = '';
-
- hs.dimmer.owner += '|'+ exp.key;
- if (hs.geckoMac && hs.dimmingGeckoFix)
- hs.setStyles(hs.dimmer, {
- background: 'url('+ hs.graphicsDir + 'geckodimmer.png)',
- opacity: 1
- });
- else
- hs.animate(hs.dimmer, { opacity: exp.dimmingOpacity }, hs.dimmingDuration);
-},
-undim : function(key) {
- if (!hs.dimmer) return;
- if (typeof key != 'undefined') hs.dimmer.owner = hs.dimmer.owner.replace('|'+ key, '');
-
- if (
- (typeof key != 'undefined' && hs.dimmer.owner != '')
- || (hs.upcoming && hs.getParam(hs.upcoming, 'dimmingOpacity'))
- ) return;
-
- if (hs.geckoMac && hs.dimmingGeckoFix) hs.dimmer.style.display = 'none';
- else hs.animate(hs.dimmer, { opacity: 0 }, hs.dimmingDuration, null, function() {
- hs.dimmer.style.display = 'none';
- });
-},
-transit : function (adj, exp) {
- var last = exp || hs.getExpander();
- exp = last;
- if (hs.upcoming) return false;
- else hs.last = last;
- hs.removeEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);
- try {
- hs.upcoming = adj;
- adj.onclick();
- } catch (e){
- hs.last = hs.upcoming = null;
- }
- try {
- if (!adj || exp.transitions[1] != 'crossfade')
- exp.close();
- } catch (e) {}
- return false;
-},
-
-previousOrNext : function (el, op) {
- var exp = hs.getExpander(el);
- if (exp) return hs.transit(exp.getAdjacentAnchor(op), exp);
- else return false;
-},
-
-previous : function (el) {
- return hs.previousOrNext(el, -1);
-},
-
-next : function (el) {
- return hs.previousOrNext(el, 1);
-},
-
-keyHandler : function(e) {
- if (!e) e = window.event;
- if (!e.target) e.target = e.srcElement; // ie
- if (typeof e.target.form != 'undefined') return true; // form element has focus
- if (!hs.fireEvent(hs, 'onKeyDown', e)) return true;
- var exp = hs.getExpander();
-
- var op = null;
- switch (e.keyCode) {
- case 70: // f
- if (exp) exp.doFullExpand();
- return true;
- case 32: // Space
- op = 2;
- break;
- case 34: // Page Down
- case 39: // Arrow right
- case 40: // Arrow down
- op = 1;
- break;
- case 8: // Backspace
- case 33: // Page Up
- case 37: // Arrow left
- case 38: // Arrow up
- op = -1;
- break;
- case 27: // Escape
- case 13: // Enter
- op = 0;
- }
- if (op !== null) {
- hs.removeEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);
- if (!hs.enableKeyListener) return true;
-
- if (e.preventDefault) e.preventDefault();
- else e.returnValue = false;
- if (exp) {
- if (op == 0) {
- exp.close();
- } else if (op == 2) {
- if (exp.slideshow) exp.slideshow.hitSpace();
- } else {
- if (exp.slideshow) exp.slideshow.pause();
- hs.previousOrNext(exp.key, op);
- }
- return false;
- }
- }
- return true;
-},
-
-
-registerOverlay : function (overlay) {
- hs.push(hs.overlays, hs.extend(overlay, { hsId: 'hsId'+ hs.idCounter++ } ));
-},
-
-
-addSlideshow : function (options) {
- var sg = options.slideshowGroup;
- if (typeof sg == 'object') {
- for (var i = 0; i < sg.length; i++) {
- var o = {};
- for (var x in options) o[x] = options[x];
- o.slideshowGroup = sg[i];
- hs.push(hs.slideshows, o);
- }
- } else {
- hs.push(hs.slideshows, options);
- }
-},
-
-getWrapperKey : function (element, expOnly) {
- var el, re = /^highslide-wrapper-([0-9]+)$/;
- // 1. look in open expanders
- el = element;
- while (el.parentNode) {
- if (el.hsKey !== undefined) return el.hsKey;
- if (el.id && re.test(el.id)) return el.id.replace(re, "$1");
- el = el.parentNode;
- }
- // 2. look in thumbnail
- if (!expOnly) {
- el = element;
- while (el.parentNode) {
- if (el.tagName && hs.isHsAnchor(el)) {
- for (var key = 0; key < hs.expanders.length; key++) {
- var exp = hs.expanders[key];
- if (exp && exp.a == el) return key;
- }
- }
- el = el.parentNode;
- }
- }
- return null;
-},
-
-getExpander : function (el, expOnly) {
- if (typeof el == 'undefined') return hs.expanders[hs.focusKey] || null;
- if (typeof el == 'number') return hs.expanders[el] || null;
- if (typeof el == 'string') el = hs.$(el);
- return hs.expanders[hs.getWrapperKey(el, expOnly)] || null;
-},
-
-isHsAnchor : function (a) {
- return (a.onclick && a.onclick.toString().replace(/\s/g, ' ').match(/hs.(htmlE|e)xpand/));
-},
-
-reOrder : function () {
- for (var i = 0; i < hs.expanders.length; i++)
- if (hs.expanders[i] && hs.expanders[i].isExpanded) hs.focusTopmost();
-},
-fireEvent : function (obj, evt, args) {
- return obj && obj[evt] ? (obj[evt](obj, args) !== false) : true;
-},
-
-mouseClickHandler : function(e)
-{
- if (!e) e = window.event;
- if (e.button > 1) return true;
- if (!e.target) e.target = e.srcElement;
-
- var el = e.target;
- while (el.parentNode
- && !(/highslide-(image|move|html|resize)/.test(el.className)))
- {
- el = el.parentNode;
- }
- var exp = hs.getExpander(el);
- if (exp && (exp.isClosing || !exp.isExpanded)) return true;
-
- if (exp && e.type == 'mousedown') {
- if (e.target.form) return true;
- var match = el.className.match(/highslide-(image|move|resize)/);
- if (match) {
- hs.dragArgs = {
- exp: exp ,
- type: match[1],
- left: exp.x.pos,
- width: exp.x.size,
- top: exp.y.pos,
- height: exp.y.size,
- clickX: e.clientX,
- clickY: e.clientY
- };
-
-
- hs.addEventListener(document, 'mousemove', hs.dragHandler);
- if (e.preventDefault) e.preventDefault(); // FF
-
- if (/highslide-(image|html)-blur/.test(exp.content.className)) {
- exp.focus();
- hs.hasFocused = true;
- }
- return false;
- }
- else if (/highslide-html/.test(el.className) && hs.focusKey != exp.key) {
- exp.focus();
- exp.doShowHide('hidden');
- }
- } else if (e.type == 'mouseup') {
-
- hs.removeEventListener(document, 'mousemove', hs.dragHandler);
-
- if (hs.dragArgs) {
- if (hs.styleRestoreCursor && hs.dragArgs.type == 'image')
- hs.dragArgs.exp.content.style.cursor = hs.styleRestoreCursor;
- var hasDragged = hs.dragArgs.hasDragged;
-
- if (!hasDragged &&!hs.hasFocused && !/(move|resize)/.test(hs.dragArgs.type)) {
- if (hs.fireEvent(exp, 'onImageClick'))
- exp.close();
- }
- else if (hasDragged || (!hasDragged && hs.hasHtmlExpanders)) {
- hs.dragArgs.exp.doShowHide('hidden');
- }
-
- if (hs.dragArgs.exp.releaseMask)
- hs.dragArgs.exp.releaseMask.style.display = 'none';
-
- if (hasDragged) hs.fireEvent(hs.dragArgs.exp, 'onDrop', hs.dragArgs);
- hs.hasFocused = false;
- hs.dragArgs = null;
-
- } else if (/highslide-image-blur/.test(el.className)) {
- el.style.cursor = hs.styleRestoreCursor;
- }
- }
- return false;
-},
-
-dragHandler : function(e)
-{
- if (!hs.dragArgs) return true;
- if (!e) e = window.event;
- var a = hs.dragArgs, exp = a.exp;
- if (exp.iframe) {
- if (!exp.releaseMask) exp.releaseMask = hs.createElement('div', null,
- { position: 'absolute', width: exp.x.size+'px', height: exp.y.size+'px',
- left: exp.x.cb+'px', top: exp.y.cb+'px', zIndex: 4, background: (hs.ie ? 'white' : 'none'),
- opacity: 0.01 },
- exp.wrapper, true);
- if (exp.releaseMask.style.display == 'none')
- exp.releaseMask.style.display = '';
- }
-
- a.dX = e.clientX - a.clickX;
- a.dY = e.clientY - a.clickY;
-
- var distance = Math.sqrt(Math.pow(a.dX, 2) + Math.pow(a.dY, 2));
- if (!a.hasDragged) a.hasDragged = (a.type != 'image' && distance > 0)
- || (distance > (hs.dragSensitivity || 5));
-
- if (a.hasDragged && e.clientX > 5 && e.clientY > 5) {
- if (!hs.fireEvent(exp, 'onDrag', a)) return false;
-
- if (a.type == 'resize') exp.resize(a);
- else {
- exp.moveTo(a.left + a.dX, a.top + a.dY);
- if (a.type == 'image') exp.content.style.cursor = 'move';
- }
- }
- return false;
-},
-
-wrapperMouseHandler : function (e) {
- try {
- if (!e) e = window.event;
- var over = /mouseover/i.test(e.type);
- if (!e.target) e.target = e.srcElement; // ie
- if (hs.ie) e.relatedTarget =
- over ? e.fromElement : e.toElement; // ie
- var exp = hs.getExpander(e.target);
- if (!exp.isExpanded) return;
- if (!exp || !e.relatedTarget || hs.getExpander(e.relatedTarget, true) == exp
- || hs.dragArgs) return;
- hs.fireEvent(exp, over ? 'onMouseOver' : 'onMouseOut', e);
- for (var i = 0; i < exp.overlays.length; i++) (function() {
- var o = hs.$('hsId'+ exp.overlays[i]);
- if (o && o.hideOnMouseOut) {
- if (over) hs.setStyles(o, { visibility: 'visible', display: '' });
- hs.animate(o, { opacity: over ? o.opacity : 0 }, o.dur);
- }
- })();
- } catch (e) {}
-},
-addEventListener : function (el, event, func) {
- if (el == document && event == 'ready') {
- hs.push(hs.onReady, func);
- }
- try {
- el.addEventListener(event, func, false);
- } catch (e) {
- try {
- el.detachEvent('on'+ event, func);
- el.attachEvent('on'+ event, func);
- } catch (e) {
- el['on'+ event] = func;
- }
- }
-},
-
-removeEventListener : function (el, event, func) {
- try {
- el.removeEventListener(event, func, false);
- } catch (e) {
- try {
- el.detachEvent('on'+ event, func);
- } catch (e) {
- el['on'+ event] = null;
- }
- }
-},
-
-preloadFullImage : function (i) {
- if (hs.continuePreloading && hs.preloadTheseImages[i] && hs.preloadTheseImages[i] != 'undefined') {
- var img = document.createElement('img');
- img.onload = function() {
- img = null;
- hs.preloadFullImage(i + 1);
- };
- img.src = hs.preloadTheseImages[i];
- }
-},
-preloadImages : function (number) {
- if (number && typeof number != 'object') hs.numberOfImagesToPreload = number;
-
- var arr = hs.getAnchors();
- for (var i = 0; i < arr.images.length && i < hs.numberOfImagesToPreload; i++) {
- hs.push(hs.preloadTheseImages, hs.getSrc(arr.images[i]));
- }
-
- // preload outlines
- if (hs.outlineType) new hs.Outline(hs.outlineType, function () { hs.preloadFullImage(0)} );
- else
-
- hs.preloadFullImage(0);
-
- // preload cursor
- if (hs.restoreCursor) var cur = hs.createElement('img', { src: hs.graphicsDir + hs.restoreCursor });
-},
-
-
-init : function () {
- if (!hs.container) {
-
- hs.getPageSize();
- hs.ieLt7 = hs.ie && hs.uaVersion < 7;
- hs.ie6SSL = hs.ieLt7 && location.protocol == 'https:';
- for (var x in hs.langDefaults) {
- if (typeof hs[x] != 'undefined') hs.lang[x] = hs[x];
- else if (typeof hs.lang[x] == 'undefined' && typeof hs.langDefaults[x] != 'undefined')
- hs.lang[x] = hs.langDefaults[x];
- }
-
- hs.container = hs.createElement('div', {
- className: 'highslide-container'
- }, {
- position: 'absolute',
- left: 0,
- top: 0,
- width: '100%',
- zIndex: hs.zIndexCounter,
- direction: 'ltr'
- },
- document.body,
- true
- );
- hs.loading = hs.createElement('a', {
- className: 'highslide-loading',
- title: hs.lang.loadingTitle,
- innerHTML: hs.lang.loadingText,
- href: 'javascript:;'
- }, {
- position: 'absolute',
- top: '-9999px',
- opacity: hs.loadingOpacity,
- zIndex: 1
- }, hs.container
- );
- hs.garbageBin = hs.createElement('div', null, { display: 'none' }, hs.container);
- hs.viewport = hs.createElement('div', {
- className: 'highslide-viewport highslide-viewport-size'
- }, {
- visibility: (hs.safari && hs.uaVersion < 525) ? 'visible' : 'hidden'
- }, hs.container, 1
- );
- hs.clearing = hs.createElement('div', null,
- { clear: 'both', paddingTop: '1px' }, null, true);
-
- // http://www.robertpenner.com/easing/
- Math.linearTween = function (t, b, c, d) {
- return c*t/d + b;
- };
- Math.easeInQuad = function (t, b, c, d) {
- return c*(t/=d)*t + b;
- };
- Math.easeOutQuad = function (t, b, c, d) {
- return -c *(t/=d)*(t-2) + b;
- };
-
- hs.hideSelects = hs.ieLt7;
- hs.hideIframes = ((window.opera && hs.uaVersion < 9) || navigator.vendor == 'KDE'
- || (hs.ie && hs.uaVersion < 5.5));
- hs.fireEvent(this, 'onActivate');
- }
-},
-ready : function() {
- if (hs.isReady) return;
- hs.isReady = true;
- for (var i = 0; i < hs.onReady.length; i++) hs.onReady[i]();
-},
-
-updateAnchors : function() {
- var el, els, all = [], images = [], htmls = [],groups = {}, re;
-
- for (var i = 0; i < hs.openerTagNames.length; i++) {
- els = document.getElementsByTagName(hs.openerTagNames[i]);
- for (var j = 0; j < els.length; j++) {
- el = els[j];
- re = hs.isHsAnchor(el);
- if (re) {
- hs.push(all, el);
- if (re[0] == 'hs.expand') hs.push(images, el);
- else if (re[0] == 'hs.htmlExpand') hs.push(htmls, el);
- var g = hs.getParam(el, 'slideshowGroup') || 'none';
- if (!groups[g]) groups[g] = [];
- hs.push(groups[g], el);
- }
- }
- }
- hs.anchors = { all: all, groups: groups, images: images, htmls: htmls };
- return hs.anchors;
-
-},
-
-getAnchors : function() {
- return hs.anchors || hs.updateAnchors();
-},
-
-
-close : function(el) {
- var exp = hs.getExpander(el);
- if (exp) exp.close();
- return false;
-}
-}; // end hs object
-hs.fx = function( elem, options, prop ){
- this.options = options;
- this.elem = elem;
- this.prop = prop;
-
- if (!options.orig) options.orig = {};
-};
-hs.fx.prototype = {
- update: function(){
- (hs.fx.step[this.prop] || hs.fx.step._default)(this);
-
- if (this.options.step)
- this.options.step.call(this.elem, this.now, this);
-
- },
- custom: function(from, to, unit){
- this.startTime = (new Date()).getTime();
- this.start = from;
- this.end = to;
- this.unit = unit;// || this.unit || "px";
- this.now = this.start;
- this.pos = this.state = 0;
-
- var self = this;
- function t(gotoEnd){
- return self.step(gotoEnd);
- }
-
- t.elem = this.elem;
-
- if ( t() && hs.timers.push(t) == 1 ) {
- hs.timerId = setInterval(function(){
- var timers = hs.timers;
-
- for ( var i = 0; i < timers.length; i++ )
- if ( !timers[i]() )
- timers.splice(i--, 1);
-
- if ( !timers.length ) {
- clearInterval(hs.timerId);
- }
- }, 13);
- }
- },
- step: function(gotoEnd){
- var t = (new Date()).getTime();
- if ( gotoEnd || t >= this.options.duration + this.startTime ) {
- this.now = this.end;
- this.pos = this.state = 1;
- this.update();
-
- this.options.curAnim[ this.prop ] = true;
-
- var done = true;
- for ( var i in this.options.curAnim )
- if ( this.options.curAnim[i] !== true )
- done = false;
-
- if ( done ) {
- if (this.options.complete) this.options.complete.call(this.elem);
- }
- return false;
- } else {
- var n = t - this.startTime;
- this.state = n / this.options.duration;
- this.pos = this.options.easing(n, 0, 1, this.options.duration);
- this.now = this.start + ((this.end - this.start) * this.pos);
- this.update();
- }
- return true;
- }
-
-};
-
-hs.extend( hs.fx, {
- step: {
-
- opacity: function(fx){
- hs.setStyles(fx.elem, { opacity: fx.now });
- },
-
- _default: function(fx){
- try {
- if ( fx.elem.style && fx.elem.style[ fx.prop ] != null )
- fx.elem.style[ fx.prop ] = fx.now + fx.unit;
- else
- fx.elem[ fx.prop ] = fx.now;
- } catch (e) {}
- }
- }
-});
-
-hs.Outline = function (outlineType, onLoad) {
- this.onLoad = onLoad;
- this.outlineType = outlineType;
- var v = hs.uaVersion, tr;
-
- this.hasAlphaImageLoader = hs.ie && v >= 5.5 && v < 7;
- if (!outlineType) {
- if (onLoad) onLoad();
- return;
- }
-
- hs.init();
- this.table = hs.createElement(
- 'table', {
- cellSpacing: 0
- }, {
- visibility: 'hidden',
- position: 'absolute',
- borderCollapse: 'collapse',
- width: 0
- },
- hs.container,
- true
- );
- var tbody = hs.createElement('tbody', null, null, this.table, 1);
-
- this.td = [];
- for (var i = 0; i <= 8; i++) {
- if (i % 3 == 0) tr = hs.createElement('tr', null, { height: 'auto' }, tbody, true);
- this.td[i] = hs.createElement('td', null, null, tr, true);
- var style = i != 4 ? { lineHeight: 0, fontSize: 0} : { position : 'relative' };
- hs.setStyles(this.td[i], style);
- }
- this.td[4].className = outlineType +' highslide-outline';
-
- this.preloadGraphic();
-};
-
-hs.Outline.prototype = {
-preloadGraphic : function () {
- var src = hs.graphicsDir + (hs.outlinesDir || "outlines/")+ this.outlineType +".png";
-
- var appendTo = hs.safari ? hs.container : null;
- this.graphic = hs.createElement('img', null, { position: 'absolute',
- top: '-9999px' }, appendTo, true); // for onload trigger
-
- var pThis = this;
- this.graphic.onload = function() { pThis.onGraphicLoad(); };
-
- this.graphic.src = src;
-},
-
-onGraphicLoad : function () {
- var o = this.offset = this.graphic.width / 4,
- pos = [[0,0],[0,-4],[-2,0],[0,-8],0,[-2,-8],[0,-2],[0,-6],[-2,-2]],
- dim = { height: (2*o) +'px', width: (2*o) +'px' };
- for (var i = 0; i <= 8; i++) {
- if (pos[i]) {
- if (this.hasAlphaImageLoader) {
- var w = (i == 1 || i == 7) ? '100%' : this.graphic.width +'px';
- var div = hs.createElement('div', null, { width: '100%', height: '100%', position: 'relative', overflow: 'hidden'}, this.td[i], true);
- hs.createElement ('div', null, {
- filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale, src='"+ this.graphic.src + "')",
- position: 'absolute',
- width: w,
- height: this.graphic.height +'px',
- left: (pos[i][0]*o)+'px',
- top: (pos[i][1]*o)+'px'
- },
- div,
- true);
- } else {
- hs.setStyles(this.td[i], { background: 'url('+ this.graphic.src +') '+ (pos[i][0]*o)+'px '+(pos[i][1]*o)+'px'});
- }
-
- if (window.opera && (i == 3 || i ==5))
- hs.createElement('div', null, dim, this.td[i], true);
-
- hs.setStyles (this.td[i], dim);
- }
- }
- this.graphic = null;
- if (hs.pendingOutlines[this.outlineType]) hs.pendingOutlines[this.outlineType].destroy();
- hs.pendingOutlines[this.outlineType] = this;
- if (this.onLoad) this.onLoad();
-},
-
-setPosition : function (pos, offset, vis, dur, easing) {
- var exp = this.exp,
- stl = exp.wrapper.style,
- offset = offset || 0,
- pos = pos || {
- x: exp.x.pos + offset,
- y: exp.y.pos + offset,
- w: exp.x.get('wsize') - 2 * offset,
- h: exp.y.get('wsize') - 2 * offset
- };
- if (vis) this.table.style.visibility = (pos.h >= 4 * this.offset)
- ? 'visible' : 'hidden';
- hs.setStyles(this.table, {
- left: (pos.x - this.offset) +'px',
- top: (pos.y - this.offset) +'px',
- width: (pos.w + 2 * this.offset) +'px'
- });
-
- pos.w -= 2 * this.offset;
- pos.h -= 2 * this.offset;
- hs.setStyles (this.td[4], {
- width: pos.w >= 0 ? pos.w +'px' : 0,
- height: pos.h >= 0 ? pos.h +'px' : 0
- });
- if (this.hasAlphaImageLoader) this.td[3].style.height
- = this.td[5].style.height = this.td[4].style.height;
-
-},
-
-destroy : function(hide) {
- if (hide) this.table.style.visibility = 'hidden';
- else hs.discardElement(this.table);
-}
-};
-
-hs.Dimension = function(exp, dim) {
- this.exp = exp;
- this.dim = dim;
- this.ucwh = dim == 'x' ? 'Width' : 'Height';
- this.wh = this.ucwh.toLowerCase();
- this.uclt = dim == 'x' ? 'Left' : 'Top';
- this.lt = this.uclt.toLowerCase();
- this.ucrb = dim == 'x' ? 'Right' : 'Bottom';
- this.rb = this.ucrb.toLowerCase();
- this.p1 = this.p2 = 0;
-};
-hs.Dimension.prototype = {
-get : function(key) {
- switch (key) {
- case 'loadingPos':
- return this.tpos + this.tb + (this.t - hs.loading['offset'+ this.ucwh]) / 2;
- case 'loadingPosXfade':
- return this.pos + this.cb+ this.p1 + (this.size - hs.loading['offset'+ this.ucwh]) / 2;
- case 'wsize':
- return this.size + 2 * this.cb + this.p1 + this.p2;
- case 'fitsize':
- return this.clientSize - this.marginMin - this.marginMax;
- case 'maxsize':
- return this.get('fitsize') - 2 * this.cb - this.p1 - this.p2 ;
- case 'opos':
- return this.pos - (this.exp.outline ? this.exp.outline.offset : 0);
- case 'osize':
- return this.get('wsize') + (this.exp.outline ? 2*this.exp.outline.offset : 0);
- case 'imgPad':
- return this.imgSize ? Math.round((this.size - this.imgSize) / 2) : 0;
-
- }
-},
-calcBorders: function() {
- // correct for borders
- this.cb = (this.exp.content['offset'+ this.ucwh] - this.t) / 2;
-
- this.marginMax = hs['margin'+ this.ucrb];
-},
-calcThumb: function() {
- this.t = this.exp.el[this.wh] ? parseInt(this.exp.el[this.wh]) :
- this.exp.el['offset'+ this.ucwh];
- this.tpos = this.exp.tpos[this.dim];
- this.tb = (this.exp.el['offset'+ this.ucwh] - this.t) / 2;
- if (this.tpos == 0 || this.tpos == -1) {
- this.tpos = (hs.page[this.wh] / 2) + hs.page['scroll'+ this.uclt];
- };
-},
-calcExpanded: function() {
- var exp = this.exp;
- this.justify = 'auto';
-
- // get alignment
- if (exp.align == 'center') this.justify = 'center';
- else if (new RegExp(this.lt).test(exp.anchor)) this.justify = null;
- else if (new RegExp(this.rb).test(exp.anchor)) this.justify = 'max';
-
-
- // size and position
- this.pos = this.tpos - this.cb + this.tb;
-
- if (this.maxHeight && this.dim == 'x')
- exp.maxWidth = Math.min(exp.maxWidth || this.full, exp.maxHeight * this.full / exp.y.full);
-
- this.size = Math.min(this.full, exp['max'+ this.ucwh] || this.full);
- this.minSize = exp.allowSizeReduction ?
- Math.min(exp['min'+ this.ucwh], this.full) :this.full;
- if (exp.isImage && exp.useBox) {
- this.size = exp[this.wh];
- this.imgSize = this.full;
- }
- if (this.dim == 'x' && hs.padToMinWidth) this.minSize = exp.minWidth;
- this.target = exp['target'+ this.dim.toUpperCase()];
- this.marginMin = hs['margin'+ this.uclt];
- this.scroll = hs.page['scroll'+ this.uclt];
- this.clientSize = hs.page[this.wh];
-},
-setSize: function(i) {
- var exp = this.exp;
- if (exp.isImage && (exp.useBox || hs.padToMinWidth)) {
- this.imgSize = i;
- this.size = Math.max(this.size, this.imgSize);
- exp.content.style[this.lt] = this.get('imgPad')+'px';
- } else
- this.size = i;
-
- exp.content.style[this.wh] = i +'px';
- exp.wrapper.style[this.wh] = this.get('wsize') +'px';
- if (exp.outline) exp.outline.setPosition();
- if (exp.releaseMask) exp.releaseMask.style[this.wh] = i +'px';
- if (this.dim == 'y' && exp.iDoc && exp.body.style.height != 'auto') try {
- exp.iDoc.body.style.overflow = 'auto';
- } catch (e) {}
- if (exp.isHtml) {
- var d = exp.scrollerDiv;
- if (this.sizeDiff === undefined)
- this.sizeDiff = exp.innerContent['offset'+ this.ucwh] - d['offset'+ this.ucwh];
- d.style[this.wh] = (this.size - this.sizeDiff) +'px';
-
- if (this.dim == 'x') exp.mediumContent.style.width = 'auto';
- if (exp.body) exp.body.style[this.wh] = 'auto';
- }
- if (this.dim == 'x' && exp.overlayBox) exp.sizeOverlayBox(true);
- if (this.dim == 'x' && exp.slideshow && exp.isImage) {
- if (i == this.full) exp.slideshow.disable('full-expand');
- else exp.slideshow.enable('full-expand');
- }
-},
-setPos: function(i) {
- this.pos = i;
- this.exp.wrapper.style[this.lt] = i +'px';
-
- if (this.exp.outline) this.exp.outline.setPosition();
-
-}
-};
-
-hs.Expander = function(a, params, custom, contentType) {
- if (document.readyState && hs.ie && !hs.isReady) {
- hs.addEventListener(document, 'ready', function() {
- new hs.Expander(a, params, custom, contentType);
- });
- return;
- }
- this.a = a;
- this.custom = custom;
- this.contentType = contentType || 'image';
- this.isHtml = (contentType == 'html');
- this.isImage = !this.isHtml;
-
- hs.continuePreloading = false;
- this.overlays = [];
- this.last = hs.last;
- hs.last = null;
- hs.init();
- var key = this.key = hs.expanders.length;
- // override inline parameters
- for (var i = 0; i < hs.overrides.length; i++) {
- var name = hs.overrides[i];
- this[name] = params && typeof params[name] != 'undefined' ?
- params[name] : hs[name];
- }
- if (!this.src) this.src = a.href;
-
- // get thumb
- var el = (params && params.thumbnailId) ? hs.$(params.thumbnailId) : a;
- el = this.thumb = el.getElementsByTagName('img')[0] || el;
- this.thumbsUserSetId = el.id || a.id;
- if (!hs.fireEvent(this, 'onInit')) return true;
-
- // check if already open
- for (var i = 0; i < hs.expanders.length; i++) {
- if (hs.expanders[i] && hs.expanders[i].a == a
- && !(this.last && this.transitions[1] == 'crossfade')) {
- hs.expanders[i].focus();
- return false;
- }
- }
-
- // cancel other
- if (!hs.allowSimultaneousLoading) for (var i = 0; i < hs.expanders.length; i++) {
- if (hs.expanders[i] && hs.expanders[i].thumb != el && !hs.expanders[i].onLoadStarted) {
- hs.expanders[i].cancelLoading();
- }
- }
- hs.expanders[key] = this;
- if (!hs.allowMultipleInstances && !hs.upcoming) {
- if (hs.expanders[key-1]) hs.expanders[key-1].close();
- if (typeof hs.focusKey != 'undefined' && hs.expanders[hs.focusKey])
- hs.expanders[hs.focusKey].close();
- }
-
- // initiate metrics
- this.el = el;
- this.tpos = this.pageOrigin || hs.getPosition(el);
- hs.getPageSize();
- var x = this.x = new hs.Dimension(this, 'x');
- x.calcThumb();
- var y = this.y = new hs.Dimension(this, 'y');
- y.calcThumb();
- if (/area/i.test(el.tagName)) this.getImageMapAreaCorrection(el);
- this.wrapper = hs.createElement(
- 'div', {
- id: 'highslide-wrapper-'+ this.key,
- className: 'highslide-wrapper '+ this.wrapperClassName
- }, {
- visibility: 'hidden',
- position: 'absolute',
- zIndex: hs.zIndexCounter += 2
- }, null, true );
-
- this.wrapper.onmouseover = this.wrapper.onmouseout = hs.wrapperMouseHandler;
- if (this.contentType == 'image' && this.outlineWhileAnimating == 2)
- this.outlineWhileAnimating = 0;
-
- // get the outline
- if (!this.outlineType
- || (this.last && this.isImage && this.transitions[1] == 'crossfade')) {
- this[this.contentType +'Create']();
-
- } else if (hs.pendingOutlines[this.outlineType]) {
- this.connectOutline();
- this[this.contentType +'Create']();
-
- } else {
- this.showLoading();
- var exp = this;
- new hs.Outline(this.outlineType,
- function () {
- exp.connectOutline();
- exp[exp.contentType +'Create']();
- }
- );
- }
- return true;
-};
-
-hs.Expander.prototype = {
-error : function(e) {
- if (hs.debug) alert ('Line '+ e.lineNumber +': '+ e.message);
- else window.location.href = this.src;
-},
-
-connectOutline : function() {
- var outline = this.outline = hs.pendingOutlines[this.outlineType];
- outline.exp = this;
- outline.table.style.zIndex = this.wrapper.style.zIndex - 1;
- hs.pendingOutlines[this.outlineType] = null;
-},
-
-showLoading : function() {
- if (this.onLoadStarted || this.loading) return;
-
- this.loading = hs.loading;
- var exp = this;
- this.loading.onclick = function() {
- exp.cancelLoading();
- };
-
-
- if (!hs.fireEvent(this, 'onShowLoading')) return;
- var exp = this,
- l = this.x.get('loadingPos') +'px',
- t = this.y.get('loadingPos') +'px';
- if (!tgt && this.last && this.transitions[1] == 'crossfade')
- var tgt = this.last;
- if (tgt) {
- l = tgt.x.get('loadingPosXfade') +'px';
- t = tgt.y.get('loadingPosXfade') +'px';
- this.loading.style.zIndex = hs.zIndexCounter++;
- }
- setTimeout(function () {
- if (exp.loading) hs.setStyles(exp.loading, { left: l, top: t, zIndex: hs.zIndexCounter++ })}
- , 100);
-},
-
-imageCreate : function() {
- var exp = this;
-
- var img = document.createElement('img');
- this.content = img;
- img.onload = function () {
- if (hs.expanders[exp.key]) exp.contentLoaded();
- };
- if (hs.blockRightClick) img.oncontextmenu = function() { return false; };
- img.className = 'highslide-image';
- hs.setStyles(img, {
- visibility: 'hidden',
- display: 'block',
- position: 'absolute',
- maxWidth: '9999px',
- zIndex: 3
- });
- img.title = hs.lang.restoreTitle;
- if (hs.safari) hs.container.appendChild(img);
- if (hs.ie && hs.flushImgSize) img.src = null;
- img.src = this.src;
-
- this.showLoading();
-},
-
-htmlCreate : function () {
- if (!hs.fireEvent(this, 'onBeforeGetContent')) return;
-
- this.content = hs.getCacheBinding(this.a);
- if (!this.content)
- this.content = hs.getNode(this.contentId);
- if (!this.content)
- this.content = hs.getSelfRendered();
- this.getInline(['maincontent']);
- if (this.maincontent) {
- var body = hs.getElementByClass(this.content, 'div', 'highslide-body');
- if (body) body.appendChild(this.maincontent);
- this.maincontent.style.display = 'block';
- }
- hs.fireEvent(this, 'onAfterGetContent');
-
- var innerContent = this.innerContent = this.content;
-
- if (/(swf|iframe)/.test(this.objectType)) this.setObjContainerSize(innerContent);
-
- // the content tree
- hs.container.appendChild(this.wrapper);
- hs.setStyles( this.wrapper, {
- position: 'static',
- padding: '0 '+ hs.marginRight +'px 0 '+ hs.marginLeft +'px'
- });
- this.content = hs.createElement(
- 'div', {
- className: 'highslide-html'
- }, {
- position: 'relative',
- zIndex: 3,
- height: 0,
- overflow: 'hidden'
- },
- this.wrapper
- );
- this.mediumContent = hs.createElement('div', null, null, this.content, 1);
- this.mediumContent.appendChild(innerContent);
-
- hs.setStyles (innerContent, {
- position: 'relative',
- display: 'block',
- direction: hs.lang.cssDirection || ''
- });
- if (this.width) innerContent.style.width = this.width +'px';
- if (this.height) hs.setStyles(innerContent, {
- height: this.height +'px',
- overflow: 'hidden'
- });
- if (innerContent.offsetWidth < this.minWidth)
- innerContent.style.width = this.minWidth +'px';
-
-
-
- if (this.objectType == 'ajax' && !hs.getCacheBinding(this.a)) {
- this.showLoading();
- var exp = this;
- var ajax = new hs.Ajax(this.a, innerContent);
- ajax.src = this.src;
- ajax.onLoad = function () { if (hs.expanders[exp.key]) exp.contentLoaded(); };
- ajax.onError = function () { location.href = exp.src; };
- ajax.run();
- }
- else
-
- if (this.objectType == 'iframe' && this.objectLoadTime == 'before') {
- this.writeExtendedContent();
- }
- else
- this.contentLoaded();
-},
-
-contentLoaded : function() {
- try {
- if (!this.content) return;
- this.content.onload = null;
- if (this.onLoadStarted) return;
- else this.onLoadStarted = true;
-
- var x = this.x, y = this.y;
-
- if (this.loading) {
- hs.setStyles(this.loading, { top: '-9999px' });
- this.loading = null;
- hs.fireEvent(this, 'onHideLoading');
- }
- if (this.isImage) {
- x.full = this.content.width;
- y.full = this.content.height;
-
- hs.setStyles(this.content, {
- width: x.t +'px',
- height: y.t +'px'
- });
- this.wrapper.appendChild(this.content);
- hs.container.appendChild(this.wrapper);
- } else if (this.htmlGetSize) this.htmlGetSize();
-
- x.calcBorders();
- y.calcBorders();
-
- hs.setStyles (this.wrapper, {
- left: (x.tpos + x.tb - x.cb) +'px',
- top: (y.tpos + x.tb - y.cb) +'px'
- });
-
-
- this.initSlideshow();
- this.getOverlays();
-
- var ratio = x.full / y.full;
- x.calcExpanded();
- this.justify(x);
-
- y.calcExpanded();
- this.justify(y);
- if (this.isHtml) this.htmlSizeOperations();
- if (this.overlayBox) this.sizeOverlayBox(0, 1);
-
-
- if (this.allowSizeReduction) {
- if (this.isImage)
- this.correctRatio(ratio);
- else this.fitOverlayBox();
- var ss = this.slideshow;
- if (ss && this.last && ss.controls && ss.fixedControls) {
- var pos = ss.overlayOptions.position || '', p;
- for (var dim in hs.oPos) for (var i = 0; i < 5; i++) {
- p = this[dim];
- if (pos.match(hs.oPos[dim][i])) {
- p.pos = this.last[dim].pos
- + (this.last[dim].p1 - p.p1)
- + (this.last[dim].size - p.size) * [0, 0, .5, 1, 1][i];
- if (ss.fixedControls == 'fit') {
- if (p.pos + p.size + p.p1 + p.p2 > p.scroll + p.clientSize - p.marginMax)
- p.pos = p.scroll + p.clientSize - p.size - p.marginMin - p.marginMax - p.p1 - p.p2;
- if (p.pos < p.scroll + p.marginMin) p.pos = p.scroll + p.marginMin;
- }
- }
- }
- }
- if (this.isImage && this.x.full > (this.x.imgSize || this.x.size)) {
- this.createFullExpand();
- if (this.overlays.length == 1) this.sizeOverlayBox();
- }
- }
- this.show();
-
- } catch (e) {
- this.error(e);
- }
-},
-
-
-setObjContainerSize : function(parent, auto) {
- var c = hs.getElementByClass(parent, 'DIV', 'highslide-body');
- if (/(iframe|swf)/.test(this.objectType)) {
- if (this.objectWidth) c.style.width = this.objectWidth +'px';
- if (this.objectHeight) c.style.height = this.objectHeight +'px';
- }
-},
-
-writeExtendedContent : function () {
- if (this.hasExtendedContent) return;
- var exp = this;
- this.body = hs.getElementByClass(this.innerContent, 'DIV', 'highslide-body');
- if (this.objectType == 'iframe') {
- this.showLoading();
- var ruler = hs.clearing.cloneNode(1);
- this.body.appendChild(ruler);
- this.newWidth = this.innerContent.offsetWidth;
- if (!this.objectWidth) this.objectWidth = ruler.offsetWidth;
- var hDiff = this.innerContent.offsetHeight - this.body.offsetHeight,
- h = this.objectHeight || hs.page.height - hDiff - hs.marginTop - hs.marginBottom,
- onload = this.objectLoadTime == 'before' ?
- ' onload="if (hs.expanders['+ this.key +']) hs.expanders['+ this.key +'].contentLoaded()" ' : '';
- this.body.innerHTML += '<iframe name="hs'+ (new Date()).getTime() +'" frameborder="0" key="'+ this.key +'" '
- +' style="width:'+ this.objectWidth +'px; height:'+ h +'px" '
- + onload +' src="'+ this.src +'" ></iframe>';
- this.ruler = this.body.getElementsByTagName('div')[0];
- this.iframe = this.body.getElementsByTagName('iframe')[0];
-
- if (this.objectLoadTime == 'after') this.correctIframeSize();
-
- }
- if (this.objectType == 'swf') {
- this.body.id = this.body.id || 'hs-flash-id-' + this.key;
- var a = this.swfOptions;
- if (!a.params) a.params = {};
- if (typeof a.params.wmode == 'undefined') a.params.wmode = 'transparent';
- if (swfobject) swfobject.embedSWF(this.src, this.body.id, this.objectWidth, this.objectHeight,
- a.version || '7', a.expressInstallSwfurl, a.flashvars, a.params, a.attributes);
- }
- this.hasExtendedContent = true;
-},
-htmlGetSize : function() {
- if (this.iframe && !this.objectHeight) { // loadtime before
- this.iframe.style.height = this.body.style.height = this.getIframePageHeight() +'px';
- }
- this.innerContent.appendChild(hs.clearing);
- if (!this.x.full) this.x.full = this.innerContent.offsetWidth;
- this.y.full = this.innerContent.offsetHeight;
- this.innerContent.removeChild(hs.clearing);
- if (hs.ie && this.newHeight > parseInt(this.innerContent.currentStyle.height)) { // ie css bug
- this.newHeight = parseInt(this.innerContent.currentStyle.height);
- }
- hs.setStyles( this.wrapper, { position: 'absolute', padding: '0'});
- hs.setStyles( this.content, { width: this.x.t +'px', height: this.y.t +'px'});
-
-},
-
-getIframePageHeight : function() {
- var h;
- try {
- var doc = this.iDoc = this.iframe.contentDocument || this.iframe.contentWindow.document;
- var clearing = doc.createElement('div');
- clearing.style.clear = 'both';
- doc.body.appendChild(clearing);
- h = clearing.offsetTop;
- if (hs.ie) h += parseInt(doc.body.currentStyle.marginTop)
- + parseInt(doc.body.currentStyle.marginBottom) - 1;
- } catch (e) { // other domain
- h = 300;
- }
- return h;
-},
-correctIframeSize : function () {
- var wDiff = this.innerContent.offsetWidth - this.ruler.offsetWidth;
- hs.discardElement(this.ruler);
- if (wDiff < 0) wDiff = 0;
-
- var hDiff = this.innerContent.offsetHeight - this.iframe.offsetHeight;
- if (this.iDoc && !this.objectHeight && !this.height && this.y.size == this.y.full) try {
- this.iDoc.body.style.overflow = 'hidden';
- } catch (e) {}
- hs.setStyles(this.iframe, {
- width: Math.abs(this.x.size - wDiff) +'px',
- height: Math.abs(this.y.size - hDiff) +'px'
- });
- hs.setStyles(this.body, {
- width: this.iframe.style.width,
- height: this.iframe.style.height
- });
-
- this.scrollingContent = this.iframe;
- this.scrollerDiv = this.scrollingContent;
-
-},
-htmlSizeOperations : function () {
-
- this.setObjContainerSize(this.innerContent);
-
-
- if (this.objectType == 'swf' && this.objectLoadTime == 'before') this.writeExtendedContent();
-
- // handle minimum size
- if (this.x.size < this.x.full && !this.allowWidthReduction) this.x.size = this.x.full;
- if (this.y.size < this.y.full && !this.allowHeightReduction) this.y.size = this.y.full;
- this.scrollerDiv = this.innerContent;
- hs.setStyles(this.mediumContent, {
- position: 'relative',
- width: this.x.size +'px'
- });
- hs.setStyles(this.innerContent, {
- border: 'none',
- width: 'auto',
- height: 'auto'
- });
- var node = hs.getElementByClass(this.innerContent, 'DIV', 'highslide-body');
- if (node && !/(iframe|swf)/.test(this.objectType)) {
- var cNode = node; // wrap to get true size
- node = hs.createElement(cNode.nodeName, null, {overflow: 'hidden'}, null, true);
- cNode.parentNode.insertBefore(node, cNode);
- node.appendChild(hs.clearing); // IE6
- node.appendChild(cNode);
-
- var wDiff = this.innerContent.offsetWidth - node.offsetWidth;
- var hDiff = this.innerContent.offsetHeight - node.offsetHeight;
- node.removeChild(hs.clearing);
-
- var kdeBugCorr = hs.safari || navigator.vendor == 'KDE' ? 1 : 0; // KDE repainting bug
- hs.setStyles(node, {
- width: (this.x.size - wDiff - kdeBugCorr) +'px',
- height: (this.y.size - hDiff) +'px',
- overflow: 'auto',
- position: 'relative'
- }
- );
- if (kdeBugCorr && cNode.offsetHeight > node.offsetHeight) {
- node.style.width = (parseInt(node.style.width) + kdeBugCorr) + 'px';
- }
- this.scrollingContent = node;
- this.scrollerDiv = this.scrollingContent;
- }
- if (this.iframe && this.objectLoadTime == 'before') this.correctIframeSize();
- if (!this.scrollingContent && this.y.size < this.mediumContent.offsetHeight) this.scrollerDiv = this.content;
-
- if (this.scrollerDiv == this.content && !this.allowWidthReduction && !/(iframe|swf)/.test(this.objectType)) {
- this.x.size += 17; // room for scrollbars
- }
- if (this.scrollerDiv && this.scrollerDiv.offsetHeight > this.scrollerDiv.parentNode.offsetHeight) {
- setTimeout("try { hs.expanders["+ this.key +"].scrollerDiv.style.overflow = 'auto'; } catch(e) {}",
- hs.expandDuration);
- }
-},
-
-getImageMapAreaCorrection : function(area) {
- var c = area.coords.split(',');
- for (var i = 0; i < c.length; i++) c[i] = parseInt(c[i]);
-
- if (area.shape.toLowerCase() == 'circle') {
- this.x.tpos += c[0] - c[2];
- this.y.tpos += c[1] - c[2];
- this.x.t = this.y.t = 2 * c[2];
- } else {
- var maxX, maxY, minX = maxX = c[0], minY = maxY = c[1];
- for (var i = 0; i < c.length; i++) {
- if (i % 2 == 0) {
- minX = Math.min(minX, c[i]);
- maxX = Math.max(maxX, c[i]);
- } else {
- minY = Math.min(minY, c[i]);
- maxY = Math.max(maxY, c[i]);
- }
- }
- this.x.tpos += minX;
- this.x.t = maxX - minX;
- this.y.tpos += minY;
- this.y.t = maxY - minY;
- }
-},
-justify : function (p, moveOnly) {
- var tgtArr, tgt = p.target, dim = p == this.x ? 'x' : 'y';
-
- if (tgt && tgt.match(/ /)) {
- tgtArr = tgt.split(' ');
- tgt = tgtArr[0];
- }
- if (tgt && hs.$(tgt)) {
- p.pos = hs.getPosition(hs.$(tgt))[dim];
- if (tgtArr && tgtArr[1] && tgtArr[1].match(/^[-]?[0-9]+px$/))
- p.pos += parseInt(tgtArr[1]);
- if (p.size < p.minSize) p.size = p.minSize;
-
- } else if (p.justify == 'auto' || p.justify == 'center') {
-
- var hasMovedMin = false;
-
- var allowReduce = p.exp.allowSizeReduction;
- if (p.justify == 'center')
- p.pos = Math.round(p.scroll + (p.clientSize + p.marginMin - p.marginMax - p.get('wsize')) / 2);
- else
- p.pos = Math.round(p.pos - ((p.get('wsize') - p.t) / 2));
- if (p.pos < p.scroll + p.marginMin) {
- p.pos = p.scroll + p.marginMin;
- hasMovedMin = true;
- }
- if (!moveOnly && p.size < p.minSize) {
- p.size = p.minSize;
- allowReduce = false;
- }
- if (p.pos + p.get('wsize') > p.scroll + p.clientSize - p.marginMax) {
- if (!moveOnly && hasMovedMin && allowReduce) {
- p.size = Math.min(p.size, p.get(dim == 'y' ? 'fitsize' : 'maxsize'));
- } else if (p.get('wsize') < p.get('fitsize')) {
- p.pos = p.scroll + p.clientSize - p.marginMax - p.get('wsize');
- } else { // image larger than viewport
- p.pos = p.scroll + p.marginMin;
- if (!moveOnly && allowReduce) p.size = p.get(dim == 'y' ? 'fitsize' : 'maxsize');
- }
- }
-
- if (!moveOnly && p.size < p.minSize) {
- p.size = p.minSize;
- allowReduce = false;
- }
-
-
- } else if (p.justify == 'max') {
- p.pos = Math.floor(p.pos - p.size + p.t);
- }
-
-
- if (p.pos < p.marginMin) {
- var tmpMin = p.pos;
- p.pos = p.marginMin;
-
- if (allowReduce && !moveOnly) p.size = p.size - (p.pos - tmpMin);
-
- }
-},
-
-correctRatio : function(ratio) {
- var x = this.x,
- y = this.y,
- changed = false,
- xSize = Math.min(x.full, x.size),
- ySize = Math.min(y.full, y.size),
- useBox = (this.useBox || hs.padToMinWidth);
-
- if (xSize / ySize > ratio) { // width greater
- xSize = ySize * ratio;
- if (xSize < x.minSize) { // below minWidth
- xSize = x.minSize;
- ySize = xSize / ratio;
- }
- changed = true;
-
- } else if (xSize / ySize < ratio) { // height greater
- ySize = xSize / ratio;
- changed = true;
- }
-
- if (hs.padToMinWidth && x.full < x.minSize) {
- x.imgSize = x.full;
- y.size = y.imgSize = y.full;
- } else if (this.useBox) {
- x.imgSize = xSize;
- y.imgSize = ySize;
- } else {
- x.size = xSize;
- y.size = ySize;
- }
- changed = this.fitOverlayBox(useBox ? null : ratio, changed);
- if (useBox && y.size < y.imgSize) {
- y.imgSize = y.size;
- x.imgSize = y.size * ratio;
- }
- if (changed || useBox) {
- x.pos = x.tpos - x.cb + x.tb;
- x.minSize = x.size;
- this.justify(x, true);
-
- y.pos = y.tpos - y.cb + y.tb;
- y.minSize = y.size;
- this.justify(y, true);
- if (this.overlayBox) this.sizeOverlayBox();
- }
-},
-fitOverlayBox : function(ratio, changed) {
- var x = this.x, y = this.y;
- if (this.overlayBox && (this.isImage || this.allowHeightReduction)) {
- while (y.size > this.minHeight && x.size > this.minWidth
- && y.get('wsize') > y.get('fitsize')) {
- y.size -= 10;
- if (ratio) x.size = y.size * ratio;
- this.sizeOverlayBox(0, 1);
- changed = true;
- }
- }
- return changed;
-},
-
-reflow : function () {
- if (this.scrollerDiv) {
- var h = /iframe/i.test(this.scrollerDiv.tagName) ? (this.getIframePageHeight() + 1) +'px' : 'auto';
- if (this.body) this.body.style.height = h;
- this.scrollerDiv.style.height = h;
- this.y.setSize(this.innerContent.offsetHeight);
- }
-},
-
-show : function () {
- var x = this.x, y = this.y;
- this.doShowHide('hidden');
- hs.fireEvent(this, 'onBeforeExpand');
- if (this.slideshow && this.slideshow.thumbstrip) this.slideshow.thumbstrip.selectThumb();
-
- // Apply size change
- this.changeSize(
- 1, {
- wrapper: {
- width : x.get('wsize'),
- height : y.get('wsize'),
- left: x.pos,
- top: y.pos
- },
- content: {
- left: x.p1 + x.get('imgPad'),
- top: y.p1 + y.get('imgPad'),
- width:x.imgSize ||x.size,
- height:y.imgSize ||y.size
- }
- },
- hs.expandDuration
- );
-},
-
-changeSize : function(up, to, dur) {
- // transition
- var trans = this.transitions,
- other = up ? (this.last ? this.last.a : null) : hs.upcoming,
- t = (trans[1] && other
- && hs.getParam(other, 'transitions')[1] == trans[1]) ?
- trans[1] : trans[0];
-
- if (this[t] && t != 'expand') {
- this[t](up, to);
- return;
- }
-
- if (this.outline && !this.outlineWhileAnimating) {
- if (up) this.outline.setPosition();
- else this.outline.destroy(
- (this.isHtml && this.preserveContent));
- }
-
-
- if (!up) this.destroyOverlays();
-
- var exp = this,
- x = exp.x,
- y = exp.y,
- easing = this.easing;
- if (!up) easing = this.easingClose || easing;
- var after = up ?
- function() {
-
- if (exp.outline) exp.outline.table.style.visibility = "visible";
- setTimeout(function() {
- exp.afterExpand();
- }, 50);
- } :
- function() {
- exp.afterClose();
- };
- if (up) hs.setStyles( this.wrapper, {
- width: x.t +'px',
- height: y.t +'px'
- });
- if (up && this.isHtml) {
- hs.setStyles(this.wrapper, {
- left: (x.tpos - x.cb + x.tb) +'px',
- top: (y.tpos - y.cb + y.tb) +'px'
- });
- }
- if (this.fadeInOut) {
- hs.setStyles(this.wrapper, { opacity: up ? 0 : 1 });
- hs.extend(to.wrapper, { opacity: up });
- }
- hs.animate( this.wrapper, to.wrapper, {
- duration: dur,
- easing: easing,
- step: function(val, args) {
- if (exp.outline && exp.outlineWhileAnimating && args.prop == 'top') {
- var fac = up ? args.pos : 1 - args.pos;
- var pos = {
- w: x.t + (x.get('wsize') - x.t) * fac,
- h: y.t + (y.get('wsize') - y.t) * fac,
- x: x.tpos + (x.pos - x.tpos) * fac,
- y: y.tpos + (y.pos - y.tpos) * fac
- };
- exp.outline.setPosition(pos, 0, 1);
- }
- if (exp.isHtml) {
- if (args.prop == 'left')
- exp.mediumContent.style.left = (x.pos - val) +'px';
- if (args.prop == 'top')
- exp.mediumContent.style.top = (y.pos - val) +'px';
- }
- }
- });
- hs.animate( this.content, to.content, dur, easing, after);
- if (up) {
- this.wrapper.style.visibility = 'visible';
- this.content.style.visibility = 'visible';
- if (this.isHtml) this.innerContent.style.visibility = 'visible';
- }
-},
-
-
-
-fade : function(up, to) {
- this.outlineWhileAnimating = false;
- var exp = this, t = up ? hs.expandDuration : 0;
-
- if (up) {
- hs.animate(this.wrapper, to.wrapper, 0);
- hs.setStyles(this.wrapper, { opacity: 0, visibility: 'visible' });
- hs.animate(this.content, to.content, 0);
- this.content.style.visibility = 'visible';
-
- hs.animate(this.wrapper, { opacity: 1 }, t, null,
- function() { exp.afterExpand(); });
- }
-
- if (this.outline) {
- this.outline.table.style.zIndex = this.wrapper.style.zIndex;
- var dir = up || -1,
- offset = this.outline.offset,
- startOff = up ? 3 : offset,
- endOff = up? offset : 3;
- for (var i = startOff; dir * i <= dir * endOff; i += dir, t += 25) {
- (function() {
- var o = up ? endOff - i : startOff - i;
- setTimeout(function() {
- exp.outline.setPosition(0, o, 1);
- }, t);
- })();
- }
- }
-
-
- if (up) {}//setTimeout(function() { exp.afterExpand(); }, t+50);
- else {
- setTimeout( function() {
- if (exp.outline) exp.outline.destroy(exp.preserveContent);
-
- exp.destroyOverlays();
-
- hs.animate( exp.wrapper, { opacity: 0 }, hs.restoreDuration, null, function(){
- exp.afterClose();
- });
- }, t);
- }
-},
-crossfade : function (up, to, from) {
- if (!up) return;
- var exp = this,
- last = this.last,
- x = this.x,
- y = this.y,
- lastX = last.x,
- lastY = last.y,
- wrapper = this.wrapper,
- content = this.content,
- overlayBox = this.overlayBox;
- hs.removeEventListener(document, 'mousemove', hs.dragHandler);
-
- hs.setStyles(content, {
- width: (x.imgSize || x.size) +'px',
- height: (y.imgSize || y.size) +'px'
- });
- if (overlayBox) overlayBox.style.overflow = 'visible';
- this.outline = last.outline;
- if (this.outline) this.outline.exp = exp;
- last.outline = null;
- var fadeBox = hs.createElement('div', {
- className: 'highslide-'+ this.contentType
- }, {
- position: 'absolute',
- zIndex: 4,
- overflow: 'hidden',
- display: 'none'
- }
- );
- var names = { oldImg: last, newImg: this };
- for (var n in names) {
- this[n] = names[n].content.cloneNode(1);
- hs.setStyles(this[n], {
- position: 'absolute',
- border: 0,
- visibility: 'visible'
- });
- fadeBox.appendChild(this[n]);
- }
- wrapper.appendChild(fadeBox);
- if (this.isHtml) hs.setStyles(this.mediumContent, {
- left: 0,
- top: 0
- });
- if (overlayBox) {
- overlayBox.className = '';
- wrapper.appendChild(overlayBox);
- }
- fadeBox.style.display = '';
- last.content.style.display = 'none';
-
-
- if (hs.safari) {
- var match = navigator.userAgent.match(/Safari\/([0-9]{3})/);
- if (match && parseInt(match[1]) < 525) this.wrapper.style.visibility = 'visible';
- }
- hs.animate(wrapper, {
- width: x.size
- }, {
- duration: hs.transitionDuration,
- step: function(val, args) {
- var pos = args.pos,
- invPos = 1 - pos;
- var prop,
- size = {},
- props = ['pos', 'size', 'p1', 'p2'];
- for (var n in props) {
- prop = props[n];
- size['x'+ prop] = Math.round(invPos * lastX[prop] + pos * x[prop]);
- size['y'+ prop] = Math.round(invPos * lastY[prop] + pos * y[prop]);
- size.ximgSize = Math.round(
- invPos * (lastX.imgSize || lastX.size) + pos * (x.imgSize || x.size));
- size.ximgPad = Math.round(invPos * lastX.get('imgPad') + pos * x.get('imgPad'));
- size.yimgSize = Math.round(
- invPos * (lastY.imgSize || lastY.size) + pos * (y.imgSize || y.size));
- size.yimgPad = Math.round(invPos * lastY.get('imgPad') + pos * y.get('imgPad'));
- }
- if (exp.outline) exp.outline.setPosition({
- x: size.xpos,
- y: size.ypos,
- w: size.xsize + size.xp1 + size.xp2 + 2 * x.cb,
- h: size.ysize + size.yp1 + size.yp2 + 2 * y.cb
- });
- last.wrapper.style.clip = 'rect('
- + (size.ypos - lastY.pos)+'px, '
- + (size.xsize + size.xp1 + size.xp2 + size.xpos + 2 * lastX.cb - lastX.pos) +'px, '
- + (size.ysize + size.yp1 + size.yp2 + size.ypos + 2 * lastY.cb - lastY.pos) +'px, '
- + (size.xpos - lastX.pos)+'px)';
-
- hs.setStyles(content, {
- top: (size.yp1 + y.get('imgPad')) +'px',
- left: (size.xp1 + x.get('imgPad')) +'px',
- marginTop: (y.pos - size.ypos) +'px',
- marginLeft: (x.pos - size.xpos) +'px'
- });
- hs.setStyles(wrapper, {
- top: size.ypos +'px',
- left: size.xpos +'px',
- width: (size.xp1 + size.xp2 + size.xsize + 2 * x.cb)+ 'px',
- height: (size.yp1 + size.yp2 + size.ysize + 2 * y.cb) + 'px'
- });
- hs.setStyles(fadeBox, {
- width: (size.ximgSize || size.xsize) + 'px',
- height: (size.yimgSize || size.ysize) +'px',
- left: (size.xp1 + size.ximgPad) +'px',
- top: (size.yp1 + size.yimgPad) +'px',
- visibility: 'visible'
- });
-
- hs.setStyles(exp.oldImg, {
- top: (lastY.pos - size.ypos + lastY.p1 - size.yp1 + lastY.get('imgPad') - size.yimgPad)+'px',
- left: (lastX.pos - size.xpos + lastX.p1 - size.xp1 + lastX.get('imgPad') - size.ximgPad)+'px'
- });
-
- hs.setStyles(exp.newImg, {
- opacity: pos,
- top: (y.pos - size.ypos + y.p1 - size.yp1 + y.get('imgPad') - size.yimgPad) +'px',
- left: (x.pos - size.xpos + x.p1 - size.xp1 + x.get('imgPad') - size.ximgPad) +'px'
- });
- if (overlayBox) hs.setStyles(overlayBox, {
- width: size.xsize + 'px',
- height: size.ysize +'px',
- left: (size.xp1 + x.cb) +'px',
- top: (size.yp1 + y.cb) +'px'
- });
- },
- complete: function () {
- wrapper.style.visibility = content.style.visibility = 'visible';
- content.style.display = 'block';
- hs.discardElement(fadeBox);
- exp.afterExpand();
- last.afterClose();
- exp.last = null;
- }
-
- });
-},
-reuseOverlay : function(o, el) {
- if (!this.last) return false;
- for (var i = 0; i < this.last.overlays.length; i++) {
- var oDiv = hs.$('hsId'+ this.last.overlays[i]);
- if (oDiv && oDiv.hsId == o.hsId) {
- this.genOverlayBox();
- oDiv.reuse = this.key;
- hs.push(this.overlays, this.last.overlays[i]);
- return true;
- }
- }
- return false;
-},
-
-
-afterExpand : function() {
- this.isExpanded = true;
-
- this.a.className += ' highslide-active-anchor';
- this.focus();
-
- if (this.isHtml && this.objectLoadTime == 'after') this.writeExtendedContent();
- if (this.iframe) {
- try {
- var exp = this,
- doc = this.iframe.contentDocument || this.iframe.contentWindow.document;
- hs.addEventListener(doc, 'mousedown', function () {
- if (hs.focusKey != exp.key) exp.focus();
- });
- } catch(e) {}
- if (hs.ie && typeof this.isClosing != 'boolean') // first open
- this.iframe.style.width = (this.objectWidth - 1) +'px'; // hasLayout
- }
- if (this.dimmingOpacity) hs.dim(this);
- if (hs.upcoming && hs.upcoming == this.a) hs.upcoming = null;
- this.prepareNextOutline();
- var p = hs.page, mX = hs.mouse.x + p.scrollLeft, mY = hs.mouse.y + p.scrollTop;
- this.mouseIsOver = this.x.pos < mX && mX < this.x.pos + this.x.get('wsize')
- && this.y.pos < mY && mY < this.y.pos + this.y.get('wsize');
- if (this.overlayBox) this.showOverlays();
- hs.fireEvent(this, 'onAfterExpand');
-
-},
-
-
-prepareNextOutline : function() {
- var key = this.key;
- var outlineType = this.outlineType;
- new hs.Outline(outlineType,
- function () { try { hs.expanders[key].preloadNext(); } catch (e) {} });
-},
-
-
-preloadNext : function() {
- var next = this.getAdjacentAnchor(1);
- if (next && next.onclick.toString().match(/hs\.expand/))
- var img = hs.createElement('img', { src: hs.getSrc(next) });
-},
-
-
-getAdjacentAnchor : function(op) {
- var current = this.getAnchorIndex(), as = hs.anchors.groups[this.slideshowGroup || 'none'];
-
- /*< ? if ($cfg->slideshow) : ?>s*/
- if (!as[current + op] && this.slideshow && this.slideshow.repeat) {
- if (op == 1) return as[0];
- else if (op == -1) return as[as.length-1];
- }
- /*< ? endif ?>s*/
- return as[current + op] || null;
-},
-
-getAnchorIndex : function() {
- var arr = hs.getAnchors().groups[this.slideshowGroup || 'none'];
- if (arr) for (var i = 0; i < arr.length; i++) {
- if (arr[i] == this.a) return i;
- }
- return null;
-},
-
-
-getNumber : function() {
- if (this[this.numberPosition]) {
- var arr = hs.anchors.groups[this.slideshowGroup || 'none'];
- if (arr) {
- var s = hs.lang.number.replace('%1', this.getAnchorIndex() + 1).replace('%2', arr.length);
- this[this.numberPosition].innerHTML =
- '<div class="highslide-number">'+ s +'</div>'+ this[this.numberPosition].innerHTML;
- }
- }
-},
-initSlideshow : function() {
- if (!this.last) {
- for (var i = 0; i < hs.slideshows.length; i++) {
- var ss = hs.slideshows[i], sg = ss.slideshowGroup;
- if (typeof sg == 'undefined' || sg === null || sg === this.slideshowGroup)
- this.slideshow = new hs.Slideshow(this.key, ss);
- }
- } else {
- this.slideshow = this.last.slideshow;
- }
- var ss = this.slideshow;
- if (!ss) return;
- var key = ss.expKey = this.key;
-
- ss.checkFirstAndLast();
- ss.disable('full-expand');
- if (ss.controls) {
- this.createOverlay(hs.extend(ss.overlayOptions || {}, {
- overlayId: ss.controls,
- hsId: 'controls',
- zIndex: 5
- }));
- }
- if (ss.thumbstrip) ss.thumbstrip.add(this);
- if (!this.last && this.autoplay) ss.play(true);
- if (ss.autoplay) {
- ss.autoplay = setTimeout(function() {
- hs.next(key);
- }, (ss.interval || 500));
- }
-},
-
-cancelLoading : function() {
- hs.discardElement (this.wrapper);
- hs.expanders[this.key] = null;
- if (hs.upcoming == this.a) hs.upcoming = null;
- hs.undim(this.key);
- if (this.loading) hs.loading.style.left = '-9999px';
- hs.fireEvent(this, 'onHideLoading');
-},
-
-writeCredits : function () {
- if (this.credits) return;
- this.credits = hs.createElement('a', {
- href: hs.creditsHref,
- target: hs.creditsTarget,
- className: 'highslide-credits',
- innerHTML: hs.lang.creditsText,
- title: hs.lang.creditsTitle
- });
- this.createOverlay({
- overlayId: this.credits,
- position: this.creditsPosition || 'top left',
- hsId: 'credits'
- });
-},
-
-getInline : function(types, addOverlay) {
- for (var i = 0; i < types.length; i++) {
- var type = types[i], s = null;
- if (type == 'caption' && !hs.fireEvent(this, 'onBeforeGetCaption')) return;
- else if (type == 'heading' && !hs.fireEvent(this, 'onBeforeGetHeading')) return;
- if (!this[type +'Id'] && this.thumbsUserSetId)
- this[type +'Id'] = type +'-for-'+ this.thumbsUserSetId;
- if (this[type +'Id']) this[type] = hs.getNode(this[type +'Id']);
- if (!this[type] && !this[type +'Text'] && this[type +'Eval']) try {
- s = eval(this[type +'Eval']);
- } catch (e) {}
- if (!this[type] && this[type +'Text']) {
- s = this[type +'Text'];
- }
- if (!this[type] && !s) {
- this[type] = hs.getNode(this.a['_'+ type + 'Id']);
- if (!this[type]) {
- var next = this.a.nextSibling;
- while (next && !hs.isHsAnchor(next)) {
- if ((new RegExp('highslide-'+ type)).test(next.className || null)) {
- if (!next.id) this.a['_'+ type + 'Id'] = next.id = 'hsId'+ hs.idCounter++;
- this[type] = hs.getNode(next.id);
- break;
- }
- next = next.nextSibling;
- }
- }
- }
- if (!this[type] && !s && this.numberPosition == type) s = '\n';
-
- if (!this[type] && s) this[type] = hs.createElement('div',
- { className: 'highslide-'+ type, innerHTML: s } );
-
- if (addOverlay && this[type]) {
- var o = { position: (type == 'heading') ? 'above' : 'below' };
- for (var x in this[type+'Overlay']) o[x] = this[type+'Overlay'][x];
- o.overlayId = this[type];
- this.createOverlay(o);
- }
- }
-},
-
-
-// on end move and resize
-doShowHide : function(visibility) {
- if (hs.hideSelects) this.showHideElements('SELECT', visibility);
- if (hs.hideIframes) this.showHideElements('IFRAME', visibility);
- if (hs.geckoMac) this.showHideElements('*', visibility);
-},
-showHideElements : function (tagName, visibility) {
- var els = document.getElementsByTagName(tagName);
- var prop = tagName == '*' ? 'overflow' : 'visibility';
- for (var i = 0; i < els.length; i++) {
- if (prop == 'visibility' || (document.defaultView.getComputedStyle(
- els[i], "").getPropertyValue('overflow') == 'auto'
- || els[i].getAttribute('hidden-by') != null)) {
- var hiddenBy = els[i].getAttribute('hidden-by');
- if (visibility == 'visible' && hiddenBy) {
- hiddenBy = hiddenBy.replace('['+ this.key +']', '');
- els[i].setAttribute('hidden-by', hiddenBy);
- if (!hiddenBy) els[i].style[prop] = els[i].origProp;
- } else if (visibility == 'hidden') { // hide if behind
- var elPos = hs.getPosition(els[i]);
- elPos.w = els[i].offsetWidth;
- elPos.h = els[i].offsetHeight;
- if (!this.dimmingOpacity) { // hide all if dimming
-
- var clearsX = (elPos.x + elPos.w < this.x.get('opos')
- || elPos.x > this.x.get('opos') + this.x.get('osize'));
- var clearsY = (elPos.y + elPos.h < this.y.get('opos')
- || elPos.y > this.y.get('opos') + this.y.get('osize'));
- }
- var wrapperKey = hs.getWrapperKey(els[i]);
- if (!clearsX && !clearsY && wrapperKey != this.key) { // element falls behind image
- if (!hiddenBy) {
- els[i].setAttribute('hidden-by', '['+ this.key +']');
- els[i].origProp = els[i].style[prop];
- els[i].style[prop] = 'hidden';
-
- } else if (hiddenBy.indexOf('['+ this.key +']') == -1) {
- els[i].setAttribute('hidden-by', hiddenBy + '['+ this.key +']');
- }
- } else if ((hiddenBy == '['+ this.key +']' || hs.focusKey == wrapperKey)
- && wrapperKey != this.key) { // on move
- els[i].setAttribute('hidden-by', '');
- els[i].style[prop] = els[i].origProp || '';
- } else if (hiddenBy && hiddenBy.indexOf('['+ this.key +']') > -1) {
- els[i].setAttribute('hidden-by', hiddenBy.replace('['+ this.key +']', ''));
- }
-
- }
- }
- }
-},
-
-focus : function() {
- this.wrapper.style.zIndex = hs.zIndexCounter += 2;
- // blur others
- for (var i = 0; i < hs.expanders.length; i++) {
- if (hs.expanders[i] && i == hs.focusKey) {
- var blurExp = hs.expanders[i];
- blurExp.content.className += ' highslide-'+ blurExp.contentType +'-blur';
- if (blurExp.isImage) {
- blurExp.content.style.cursor = hs.ie ? 'hand' : 'pointer';
- blurExp.content.title = hs.lang.focusTitle;
- }
- hs.fireEvent(blurExp, 'onBlur');
- }
- }
-
- // focus this
- if (this.outline) this.outline.table.style.zIndex
- = this.wrapper.style.zIndex - 1;
- this.content.className = 'highslide-'+ this.contentType;
- if (this.isImage) {
- this.content.title = hs.lang.restoreTitle;
-
- if (hs.restoreCursor) {
- hs.styleRestoreCursor = window.opera ? 'pointer' : 'url('+ hs.graphicsDir + hs.restoreCursor +'), pointer';
- if (hs.ie && hs.uaVersion < 6) hs.styleRestoreCursor = 'hand';
- this.content.style.cursor = hs.styleRestoreCursor;
- }
- }
- hs.focusKey = this.key;
- hs.addEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);
- hs.fireEvent(this, 'onFocus');
-},
-moveTo: function(x, y) {
- this.x.setPos(x);
- this.y.setPos(y);
-},
-resize : function (e) {
- var w, h, r = e.width / e.height;
- w = Math.max(e.width + e.dX, Math.min(this.minWidth, this.x.full));
- if (this.isImage && Math.abs(w - this.x.full) < 12) w = this.x.full;
- h = this.isHtml ? e.height + e.dY : w / r;
- if (h < Math.min(this.minHeight, this.y.full)) {
- h = Math.min(this.minHeight, this.y.full);
- if (this.isImage) w = h * r;
- }
- this.resizeTo(w, h);
-},
-resizeTo: function(w, h) {
- this.y.setSize(h);
- this.x.setSize(w);
- this.wrapper.style.height = this.y.get('wsize') +'px';
-},
-
-close : function() {
- if (this.isClosing || !this.isExpanded) return;
- if (this.transitions[1] == 'crossfade' && hs.upcoming) {
- hs.getExpander(hs.upcoming).cancelLoading();
- hs.upcoming = null;
- }
- if (!hs.fireEvent(this, 'onBeforeClose')) return;
- this.isClosing = true;
- if (this.slideshow && !hs.upcoming) this.slideshow.pause();
-
- hs.removeEventListener(document, window.opera ? 'keypress' : 'keydown', hs.keyHandler);
-
- try {
- if (this.isHtml) this.htmlPrepareClose();
- this.content.style.cursor = 'default';
- this.changeSize(
- 0, {
- wrapper: {
- width : this.x.t,
- height : this.y.t,
- left: this.x.tpos - this.x.cb + this.x.tb,
- top: this.y.tpos - this.y.cb + this.y.tb
- },
- content: {
- left: 0,
- top: 0,
- width: this.x.t,
- height: this.y.t
- }
- }, hs.restoreDuration
- );
- } catch (e) { this.afterClose(); }
-},
-
-htmlPrepareClose : function() {
- if (hs.geckoMac) { // bad redraws
- if (!hs.mask) hs.mask = hs.createElement('div', null,
- { position: 'absolute' }, hs.container);
- hs.setStyles(hs.mask, { width: this.x.size +'px', height: this.y.size +'px',
- left: this.x.pos +'px', top: this.y.pos +'px', display: 'block' });
- }
- if (this.objectType == 'swf') try { hs.$(this.body.id).StopPlay(); } catch (e) {}
-
- if (this.objectLoadTime == 'after' && !this.preserveContent) this.destroyObject();
- if (this.scrollerDiv && this.scrollerDiv != this.scrollingContent)
- this.scrollerDiv.style.overflow = 'hidden';
-},
-
-destroyObject : function () {
- if (hs.ie && this.iframe)
- try { this.iframe.contentWindow.document.body.innerHTML = ''; } catch (e) {}
- if (this.objectType == 'swf') swfobject.removeSWF(this.body.id);
- this.body.innerHTML = '';
-},
-
-sleep : function() {
- if (this.outline) this.outline.table.style.display = 'none';
- this.releaseMask = null;
- this.wrapper.style.display = 'none';
- hs.push(hs.sleeping, this);
-},
-
-awake : function() {try {
-
- hs.expanders[this.key] = this;
-
- if (!hs.allowMultipleInstances &&hs.focusKey != this.key) {
- try { hs.expanders[hs.focusKey].close(); } catch (e){}
- }
-
- var z = hs.zIndexCounter++, stl = { display: '', zIndex: z };
- hs.setStyles (this.wrapper, stl);
- this.isClosing = false;
-
- var o = this.outline || 0;
- if (o) {
- if (!this.outlineWhileAnimating) stl.visibility = 'hidden';
- hs.setStyles (o.table, stl);
- }
- if (this.slideshow) {
- this.initSlideshow();
- }
-
- this.show();
-} catch (e) {}
-
-
-},
-
-createOverlay : function (o) {
- var el = o.overlayId,
- relToVP = (o.relativeTo == 'viewport' && !/panel$/.test(o.position));
- if (typeof el == 'string') el = hs.getNode(el);
- if (o.html) el = hs.createElement('div', { innerHTML: o.html });
- if (!el || typeof el == 'string') return;
- if (!hs.fireEvent(this, 'onCreateOverlay', { overlay: el })) return;
- el.style.display = 'block';
- o.hsId = o.hsId || o.overlayId;
- if (this.transitions[1] == 'crossfade' && this.reuseOverlay(o, el)) return;
- this.genOverlayBox();
- var width = o.width && /^[0-9]+(px|%)$/.test(o.width) ? o.width : 'auto';
- if (/^(left|right)panel$/.test(o.position) && !/^[0-9]+px$/.test(o.width)) width = '200px';
- var overlay = hs.createElement(
- 'div', {
- id: 'hsId'+ hs.idCounter++,
- hsId: o.hsId
- }, {
- position: 'absolute',
- visibility: 'hidden',
- width: width,
- direction: hs.lang.cssDirection || '',
- opacity: 0
- },
- relToVP ? hs.viewport :this.overlayBox,
- true
- );
- if (relToVP) overlay.hsKey = this.key;
-
- overlay.appendChild(el);
- hs.extend(overlay, {
- opacity: 1,
- offsetX: 0,
- offsetY: 0,
- dur: (o.fade === 0 || o.fade === false || (o.fade == 2 && hs.ie)) ? 0 : 250
- });
- hs.extend(overlay, o);
-
-
- if (this.gotOverlays) {
- this.positionOverlay(overlay);
- if (!overlay.hideOnMouseOut || this.mouseIsOver)
- hs.animate(overlay, { opacity: overlay.opacity }, overlay.dur);
- }
- hs.push(this.overlays, hs.idCounter - 1);
-},
-positionOverlay : function(overlay) {
- var p = overlay.position || 'middle center',
- relToVP = (overlay.relativeTo == 'viewport'),
- offX = overlay.offsetX,
- offY = overlay.offsetY;
- if (relToVP) {
- hs.viewport.style.display = 'block';
- overlay.hsKey = this.key;
- if (overlay.offsetWidth > overlay.parentNode.offsetWidth)
- overlay.style.width = '100%';
- } else
- if (overlay.parentNode != this.overlayBox) this.overlayBox.appendChild(overlay);
- if (/left$/.test(p)) overlay.style.left = offX +'px';
-
- if (/center$/.test(p)) hs.setStyles (overlay, {
- left: '50%',
- marginLeft: (offX - Math.round(overlay.offsetWidth / 2)) +'px'
- });
-
- if (/right$/.test(p)) overlay.style.right = - offX +'px';
-
- if (/^leftpanel$/.test(p)) {
- hs.setStyles(overlay, {
- right: '100%',
- marginRight: this.x.cb +'px',
- top: - this.y.cb +'px',
- bottom: - this.y.cb +'px',
- overflow: 'auto'
- });
- this.x.p1 = overlay.offsetWidth;
-
- } else if (/^rightpanel$/.test(p)) {
- hs.setStyles(overlay, {
- left: '100%',
- marginLeft: this.x.cb +'px',
- top: - this.y.cb +'px',
- bottom: - this.y.cb +'px',
- overflow: 'auto'
- });
- this.x.p2 = overlay.offsetWidth;
- }
- var parOff = overlay.parentNode.offsetHeight;
- overlay.style.height = 'auto';
- if (relToVP && overlay.offsetHeight > parOff)
- overlay.style.height = hs.ieLt7 ? parOff +'px' : '100%';
-
- if (/^top/.test(p)) overlay.style.top = offY +'px';
- if (/^middle/.test(p)) hs.setStyles (overlay, {
- top: '50%',
- marginTop: (offY - Math.round(overlay.offsetHeight / 2)) +'px'
- });
- if (/^bottom/.test(p)) overlay.style.bottom = - offY +'px';
- if (/^above$/.test(p)) {
- hs.setStyles(overlay, {
- left: (- this.x.p1 - this.x.cb) +'px',
- right: (- this.x.p2 - this.x.cb) +'px',
- bottom: '100%',
- marginBottom: this.y.cb +'px',
- width: 'auto'
- });
- this.y.p1 = overlay.offsetHeight;
-
- } else if (/^below$/.test(p)) {
- hs.setStyles(overlay, {
- position: 'relative',
- left: (- this.x.p1 - this.x.cb) +'px',
- right: (- this.x.p2 - this.x.cb) +'px',
- top: '100%',
- marginTop: this.y.cb +'px',
- width: 'auto'
- });
- this.y.p2 = overlay.offsetHeight;
- overlay.style.position = 'absolute';
- }
-},
-
-getOverlays : function() {
- this.getInline(['heading', 'caption'], true);
- this.getNumber();
- if (this.caption) hs.fireEvent(this, 'onAfterGetCaption');
- if (this.heading) hs.fireEvent(this, 'onAfterGetHeading');
- if (this.heading && this.dragByHeading) this.heading.className += ' highslide-move';
- if (hs.showCredits) this.writeCredits();
- for (var i = 0; i < hs.overlays.length; i++) {
- var o = hs.overlays[i], tId = o.thumbnailId, sg = o.slideshowGroup;
- if ((!tId && !sg) || (tId && tId == this.thumbsUserSetId)
- || (sg && sg === this.slideshowGroup)) {
- if (this.isImage || (this.isHtml && o.useOnHtml))
- this.createOverlay(o);
- }
- }
- var os = [];
- for (var i = 0; i < this.overlays.length; i++) {
- var o = hs.$('hsId'+ this.overlays[i]);
- if (/panel$/.test(o.position)) this.positionOverlay(o);
- else hs.push(os, o);
- }
- for (var i = 0; i < os.length; i++) this.positionOverlay(os[i]);
- this.gotOverlays = true;
-},
-genOverlayBox : function() {
- if (!this.overlayBox) this.overlayBox = hs.createElement (
- 'div', {
- className: this.wrapperClassName
- }, {
- position : 'absolute',
- width: (this.x.size || (this.useBox ? this.width : null)
- || this.x.full) +'px',
- height: (this.y.size || this.y.full) +'px',
- visibility : 'hidden',
- overflow : 'hidden',
- zIndex : hs.ie ? 4 : 'auto'
- },
- hs.container,
- true
- );
-},
-sizeOverlayBox : function(doWrapper, doPanels) {
- var overlayBox = this.overlayBox,
- x = this.x,
- y = this.y;
- hs.setStyles( overlayBox, {
- width: x.size +'px',
- height: y.size +'px'
- });
- if (doWrapper || doPanels) {
- for (var i = 0; i < this.overlays.length; i++) {
- var o = hs.$('hsId'+ this.overlays[i]);
- var ie6 = (hs.ieLt7 || document.compatMode == 'BackCompat');
- if (o && /^(above|below)$/.test(o.position)) {
- if (ie6) {
- o.style.width = (overlayBox.offsetWidth + 2 * x.cb
- + x.p1 + x.p2) +'px';
- }
- y[o.position == 'above' ? 'p1' : 'p2'] = o.offsetHeight;
- }
- if (o && ie6 && /^(left|right)panel$/.test(o.position)) {
- o.style.height = (overlayBox.offsetHeight + 2* y.cb) +'px';
- }
- }
- }
- if (doWrapper) {
- hs.setStyles(this.content, {
- top: y.p1 +'px'
- });
- hs.setStyles(overlayBox, {
- top: (y.p1 + y.cb) +'px'
- });
- }
-},
-
-showOverlays : function() {
- var b = this.overlayBox;
- b.className = '';
- hs.setStyles(b, {
- top: (this.y.p1 + this.y.cb) +'px',
- left: (this.x.p1 + this.x.cb) +'px',
- overflow : 'visible'
- });
- if (hs.safari) b.style.visibility = 'visible';
- this.wrapper.appendChild (b);
- for (var i = 0; i < this.overlays.length; i++) {
- var o = hs.$('hsId'+ this.overlays[i]);
- o.style.zIndex = o.zIndex || 4;
- if (!o.hideOnMouseOut || this.mouseIsOver) {
- o.style.visibility = 'visible';
- hs.setStyles(o, { visibility: 'visible', display: '' });
- hs.animate(o, { opacity: o.opacity }, o.dur);
- }
- }
-},
-
-destroyOverlays : function() {
- if (!this.overlays.length) return;
- if (this.slideshow) {
- var c = this.slideshow.controls;
- if (c && hs.getExpander(c) == this) c.parentNode.removeChild(c);
- }
- for (var i = 0; i < this.overlays.length; i++) {
- var o = hs.$('hsId'+ this.overlays[i]);
- if (o && o.parentNode == hs.viewport && hs.getExpander(o) == this) hs.discardElement(o);
- }
- if (this.isHtml && this.preserveContent) {
- this.overlayBox.style.top = '-9999px';
- hs.container.appendChild(this.overlayBox);
- } else
- hs.discardElement(this.overlayBox);
-},
-
-
-
-createFullExpand : function () {
- if (this.slideshow && this.slideshow.controls) {
- this.slideshow.enable('full-expand');
- return;
- }
- this.fullExpandLabel = hs.createElement(
- 'a', {
- href: 'javascript:hs.expanders['+ this.key +'].doFullExpand();',
- title: hs.lang.fullExpandTitle,
- className: 'highslide-full-expand'
- }
- );
- if (!hs.fireEvent(this, 'onCreateFullExpand')) return;
-
- this.createOverlay({
- overlayId: this.fullExpandLabel,
- position: hs.fullExpandPosition,
- hideOnMouseOut: true,
- opacity: hs.fullExpandOpacity
- });
-},
-
-doFullExpand : function () {
- try {
- if (!hs.fireEvent(this, 'onDoFullExpand')) return;
- if (this.fullExpandLabel) hs.discardElement(this.fullExpandLabel);
-
- this.focus();
- var xSize = this.x.size;
- this.resizeTo(this.x.full, this.y.full);
-
- var xpos = this.x.pos - (this.x.size - xSize) / 2;
- if (xpos < hs.marginLeft) xpos = hs.marginLeft;
-
- this.moveTo(xpos, this.y.pos);
- this.doShowHide('hidden');
-
- } catch (e) {
- this.error(e);
- }
-},
-
-
-afterClose : function () {
- this.a.className = this.a.className.replace('highslide-active-anchor', '');
-
- this.doShowHide('visible');
-
- if (this.isHtml && this.preserveContent
- && this.transitions[1] != 'crossfade') {
- this.sleep();
- } else {
- if (this.outline && this.outlineWhileAnimating) this.outline.destroy();
-
- hs.discardElement(this.wrapper);
- }
- if (hs.mask) hs.mask.style.display = 'none';
- this.destroyOverlays();
- if (!hs.viewport.childNodes.length) hs.viewport.style.display = 'none';
-
- if (this.dimmingOpacity) hs.undim(this.key);
- hs.fireEvent(this, 'onAfterClose');
- hs.expanders[this.key] = null;
- hs.reOrder();
-}
-
-};
-
-
-// hs.Ajax object prototype
-hs.Ajax = function (a, content, pre) {
- this.a = a;
- this.content = content;
- this.pre = pre;
-};
-
-hs.Ajax.prototype = {
-run : function () {
- var xhr;
- if (!this.src) this.src = hs.getSrc(this.a);
- if (this.src.match('#')) {
- var arr = this.src.split('#');
- this.src = arr[0];
- this.id = arr[1];
- }
- if (hs.cachedGets[this.src]) {
- this.cachedGet = hs.cachedGets[this.src];
- if (this.id) this.getElementContent();
- else this.loadHTML();
- return;
- }
- try { xhr = new XMLHttpRequest(); }
- catch (e) {
- try { xhr = new ActiveXObject("Msxml2.XMLHTTP"); }
- catch (e) {
- try { xhr = new ActiveXObject("Microsoft.XMLHTTP"); }
- catch (e) { this.onError(); }
- }
- }
- var pThis = this;
- xhr.onreadystatechange = function() {
- if(pThis.xhr.readyState == 4) {
- if (pThis.id) pThis.getElementContent();
- else pThis.loadHTML();
- }
- };
- var src = this.src;
- this.xhr = xhr;
- if (hs.forceAjaxReload)
- src = src.replace(/$/, (/\?/.test(src) ? '&' : '?') +'dummy='+ (new Date()).getTime());
- xhr.open('GET', src, true);
- xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
- xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
- xhr.send(null);
-},
-
-getElementContent : function() {
- hs.init();
- var attribs = window.opera || hs.ie6SSL ? { src: 'about:blank' } : null;
-
- this.iframe = hs.createElement('iframe', attribs,
- { position: 'absolute', top: '-9999px' }, hs.container);
-
- this.loadHTML();
-},
-
-loadHTML : function() {
- var s = this.cachedGet || this.xhr.responseText,
- regBody;
- if (this.pre) hs.cachedGets[this.src] = s;
- if (!hs.ie || hs.uaVersion >= 5.5) {
- s = s.replace(new RegExp('<link[^>]*>', 'gi'), '')
- .replace(new RegExp('<script[^>]*>.*?</script>', 'gi'), '');
- if (this.iframe) {
- var doc = this.iframe.contentDocument;
- if (!doc && this.iframe.contentWindow) doc = this.iframe.contentWindow.document;
- if (!doc) { // Opera
- var pThis = this;
- setTimeout(function() { pThis.loadHTML(); }, 25);
- return;
- }
- doc.open();
- doc.write(s);
- doc.close();
- try { s = doc.getElementById(this.id).innerHTML; } catch (e) {
- try { s = this.iframe.document.getElementById(this.id).innerHTML; } catch (e) {} // opera
- }
- hs.discardElement(this.iframe);
- } else {
- regBody = /(<body[^>]*>|<\/body>)/ig;
- if (regBody.test(s)) s = s.split(regBody)[hs.ie ? 1 : 2];
-
- }
- }
- hs.getElementByClass(this.content, 'DIV', 'highslide-body').innerHTML = s;
- this.onLoad();
- for (var x in this) this[x] = null;
-}
-};
-
-
-hs.Slideshow = function (expKey, options) {
- if (hs.dynamicallyUpdateAnchors !== false) hs.updateAnchors();
- this.expKey = expKey;
- for (var x in options) this[x] = options[x];
- if (this.useControls) this.getControls();
- if (this.thumbstrip) this.thumbstrip = hs.Thumbstrip(this);
-};
-hs.Slideshow.prototype = {
-getControls: function() {
- this.controls = hs.createElement('div', { innerHTML: hs.replaceLang(hs.skin.controls) },
- null, hs.container);
-
- var buttons = ['play', 'pause', 'previous', 'next', 'move', 'full-expand', 'close'];
- this.btn = {};
- var pThis = this;
- for (var i = 0; i < buttons.length; i++) {
- this.btn[buttons[i]] = hs.getElementByClass(this.controls, 'li', 'highslide-'+ buttons[i]);
- this.enable(buttons[i]);
- }
- this.btn.pause.style.display = 'none';
- //this.disable('full-expand');
-},
-checkFirstAndLast: function() {
- if (this.repeat || !this.controls) return;
- var exp = hs.expanders[this.expKey],
- cur = exp.getAnchorIndex(),
- re = /disabled$/;
- if (cur == 0)
- this.disable('previous');
- else if (re.test(this.btn.previous.getElementsByTagName('a')[0].className))
- this.enable('previous');
- if (cur + 1 == hs.anchors.groups[exp.slideshowGroup || 'none'].length) {
- this.disable('next');
- this.disable('play');
- } else if (re.test(this.btn.next.getElementsByTagName('a')[0].className)) {
- this.enable('next');
- this.enable('play');
- }
-},
-enable: function(btn) {
- if (!this.btn) return;
- var sls = this, a = this.btn[btn].getElementsByTagName('a')[0], re = /disabled$/;
- a.onclick = function() {
- sls[btn]();
- return false;
- };
- if (re.test(a.className)) a.className = a.className.replace(re, '');
-},
-disable: function(btn) {
- if (!this.btn) return;
- var a = this.btn[btn].getElementsByTagName('a')[0];
- a.onclick = function() { return false; };
- if (!/disabled$/.test(a.className)) a.className += ' disabled';
-},
-hitSpace: function() {
- if (this.autoplay) this.pause();
- else this.play();
-},
-play: function(wait) {
- if (this.btn) {
- this.btn.play.style.display = 'none';
- this.btn.pause.style.display = '';
- }
-
- this.autoplay = true;
- if (!wait) hs.next(this.expKey);
-},
-pause: function() {
- if (this.btn) {
- this.btn.pause.style.display = 'none';
- this.btn.play.style.display = '';
- }
-
- clearTimeout(this.autoplay);
- this.autoplay = null;
-},
-previous: function() {
- this.pause();
- hs.previous(this.btn.previous);
-},
-next: function() {
- this.pause();
- hs.next(this.btn.next);
-},
-move: function() {},
-'full-expand': function() {
- hs.getExpander().doFullExpand();
-},
-close: function() {
- hs.close(this.btn.close);
-}
-};
-hs.Thumbstrip = function(slideshow) {
- function add (exp) {
- hs.extend(options || {}, {
- overlayId: dom,
- hsId: 'thumbstrip',
- className: 'highslide-thumbstrip-'+ mode +'-overlay ' + (options.className || '')
- });
- if (hs.ieLt7) options.fade = 0;
- exp.createOverlay(options);
- hs.setStyles(dom.parentNode, { overflow: 'hidden' });
- };
-
- function scroll (delta) {
- selectThumb(undefined, Math.round(delta * dom[isX ? 'offsetWidth' : 'offsetHeight'] * 0.7));
- };
-
- function selectThumb (i, scrollBy) {
- if (i === undefined) for (var j = 0; j < group.length; j++) {
- if (group[j] == hs.expanders[slideshow.expKey].a) {
- i = j;
- break;
- }
- }
- if (i === undefined) return;
- var as = dom.getElementsByTagName('a'),
- active = as[i],
- cell = active.parentNode,
- left = isX ? 'Left' : 'Top',
- right = isX ? 'Right' : 'Bottom',
- width = isX ? 'Width' : 'Height',
- offsetLeft = 'offset' + left,
- offsetWidth = 'offset' + width,
- overlayWidth = div.parentNode.parentNode[offsetWidth],
- minTblPos = overlayWidth - table[offsetWidth],
- curTblPos = parseInt(table.style[isX ? 'left' : 'top']) || 0,
- tblPos = curTblPos,
- mgnRight = 20;
- if (scrollBy !== undefined) {
- tblPos = curTblPos - scrollBy;
-
- if (minTblPos > 0) minTblPos = 0;
- if (tblPos > 0) tblPos = 0;
- if (tblPos < minTblPos) tblPos = minTblPos;
-
-
- } else {
- for (var j = 0; j < as.length; j++) as[j].className = '';
- active.className = 'highslide-active-anchor';
- var activeLeft = i > 0 ? as[i - 1].parentNode[offsetLeft] : cell[offsetLeft],
- activeRight = cell[offsetLeft] + cell[offsetWidth] +
- (as[i + 1] ? as[i + 1].parentNode[offsetWidth] : 0);
- if (activeRight > overlayWidth - curTblPos) tblPos = overlayWidth - activeRight;
- else if (activeLeft < -curTblPos) tblPos = -activeLeft;
- }
- var markerPos = cell[offsetLeft] + (cell[offsetWidth] - marker[offsetWidth]) / 2 + tblPos;
- hs.animate(table, isX ? { left: tblPos } : { top: tblPos }, null, 'easeOutQuad');
- hs.animate(marker, isX ? { left: markerPos } : { top: markerPos }, null, 'easeOutQuad');
- scrollUp.style.display = tblPos < 0 ? 'block' : 'none';
- scrollDown.style.display = (tblPos > minTblPos) ? 'block' : 'none';
-
- };
-
-
- // initialize
- var group = hs.anchors.groups[hs.expanders[slideshow.expKey].slideshowGroup || 'none'],
- options = slideshow.thumbstrip,
- mode = options.mode || 'horizontal',
- floatMode = (mode == 'float'),
- tree = floatMode ? ['div', 'ul', 'li', 'span'] : ['table', 'tbody', 'tr', 'td'],
- isX = (mode == 'horizontal'),
- dom = hs.createElement('div', {
- className: 'highslide-thumbstrip highslide-thumbstrip-'+ mode,
- innerHTML:
- '<div class="highslide-thumbstrip-inner">'+
- '<'+ tree[0] +'><'+ tree[1] +'></'+ tree[1] +'></'+ tree[0] +'></div>'+
- '<div class="highslide-scroll-up"><div></div></div>'+
- '<div class="highslide-scroll-down"><div></div></div>'+
- '<div class="highslide-marker"><div></div></div>'
- }, {
- display: 'none'
- }, hs.container),
- domCh = dom.childNodes,
- div = domCh[0],
- scrollUp = domCh[1],
- scrollDown = domCh[2],
- marker = domCh[3],
- table = div.firstChild,
- tbody = dom.getElementsByTagName(tree[1])[0],
- tr;
- for (var i = 0; i < group.length; i++) {
- if (i == 0 || !isX) tr = hs.createElement(tree[2], null, null, tbody);
- (function(){
- var a = group[i],
- cell = hs.createElement(tree[3], null, null, tr),
- pI = i;
- hs.createElement('a', {
- href: a.href,
- onclick: function() {
- hs.getExpander(this).focus();
- return hs.transit(a);
- },
- innerHTML: hs.stripItemFormatter ? hs.stripItemFormatter(a) : a.innerHTML
- }, null, cell);
- })();
- }
- if (!floatMode) {
- scrollUp.onclick = function () { scroll(-1); };
- scrollDown.onclick = function() { scroll(1); };
- hs.addEventListener(tbody, document.onmousewheel !== undefined ?
- 'mousewheel' : 'DOMMouseScroll', function(e) {
- var delta = 0;
- e = e || window.event;
- if (e.wheelDelta) {
- delta = e.wheelDelta/120;
- if (hs.opera) delta = -delta;
- } else if (e.detail) {
- delta = -e.detail/3;
- }
- if (delta) scroll(-delta * 0.2);
- if (e.preventDefault) e.preventDefault();
- e.returnValue = false;
- });
- }
-
- return {
- add: add,
- selectThumb: selectThumb
- }
-};
-hs.langDefaults = hs.lang;
-// history
-var HsExpander = hs.Expander;
-if (hs.ie && window == window.top) {
- (function () {
- try {
- document.documentElement.doScroll('left');
- } catch (e) {
- setTimeout(arguments.callee, 50);
- return;
- }
- hs.ready();
- })();
-}
-hs.addEventListener(document, 'DOMContentLoaded', hs.ready);
-hs.addEventListener(window, 'load', hs.ready);
-
-// set handlers
-hs.addEventListener(document, 'ready', function() {
- if (hs.expandCursor || hs.dimmingOpacity) {
- var style = hs.createElement('style', { type: 'text/css' }, null,
- document.getElementsByTagName('HEAD')[0]);
-
- function addRule(sel, dec) {
- if (!hs.ie) {
- style.appendChild(document.createTextNode(sel + " {" + dec + "}"));
- } else {
- var last = document.styleSheets[document.styleSheets.length - 1];
- if (typeof(last.addRule) == "object") last.addRule(sel, dec);
- }
- }
- function fix(prop) {
- return 'expression( ( ( ignoreMe = document.documentElement.'+ prop +
- ' ? document.documentElement.'+ prop +' : document.body.'+ prop +' ) ) + \'px\' );';
- }
- if (hs.expandCursor) addRule ('.highslide img',
- 'cursor: url('+ hs.graphicsDir + hs.expandCursor +'), pointer !important;');
- addRule ('.highslide-viewport-size',
- hs.ie && (hs.uaVersion < 7 || document.compatMode == 'BackCompat') ?
- 'position: absolute; '+
- 'left:'+ fix('scrollLeft') +
- 'top:'+ fix('scrollTop') +
- 'width:'+ fix('clientWidth') +
- 'height:'+ fix('clientHeight') :
- 'position: fixed; width: 100%; height: 100%; left: 0; top: 0');
- }
-});
-hs.addEventListener(window, 'resize', function() {
- hs.getPageSize();
- if (hs.viewport) for (var i = 0; i < hs.viewport.childNodes.length; i++) {
- var node = hs.viewport.childNodes[i],
- exp = hs.getExpander(node);
- exp.positionOverlay(node);
- if (node.hsId == 'thumbstrip') exp.slideshow.thumbstrip.selectThumb();
- }
-});
-hs.addEventListener(document, 'mousemove', function(e) {
- hs.mouse = { x: e.clientX, y: e.clientY };
-});
-hs.addEventListener(document, 'mousedown', hs.mouseClickHandler);
-hs.addEventListener(document, 'mouseup', hs.mouseClickHandler);
-hs.addEventListener(document, 'ready', hs.setClickEvents);
-hs.addEventListener(window, 'load', hs.preloadImages);
-hs.addEventListener(window, 'load', hs.preloadAjax);
-} \ No newline at end of file
diff --git a/tools/infra-dashboard/js/highslide.config.min.js b/tools/infra-dashboard/js/highslide.config.min.js
deleted file mode 100644
index 4d1a9b3d..00000000
--- a/tools/infra-dashboard/js/highslide.config.min.js
+++ /dev/null
@@ -1 +0,0 @@
-hs.outlineType="rounded-white",hs.wrapperClassName="draggable-header",hs.captionEval="this.a.title",hs.showCredits=!1,hs.marginTop=20,hs.marginRight=20,hs.marginBottom=20,hs.marginLeft=20; \ No newline at end of file
diff --git a/tools/infra-dashboard/js/jquery-1.7.2.js b/tools/infra-dashboard/js/jquery-1.7.2.js
deleted file mode 100644
index 3774ff98..00000000
--- a/tools/infra-dashboard/js/jquery-1.7.2.js
+++ /dev/null
@@ -1,9404 +0,0 @@
-/*!
- * jQuery JavaScript Library v1.7.2
- * http://jquery.com/
- *
- * Copyright 2011, John Resig
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * Includes Sizzle.js
- * http://sizzlejs.com/
- * Copyright 2011, The Dojo Foundation
- * Released under the MIT, BSD, and GPL Licenses.
- *
- * Date: Wed Mar 21 12:46:34 2012 -0700
- */
-(function( window, undefined ) {
-
-// Use the correct document accordingly with window argument (sandbox)
-var document = window.document,
- navigator = window.navigator,
- location = window.location;
-var jQuery = (function() {
-
-// Define a local copy of jQuery
-var jQuery = function( selector, context ) {
- // The jQuery object is actually just the init constructor 'enhanced'
- return new jQuery.fn.init( selector, context, rootjQuery );
- },
-
- // Map over jQuery in case of overwrite
- _jQuery = window.jQuery,
-
- // Map over the $ in case of overwrite
- _$ = window.$,
-
- // A central reference to the root jQuery(document)
- rootjQuery,
-
- // A simple way to check for HTML strings or ID strings
- // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
- quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
-
- // Check if a string has a non-whitespace character in it
- rnotwhite = /\S/,
-
- // Used for trimming whitespace
- trimLeft = /^\s+/,
- trimRight = /\s+$/,
-
- // Match a standalone tag
- rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
-
- // JSON RegExp
- rvalidchars = /^[\],:{}\s]*$/,
- rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
- rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
- rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
-
- // Useragent RegExp
- rwebkit = /(webkit)[ \/]([\w.]+)/,
- ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
- rmsie = /(msie) ([\w.]+)/,
- rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
-
- // Matches dashed string for camelizing
- rdashAlpha = /-([a-z]|[0-9])/ig,
- rmsPrefix = /^-ms-/,
-
- // Used by jQuery.camelCase as callback to replace()
- fcamelCase = function( all, letter ) {
- return ( letter + "" ).toUpperCase();
- },
-
- // Keep a UserAgent string for use with jQuery.browser
- userAgent = navigator.userAgent,
-
- // For matching the engine and version of the browser
- browserMatch,
-
- // The deferred used on DOM ready
- readyList,
-
- // The ready event handler
- DOMContentLoaded,
-
- // Save a reference to some core methods
- toString = Object.prototype.toString,
- hasOwn = Object.prototype.hasOwnProperty,
- push = Array.prototype.push,
- slice = Array.prototype.slice,
- trim = String.prototype.trim,
- indexOf = Array.prototype.indexOf,
-
- // [[Class]] -> type pairs
- class2type = {};
-
-jQuery.fn = jQuery.prototype = {
- constructor: jQuery,
- init: function( selector, context, rootjQuery ) {
- var match, elem, ret, doc;
-
- // Handle $(""), $(null), or $(undefined)
- if ( !selector ) {
- return this;
- }
-
- // Handle $(DOMElement)
- if ( selector.nodeType ) {
- this.context = this[0] = selector;
- this.length = 1;
- return this;
- }
-
- // The body element only exists once, optimize finding it
- if ( selector === "body" && !context && document.body ) {
- this.context = document;
- this[0] = document.body;
- this.selector = selector;
- this.length = 1;
- return this;
- }
-
- // Handle HTML strings
- if ( typeof selector === "string" ) {
- // Are we dealing with HTML string or an ID?
- if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
- // Assume that strings that start and end with <> are HTML and skip the regex check
- match = [ null, selector, null ];
-
- } else {
- match = quickExpr.exec( selector );
- }
-
- // Verify a match, and that no context was specified for #id
- if ( match && (match[1] || !context) ) {
-
- // HANDLE: $(html) -> $(array)
- if ( match[1] ) {
- context = context instanceof jQuery ? context[0] : context;
- doc = ( context ? context.ownerDocument || context : document );
-
- // If a single string is passed in and it's a single tag
- // just do a createElement and skip the rest
- ret = rsingleTag.exec( selector );
-
- if ( ret ) {
- if ( jQuery.isPlainObject( context ) ) {
- selector = [ document.createElement( ret[1] ) ];
- jQuery.fn.attr.call( selector, context, true );
-
- } else {
- selector = [ doc.createElement( ret[1] ) ];
- }
-
- } else {
- ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
- selector = ( ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment ).childNodes;
- }
-
- return jQuery.merge( this, selector );
-
- // HANDLE: $("#id")
- } else {
- elem = document.getElementById( match[2] );
-
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- if ( elem && elem.parentNode ) {
- // Handle the case where IE and Opera return items
- // by name instead of ID
- if ( elem.id !== match[2] ) {
- return rootjQuery.find( selector );
- }
-
- // Otherwise, we inject the element directly into the jQuery object
- this.length = 1;
- this[0] = elem;
- }
-
- this.context = document;
- this.selector = selector;
- return this;
- }
-
- // HANDLE: $(expr, $(...))
- } else if ( !context || context.jquery ) {
- return ( context || rootjQuery ).find( selector );
-
- // HANDLE: $(expr, context)
- // (which is just equivalent to: $(context).find(expr)
- } else {
- return this.constructor( context ).find( selector );
- }
-
- // HANDLE: $(function)
- // Shortcut for document ready
- } else if ( jQuery.isFunction( selector ) ) {
- return rootjQuery.ready( selector );
- }
-
- if ( selector.selector !== undefined ) {
- this.selector = selector.selector;
- this.context = selector.context;
- }
-
- return jQuery.makeArray( selector, this );
- },
-
- // Start with an empty selector
- selector: "",
-
- // The current version of jQuery being used
- jquery: "1.7.2",
-
- // The default length of a jQuery object is 0
- length: 0,
-
- // The number of elements contained in the matched element set
- size: function() {
- return this.length;
- },
-
- toArray: function() {
- return slice.call( this, 0 );
- },
-
- // Get the Nth element in the matched element set OR
- // Get the whole matched element set as a clean array
- get: function( num ) {
- return num == null ?
-
- // Return a 'clean' array
- this.toArray() :
-
- // Return just the object
- ( num < 0 ? this[ this.length + num ] : this[ num ] );
- },
-
- // Take an array of elements and push it onto the stack
- // (returning the new matched element set)
- pushStack: function( elems, name, selector ) {
- // Build a new jQuery matched element set
- var ret = this.constructor();
-
- if ( jQuery.isArray( elems ) ) {
- push.apply( ret, elems );
-
- } else {
- jQuery.merge( ret, elems );
- }
-
- // Add the old object onto the stack (as a reference)
- ret.prevObject = this;
-
- ret.context = this.context;
-
- if ( name === "find" ) {
- ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;
- } else if ( name ) {
- ret.selector = this.selector + "." + name + "(" + selector + ")";
- }
-
- // Return the newly-formed element set
- return ret;
- },
-
- // Execute a callback for every element in the matched set.
- // (You can seed the arguments with an array of args, but this is
- // only used internally.)
- each: function( callback, args ) {
- return jQuery.each( this, callback, args );
- },
-
- ready: function( fn ) {
- // Attach the listeners
- jQuery.bindReady();
-
- // Add the callback
- readyList.add( fn );
-
- return this;
- },
-
- eq: function( i ) {
- i = +i;
- return i === -1 ?
- this.slice( i ) :
- this.slice( i, i + 1 );
- },
-
- first: function() {
- return this.eq( 0 );
- },
-
- last: function() {
- return this.eq( -1 );
- },
-
- slice: function() {
- return this.pushStack( slice.apply( this, arguments ),
- "slice", slice.call(arguments).join(",") );
- },
-
- map: function( callback ) {
- return this.pushStack( jQuery.map(this, function( elem, i ) {
- return callback.call( elem, i, elem );
- }));
- },
-
- end: function() {
- return this.prevObject || this.constructor(null);
- },
-
- // For internal use only.
- // Behaves like an Array's method, not like a jQuery method.
- push: push,
- sort: [].sort,
- splice: [].splice
-};
-
-// Give the init function the jQuery prototype for later instantiation
-jQuery.fn.init.prototype = jQuery.fn;
-
-jQuery.extend = jQuery.fn.extend = function() {
- var options, name, src, copy, copyIsArray, clone,
- target = arguments[0] || {},
- i = 1,
- length = arguments.length,
- deep = false;
-
- // Handle a deep copy situation
- if ( typeof target === "boolean" ) {
- deep = target;
- target = arguments[1] || {};
- // skip the boolean and the target
- i = 2;
- }
-
- // Handle case when target is a string or something (possible in deep copy)
- if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
- target = {};
- }
-
- // extend jQuery itself if only one argument is passed
- if ( length === i ) {
- target = this;
- --i;
- }
-
- for ( ; i < length; i++ ) {
- // Only deal with non-null/undefined values
- if ( (options = arguments[ i ]) != null ) {
- // Extend the base object
- for ( name in options ) {
- src = target[ name ];
- copy = options[ name ];
-
- // Prevent never-ending loop
- if ( target === copy ) {
- continue;
- }
-
- // Recurse if we're merging plain objects or arrays
- if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
- if ( copyIsArray ) {
- copyIsArray = false;
- clone = src && jQuery.isArray(src) ? src : [];
-
- } else {
- clone = src && jQuery.isPlainObject(src) ? src : {};
- }
-
- // Never move original objects, clone them
- target[ name ] = jQuery.extend( deep, clone, copy );
-
- // Don't bring in undefined values
- } else if ( copy !== undefined ) {
- target[ name ] = copy;
- }
- }
- }
- }
-
- // Return the modified object
- return target;
-};
-
-jQuery.extend({
- noConflict: function( deep ) {
- if ( window.$ === jQuery ) {
- window.$ = _$;
- }
-
- if ( deep && window.jQuery === jQuery ) {
- window.jQuery = _jQuery;
- }
-
- return jQuery;
- },
-
- // Is the DOM ready to be used? Set to true once it occurs.
- isReady: false,
-
- // A counter to track how many items to wait for before
- // the ready event fires. See #6781
- readyWait: 1,
-
- // Hold (or release) the ready event
- holdReady: function( hold ) {
- if ( hold ) {
- jQuery.readyWait++;
- } else {
- jQuery.ready( true );
- }
- },
-
- // Handle when the DOM is ready
- ready: function( wait ) {
- // Either a released hold or an DOMready/load event and not yet ready
- if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
- // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
- if ( !document.body ) {
- return setTimeout( jQuery.ready, 1 );
- }
-
- // Remember that the DOM is ready
- jQuery.isReady = true;
-
- // If a normal DOM Ready event fired, decrement, and wait if need be
- if ( wait !== true && --jQuery.readyWait > 0 ) {
- return;
- }
-
- // If there are functions bound, to execute
- readyList.fireWith( document, [ jQuery ] );
-
- // Trigger any bound ready events
- if ( jQuery.fn.trigger ) {
- jQuery( document ).trigger( "ready" ).off( "ready" );
- }
- }
- },
-
- bindReady: function() {
- if ( readyList ) {
- return;
- }
-
- readyList = jQuery.Callbacks( "once memory" );
-
- // Catch cases where $(document).ready() is called after the
- // browser event has already occurred.
- if ( document.readyState === "complete" ) {
- // Handle it asynchronously to allow scripts the opportunity to delay ready
- return setTimeout( jQuery.ready, 1 );
- }
-
- // Mozilla, Opera and webkit nightlies currently support this event
- if ( document.addEventListener ) {
- // Use the handy event callback
- document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
-
- // A fallback to window.onload, that will always work
- window.addEventListener( "load", jQuery.ready, false );
-
- // If IE event model is used
- } else if ( document.attachEvent ) {
- // ensure firing before onload,
- // maybe late but safe also for iframes
- document.attachEvent( "onreadystatechange", DOMContentLoaded );
-
- // A fallback to window.onload, that will always work
- window.attachEvent( "onload", jQuery.ready );
-
- // If IE and not a frame
- // continually check to see if the document is ready
- var toplevel = false;
-
- try {
- toplevel = window.frameElement == null;
- } catch(e) {}
-
- if ( document.documentElement.doScroll && toplevel ) {
- doScrollCheck();
- }
- }
- },
-
- // See test/unit/core.js for details concerning isFunction.
- // Since version 1.3, DOM methods and functions like alert
- // aren't supported. They return false on IE (#2968).
- isFunction: function( obj ) {
- return jQuery.type(obj) === "function";
- },
-
- isArray: Array.isArray || function( obj ) {
- return jQuery.type(obj) === "array";
- },
-
- isWindow: function( obj ) {
- return obj != null && obj == obj.window;
- },
-
- isNumeric: function( obj ) {
- return !isNaN( parseFloat(obj) ) && isFinite( obj );
- },
-
- type: function( obj ) {
- return obj == null ?
- String( obj ) :
- class2type[ toString.call(obj) ] || "object";
- },
-
- isPlainObject: function( obj ) {
- // Must be an Object.
- // Because of IE, we also have to check the presence of the constructor property.
- // Make sure that DOM nodes and window objects don't pass through, as well
- if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
- return false;
- }
-
- try {
- // Not own constructor property must be Object
- if ( obj.constructor &&
- !hasOwn.call(obj, "constructor") &&
- !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
- return false;
- }
- } catch ( e ) {
- // IE8,9 Will throw exceptions on certain host objects #9897
- return false;
- }
-
- // Own properties are enumerated firstly, so to speed up,
- // if last one is own, then all properties are own.
-
- var key;
- for ( key in obj ) {}
-
- return key === undefined || hasOwn.call( obj, key );
- },
-
- isEmptyObject: function( obj ) {
- for ( var name in obj ) {
- return false;
- }
- return true;
- },
-
- error: function( msg ) {
- throw new Error( msg );
- },
-
- parseJSON: function( data ) {
- if ( typeof data !== "string" || !data ) {
- return null;
- }
-
- // Make sure leading/trailing whitespace is removed (IE can't handle it)
- data = jQuery.trim( data );
-
- // Attempt to parse using the native JSON parser first
- if ( window.JSON && window.JSON.parse ) {
- return window.JSON.parse( data );
- }
-
- // Make sure the incoming data is actual JSON
- // Logic borrowed from http://json.org/json2.js
- if ( rvalidchars.test( data.replace( rvalidescape, "@" )
- .replace( rvalidtokens, "]" )
- .replace( rvalidbraces, "")) ) {
-
- return ( new Function( "return " + data ) )();
-
- }
- jQuery.error( "Invalid JSON: " + data );
- },
-
- // Cross-browser xml parsing
- parseXML: function( data ) {
- if ( typeof data !== "string" || !data ) {
- return null;
- }
- var xml, tmp;
- try {
- if ( window.DOMParser ) { // Standard
- tmp = new DOMParser();
- xml = tmp.parseFromString( data , "text/xml" );
- } else { // IE
- xml = new ActiveXObject( "Microsoft.XMLDOM" );
- xml.async = "false";
- xml.loadXML( data );
- }
- } catch( e ) {
- xml = undefined;
- }
- if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
- jQuery.error( "Invalid XML: " + data );
- }
- return xml;
- },
-
- noop: function() {},
-
- // Evaluates a script in a global context
- // Workarounds based on findings by Jim Driscoll
- // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
- globalEval: function( data ) {
- if ( data && rnotwhite.test( data ) ) {
- // We use execScript on Internet Explorer
- // We use an anonymous function so that context is window
- // rather than jQuery in Firefox
- ( window.execScript || function( data ) {
- window[ "eval" ].call( window, data );
- } )( data );
- }
- },
-
- // Convert dashed to camelCase; used by the css and data modules
- // Microsoft forgot to hump their vendor prefix (#9572)
- camelCase: function( string ) {
- return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
- },
-
- nodeName: function( elem, name ) {
- return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
- },
-
- // args is for internal usage only
- each: function( object, callback, args ) {
- var name, i = 0,
- length = object.length,
- isObj = length === undefined || jQuery.isFunction( object );
-
- if ( args ) {
- if ( isObj ) {
- for ( name in object ) {
- if ( callback.apply( object[ name ], args ) === false ) {
- break;
- }
- }
- } else {
- for ( ; i < length; ) {
- if ( callback.apply( object[ i++ ], args ) === false ) {
- break;
- }
- }
- }
-
- // A special, fast, case for the most common use of each
- } else {
- if ( isObj ) {
- for ( name in object ) {
- if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
- break;
- }
- }
- } else {
- for ( ; i < length; ) {
- if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
- break;
- }
- }
- }
- }
-
- return object;
- },
-
- // Use native String.trim function wherever possible
- trim: trim ?
- function( text ) {
- return text == null ?
- "" :
- trim.call( text );
- } :
-
- // Otherwise use our own trimming functionality
- function( text ) {
- return text == null ?
- "" :
- text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
- },
-
- // results is for internal usage only
- makeArray: function( array, results ) {
- var ret = results || [];
-
- if ( array != null ) {
- // The window, strings (and functions) also have 'length'
- // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
- var type = jQuery.type( array );
-
- if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
- push.call( ret, array );
- } else {
- jQuery.merge( ret, array );
- }
- }
-
- return ret;
- },
-
- inArray: function( elem, array, i ) {
- var len;
-
- if ( array ) {
- if ( indexOf ) {
- return indexOf.call( array, elem, i );
- }
-
- len = array.length;
- i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
-
- for ( ; i < len; i++ ) {
- // Skip accessing in sparse arrays
- if ( i in array && array[ i ] === elem ) {
- return i;
- }
- }
- }
-
- return -1;
- },
-
- merge: function( first, second ) {
- var i = first.length,
- j = 0;
-
- if ( typeof second.length === "number" ) {
- for ( var l = second.length; j < l; j++ ) {
- first[ i++ ] = second[ j ];
- }
-
- } else {
- while ( second[j] !== undefined ) {
- first[ i++ ] = second[ j++ ];
- }
- }
-
- first.length = i;
-
- return first;
- },
-
- grep: function( elems, callback, inv ) {
- var ret = [], retVal;
- inv = !!inv;
-
- // Go through the array, only saving the items
- // that pass the validator function
- for ( var i = 0, length = elems.length; i < length; i++ ) {
- retVal = !!callback( elems[ i ], i );
- if ( inv !== retVal ) {
- ret.push( elems[ i ] );
- }
- }
-
- return ret;
- },
-
- // arg is for internal usage only
- map: function( elems, callback, arg ) {
- var value, key, ret = [],
- i = 0,
- length = elems.length,
- // jquery objects are treated as arrays
- isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;
-
- // Go through the array, translating each of the items to their
- if ( isArray ) {
- for ( ; i < length; i++ ) {
- value = callback( elems[ i ], i, arg );
-
- if ( value != null ) {
- ret[ ret.length ] = value;
- }
- }
-
- // Go through every key on the object,
- } else {
- for ( key in elems ) {
- value = callback( elems[ key ], key, arg );
-
- if ( value != null ) {
- ret[ ret.length ] = value;
- }
- }
- }
-
- // Flatten any nested arrays
- return ret.concat.apply( [], ret );
- },
-
- // A global GUID counter for objects
- guid: 1,
-
- // Bind a function to a context, optionally partially applying any
- // arguments.
- proxy: function( fn, context ) {
- if ( typeof context === "string" ) {
- var tmp = fn[ context ];
- context = fn;
- fn = tmp;
- }
-
- // Quick check to determine if target is callable, in the spec
- // this throws a TypeError, but we will just return undefined.
- if ( !jQuery.isFunction( fn ) ) {
- return undefined;
- }
-
- // Simulated bind
- var args = slice.call( arguments, 2 ),
- proxy = function() {
- return fn.apply( context, args.concat( slice.call( arguments ) ) );
- };
-
- // Set the guid of unique handler to the same of original handler, so it can be removed
- proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
-
- return proxy;
- },
-
- // Mutifunctional method to get and set values to a collection
- // The value/s can optionally be executed if it's a function
- access: function( elems, fn, key, value, chainable, emptyGet, pass ) {
- var exec,
- bulk = key == null,
- i = 0,
- length = elems.length;
-
- // Sets many values
- if ( key && typeof key === "object" ) {
- for ( i in key ) {
- jQuery.access( elems, fn, i, key[i], 1, emptyGet, value );
- }
- chainable = 1;
-
- // Sets one value
- } else if ( value !== undefined ) {
- // Optionally, function values get executed if exec is true
- exec = pass === undefined && jQuery.isFunction( value );
-
- if ( bulk ) {
- // Bulk operations only iterate when executing function values
- if ( exec ) {
- exec = fn;
- fn = function( elem, key, value ) {
- return exec.call( jQuery( elem ), value );
- };
-
- // Otherwise they run against the entire set
- } else {
- fn.call( elems, value );
- fn = null;
- }
- }
-
- if ( fn ) {
- for (; i < length; i++ ) {
- fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
- }
- }
-
- chainable = 1;
- }
-
- return chainable ?
- elems :
-
- // Gets
- bulk ?
- fn.call( elems ) :
- length ? fn( elems[0], key ) : emptyGet;
- },
-
- now: function() {
- return ( new Date() ).getTime();
- },
-
- // Use of jQuery.browser is frowned upon.
- // More details: http://docs.jquery.com/Utilities/jQuery.browser
- uaMatch: function( ua ) {
- ua = ua.toLowerCase();
-
- var match = rwebkit.exec( ua ) ||
- ropera.exec( ua ) ||
- rmsie.exec( ua ) ||
- ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
- [];
-
- return { browser: match[1] || "", version: match[2] || "0" };
- },
-
- sub: function() {
- function jQuerySub( selector, context ) {
- return new jQuerySub.fn.init( selector, context );
- }
- jQuery.extend( true, jQuerySub, this );
- jQuerySub.superclass = this;
- jQuerySub.fn = jQuerySub.prototype = this();
- jQuerySub.fn.constructor = jQuerySub;
- jQuerySub.sub = this.sub;
- jQuerySub.fn.init = function init( selector, context ) {
- if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) {
- context = jQuerySub( context );
- }
-
- return jQuery.fn.init.call( this, selector, context, rootjQuerySub );
- };
- jQuerySub.fn.init.prototype = jQuerySub.fn;
- var rootjQuerySub = jQuerySub(document);
- return jQuerySub;
- },
-
- browser: {}
-});
-
-// Populate the class2type map
-jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
- class2type[ "[object " + name + "]" ] = name.toLowerCase();
-});
-
-browserMatch = jQuery.uaMatch( userAgent );
-if ( browserMatch.browser ) {
- jQuery.browser[ browserMatch.browser ] = true;
- jQuery.browser.version = browserMatch.version;
-}
-
-// Deprecated, use jQuery.browser.webkit instead
-if ( jQuery.browser.webkit ) {
- jQuery.browser.safari = true;
-}
-
-// IE doesn't match non-breaking spaces with \s
-if ( rnotwhite.test( "\xA0" ) ) {
- trimLeft = /^[\s\xA0]+/;
- trimRight = /[\s\xA0]+$/;
-}
-
-// All jQuery objects should point back to these
-rootjQuery = jQuery(document);
-
-// Cleanup functions for the document ready method
-if ( document.addEventListener ) {
- DOMContentLoaded = function() {
- document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
- jQuery.ready();
- };
-
-} else if ( document.attachEvent ) {
- DOMContentLoaded = function() {
- // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
- if ( document.readyState === "complete" ) {
- document.detachEvent( "onreadystatechange", DOMContentLoaded );
- jQuery.ready();
- }
- };
-}
-
-// The DOM ready check for Internet Explorer
-function doScrollCheck() {
- if ( jQuery.isReady ) {
- return;
- }
-
- try {
- // If IE is used, use the trick by Diego Perini
- // http://javascript.nwbox.com/IEContentLoaded/
- document.documentElement.doScroll("left");
- } catch(e) {
- setTimeout( doScrollCheck, 1 );
- return;
- }
-
- // and execute any waiting functions
- jQuery.ready();
-}
-
-return jQuery;
-
-})();
-
-
-// String to Object flags format cache
-var flagsCache = {};
-
-// Convert String-formatted flags into Object-formatted ones and store in cache
-function createFlags( flags ) {
- var object = flagsCache[ flags ] = {},
- i, length;
- flags = flags.split( /\s+/ );
- for ( i = 0, length = flags.length; i < length; i++ ) {
- object[ flags[i] ] = true;
- }
- return object;
-}
-
-/*
- * Create a callback list using the following parameters:
- *
- * flags: an optional list of space-separated flags that will change how
- * the callback list behaves
- *
- * By default a callback list will act like an event callback list and can be
- * "fired" multiple times.
- *
- * Possible flags:
- *
- * once: will ensure the callback list can only be fired once (like a Deferred)
- *
- * memory: will keep track of previous values and will call any callback added
- * after the list has been fired right away with the latest "memorized"
- * values (like a Deferred)
- *
- * unique: will ensure a callback can only be added once (no duplicate in the list)
- *
- * stopOnFalse: interrupt callings when a callback returns false
- *
- */
-jQuery.Callbacks = function( flags ) {
-
- // Convert flags from String-formatted to Object-formatted
- // (we check in cache first)
- flags = flags ? ( flagsCache[ flags ] || createFlags( flags ) ) : {};
-
- var // Actual callback list
- list = [],
- // Stack of fire calls for repeatable lists
- stack = [],
- // Last fire value (for non-forgettable lists)
- memory,
- // Flag to know if list was already fired
- fired,
- // Flag to know if list is currently firing
- firing,
- // First callback to fire (used internally by add and fireWith)
- firingStart,
- // End of the loop when firing
- firingLength,
- // Index of currently firing callback (modified by remove if needed)
- firingIndex,
- // Add one or several callbacks to the list
- add = function( args ) {
- var i,
- length,
- elem,
- type,
- actual;
- for ( i = 0, length = args.length; i < length; i++ ) {
- elem = args[ i ];
- type = jQuery.type( elem );
- if ( type === "array" ) {
- // Inspect recursively
- add( elem );
- } else if ( type === "function" ) {
- // Add if not in unique mode and callback is not in
- if ( !flags.unique || !self.has( elem ) ) {
- list.push( elem );
- }
- }
- }
- },
- // Fire callbacks
- fire = function( context, args ) {
- args = args || [];
- memory = !flags.memory || [ context, args ];
- fired = true;
- firing = true;
- firingIndex = firingStart || 0;
- firingStart = 0;
- firingLength = list.length;
- for ( ; list && firingIndex < firingLength; firingIndex++ ) {
- if ( list[ firingIndex ].apply( context, args ) === false && flags.stopOnFalse ) {
- memory = true; // Mark as halted
- break;
- }
- }
- firing = false;
- if ( list ) {
- if ( !flags.once ) {
- if ( stack && stack.length ) {
- memory = stack.shift();
- self.fireWith( memory[ 0 ], memory[ 1 ] );
- }
- } else if ( memory === true ) {
- self.disable();
- } else {
- list = [];
- }
- }
- },
- // Actual Callbacks object
- self = {
- // Add a callback or a collection of callbacks to the list
- add: function() {
- if ( list ) {
- var length = list.length;
- add( arguments );
- // Do we need to add the callbacks to the
- // current firing batch?
- if ( firing ) {
- firingLength = list.length;
- // With memory, if we're not firing then
- // we should call right away, unless previous
- // firing was halted (stopOnFalse)
- } else if ( memory && memory !== true ) {
- firingStart = length;
- fire( memory[ 0 ], memory[ 1 ] );
- }
- }
- return this;
- },
- // Remove a callback from the list
- remove: function() {
- if ( list ) {
- var args = arguments,
- argIndex = 0,
- argLength = args.length;
- for ( ; argIndex < argLength ; argIndex++ ) {
- for ( var i = 0; i < list.length; i++ ) {
- if ( args[ argIndex ] === list[ i ] ) {
- // Handle firingIndex and firingLength
- if ( firing ) {
- if ( i <= firingLength ) {
- firingLength--;
- if ( i <= firingIndex ) {
- firingIndex--;
- }
- }
- }
- // Remove the element
- list.splice( i--, 1 );
- // If we have some unicity property then
- // we only need to do this once
- if ( flags.unique ) {
- break;
- }
- }
- }
- }
- }
- return this;
- },
- // Control if a given callback is in the list
- has: function( fn ) {
- if ( list ) {
- var i = 0,
- length = list.length;
- for ( ; i < length; i++ ) {
- if ( fn === list[ i ] ) {
- return true;
- }
- }
- }
- return false;
- },
- // Remove all callbacks from the list
- empty: function() {
- list = [];
- return this;
- },
- // Have the list do nothing anymore
- disable: function() {
- list = stack = memory = undefined;
- return this;
- },
- // Is it disabled?
- disabled: function() {
- return !list;
- },
- // Lock the list in its current state
- lock: function() {
- stack = undefined;
- if ( !memory || memory === true ) {
- self.disable();
- }
- return this;
- },
- // Is it locked?
- locked: function() {
- return !stack;
- },
- // Call all callbacks with the given context and arguments
- fireWith: function( context, args ) {
- if ( stack ) {
- if ( firing ) {
- if ( !flags.once ) {
- stack.push( [ context, args ] );
- }
- } else if ( !( flags.once && memory ) ) {
- fire( context, args );
- }
- }
- return this;
- },
- // Call all the callbacks with the given arguments
- fire: function() {
- self.fireWith( this, arguments );
- return this;
- },
- // To know if the callbacks have already been called at least once
- fired: function() {
- return !!fired;
- }
- };
-
- return self;
-};
-
-
-
-
-var // Static reference to slice
- sliceDeferred = [].slice;
-
-jQuery.extend({
-
- Deferred: function( func ) {
- var doneList = jQuery.Callbacks( "once memory" ),
- failList = jQuery.Callbacks( "once memory" ),
- progressList = jQuery.Callbacks( "memory" ),
- state = "pending",
- lists = {
- resolve: doneList,
- reject: failList,
- notify: progressList
- },
- promise = {
- done: doneList.add,
- fail: failList.add,
- progress: progressList.add,
-
- state: function() {
- return state;
- },
-
- // Deprecated
- isResolved: doneList.fired,
- isRejected: failList.fired,
-
- then: function( doneCallbacks, failCallbacks, progressCallbacks ) {
- deferred.done( doneCallbacks ).fail( failCallbacks ).progress( progressCallbacks );
- return this;
- },
- always: function() {
- deferred.done.apply( deferred, arguments ).fail.apply( deferred, arguments );
- return this;
- },
- pipe: function( fnDone, fnFail, fnProgress ) {
- return jQuery.Deferred(function( newDefer ) {
- jQuery.each( {
- done: [ fnDone, "resolve" ],
- fail: [ fnFail, "reject" ],
- progress: [ fnProgress, "notify" ]
- }, function( handler, data ) {
- var fn = data[ 0 ],
- action = data[ 1 ],
- returned;
- if ( jQuery.isFunction( fn ) ) {
- deferred[ handler ](function() {
- returned = fn.apply( this, arguments );
- if ( returned && jQuery.isFunction( returned.promise ) ) {
- returned.promise().then( newDefer.resolve, newDefer.reject, newDefer.notify );
- } else {
- newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] );
- }
- });
- } else {
- deferred[ handler ]( newDefer[ action ] );
- }
- });
- }).promise();
- },
- // Get a promise for this deferred
- // If obj is provided, the promise aspect is added to the object
- promise: function( obj ) {
- if ( obj == null ) {
- obj = promise;
- } else {
- for ( var key in promise ) {
- obj[ key ] = promise[ key ];
- }
- }
- return obj;
- }
- },
- deferred = promise.promise({}),
- key;
-
- for ( key in lists ) {
- deferred[ key ] = lists[ key ].fire;
- deferred[ key + "With" ] = lists[ key ].fireWith;
- }
-
- // Handle state
- deferred.done( function() {
- state = "resolved";
- }, failList.disable, progressList.lock ).fail( function() {
- state = "rejected";
- }, doneList.disable, progressList.lock );
-
- // Call given func if any
- if ( func ) {
- func.call( deferred, deferred );
- }
-
- // All done!
- return deferred;
- },
-
- // Deferred helper
- when: function( firstParam ) {
- var args = sliceDeferred.call( arguments, 0 ),
- i = 0,
- length = args.length,
- pValues = new Array( length ),
- count = length,
- pCount = length,
- deferred = length <= 1 && firstParam && jQuery.isFunction( firstParam.promise ) ?
- firstParam :
- jQuery.Deferred(),
- promise = deferred.promise();
- function resolveFunc( i ) {
- return function( value ) {
- args[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
- if ( !( --count ) ) {
- deferred.resolveWith( deferred, args );
- }
- };
- }
- function progressFunc( i ) {
- return function( value ) {
- pValues[ i ] = arguments.length > 1 ? sliceDeferred.call( arguments, 0 ) : value;
- deferred.notifyWith( promise, pValues );
- };
- }
- if ( length > 1 ) {
- for ( ; i < length; i++ ) {
- if ( args[ i ] && args[ i ].promise && jQuery.isFunction( args[ i ].promise ) ) {
- args[ i ].promise().then( resolveFunc(i), deferred.reject, progressFunc(i) );
- } else {
- --count;
- }
- }
- if ( !count ) {
- deferred.resolveWith( deferred, args );
- }
- } else if ( deferred !== firstParam ) {
- deferred.resolveWith( deferred, length ? [ firstParam ] : [] );
- }
- return promise;
- }
-});
-
-
-
-
-jQuery.support = (function() {
-
- var support,
- all,
- a,
- select,
- opt,
- input,
- fragment,
- tds,
- events,
- eventName,
- i,
- isSupported,
- div = document.createElement( "div" ),
- documentElement = document.documentElement;
-
- // Preliminary tests
- div.setAttribute("className", "t");
- div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
-
- all = div.getElementsByTagName( "*" );
- a = div.getElementsByTagName( "a" )[ 0 ];
-
- // Can't get basic test support
- if ( !all || !all.length || !a ) {
- return {};
- }
-
- // First batch of supports tests
- select = document.createElement( "select" );
- opt = select.appendChild( document.createElement("option") );
- input = div.getElementsByTagName( "input" )[ 0 ];
-
- support = {
- // IE strips leading whitespace when .innerHTML is used
- leadingWhitespace: ( div.firstChild.nodeType === 3 ),
-
- // Make sure that tbody elements aren't automatically inserted
- // IE will insert them into empty tables
- tbody: !div.getElementsByTagName("tbody").length,
-
- // Make sure that link elements get serialized correctly by innerHTML
- // This requires a wrapper element in IE
- htmlSerialize: !!div.getElementsByTagName("link").length,
-
- // Get the style information from getAttribute
- // (IE uses .cssText instead)
- style: /top/.test( a.getAttribute("style") ),
-
- // Make sure that URLs aren't manipulated
- // (IE normalizes it by default)
- hrefNormalized: ( a.getAttribute("href") === "/a" ),
-
- // Make sure that element opacity exists
- // (IE uses filter instead)
- // Use a regex to work around a WebKit issue. See #5145
- opacity: /^0.55/.test( a.style.opacity ),
-
- // Verify style float existence
- // (IE uses styleFloat instead of cssFloat)
- cssFloat: !!a.style.cssFloat,
-
- // Make sure that if no value is specified for a checkbox
- // that it defaults to "on".
- // (WebKit defaults to "" instead)
- checkOn: ( input.value === "on" ),
-
- // Make sure that a selected-by-default option has a working selected property.
- // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
- optSelected: opt.selected,
-
- // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
- getSetAttribute: div.className !== "t",
-
- // Tests for enctype support on a form(#6743)
- enctype: !!document.createElement("form").enctype,
-
- // Makes sure cloning an html5 element does not cause problems
- // Where outerHTML is undefined, this still works
- html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",
-
- // Will be defined later
- submitBubbles: true,
- changeBubbles: true,
- focusinBubbles: false,
- deleteExpando: true,
- noCloneEvent: true,
- inlineBlockNeedsLayout: false,
- shrinkWrapBlocks: false,
- reliableMarginRight: true,
- pixelMargin: true
- };
-
- // jQuery.boxModel DEPRECATED in 1.3, use jQuery.support.boxModel instead
- jQuery.boxModel = support.boxModel = (document.compatMode === "CSS1Compat");
-
- // Make sure checked status is properly cloned
- input.checked = true;
- support.noCloneChecked = input.cloneNode( true ).checked;
-
- // Make sure that the options inside disabled selects aren't marked as disabled
- // (WebKit marks them as disabled)
- select.disabled = true;
- support.optDisabled = !opt.disabled;
-
- // Test to see if it's possible to delete an expando from an element
- // Fails in Internet Explorer
- try {
- delete div.test;
- } catch( e ) {
- support.deleteExpando = false;
- }
-
- if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
- div.attachEvent( "onclick", function() {
- // Cloning a node shouldn't copy over any
- // bound event handlers (IE does this)
- support.noCloneEvent = false;
- });
- div.cloneNode( true ).fireEvent( "onclick" );
- }
-
- // Check if a radio maintains its value
- // after being appended to the DOM
- input = document.createElement("input");
- input.value = "t";
- input.setAttribute("type", "radio");
- support.radioValue = input.value === "t";
-
- input.setAttribute("checked", "checked");
-
- // #11217 - WebKit loses check when the name is after the checked attribute
- input.setAttribute( "name", "t" );
-
- div.appendChild( input );
- fragment = document.createDocumentFragment();
- fragment.appendChild( div.lastChild );
-
- // WebKit doesn't clone checked state correctly in fragments
- support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
-
- // Check if a disconnected checkbox will retain its checked
- // value of true after appended to the DOM (IE6/7)
- support.appendChecked = input.checked;
-
- fragment.removeChild( input );
- fragment.appendChild( div );
-
- // Technique from Juriy Zaytsev
- // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
- // We only care about the case where non-standard event systems
- // are used, namely in IE. Short-circuiting here helps us to
- // avoid an eval call (in setAttribute) which can cause CSP
- // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
- if ( div.attachEvent ) {
- for ( i in {
- submit: 1,
- change: 1,
- focusin: 1
- }) {
- eventName = "on" + i;
- isSupported = ( eventName in div );
- if ( !isSupported ) {
- div.setAttribute( eventName, "return;" );
- isSupported = ( typeof div[ eventName ] === "function" );
- }
- support[ i + "Bubbles" ] = isSupported;
- }
- }
-
- fragment.removeChild( div );
-
- // Null elements to avoid leaks in IE
- fragment = select = opt = div = input = null;
-
- // Run tests that need a body at doc ready
- jQuery(function() {
- var container, outer, inner, table, td, offsetSupport,
- marginDiv, conMarginTop, style, html, positionTopLeftWidthHeight,
- paddingMarginBorderVisibility, paddingMarginBorder,
- body = document.getElementsByTagName("body")[0];
-
- if ( !body ) {
- // Return for frameset docs that don't have a body
- return;
- }
-
- conMarginTop = 1;
- paddingMarginBorder = "padding:0;margin:0;border:";
- positionTopLeftWidthHeight = "position:absolute;top:0;left:0;width:1px;height:1px;";
- paddingMarginBorderVisibility = paddingMarginBorder + "0;visibility:hidden;";
- style = "style='" + positionTopLeftWidthHeight + paddingMarginBorder + "5px solid #000;";
- html = "<div " + style + "display:block;'><div style='" + paddingMarginBorder + "0;display:block;overflow:hidden;'></div></div>" +
- "<table " + style + "' cellpadding='0' cellspacing='0'>" +
- "<tr><td></td></tr></table>";
-
- container = document.createElement("div");
- container.style.cssText = paddingMarginBorderVisibility + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px";
- body.insertBefore( container, body.firstChild );
-
- // Construct the test element
- div = document.createElement("div");
- container.appendChild( div );
-
- // Check if table cells still have offsetWidth/Height when they are set
- // to display:none and there are still other visible table cells in a
- // table row; if so, offsetWidth/Height are not reliable for use when
- // determining if an element has been hidden directly using
- // display:none (it is still safe to use offsets if a parent element is
- // hidden; don safety goggles and see bug #4512 for more information).
- // (only IE 8 fails this test)
- div.innerHTML = "<table><tr><td style='" + paddingMarginBorder + "0;display:none'></td><td>t</td></tr></table>";
- tds = div.getElementsByTagName( "td" );
- isSupported = ( tds[ 0 ].offsetHeight === 0 );
-
- tds[ 0 ].style.display = "";
- tds[ 1 ].style.display = "none";
-
- // Check if empty table cells still have offsetWidth/Height
- // (IE <= 8 fail this test)
- support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
-
- // Check if div with explicit width and no margin-right incorrectly
- // gets computed margin-right based on width of container. For more
- // info see bug #3333
- // Fails in WebKit before Feb 2011 nightlies
- // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
- if ( window.getComputedStyle ) {
- div.innerHTML = "";
- marginDiv = document.createElement( "div" );
- marginDiv.style.width = "0";
- marginDiv.style.marginRight = "0";
- div.style.width = "2px";
- div.appendChild( marginDiv );
- support.reliableMarginRight =
- ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
- }
-
- if ( typeof div.style.zoom !== "undefined" ) {
- // Check if natively block-level elements act like inline-block
- // elements when setting their display to 'inline' and giving
- // them layout
- // (IE < 8 does this)
- div.innerHTML = "";
- div.style.width = div.style.padding = "1px";
- div.style.border = 0;
- div.style.overflow = "hidden";
- div.style.display = "inline";
- div.style.zoom = 1;
- support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
-
- // Check if elements with layout shrink-wrap their children
- // (IE 6 does this)
- div.style.display = "block";
- div.style.overflow = "visible";
- div.innerHTML = "<div style='width:5px;'></div>";
- support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
- }
-
- div.style.cssText = positionTopLeftWidthHeight + paddingMarginBorderVisibility;
- div.innerHTML = html;
-
- outer = div.firstChild;
- inner = outer.firstChild;
- td = outer.nextSibling.firstChild.firstChild;
-
- offsetSupport = {
- doesNotAddBorder: ( inner.offsetTop !== 5 ),
- doesAddBorderForTableAndCells: ( td.offsetTop === 5 )
- };
-
- inner.style.position = "fixed";
- inner.style.top = "20px";
-
- // safari subtracts parent border width here which is 5px
- offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 );
- inner.style.position = inner.style.top = "";
-
- outer.style.overflow = "hidden";
- outer.style.position = "relative";
-
- offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 );
- offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop );
-
- if ( window.getComputedStyle ) {
- div.style.marginTop = "1%";
- support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%";
- }
-
- if ( typeof container.style.zoom !== "undefined" ) {
- container.style.zoom = 1;
- }
-
- body.removeChild( container );
- marginDiv = div = container = null;
-
- jQuery.extend( support, offsetSupport );
- });
-
- return support;
-})();
-
-
-
-
-var rbrace = /^(?:\{.*\}|\[.*\])$/,
- rmultiDash = /([A-Z])/g;
-
-jQuery.extend({
- cache: {},
-
- // Please use with caution
- uuid: 0,
-
- // Unique for each copy of jQuery on the page
- // Non-digits removed to match rinlinejQuery
- expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ),
-
- // The following elements throw uncatchable exceptions if you
- // attempt to add expando properties to them.
- noData: {
- "embed": true,
- // Ban all objects except for Flash (which handle expandos)
- "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
- "applet": true
- },
-
- hasData: function( elem ) {
- elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
- return !!elem && !isEmptyDataObject( elem );
- },
-
- data: function( elem, name, data, pvt /* Internal Use Only */ ) {
- if ( !jQuery.acceptData( elem ) ) {
- return;
- }
-
- var privateCache, thisCache, ret,
- internalKey = jQuery.expando,
- getByName = typeof name === "string",
-
- // We have to handle DOM nodes and JS objects differently because IE6-7
- // can't GC object references properly across the DOM-JS boundary
- isNode = elem.nodeType,
-
- // Only DOM nodes need the global jQuery cache; JS object data is
- // attached directly to the object so GC can occur automatically
- cache = isNode ? jQuery.cache : elem,
-
- // Only defining an ID for JS objects if its cache already exists allows
- // the code to shortcut on the same path as a DOM node with no cache
- id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey,
- isEvents = name === "events";
-
- // Avoid doing any more work than we need to when trying to get data on an
- // object that has no data at all
- if ( (!id || !cache[id] || (!isEvents && !pvt && !cache[id].data)) && getByName && data === undefined ) {
- return;
- }
-
- if ( !id ) {
- // Only DOM nodes need a new unique ID for each element since their data
- // ends up in the global cache
- if ( isNode ) {
- elem[ internalKey ] = id = ++jQuery.uuid;
- } else {
- id = internalKey;
- }
- }
-
- if ( !cache[ id ] ) {
- cache[ id ] = {};
-
- // Avoids exposing jQuery metadata on plain JS objects when the object
- // is serialized using JSON.stringify
- if ( !isNode ) {
- cache[ id ].toJSON = jQuery.noop;
- }
- }
-
- // An object can be passed to jQuery.data instead of a key/value pair; this gets
- // shallow copied over onto the existing cache
- if ( typeof name === "object" || typeof name === "function" ) {
- if ( pvt ) {
- cache[ id ] = jQuery.extend( cache[ id ], name );
- } else {
- cache[ id ].data = jQuery.extend( cache[ id ].data, name );
- }
- }
-
- privateCache = thisCache = cache[ id ];
-
- // jQuery data() is stored in a separate object inside the object's internal data
- // cache in order to avoid key collisions between internal data and user-defined
- // data.
- if ( !pvt ) {
- if ( !thisCache.data ) {
- thisCache.data = {};
- }
-
- thisCache = thisCache.data;
- }
-
- if ( data !== undefined ) {
- thisCache[ jQuery.camelCase( name ) ] = data;
- }
-
- // Users should not attempt to inspect the internal events object using jQuery.data,
- // it is undocumented and subject to change. But does anyone listen? No.
- if ( isEvents && !thisCache[ name ] ) {
- return privateCache.events;
- }
-
- // Check for both converted-to-camel and non-converted data property names
- // If a data property was specified
- if ( getByName ) {
-
- // First Try to find as-is property data
- ret = thisCache[ name ];
-
- // Test for null|undefined property data
- if ( ret == null ) {
-
- // Try to find the camelCased property
- ret = thisCache[ jQuery.camelCase( name ) ];
- }
- } else {
- ret = thisCache;
- }
-
- return ret;
- },
-
- removeData: function( elem, name, pvt /* Internal Use Only */ ) {
- if ( !jQuery.acceptData( elem ) ) {
- return;
- }
-
- var thisCache, i, l,
-
- // Reference to internal data cache key
- internalKey = jQuery.expando,
-
- isNode = elem.nodeType,
-
- // See jQuery.data for more information
- cache = isNode ? jQuery.cache : elem,
-
- // See jQuery.data for more information
- id = isNode ? elem[ internalKey ] : internalKey;
-
- // If there is already no cache entry for this object, there is no
- // purpose in continuing
- if ( !cache[ id ] ) {
- return;
- }
-
- if ( name ) {
-
- thisCache = pvt ? cache[ id ] : cache[ id ].data;
-
- if ( thisCache ) {
-
- // Support array or space separated string names for data keys
- if ( !jQuery.isArray( name ) ) {
-
- // try the string as a key before any manipulation
- if ( name in thisCache ) {
- name = [ name ];
- } else {
-
- // split the camel cased version by spaces unless a key with the spaces exists
- name = jQuery.camelCase( name );
- if ( name in thisCache ) {
- name = [ name ];
- } else {
- name = name.split( " " );
- }
- }
- }
-
- for ( i = 0, l = name.length; i < l; i++ ) {
- delete thisCache[ name[i] ];
- }
-
- // If there is no data left in the cache, we want to continue
- // and let the cache object itself get destroyed
- if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) {
- return;
- }
- }
- }
-
- // See jQuery.data for more information
- if ( !pvt ) {
- delete cache[ id ].data;
-
- // Don't destroy the parent cache unless the internal data object
- // had been the only thing left in it
- if ( !isEmptyDataObject(cache[ id ]) ) {
- return;
- }
- }
-
- // Browsers that fail expando deletion also refuse to delete expandos on
- // the window, but it will allow it on all other JS objects; other browsers
- // don't care
- // Ensure that `cache` is not a window object #10080
- if ( jQuery.support.deleteExpando || !cache.setInterval ) {
- delete cache[ id ];
- } else {
- cache[ id ] = null;
- }
-
- // We destroyed the cache and need to eliminate the expando on the node to avoid
- // false lookups in the cache for entries that no longer exist
- if ( isNode ) {
- // IE does not allow us to delete expando properties from nodes,
- // nor does it have a removeAttribute function on Document nodes;
- // we must handle all of these cases
- if ( jQuery.support.deleteExpando ) {
- delete elem[ internalKey ];
- } else if ( elem.removeAttribute ) {
- elem.removeAttribute( internalKey );
- } else {
- elem[ internalKey ] = null;
- }
- }
- },
-
- // For internal use only.
- _data: function( elem, name, data ) {
- return jQuery.data( elem, name, data, true );
- },
-
- // A method for determining if a DOM node can handle the data expando
- acceptData: function( elem ) {
- if ( elem.nodeName ) {
- var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
-
- if ( match ) {
- return !(match === true || elem.getAttribute("classid") !== match);
- }
- }
-
- return true;
- }
-});
-
-jQuery.fn.extend({
- data: function( key, value ) {
- var parts, part, attr, name, l,
- elem = this[0],
- i = 0,
- data = null;
-
- // Gets all values
- if ( key === undefined ) {
- if ( this.length ) {
- data = jQuery.data( elem );
-
- if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
- attr = elem.attributes;
- for ( l = attr.length; i < l; i++ ) {
- name = attr[i].name;
-
- if ( name.indexOf( "data-" ) === 0 ) {
- name = jQuery.camelCase( name.substring(5) );
-
- dataAttr( elem, name, data[ name ] );
- }
- }
- jQuery._data( elem, "parsedAttrs", true );
- }
- }
-
- return data;
- }
-
- // Sets multiple values
- if ( typeof key === "object" ) {
- return this.each(function() {
- jQuery.data( this, key );
- });
- }
-
- parts = key.split( ".", 2 );
- parts[1] = parts[1] ? "." + parts[1] : "";
- part = parts[1] + "!";
-
- return jQuery.access( this, function( value ) {
-
- if ( value === undefined ) {
- data = this.triggerHandler( "getData" + part, [ parts[0] ] );
-
- // Try to fetch any internally stored data first
- if ( data === undefined && elem ) {
- data = jQuery.data( elem, key );
- data = dataAttr( elem, key, data );
- }
-
- return data === undefined && parts[1] ?
- this.data( parts[0] ) :
- data;
- }
-
- parts[1] = value;
- this.each(function() {
- var self = jQuery( this );
-
- self.triggerHandler( "setData" + part, parts );
- jQuery.data( this, key, value );
- self.triggerHandler( "changeData" + part, parts );
- });
- }, null, value, arguments.length > 1, null, false );
- },
-
- removeData: function( key ) {
- return this.each(function() {
- jQuery.removeData( this, key );
- });
- }
-});
-
-function dataAttr( elem, key, data ) {
- // If nothing was found internally, try to fetch any
- // data from the HTML5 data-* attribute
- if ( data === undefined && elem.nodeType === 1 ) {
-
- var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
-
- data = elem.getAttribute( name );
-
- if ( typeof data === "string" ) {
- try {
- data = data === "true" ? true :
- data === "false" ? false :
- data === "null" ? null :
- jQuery.isNumeric( data ) ? +data :
- rbrace.test( data ) ? jQuery.parseJSON( data ) :
- data;
- } catch( e ) {}
-
- // Make sure we set the data so it isn't changed later
- jQuery.data( elem, key, data );
-
- } else {
- data = undefined;
- }
- }
-
- return data;
-}
-
-// checks a cache object for emptiness
-function isEmptyDataObject( obj ) {
- for ( var name in obj ) {
-
- // if the public data object is empty, the private is still empty
- if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
- continue;
- }
- if ( name !== "toJSON" ) {
- return false;
- }
- }
-
- return true;
-}
-
-
-
-
-function handleQueueMarkDefer( elem, type, src ) {
- var deferDataKey = type + "defer",
- queueDataKey = type + "queue",
- markDataKey = type + "mark",
- defer = jQuery._data( elem, deferDataKey );
- if ( defer &&
- ( src === "queue" || !jQuery._data(elem, queueDataKey) ) &&
- ( src === "mark" || !jQuery._data(elem, markDataKey) ) ) {
- // Give room for hard-coded callbacks to fire first
- // and eventually mark/queue something else on the element
- setTimeout( function() {
- if ( !jQuery._data( elem, queueDataKey ) &&
- !jQuery._data( elem, markDataKey ) ) {
- jQuery.removeData( elem, deferDataKey, true );
- defer.fire();
- }
- }, 0 );
- }
-}
-
-jQuery.extend({
-
- _mark: function( elem, type ) {
- if ( elem ) {
- type = ( type || "fx" ) + "mark";
- jQuery._data( elem, type, (jQuery._data( elem, type ) || 0) + 1 );
- }
- },
-
- _unmark: function( force, elem, type ) {
- if ( force !== true ) {
- type = elem;
- elem = force;
- force = false;
- }
- if ( elem ) {
- type = type || "fx";
- var key = type + "mark",
- count = force ? 0 : ( (jQuery._data( elem, key ) || 1) - 1 );
- if ( count ) {
- jQuery._data( elem, key, count );
- } else {
- jQuery.removeData( elem, key, true );
- handleQueueMarkDefer( elem, type, "mark" );
- }
- }
- },
-
- queue: function( elem, type, data ) {
- var q;
- if ( elem ) {
- type = ( type || "fx" ) + "queue";
- q = jQuery._data( elem, type );
-
- // Speed up dequeue by getting out quickly if this is just a lookup
- if ( data ) {
- if ( !q || jQuery.isArray(data) ) {
- q = jQuery._data( elem, type, jQuery.makeArray(data) );
- } else {
- q.push( data );
- }
- }
- return q || [];
- }
- },
-
- dequeue: function( elem, type ) {
- type = type || "fx";
-
- var queue = jQuery.queue( elem, type ),
- fn = queue.shift(),
- hooks = {};
-
- // If the fx queue is dequeued, always remove the progress sentinel
- if ( fn === "inprogress" ) {
- fn = queue.shift();
- }
-
- if ( fn ) {
- // Add a progress sentinel to prevent the fx queue from being
- // automatically dequeued
- if ( type === "fx" ) {
- queue.unshift( "inprogress" );
- }
-
- jQuery._data( elem, type + ".run", hooks );
- fn.call( elem, function() {
- jQuery.dequeue( elem, type );
- }, hooks );
- }
-
- if ( !queue.length ) {
- jQuery.removeData( elem, type + "queue " + type + ".run", true );
- handleQueueMarkDefer( elem, type, "queue" );
- }
- }
-});
-
-jQuery.fn.extend({
- queue: function( type, data ) {
- var setter = 2;
-
- if ( typeof type !== "string" ) {
- data = type;
- type = "fx";
- setter--;
- }
-
- if ( arguments.length < setter ) {
- return jQuery.queue( this[0], type );
- }
-
- return data === undefined ?
- this :
- this.each(function() {
- var queue = jQuery.queue( this, type, data );
-
- if ( type === "fx" && queue[0] !== "inprogress" ) {
- jQuery.dequeue( this, type );
- }
- });
- },
- dequeue: function( type ) {
- return this.each(function() {
- jQuery.dequeue( this, type );
- });
- },
- // Based off of the plugin by Clint Helfers, with permission.
- // http://blindsignals.com/index.php/2009/07/jquery-delay/
- delay: function( time, type ) {
- time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
- type = type || "fx";
-
- return this.queue( type, function( next, hooks ) {
- var timeout = setTimeout( next, time );
- hooks.stop = function() {
- clearTimeout( timeout );
- };
- });
- },
- clearQueue: function( type ) {
- return this.queue( type || "fx", [] );
- },
- // Get a promise resolved when queues of a certain type
- // are emptied (fx is the type by default)
- promise: function( type, object ) {
- if ( typeof type !== "string" ) {
- object = type;
- type = undefined;
- }
- type = type || "fx";
- var defer = jQuery.Deferred(),
- elements = this,
- i = elements.length,
- count = 1,
- deferDataKey = type + "defer",
- queueDataKey = type + "queue",
- markDataKey = type + "mark",
- tmp;
- function resolve() {
- if ( !( --count ) ) {
- defer.resolveWith( elements, [ elements ] );
- }
- }
- while( i-- ) {
- if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
- ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) ||
- jQuery.data( elements[ i ], markDataKey, undefined, true ) ) &&
- jQuery.data( elements[ i ], deferDataKey, jQuery.Callbacks( "once memory" ), true ) )) {
- count++;
- tmp.add( resolve );
- }
- }
- resolve();
- return defer.promise( object );
- }
-});
-
-
-
-
-var rclass = /[\n\t\r]/g,
- rspace = /\s+/,
- rreturn = /\r/g,
- rtype = /^(?:button|input)$/i,
- rfocusable = /^(?:button|input|object|select|textarea)$/i,
- rclickable = /^a(?:rea)?$/i,
- rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
- getSetAttribute = jQuery.support.getSetAttribute,
- nodeHook, boolHook, fixSpecified;
-
-jQuery.fn.extend({
- attr: function( name, value ) {
- return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
- },
-
- removeAttr: function( name ) {
- return this.each(function() {
- jQuery.removeAttr( this, name );
- });
- },
-
- prop: function( name, value ) {
- return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
- },
-
- removeProp: function( name ) {
- name = jQuery.propFix[ name ] || name;
- return this.each(function() {
- // try/catch handles cases where IE balks (such as removing a property on window)
- try {
- this[ name ] = undefined;
- delete this[ name ];
- } catch( e ) {}
- });
- },
-
- addClass: function( value ) {
- var classNames, i, l, elem,
- setClass, c, cl;
-
- if ( jQuery.isFunction( value ) ) {
- return this.each(function( j ) {
- jQuery( this ).addClass( value.call(this, j, this.className) );
- });
- }
-
- if ( value && typeof value === "string" ) {
- classNames = value.split( rspace );
-
- for ( i = 0, l = this.length; i < l; i++ ) {
- elem = this[ i ];
-
- if ( elem.nodeType === 1 ) {
- if ( !elem.className && classNames.length === 1 ) {
- elem.className = value;
-
- } else {
- setClass = " " + elem.className + " ";
-
- for ( c = 0, cl = classNames.length; c < cl; c++ ) {
- if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) {
- setClass += classNames[ c ] + " ";
- }
- }
- elem.className = jQuery.trim( setClass );
- }
- }
- }
- }
-
- return this;
- },
-
- removeClass: function( value ) {
- var classNames, i, l, elem, className, c, cl;
-
- if ( jQuery.isFunction( value ) ) {
- return this.each(function( j ) {
- jQuery( this ).removeClass( value.call(this, j, this.className) );
- });
- }
-
- if ( (value && typeof value === "string") || value === undefined ) {
- classNames = ( value || "" ).split( rspace );
-
- for ( i = 0, l = this.length; i < l; i++ ) {
- elem = this[ i ];
-
- if ( elem.nodeType === 1 && elem.className ) {
- if ( value ) {
- className = (" " + elem.className + " ").replace( rclass, " " );
- for ( c = 0, cl = classNames.length; c < cl; c++ ) {
- className = className.replace(" " + classNames[ c ] + " ", " ");
- }
- elem.className = jQuery.trim( className );
-
- } else {
- elem.className = "";
- }
- }
- }
- }
-
- return this;
- },
-
- toggleClass: function( value, stateVal ) {
- var type = typeof value,
- isBool = typeof stateVal === "boolean";
-
- if ( jQuery.isFunction( value ) ) {
- return this.each(function( i ) {
- jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
- });
- }
-
- return this.each(function() {
- if ( type === "string" ) {
- // toggle individual class names
- var className,
- i = 0,
- self = jQuery( this ),
- state = stateVal,
- classNames = value.split( rspace );
-
- while ( (className = classNames[ i++ ]) ) {
- // check each className given, space seperated list
- state = isBool ? state : !self.hasClass( className );
- self[ state ? "addClass" : "removeClass" ]( className );
- }
-
- } else if ( type === "undefined" || type === "boolean" ) {
- if ( this.className ) {
- // store className if set
- jQuery._data( this, "__className__", this.className );
- }
-
- // toggle whole className
- this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
- }
- });
- },
-
- hasClass: function( selector ) {
- var className = " " + selector + " ",
- i = 0,
- l = this.length;
- for ( ; i < l; i++ ) {
- if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
- return true;
- }
- }
-
- return false;
- },
-
- val: function( value ) {
- var hooks, ret, isFunction,
- elem = this[0];
-
- if ( !arguments.length ) {
- if ( elem ) {
- hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
-
- if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
- return ret;
- }
-
- ret = elem.value;
-
- return typeof ret === "string" ?
- // handle most common string cases
- ret.replace(rreturn, "") :
- // handle cases where value is null/undef or number
- ret == null ? "" : ret;
- }
-
- return;
- }
-
- isFunction = jQuery.isFunction( value );
-
- return this.each(function( i ) {
- var self = jQuery(this), val;
-
- if ( this.nodeType !== 1 ) {
- return;
- }
-
- if ( isFunction ) {
- val = value.call( this, i, self.val() );
- } else {
- val = value;
- }
-
- // Treat null/undefined as ""; convert numbers to string
- if ( val == null ) {
- val = "";
- } else if ( typeof val === "number" ) {
- val += "";
- } else if ( jQuery.isArray( val ) ) {
- val = jQuery.map(val, function ( value ) {
- return value == null ? "" : value + "";
- });
- }
-
- hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
-
- // If set returns undefined, fall back to normal setting
- if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
- this.value = val;
- }
- });
- }
-});
-
-jQuery.extend({
- valHooks: {
- option: {
- get: function( elem ) {
- // attributes.value is undefined in Blackberry 4.7 but
- // uses .value. See #6932
- var val = elem.attributes.value;
- return !val || val.specified ? elem.value : elem.text;
- }
- },
- select: {
- get: function( elem ) {
- var value, i, max, option,
- index = elem.selectedIndex,
- values = [],
- options = elem.options,
- one = elem.type === "select-one";
-
- // Nothing was selected
- if ( index < 0 ) {
- return null;
- }
-
- // Loop through all the selected options
- i = one ? index : 0;
- max = one ? index + 1 : options.length;
- for ( ; i < max; i++ ) {
- option = options[ i ];
-
- // Don't return options that are disabled or in a disabled optgroup
- if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
- (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
-
- // Get the specific value for the option
- value = jQuery( option ).val();
-
- // We don't need an array for one selects
- if ( one ) {
- return value;
- }
-
- // Multi-Selects return an array
- values.push( value );
- }
- }
-
- // Fixes Bug #2551 -- select.val() broken in IE after form.reset()
- if ( one && !values.length && options.length ) {
- return jQuery( options[ index ] ).val();
- }
-
- return values;
- },
-
- set: function( elem, value ) {
- var values = jQuery.makeArray( value );
-
- jQuery(elem).find("option").each(function() {
- this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
- });
-
- if ( !values.length ) {
- elem.selectedIndex = -1;
- }
- return values;
- }
- }
- },
-
- attrFn: {
- val: true,
- css: true,
- html: true,
- text: true,
- data: true,
- width: true,
- height: true,
- offset: true
- },
-
- attr: function( elem, name, value, pass ) {
- var ret, hooks, notxml,
- nType = elem.nodeType;
-
- // don't get/set attributes on text, comment and attribute nodes
- if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
- return;
- }
-
- if ( pass && name in jQuery.attrFn ) {
- return jQuery( elem )[ name ]( value );
- }
-
- // Fallback to prop when attributes are not supported
- if ( typeof elem.getAttribute === "undefined" ) {
- return jQuery.prop( elem, name, value );
- }
-
- notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
-
- // All attributes are lowercase
- // Grab necessary hook if one is defined
- if ( notxml ) {
- name = name.toLowerCase();
- hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
- }
-
- if ( value !== undefined ) {
-
- if ( value === null ) {
- jQuery.removeAttr( elem, name );
- return;
-
- } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
- return ret;
-
- } else {
- elem.setAttribute( name, "" + value );
- return value;
- }
-
- } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) {
- return ret;
-
- } else {
-
- ret = elem.getAttribute( name );
-
- // Non-existent attributes return null, we normalize to undefined
- return ret === null ?
- undefined :
- ret;
- }
- },
-
- removeAttr: function( elem, value ) {
- var propName, attrNames, name, l, isBool,
- i = 0;
-
- if ( value && elem.nodeType === 1 ) {
- attrNames = value.toLowerCase().split( rspace );
- l = attrNames.length;
-
- for ( ; i < l; i++ ) {
- name = attrNames[ i ];
-
- if ( name ) {
- propName = jQuery.propFix[ name ] || name;
- isBool = rboolean.test( name );
-
- // See #9699 for explanation of this approach (setting first, then removal)
- // Do not do this for boolean attributes (see #10870)
- if ( !isBool ) {
- jQuery.attr( elem, name, "" );
- }
- elem.removeAttribute( getSetAttribute ? name : propName );
-
- // Set corresponding property to false for boolean attributes
- if ( isBool && propName in elem ) {
- elem[ propName ] = false;
- }
- }
- }
- }
- },
-
- attrHooks: {
- type: {
- set: function( elem, value ) {
- // We can't allow the type property to be changed (since it causes problems in IE)
- if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
- jQuery.error( "type property can't be changed" );
- } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
- // Setting the type on a radio button after the value resets the value in IE6-9
- // Reset value to it's default in case type is set after value
- // This is for element creation
- var val = elem.value;
- elem.setAttribute( "type", value );
- if ( val ) {
- elem.value = val;
- }
- return value;
- }
- }
- },
- // Use the value property for back compat
- // Use the nodeHook for button elements in IE6/7 (#1954)
- value: {
- get: function( elem, name ) {
- if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
- return nodeHook.get( elem, name );
- }
- return name in elem ?
- elem.value :
- null;
- },
- set: function( elem, value, name ) {
- if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
- return nodeHook.set( elem, value, name );
- }
- // Does not return so that setAttribute is also used
- elem.value = value;
- }
- }
- },
-
- propFix: {
- tabindex: "tabIndex",
- readonly: "readOnly",
- "for": "htmlFor",
- "class": "className",
- maxlength: "maxLength",
- cellspacing: "cellSpacing",
- cellpadding: "cellPadding",
- rowspan: "rowSpan",
- colspan: "colSpan",
- usemap: "useMap",
- frameborder: "frameBorder",
- contenteditable: "contentEditable"
- },
-
- prop: function( elem, name, value ) {
- var ret, hooks, notxml,
- nType = elem.nodeType;
-
- // don't get/set properties on text, comment and attribute nodes
- if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
- return;
- }
-
- notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
-
- if ( notxml ) {
- // Fix name and attach hooks
- name = jQuery.propFix[ name ] || name;
- hooks = jQuery.propHooks[ name ];
- }
-
- if ( value !== undefined ) {
- if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
- return ret;
-
- } else {
- return ( elem[ name ] = value );
- }
-
- } else {
- if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
- return ret;
-
- } else {
- return elem[ name ];
- }
- }
- },
-
- propHooks: {
- tabIndex: {
- get: function( elem ) {
- // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
- // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
- var attributeNode = elem.getAttributeNode("tabindex");
-
- return attributeNode && attributeNode.specified ?
- parseInt( attributeNode.value, 10 ) :
- rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
- 0 :
- undefined;
- }
- }
- }
-});
-
-// Add the tabIndex propHook to attrHooks for back-compat (different case is intentional)
-jQuery.attrHooks.tabindex = jQuery.propHooks.tabIndex;
-
-// Hook for boolean attributes
-boolHook = {
- get: function( elem, name ) {
- // Align boolean attributes with corresponding properties
- // Fall back to attribute presence where some booleans are not supported
- var attrNode,
- property = jQuery.prop( elem, name );
- return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ?
- name.toLowerCase() :
- undefined;
- },
- set: function( elem, value, name ) {
- var propName;
- if ( value === false ) {
- // Remove boolean attributes when set to false
- jQuery.removeAttr( elem, name );
- } else {
- // value is true since we know at this point it's type boolean and not false
- // Set boolean attributes to the same name and set the DOM property
- propName = jQuery.propFix[ name ] || name;
- if ( propName in elem ) {
- // Only set the IDL specifically if it already exists on the element
- elem[ propName ] = true;
- }
-
- elem.setAttribute( name, name.toLowerCase() );
- }
- return name;
- }
-};
-
-// IE6/7 do not support getting/setting some attributes with get/setAttribute
-if ( !getSetAttribute ) {
-
- fixSpecified = {
- name: true,
- id: true,
- coords: true
- };
-
- // Use this for any attribute in IE6/7
- // This fixes almost every IE6/7 issue
- nodeHook = jQuery.valHooks.button = {
- get: function( elem, name ) {
- var ret;
- ret = elem.getAttributeNode( name );
- return ret && ( fixSpecified[ name ] ? ret.nodeValue !== "" : ret.specified ) ?
- ret.nodeValue :
- undefined;
- },
- set: function( elem, value, name ) {
- // Set the existing or create a new attribute node
- var ret = elem.getAttributeNode( name );
- if ( !ret ) {
- ret = document.createAttribute( name );
- elem.setAttributeNode( ret );
- }
- return ( ret.nodeValue = value + "" );
- }
- };
-
- // Apply the nodeHook to tabindex
- jQuery.attrHooks.tabindex.set = nodeHook.set;
-
- // Set width and height to auto instead of 0 on empty string( Bug #8150 )
- // This is for removals
- jQuery.each([ "width", "height" ], function( i, name ) {
- jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
- set: function( elem, value ) {
- if ( value === "" ) {
- elem.setAttribute( name, "auto" );
- return value;
- }
- }
- });
- });
-
- // Set contenteditable to false on removals(#10429)
- // Setting to empty string throws an error as an invalid value
- jQuery.attrHooks.contenteditable = {
- get: nodeHook.get,
- set: function( elem, value, name ) {
- if ( value === "" ) {
- value = "false";
- }
- nodeHook.set( elem, value, name );
- }
- };
-}
-
-
-// Some attributes require a special call on IE
-if ( !jQuery.support.hrefNormalized ) {
- jQuery.each([ "href", "src", "width", "height" ], function( i, name ) {
- jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
- get: function( elem ) {
- var ret = elem.getAttribute( name, 2 );
- return ret === null ? undefined : ret;
- }
- });
- });
-}
-
-if ( !jQuery.support.style ) {
- jQuery.attrHooks.style = {
- get: function( elem ) {
- // Return undefined in the case of empty string
- // Normalize to lowercase since IE uppercases css property names
- return elem.style.cssText.toLowerCase() || undefined;
- },
- set: function( elem, value ) {
- return ( elem.style.cssText = "" + value );
- }
- };
-}
-
-// Safari mis-reports the default selected property of an option
-// Accessing the parent's selectedIndex property fixes it
-if ( !jQuery.support.optSelected ) {
- jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
- get: function( elem ) {
- var parent = elem.parentNode;
-
- if ( parent ) {
- parent.selectedIndex;
-
- // Make sure that it also works with optgroups, see #5701
- if ( parent.parentNode ) {
- parent.parentNode.selectedIndex;
- }
- }
- return null;
- }
- });
-}
-
-// IE6/7 call enctype encoding
-if ( !jQuery.support.enctype ) {
- jQuery.propFix.enctype = "encoding";
-}
-
-// Radios and checkboxes getter/setter
-if ( !jQuery.support.checkOn ) {
- jQuery.each([ "radio", "checkbox" ], function() {
- jQuery.valHooks[ this ] = {
- get: function( elem ) {
- // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
- return elem.getAttribute("value") === null ? "on" : elem.value;
- }
- };
- });
-}
-jQuery.each([ "radio", "checkbox" ], function() {
- jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
- set: function( elem, value ) {
- if ( jQuery.isArray( value ) ) {
- return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
- }
- }
- });
-});
-
-
-
-
-var rformElems = /^(?:textarea|input|select)$/i,
- rtypenamespace = /^([^\.]*)?(?:\.(.+))?$/,
- rhoverHack = /(?:^|\s)hover(\.\S+)?\b/,
- rkeyEvent = /^key/,
- rmouseEvent = /^(?:mouse|contextmenu)|click/,
- rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
- rquickIs = /^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,
- quickParse = function( selector ) {
- var quick = rquickIs.exec( selector );
- if ( quick ) {
- // 0 1 2 3
- // [ _, tag, id, class ]
- quick[1] = ( quick[1] || "" ).toLowerCase();
- quick[3] = quick[3] && new RegExp( "(?:^|\\s)" + quick[3] + "(?:\\s|$)" );
- }
- return quick;
- },
- quickIs = function( elem, m ) {
- var attrs = elem.attributes || {};
- return (
- (!m[1] || elem.nodeName.toLowerCase() === m[1]) &&
- (!m[2] || (attrs.id || {}).value === m[2]) &&
- (!m[3] || m[3].test( (attrs[ "class" ] || {}).value ))
- );
- },
- hoverHack = function( events ) {
- return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" );
- };
-
-/*
- * Helper functions for managing events -- not part of the public interface.
- * Props to Dean Edwards' addEvent library for many of the ideas.
- */
-jQuery.event = {
-
- add: function( elem, types, handler, data, selector ) {
-
- var elemData, eventHandle, events,
- t, tns, type, namespaces, handleObj,
- handleObjIn, quick, handlers, special;
-
- // Don't attach events to noData or text/comment nodes (allow plain objects tho)
- if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) {
- return;
- }
-
- // Caller can pass in an object of custom data in lieu of the handler
- if ( handler.handler ) {
- handleObjIn = handler;
- handler = handleObjIn.handler;
- selector = handleObjIn.selector;
- }
-
- // Make sure that the handler has a unique ID, used to find/remove it later
- if ( !handler.guid ) {
- handler.guid = jQuery.guid++;
- }
-
- // Init the element's event structure and main handler, if this is the first
- events = elemData.events;
- if ( !events ) {
- elemData.events = events = {};
- }
- eventHandle = elemData.handle;
- if ( !eventHandle ) {
- elemData.handle = eventHandle = function( e ) {
- // Discard the second event of a jQuery.event.trigger() and
- // when an event is called after a page has unloaded
- return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ?
- jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
- undefined;
- };
- // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
- eventHandle.elem = elem;
- }
-
- // Handle multiple events separated by a space
- // jQuery(...).bind("mouseover mouseout", fn);
- types = jQuery.trim( hoverHack(types) ).split( " " );
- for ( t = 0; t < types.length; t++ ) {
-
- tns = rtypenamespace.exec( types[t] ) || [];
- type = tns[1];
- namespaces = ( tns[2] || "" ).split( "." ).sort();
-
- // If event changes its type, use the special event handlers for the changed type
- special = jQuery.event.special[ type ] || {};
-
- // If selector defined, determine special event api type, otherwise given type
- type = ( selector ? special.delegateType : special.bindType ) || type;
-
- // Update special based on newly reset type
- special = jQuery.event.special[ type ] || {};
-
- // handleObj is passed to all event handlers
- handleObj = jQuery.extend({
- type: type,
- origType: tns[1],
- data: data,
- handler: handler,
- guid: handler.guid,
- selector: selector,
- quick: selector && quickParse( selector ),
- namespace: namespaces.join(".")
- }, handleObjIn );
-
- // Init the event handler queue if we're the first
- handlers = events[ type ];
- if ( !handlers ) {
- handlers = events[ type ] = [];
- handlers.delegateCount = 0;
-
- // Only use addEventListener/attachEvent if the special events handler returns false
- if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
- // Bind the global event handler to the element
- if ( elem.addEventListener ) {
- elem.addEventListener( type, eventHandle, false );
-
- } else if ( elem.attachEvent ) {
- elem.attachEvent( "on" + type, eventHandle );
- }
- }
- }
-
- if ( special.add ) {
- special.add.call( elem, handleObj );
-
- if ( !handleObj.handler.guid ) {
- handleObj.handler.guid = handler.guid;
- }
- }
-
- // Add to the element's handler list, delegates in front
- if ( selector ) {
- handlers.splice( handlers.delegateCount++, 0, handleObj );
- } else {
- handlers.push( handleObj );
- }
-
- // Keep track of which events have ever been used, for event optimization
- jQuery.event.global[ type ] = true;
- }
-
- // Nullify elem to prevent memory leaks in IE
- elem = null;
- },
-
- global: {},
-
- // Detach an event or set of events from an element
- remove: function( elem, types, handler, selector, mappedTypes ) {
-
- var elemData = jQuery.hasData( elem ) && jQuery._data( elem ),
- t, tns, type, origType, namespaces, origCount,
- j, events, special, handle, eventType, handleObj;
-
- if ( !elemData || !(events = elemData.events) ) {
- return;
- }
-
- // Once for each type.namespace in types; type may be omitted
- types = jQuery.trim( hoverHack( types || "" ) ).split(" ");
- for ( t = 0; t < types.length; t++ ) {
- tns = rtypenamespace.exec( types[t] ) || [];
- type = origType = tns[1];
- namespaces = tns[2];
-
- // Unbind all events (on this namespace, if provided) for the element
- if ( !type ) {
- for ( type in events ) {
- jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
- }
- continue;
- }
-
- special = jQuery.event.special[ type ] || {};
- type = ( selector? special.delegateType : special.bindType ) || type;
- eventType = events[ type ] || [];
- origCount = eventType.length;
- namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
-
- // Remove matching events
- for ( j = 0; j < eventType.length; j++ ) {
- handleObj = eventType[ j ];
-
- if ( ( mappedTypes || origType === handleObj.origType ) &&
- ( !handler || handler.guid === handleObj.guid ) &&
- ( !namespaces || namespaces.test( handleObj.namespace ) ) &&
- ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
- eventType.splice( j--, 1 );
-
- if ( handleObj.selector ) {
- eventType.delegateCount--;
- }
- if ( special.remove ) {
- special.remove.call( elem, handleObj );
- }
- }
- }
-
- // Remove generic event handler if we removed something and no more handlers exist
- // (avoids potential for endless recursion during removal of special event handlers)
- if ( eventType.length === 0 && origCount !== eventType.length ) {
- if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
- jQuery.removeEvent( elem, type, elemData.handle );
- }
-
- delete events[ type ];
- }
- }
-
- // Remove the expando if it's no longer used
- if ( jQuery.isEmptyObject( events ) ) {
- handle = elemData.handle;
- if ( handle ) {
- handle.elem = null;
- }
-
- // removeData also checks for emptiness and clears the expando if empty
- // so use it instead of delete
- jQuery.removeData( elem, [ "events", "handle" ], true );
- }
- },
-
- // Events that are safe to short-circuit if no handlers are attached.
- // Native DOM events should not be added, they may have inline handlers.
- customEvent: {
- "getData": true,
- "setData": true,
- "changeData": true
- },
-
- trigger: function( event, data, elem, onlyHandlers ) {
- // Don't do events on text and comment nodes
- if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) {
- return;
- }
-
- // Event object or event type
- var type = event.type || event,
- namespaces = [],
- cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType;
-
- // focus/blur morphs to focusin/out; ensure we're not firing them right now
- if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
- return;
- }
-
- if ( type.indexOf( "!" ) >= 0 ) {
- // Exclusive events trigger only for the exact event (no namespaces)
- type = type.slice(0, -1);
- exclusive = true;
- }
-
- if ( type.indexOf( "." ) >= 0 ) {
- // Namespaced trigger; create a regexp to match event type in handle()
- namespaces = type.split(".");
- type = namespaces.shift();
- namespaces.sort();
- }
-
- if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) {
- // No jQuery handlers for this event type, and it can't have inline handlers
- return;
- }
-
- // Caller can pass in an Event, Object, or just an event type string
- event = typeof event === "object" ?
- // jQuery.Event object
- event[ jQuery.expando ] ? event :
- // Object literal
- new jQuery.Event( type, event ) :
- // Just the event type (string)
- new jQuery.Event( type );
-
- event.type = type;
- event.isTrigger = true;
- event.exclusive = exclusive;
- event.namespace = namespaces.join( "." );
- event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)") : null;
- ontype = type.indexOf( ":" ) < 0 ? "on" + type : "";
-
- // Handle a global trigger
- if ( !elem ) {
-
- // TODO: Stop taunting the data cache; remove global events and always attach to document
- cache = jQuery.cache;
- for ( i in cache ) {
- if ( cache[ i ].events && cache[ i ].events[ type ] ) {
- jQuery.event.trigger( event, data, cache[ i ].handle.elem, true );
- }
- }
- return;
- }
-
- // Clean up the event in case it is being reused
- event.result = undefined;
- if ( !event.target ) {
- event.target = elem;
- }
-
- // Clone any incoming data and prepend the event, creating the handler arg list
- data = data != null ? jQuery.makeArray( data ) : [];
- data.unshift( event );
-
- // Allow special events to draw outside the lines
- special = jQuery.event.special[ type ] || {};
- if ( special.trigger && special.trigger.apply( elem, data ) === false ) {
- return;
- }
-
- // Determine event propagation path in advance, per W3C events spec (#9951)
- // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
- eventPath = [[ elem, special.bindType || type ]];
- if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
-
- bubbleType = special.delegateType || type;
- cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode;
- old = null;
- for ( ; cur; cur = cur.parentNode ) {
- eventPath.push([ cur, bubbleType ]);
- old = cur;
- }
-
- // Only add window if we got to document (e.g., not plain obj or detached DOM)
- if ( old && old === elem.ownerDocument ) {
- eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]);
- }
- }
-
- // Fire handlers on the event path
- for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) {
-
- cur = eventPath[i][0];
- event.type = eventPath[i][1];
-
- handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
- if ( handle ) {
- handle.apply( cur, data );
- }
- // Note that this is a bare JS function and not a jQuery handler
- handle = ontype && cur[ ontype ];
- if ( handle && jQuery.acceptData( cur ) && handle.apply( cur, data ) === false ) {
- event.preventDefault();
- }
- }
- event.type = type;
-
- // If nobody prevented the default action, do it now
- if ( !onlyHandlers && !event.isDefaultPrevented() ) {
-
- if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) &&
- !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
-
- // Call a native DOM method on the target with the same name name as the event.
- // Can't use an .isFunction() check here because IE6/7 fails that test.
- // Don't do default actions on window, that's where global variables be (#6170)
- // IE<9 dies on focus/blur to hidden element (#1486)
- if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) {
-
- // Don't re-trigger an onFOO event when we call its FOO() method
- old = elem[ ontype ];
-
- if ( old ) {
- elem[ ontype ] = null;
- }
-
- // Prevent re-triggering of the same event, since we already bubbled it above
- jQuery.event.triggered = type;
- elem[ type ]();
- jQuery.event.triggered = undefined;
-
- if ( old ) {
- elem[ ontype ] = old;
- }
- }
- }
- }
-
- return event.result;
- },
-
- dispatch: function( event ) {
-
- // Make a writable jQuery.Event from the native event object
- event = jQuery.event.fix( event || window.event );
-
- var handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []),
- delegateCount = handlers.delegateCount,
- args = [].slice.call( arguments, 0 ),
- run_all = !event.exclusive && !event.namespace,
- special = jQuery.event.special[ event.type ] || {},
- handlerQueue = [],
- i, j, cur, jqcur, ret, selMatch, matched, matches, handleObj, sel, related;
-
- // Use the fix-ed jQuery.Event rather than the (read-only) native event
- args[0] = event;
- event.delegateTarget = this;
-
- // Call the preDispatch hook for the mapped type, and let it bail if desired
- if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
- return;
- }
-
- // Determine handlers that should run if there are delegated events
- // Avoid non-left-click bubbling in Firefox (#3861)
- if ( delegateCount && !(event.button && event.type === "click") ) {
-
- // Pregenerate a single jQuery object for reuse with .is()
- jqcur = jQuery(this);
- jqcur.context = this.ownerDocument || this;
-
- for ( cur = event.target; cur != this; cur = cur.parentNode || this ) {
-
- // Don't process events on disabled elements (#6911, #8165)
- if ( cur.disabled !== true ) {
- selMatch = {};
- matches = [];
- jqcur[0] = cur;
- for ( i = 0; i < delegateCount; i++ ) {
- handleObj = handlers[ i ];
- sel = handleObj.selector;
-
- if ( selMatch[ sel ] === undefined ) {
- selMatch[ sel ] = (
- handleObj.quick ? quickIs( cur, handleObj.quick ) : jqcur.is( sel )
- );
- }
- if ( selMatch[ sel ] ) {
- matches.push( handleObj );
- }
- }
- if ( matches.length ) {
- handlerQueue.push({ elem: cur, matches: matches });
- }
- }
- }
- }
-
- // Add the remaining (directly-bound) handlers
- if ( handlers.length > delegateCount ) {
- handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) });
- }
-
- // Run delegates first; they may want to stop propagation beneath us
- for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) {
- matched = handlerQueue[ i ];
- event.currentTarget = matched.elem;
-
- for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) {
- handleObj = matched.matches[ j ];
-
- // Triggered event must either 1) be non-exclusive and have no namespace, or
- // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
- if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) {
-
- event.data = handleObj.data;
- event.handleObj = handleObj;
-
- ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
- .apply( matched.elem, args );
-
- if ( ret !== undefined ) {
- event.result = ret;
- if ( ret === false ) {
- event.preventDefault();
- event.stopPropagation();
- }
- }
- }
- }
- }
-
- // Call the postDispatch hook for the mapped type
- if ( special.postDispatch ) {
- special.postDispatch.call( this, event );
- }
-
- return event.result;
- },
-
- // Includes some event props shared by KeyEvent and MouseEvent
- // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 ***
- props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
-
- fixHooks: {},
-
- keyHooks: {
- props: "char charCode key keyCode".split(" "),
- filter: function( event, original ) {
-
- // Add which for key events
- if ( event.which == null ) {
- event.which = original.charCode != null ? original.charCode : original.keyCode;
- }
-
- return event;
- }
- },
-
- mouseHooks: {
- props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
- filter: function( event, original ) {
- var eventDoc, doc, body,
- button = original.button,
- fromElement = original.fromElement;
-
- // Calculate pageX/Y if missing and clientX/Y available
- if ( event.pageX == null && original.clientX != null ) {
- eventDoc = event.target.ownerDocument || document;
- doc = eventDoc.documentElement;
- body = eventDoc.body;
-
- event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
- event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
- }
-
- // Add relatedTarget, if necessary
- if ( !event.relatedTarget && fromElement ) {
- event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
- }
-
- // Add which for click: 1 === left; 2 === middle; 3 === right
- // Note: button is not normalized, so don't use it
- if ( !event.which && button !== undefined ) {
- event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
- }
-
- return event;
- }
- },
-
- fix: function( event ) {
- if ( event[ jQuery.expando ] ) {
- return event;
- }
-
- // Create a writable copy of the event object and normalize some properties
- var i, prop,
- originalEvent = event,
- fixHook = jQuery.event.fixHooks[ event.type ] || {},
- copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
-
- event = jQuery.Event( originalEvent );
-
- for ( i = copy.length; i; ) {
- prop = copy[ --i ];
- event[ prop ] = originalEvent[ prop ];
- }
-
- // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2)
- if ( !event.target ) {
- event.target = originalEvent.srcElement || document;
- }
-
- // Target should not be a text node (#504, Safari)
- if ( event.target.nodeType === 3 ) {
- event.target = event.target.parentNode;
- }
-
- // For mouse/key events; add metaKey if it's not there (#3368, IE6/7/8)
- if ( event.metaKey === undefined ) {
- event.metaKey = event.ctrlKey;
- }
-
- return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
- },
-
- special: {
- ready: {
- // Make sure the ready event is setup
- setup: jQuery.bindReady
- },
-
- load: {
- // Prevent triggered image.load events from bubbling to window.load
- noBubble: true
- },
-
- focus: {
- delegateType: "focusin"
- },
- blur: {
- delegateType: "focusout"
- },
-
- beforeunload: {
- setup: function( data, namespaces, eventHandle ) {
- // We only want to do this special case on windows
- if ( jQuery.isWindow( this ) ) {
- this.onbeforeunload = eventHandle;
- }
- },
-
- teardown: function( namespaces, eventHandle ) {
- if ( this.onbeforeunload === eventHandle ) {
- this.onbeforeunload = null;
- }
- }
- }
- },
-
- simulate: function( type, elem, event, bubble ) {
- // Piggyback on a donor event to simulate a different one.
- // Fake originalEvent to avoid donor's stopPropagation, but if the
- // simulated event prevents default then we do the same on the donor.
- var e = jQuery.extend(
- new jQuery.Event(),
- event,
- { type: type,
- isSimulated: true,
- originalEvent: {}
- }
- );
- if ( bubble ) {
- jQuery.event.trigger( e, null, elem );
- } else {
- jQuery.event.dispatch.call( elem, e );
- }
- if ( e.isDefaultPrevented() ) {
- event.preventDefault();
- }
- }
-};
-
-// Some plugins are using, but it's undocumented/deprecated and will be removed.
-// The 1.7 special event interface should provide all the hooks needed now.
-jQuery.event.handle = jQuery.event.dispatch;
-
-jQuery.removeEvent = document.removeEventListener ?
- function( elem, type, handle ) {
- if ( elem.removeEventListener ) {
- elem.removeEventListener( type, handle, false );
- }
- } :
- function( elem, type, handle ) {
- if ( elem.detachEvent ) {
- elem.detachEvent( "on" + type, handle );
- }
- };
-
-jQuery.Event = function( src, props ) {
- // Allow instantiation without the 'new' keyword
- if ( !(this instanceof jQuery.Event) ) {
- return new jQuery.Event( src, props );
- }
-
- // Event object
- if ( src && src.type ) {
- this.originalEvent = src;
- this.type = src.type;
-
- // Events bubbling up the document may have been marked as prevented
- // by a handler lower down the tree; reflect the correct value.
- this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||
- src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
-
- // Event type
- } else {
- this.type = src;
- }
-
- // Put explicitly provided properties onto the event object
- if ( props ) {
- jQuery.extend( this, props );
- }
-
- // Create a timestamp if incoming event doesn't have one
- this.timeStamp = src && src.timeStamp || jQuery.now();
-
- // Mark it as fixed
- this[ jQuery.expando ] = true;
-};
-
-function returnFalse() {
- return false;
-}
-function returnTrue() {
- return true;
-}
-
-// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
-// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
-jQuery.Event.prototype = {
- preventDefault: function() {
- this.isDefaultPrevented = returnTrue;
-
- var e = this.originalEvent;
- if ( !e ) {
- return;
- }
-
- // if preventDefault exists run it on the original event
- if ( e.preventDefault ) {
- e.preventDefault();
-
- // otherwise set the returnValue property of the original event to false (IE)
- } else {
- e.returnValue = false;
- }
- },
- stopPropagation: function() {
- this.isPropagationStopped = returnTrue;
-
- var e = this.originalEvent;
- if ( !e ) {
- return;
- }
- // if stopPropagation exists run it on the original event
- if ( e.stopPropagation ) {
- e.stopPropagation();
- }
- // otherwise set the cancelBubble property of the original event to true (IE)
- e.cancelBubble = true;
- },
- stopImmediatePropagation: function() {
- this.isImmediatePropagationStopped = returnTrue;
- this.stopPropagation();
- },
- isDefaultPrevented: returnFalse,
- isPropagationStopped: returnFalse,
- isImmediatePropagationStopped: returnFalse
-};
-
-// Create mouseenter/leave events using mouseover/out and event-time checks
-jQuery.each({
- mouseenter: "mouseover",
- mouseleave: "mouseout"
-}, function( orig, fix ) {
- jQuery.event.special[ orig ] = {
- delegateType: fix,
- bindType: fix,
-
- handle: function( event ) {
- var target = this,
- related = event.relatedTarget,
- handleObj = event.handleObj,
- selector = handleObj.selector,
- ret;
-
- // For mousenter/leave call the handler if related is outside the target.
- // NB: No relatedTarget if the mouse left/entered the browser window
- if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
- event.type = handleObj.origType;
- ret = handleObj.handler.apply( this, arguments );
- event.type = fix;
- }
- return ret;
- }
- };
-});
-
-// IE submit delegation
-if ( !jQuery.support.submitBubbles ) {
-
- jQuery.event.special.submit = {
- setup: function() {
- // Only need this for delegated form submit events
- if ( jQuery.nodeName( this, "form" ) ) {
- return false;
- }
-
- // Lazy-add a submit handler when a descendant form may potentially be submitted
- jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
- // Node name check avoids a VML-related crash in IE (#9807)
- var elem = e.target,
- form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
- if ( form && !form._submit_attached ) {
- jQuery.event.add( form, "submit._submit", function( event ) {
- event._submit_bubble = true;
- });
- form._submit_attached = true;
- }
- });
- // return undefined since we don't need an event listener
- },
-
- postDispatch: function( event ) {
- // If form was submitted by the user, bubble the event up the tree
- if ( event._submit_bubble ) {
- delete event._submit_bubble;
- if ( this.parentNode && !event.isTrigger ) {
- jQuery.event.simulate( "submit", this.parentNode, event, true );
- }
- }
- },
-
- teardown: function() {
- // Only need this for delegated form submit events
- if ( jQuery.nodeName( this, "form" ) ) {
- return false;
- }
-
- // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
- jQuery.event.remove( this, "._submit" );
- }
- };
-}
-
-// IE change delegation and checkbox/radio fix
-if ( !jQuery.support.changeBubbles ) {
-
- jQuery.event.special.change = {
-
- setup: function() {
-
- if ( rformElems.test( this.nodeName ) ) {
- // IE doesn't fire change on a check/radio until blur; trigger it on click
- // after a propertychange. Eat the blur-change in special.change.handle.
- // This still fires onchange a second time for check/radio after blur.
- if ( this.type === "checkbox" || this.type === "radio" ) {
- jQuery.event.add( this, "propertychange._change", function( event ) {
- if ( event.originalEvent.propertyName === "checked" ) {
- this._just_changed = true;
- }
- });
- jQuery.event.add( this, "click._change", function( event ) {
- if ( this._just_changed && !event.isTrigger ) {
- this._just_changed = false;
- jQuery.event.simulate( "change", this, event, true );
- }
- });
- }
- return false;
- }
- // Delegated event; lazy-add a change handler on descendant inputs
- jQuery.event.add( this, "beforeactivate._change", function( e ) {
- var elem = e.target;
-
- if ( rformElems.test( elem.nodeName ) && !elem._change_attached ) {
- jQuery.event.add( elem, "change._change", function( event ) {
- if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
- jQuery.event.simulate( "change", this.parentNode, event, true );
- }
- });
- elem._change_attached = true;
- }
- });
- },
-
- handle: function( event ) {
- var elem = event.target;
-
- // Swallow native change events from checkbox/radio, we already triggered them above
- if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
- return event.handleObj.handler.apply( this, arguments );
- }
- },
-
- teardown: function() {
- jQuery.event.remove( this, "._change" );
-
- return rformElems.test( this.nodeName );
- }
- };
-}
-
-// Create "bubbling" focus and blur events
-if ( !jQuery.support.focusinBubbles ) {
- jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
-
- // Attach a single capturing handler while someone wants focusin/focusout
- var attaches = 0,
- handler = function( event ) {
- jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
- };
-
- jQuery.event.special[ fix ] = {
- setup: function() {
- if ( attaches++ === 0 ) {
- document.addEventListener( orig, handler, true );
- }
- },
- teardown: function() {
- if ( --attaches === 0 ) {
- document.removeEventListener( orig, handler, true );
- }
- }
- };
- });
-}
-
-jQuery.fn.extend({
-
- on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
- var origFn, type;
-
- // Types can be a map of types/handlers
- if ( typeof types === "object" ) {
- // ( types-Object, selector, data )
- if ( typeof selector !== "string" ) { // && selector != null
- // ( types-Object, data )
- data = data || selector;
- selector = undefined;
- }
- for ( type in types ) {
- this.on( type, selector, data, types[ type ], one );
- }
- return this;
- }
-
- if ( data == null && fn == null ) {
- // ( types, fn )
- fn = selector;
- data = selector = undefined;
- } else if ( fn == null ) {
- if ( typeof selector === "string" ) {
- // ( types, selector, fn )
- fn = data;
- data = undefined;
- } else {
- // ( types, data, fn )
- fn = data;
- data = selector;
- selector = undefined;
- }
- }
- if ( fn === false ) {
- fn = returnFalse;
- } else if ( !fn ) {
- return this;
- }
-
- if ( one === 1 ) {
- origFn = fn;
- fn = function( event ) {
- // Can use an empty set, since event contains the info
- jQuery().off( event );
- return origFn.apply( this, arguments );
- };
- // Use same guid so caller can remove using origFn
- fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
- }
- return this.each( function() {
- jQuery.event.add( this, types, fn, data, selector );
- });
- },
- one: function( types, selector, data, fn ) {
- return this.on( types, selector, data, fn, 1 );
- },
- off: function( types, selector, fn ) {
- if ( types && types.preventDefault && types.handleObj ) {
- // ( event ) dispatched jQuery.Event
- var handleObj = types.handleObj;
- jQuery( types.delegateTarget ).off(
- handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
- handleObj.selector,
- handleObj.handler
- );
- return this;
- }
- if ( typeof types === "object" ) {
- // ( types-object [, selector] )
- for ( var type in types ) {
- this.off( type, selector, types[ type ] );
- }
- return this;
- }
- if ( selector === false || typeof selector === "function" ) {
- // ( types [, fn] )
- fn = selector;
- selector = undefined;
- }
- if ( fn === false ) {
- fn = returnFalse;
- }
- return this.each(function() {
- jQuery.event.remove( this, types, fn, selector );
- });
- },
-
- bind: function( types, data, fn ) {
- return this.on( types, null, data, fn );
- },
- unbind: function( types, fn ) {
- return this.off( types, null, fn );
- },
-
- live: function( types, data, fn ) {
- jQuery( this.context ).on( types, this.selector, data, fn );
- return this;
- },
- die: function( types, fn ) {
- jQuery( this.context ).off( types, this.selector || "**", fn );
- return this;
- },
-
- delegate: function( selector, types, data, fn ) {
- return this.on( types, selector, data, fn );
- },
- undelegate: function( selector, types, fn ) {
- // ( namespace ) or ( selector, types [, fn] )
- return arguments.length == 1? this.off( selector, "**" ) : this.off( types, selector, fn );
- },
-
- trigger: function( type, data ) {
- return this.each(function() {
- jQuery.event.trigger( type, data, this );
- });
- },
- triggerHandler: function( type, data ) {
- if ( this[0] ) {
- return jQuery.event.trigger( type, data, this[0], true );
- }
- },
-
- toggle: function( fn ) {
- // Save reference to arguments for access in closure
- var args = arguments,
- guid = fn.guid || jQuery.guid++,
- i = 0,
- toggler = function( event ) {
- // Figure out which function to execute
- var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
- jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
-
- // Make sure that clicks stop
- event.preventDefault();
-
- // and execute the function
- return args[ lastToggle ].apply( this, arguments ) || false;
- };
-
- // link all the functions, so any of them can unbind this click handler
- toggler.guid = guid;
- while ( i < args.length ) {
- args[ i++ ].guid = guid;
- }
-
- return this.click( toggler );
- },
-
- hover: function( fnOver, fnOut ) {
- return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
- }
-});
-
-jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
- "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
- "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
-
- // Handle event binding
- jQuery.fn[ name ] = function( data, fn ) {
- if ( fn == null ) {
- fn = data;
- data = null;
- }
-
- return arguments.length > 0 ?
- this.on( name, null, data, fn ) :
- this.trigger( name );
- };
-
- if ( jQuery.attrFn ) {
- jQuery.attrFn[ name ] = true;
- }
-
- if ( rkeyEvent.test( name ) ) {
- jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks;
- }
-
- if ( rmouseEvent.test( name ) ) {
- jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks;
- }
-});
-
-
-
-/*!
- * Sizzle CSS Selector Engine
- * Copyright 2011, The Dojo Foundation
- * Released under the MIT, BSD, and GPL Licenses.
- * More information: http://sizzlejs.com/
- */
-(function(){
-
-var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
- expando = "sizcache" + (Math.random() + '').replace('.', ''),
- done = 0,
- toString = Object.prototype.toString,
- hasDuplicate = false,
- baseHasDuplicate = true,
- rBackslash = /\\/g,
- rReturn = /\r\n/g,
- rNonWord = /\W/;
-
-// Here we check if the JavaScript engine is using some sort of
-// optimization where it does not always call our comparision
-// function. If that is the case, discard the hasDuplicate value.
-// Thus far that includes Google Chrome.
-[0, 0].sort(function() {
- baseHasDuplicate = false;
- return 0;
-});
-
-var Sizzle = function( selector, context, results, seed ) {
- results = results || [];
- context = context || document;
-
- var origContext = context;
-
- if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
- return [];
- }
-
- if ( !selector || typeof selector !== "string" ) {
- return results;
- }
-
- var m, set, checkSet, extra, ret, cur, pop, i,
- prune = true,
- contextXML = Sizzle.isXML( context ),
- parts = [],
- soFar = selector;
-
- // Reset the position of the chunker regexp (start from head)
- do {
- chunker.exec( "" );
- m = chunker.exec( soFar );
-
- if ( m ) {
- soFar = m[3];
-
- parts.push( m[1] );
-
- if ( m[2] ) {
- extra = m[3];
- break;
- }
- }
- } while ( m );
-
- if ( parts.length > 1 && origPOS.exec( selector ) ) {
-
- if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
- set = posProcess( parts[0] + parts[1], context, seed );
-
- } else {
- set = Expr.relative[ parts[0] ] ?
- [ context ] :
- Sizzle( parts.shift(), context );
-
- while ( parts.length ) {
- selector = parts.shift();
-
- if ( Expr.relative[ selector ] ) {
- selector += parts.shift();
- }
-
- set = posProcess( selector, set, seed );
- }
- }
-
- } else {
- // Take a shortcut and set the context if the root selector is an ID
- // (but not if it'll be faster if the inner selector is an ID)
- if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
- Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
-
- ret = Sizzle.find( parts.shift(), context, contextXML );
- context = ret.expr ?
- Sizzle.filter( ret.expr, ret.set )[0] :
- ret.set[0];
- }
-
- if ( context ) {
- ret = seed ?
- { expr: parts.pop(), set: makeArray(seed) } :
- Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
-
- set = ret.expr ?
- Sizzle.filter( ret.expr, ret.set ) :
- ret.set;
-
- if ( parts.length > 0 ) {
- checkSet = makeArray( set );
-
- } else {
- prune = false;
- }
-
- while ( parts.length ) {
- cur = parts.pop();
- pop = cur;
-
- if ( !Expr.relative[ cur ] ) {
- cur = "";
- } else {
- pop = parts.pop();
- }
-
- if ( pop == null ) {
- pop = context;
- }
-
- Expr.relative[ cur ]( checkSet, pop, contextXML );
- }
-
- } else {
- checkSet = parts = [];
- }
- }
-
- if ( !checkSet ) {
- checkSet = set;
- }
-
- if ( !checkSet ) {
- Sizzle.error( cur || selector );
- }
-
- if ( toString.call(checkSet) === "[object Array]" ) {
- if ( !prune ) {
- results.push.apply( results, checkSet );
-
- } else if ( context && context.nodeType === 1 ) {
- for ( i = 0; checkSet[i] != null; i++ ) {
- if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
- results.push( set[i] );
- }
- }
-
- } else {
- for ( i = 0; checkSet[i] != null; i++ ) {
- if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
- results.push( set[i] );
- }
- }
- }
-
- } else {
- makeArray( checkSet, results );
- }
-
- if ( extra ) {
- Sizzle( extra, origContext, results, seed );
- Sizzle.uniqueSort( results );
- }
-
- return results;
-};
-
-Sizzle.uniqueSort = function( results ) {
- if ( sortOrder ) {
- hasDuplicate = baseHasDuplicate;
- results.sort( sortOrder );
-
- if ( hasDuplicate ) {
- for ( var i = 1; i < results.length; i++ ) {
- if ( results[i] === results[ i - 1 ] ) {
- results.splice( i--, 1 );
- }
- }
- }
- }
-
- return results;
-};
-
-Sizzle.matches = function( expr, set ) {
- return Sizzle( expr, null, null, set );
-};
-
-Sizzle.matchesSelector = function( node, expr ) {
- return Sizzle( expr, null, null, [node] ).length > 0;
-};
-
-Sizzle.find = function( expr, context, isXML ) {
- var set, i, len, match, type, left;
-
- if ( !expr ) {
- return [];
- }
-
- for ( i = 0, len = Expr.order.length; i < len; i++ ) {
- type = Expr.order[i];
-
- if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
- left = match[1];
- match.splice( 1, 1 );
-
- if ( left.substr( left.length - 1 ) !== "\\" ) {
- match[1] = (match[1] || "").replace( rBackslash, "" );
- set = Expr.find[ type ]( match, context, isXML );
-
- if ( set != null ) {
- expr = expr.replace( Expr.match[ type ], "" );
- break;
- }
- }
- }
- }
-
- if ( !set ) {
- set = typeof context.getElementsByTagName !== "undefined" ?
- context.getElementsByTagName( "*" ) :
- [];
- }
-
- return { set: set, expr: expr };
-};
-
-Sizzle.filter = function( expr, set, inplace, not ) {
- var match, anyFound,
- type, found, item, filter, left,
- i, pass,
- old = expr,
- result = [],
- curLoop = set,
- isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
-
- while ( expr && set.length ) {
- for ( type in Expr.filter ) {
- if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
- filter = Expr.filter[ type ];
- left = match[1];
-
- anyFound = false;
-
- match.splice(1,1);
-
- if ( left.substr( left.length - 1 ) === "\\" ) {
- continue;
- }
-
- if ( curLoop === result ) {
- result = [];
- }
-
- if ( Expr.preFilter[ type ] ) {
- match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
-
- if ( !match ) {
- anyFound = found = true;
-
- } else if ( match === true ) {
- continue;
- }
- }
-
- if ( match ) {
- for ( i = 0; (item = curLoop[i]) != null; i++ ) {
- if ( item ) {
- found = filter( item, match, i, curLoop );
- pass = not ^ found;
-
- if ( inplace && found != null ) {
- if ( pass ) {
- anyFound = true;
-
- } else {
- curLoop[i] = false;
- }
-
- } else if ( pass ) {
- result.push( item );
- anyFound = true;
- }
- }
- }
- }
-
- if ( found !== undefined ) {
- if ( !inplace ) {
- curLoop = result;
- }
-
- expr = expr.replace( Expr.match[ type ], "" );
-
- if ( !anyFound ) {
- return [];
- }
-
- break;
- }
- }
- }
-
- // Improper expression
- if ( expr === old ) {
- if ( anyFound == null ) {
- Sizzle.error( expr );
-
- } else {
- break;
- }
- }
-
- old = expr;
- }
-
- return curLoop;
-};
-
-Sizzle.error = function( msg ) {
- throw new Error( "Syntax error, unrecognized expression: " + msg );
-};
-
-/**
- * Utility function for retreiving the text value of an array of DOM nodes
- * @param {Array|Element} elem
- */
-var getText = Sizzle.getText = function( elem ) {
- var i, node,
- nodeType = elem.nodeType,
- ret = "";
-
- if ( nodeType ) {
- if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
- // Use textContent || innerText for elements
- if ( typeof elem.textContent === 'string' ) {
- return elem.textContent;
- } else if ( typeof elem.innerText === 'string' ) {
- // Replace IE's carriage returns
- return elem.innerText.replace( rReturn, '' );
- } else {
- // Traverse it's children
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling) {
- ret += getText( elem );
- }
- }
- } else if ( nodeType === 3 || nodeType === 4 ) {
- return elem.nodeValue;
- }
- } else {
-
- // If no nodeType, this is expected to be an array
- for ( i = 0; (node = elem[i]); i++ ) {
- // Do not traverse comment nodes
- if ( node.nodeType !== 8 ) {
- ret += getText( node );
- }
- }
- }
- return ret;
-};
-
-var Expr = Sizzle.selectors = {
- order: [ "ID", "NAME", "TAG" ],
-
- match: {
- ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
- CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
- NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
- ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,
- TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
- CHILD: /:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,
- POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
- PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
- },
-
- leftMatch: {},
-
- attrMap: {
- "class": "className",
- "for": "htmlFor"
- },
-
- attrHandle: {
- href: function( elem ) {
- return elem.getAttribute( "href" );
- },
- type: function( elem ) {
- return elem.getAttribute( "type" );
- }
- },
-
- relative: {
- "+": function(checkSet, part){
- var isPartStr = typeof part === "string",
- isTag = isPartStr && !rNonWord.test( part ),
- isPartStrNotTag = isPartStr && !isTag;
-
- if ( isTag ) {
- part = part.toLowerCase();
- }
-
- for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
- if ( (elem = checkSet[i]) ) {
- while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
-
- checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
- elem || false :
- elem === part;
- }
- }
-
- if ( isPartStrNotTag ) {
- Sizzle.filter( part, checkSet, true );
- }
- },
-
- ">": function( checkSet, part ) {
- var elem,
- isPartStr = typeof part === "string",
- i = 0,
- l = checkSet.length;
-
- if ( isPartStr && !rNonWord.test( part ) ) {
- part = part.toLowerCase();
-
- for ( ; i < l; i++ ) {
- elem = checkSet[i];
-
- if ( elem ) {
- var parent = elem.parentNode;
- checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
- }
- }
-
- } else {
- for ( ; i < l; i++ ) {
- elem = checkSet[i];
-
- if ( elem ) {
- checkSet[i] = isPartStr ?
- elem.parentNode :
- elem.parentNode === part;
- }
- }
-
- if ( isPartStr ) {
- Sizzle.filter( part, checkSet, true );
- }
- }
- },
-
- "": function(checkSet, part, isXML){
- var nodeCheck,
- doneName = done++,
- checkFn = dirCheck;
-
- if ( typeof part === "string" && !rNonWord.test( part ) ) {
- part = part.toLowerCase();
- nodeCheck = part;
- checkFn = dirNodeCheck;
- }
-
- checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
- },
-
- "~": function( checkSet, part, isXML ) {
- var nodeCheck,
- doneName = done++,
- checkFn = dirCheck;
-
- if ( typeof part === "string" && !rNonWord.test( part ) ) {
- part = part.toLowerCase();
- nodeCheck = part;
- checkFn = dirNodeCheck;
- }
-
- checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
- }
- },
-
- find: {
- ID: function( match, context, isXML ) {
- if ( typeof context.getElementById !== "undefined" && !isXML ) {
- var m = context.getElementById(match[1]);
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- return m && m.parentNode ? [m] : [];
- }
- },
-
- NAME: function( match, context ) {
- if ( typeof context.getElementsByName !== "undefined" ) {
- var ret = [],
- results = context.getElementsByName( match[1] );
-
- for ( var i = 0, l = results.length; i < l; i++ ) {
- if ( results[i].getAttribute("name") === match[1] ) {
- ret.push( results[i] );
- }
- }
-
- return ret.length === 0 ? null : ret;
- }
- },
-
- TAG: function( match, context ) {
- if ( typeof context.getElementsByTagName !== "undefined" ) {
- return context.getElementsByTagName( match[1] );
- }
- }
- },
- preFilter: {
- CLASS: function( match, curLoop, inplace, result, not, isXML ) {
- match = " " + match[1].replace( rBackslash, "" ) + " ";
-
- if ( isXML ) {
- return match;
- }
-
- for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
- if ( elem ) {
- if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n\r]/g, " ").indexOf(match) >= 0) ) {
- if ( !inplace ) {
- result.push( elem );
- }
-
- } else if ( inplace ) {
- curLoop[i] = false;
- }
- }
- }
-
- return false;
- },
-
- ID: function( match ) {
- return match[1].replace( rBackslash, "" );
- },
-
- TAG: function( match, curLoop ) {
- return match[1].replace( rBackslash, "" ).toLowerCase();
- },
-
- CHILD: function( match ) {
- if ( match[1] === "nth" ) {
- if ( !match[2] ) {
- Sizzle.error( match[0] );
- }
-
- match[2] = match[2].replace(/^\+|\s*/g, '');
-
- // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
- var test = /(-?)(\d*)(?:n([+\-]?\d*))?/.exec(
- match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
- !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
-
- // calculate the numbers (first)n+(last) including if they are negative
- match[2] = (test[1] + (test[2] || 1)) - 0;
- match[3] = test[3] - 0;
- }
- else if ( match[2] ) {
- Sizzle.error( match[0] );
- }
-
- // TODO: Move to normal caching system
- match[0] = done++;
-
- return match;
- },
-
- ATTR: function( match, curLoop, inplace, result, not, isXML ) {
- var name = match[1] = match[1].replace( rBackslash, "" );
-
- if ( !isXML && Expr.attrMap[name] ) {
- match[1] = Expr.attrMap[name];
- }
-
- // Handle if an un-quoted value was used
- match[4] = ( match[4] || match[5] || "" ).replace( rBackslash, "" );
-
- if ( match[2] === "~=" ) {
- match[4] = " " + match[4] + " ";
- }
-
- return match;
- },
-
- PSEUDO: function( match, curLoop, inplace, result, not ) {
- if ( match[1] === "not" ) {
- // If we're dealing with a complex expression, or a simple one
- if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
- match[3] = Sizzle(match[3], null, null, curLoop);
-
- } else {
- var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
-
- if ( !inplace ) {
- result.push.apply( result, ret );
- }
-
- return false;
- }
-
- } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
- return true;
- }
-
- return match;
- },
-
- POS: function( match ) {
- match.unshift( true );
-
- return match;
- }
- },
-
- filters: {
- enabled: function( elem ) {
- return elem.disabled === false && elem.type !== "hidden";
- },
-
- disabled: function( elem ) {
- return elem.disabled === true;
- },
-
- checked: function( elem ) {
- return elem.checked === true;
- },
-
- selected: function( elem ) {
- // Accessing this property makes selected-by-default
- // options in Safari work properly
- if ( elem.parentNode ) {
- elem.parentNode.selectedIndex;
- }
-
- return elem.selected === true;
- },
-
- parent: function( elem ) {
- return !!elem.firstChild;
- },
-
- empty: function( elem ) {
- return !elem.firstChild;
- },
-
- has: function( elem, i, match ) {
- return !!Sizzle( match[3], elem ).length;
- },
-
- header: function( elem ) {
- return (/h\d/i).test( elem.nodeName );
- },
-
- text: function( elem ) {
- var attr = elem.getAttribute( "type" ), type = elem.type;
- // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
- // use getAttribute instead to test this case
- return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null );
- },
-
- radio: function( elem ) {
- return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type;
- },
-
- checkbox: function( elem ) {
- return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type;
- },
-
- file: function( elem ) {
- return elem.nodeName.toLowerCase() === "input" && "file" === elem.type;
- },
-
- password: function( elem ) {
- return elem.nodeName.toLowerCase() === "input" && "password" === elem.type;
- },
-
- submit: function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return (name === "input" || name === "button") && "submit" === elem.type;
- },
-
- image: function( elem ) {
- return elem.nodeName.toLowerCase() === "input" && "image" === elem.type;
- },
-
- reset: function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return (name === "input" || name === "button") && "reset" === elem.type;
- },
-
- button: function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && "button" === elem.type || name === "button";
- },
-
- input: function( elem ) {
- return (/input|select|textarea|button/i).test( elem.nodeName );
- },
-
- focus: function( elem ) {
- return elem === elem.ownerDocument.activeElement;
- }
- },
- setFilters: {
- first: function( elem, i ) {
- return i === 0;
- },
-
- last: function( elem, i, match, array ) {
- return i === array.length - 1;
- },
-
- even: function( elem, i ) {
- return i % 2 === 0;
- },
-
- odd: function( elem, i ) {
- return i % 2 === 1;
- },
-
- lt: function( elem, i, match ) {
- return i < match[3] - 0;
- },
-
- gt: function( elem, i, match ) {
- return i > match[3] - 0;
- },
-
- nth: function( elem, i, match ) {
- return match[3] - 0 === i;
- },
-
- eq: function( elem, i, match ) {
- return match[3] - 0 === i;
- }
- },
- filter: {
- PSEUDO: function( elem, match, i, array ) {
- var name = match[1],
- filter = Expr.filters[ name ];
-
- if ( filter ) {
- return filter( elem, i, match, array );
-
- } else if ( name === "contains" ) {
- return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;
-
- } else if ( name === "not" ) {
- var not = match[3];
-
- for ( var j = 0, l = not.length; j < l; j++ ) {
- if ( not[j] === elem ) {
- return false;
- }
- }
-
- return true;
-
- } else {
- Sizzle.error( name );
- }
- },
-
- CHILD: function( elem, match ) {
- var first, last,
- doneName, parent, cache,
- count, diff,
- type = match[1],
- node = elem;
-
- switch ( type ) {
- case "only":
- case "first":
- while ( (node = node.previousSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
- }
- }
-
- if ( type === "first" ) {
- return true;
- }
-
- node = elem;
-
- /* falls through */
- case "last":
- while ( (node = node.nextSibling) ) {
- if ( node.nodeType === 1 ) {
- return false;
- }
- }
-
- return true;
-
- case "nth":
- first = match[2];
- last = match[3];
-
- if ( first === 1 && last === 0 ) {
- return true;
- }
-
- doneName = match[0];
- parent = elem.parentNode;
-
- if ( parent && (parent[ expando ] !== doneName || !elem.nodeIndex) ) {
- count = 0;
-
- for ( node = parent.firstChild; node; node = node.nextSibling ) {
- if ( node.nodeType === 1 ) {
- node.nodeIndex = ++count;
- }
- }
-
- parent[ expando ] = doneName;
- }
-
- diff = elem.nodeIndex - last;
-
- if ( first === 0 ) {
- return diff === 0;
-
- } else {
- return ( diff % first === 0 && diff / first >= 0 );
- }
- }
- },
-
- ID: function( elem, match ) {
- return elem.nodeType === 1 && elem.getAttribute("id") === match;
- },
-
- TAG: function( elem, match ) {
- return (match === "*" && elem.nodeType === 1) || !!elem.nodeName && elem.nodeName.toLowerCase() === match;
- },
-
- CLASS: function( elem, match ) {
- return (" " + (elem.className || elem.getAttribute("class")) + " ")
- .indexOf( match ) > -1;
- },
-
- ATTR: function( elem, match ) {
- var name = match[1],
- result = Sizzle.attr ?
- Sizzle.attr( elem, name ) :
- Expr.attrHandle[ name ] ?
- Expr.attrHandle[ name ]( elem ) :
- elem[ name ] != null ?
- elem[ name ] :
- elem.getAttribute( name ),
- value = result + "",
- type = match[2],
- check = match[4];
-
- return result == null ?
- type === "!=" :
- !type && Sizzle.attr ?
- result != null :
- type === "=" ?
- value === check :
- type === "*=" ?
- value.indexOf(check) >= 0 :
- type === "~=" ?
- (" " + value + " ").indexOf(check) >= 0 :
- !check ?
- value && result !== false :
- type === "!=" ?
- value !== check :
- type === "^=" ?
- value.indexOf(check) === 0 :
- type === "$=" ?
- value.substr(value.length - check.length) === check :
- type === "|=" ?
- value === check || value.substr(0, check.length + 1) === check + "-" :
- false;
- },
-
- POS: function( elem, match, i, array ) {
- var name = match[2],
- filter = Expr.setFilters[ name ];
-
- if ( filter ) {
- return filter( elem, i, match, array );
- }
- }
- }
-};
-
-var origPOS = Expr.match.POS,
- fescape = function(all, num){
- return "\\" + (num - 0 + 1);
- };
-
-for ( var type in Expr.match ) {
- Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
- Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
-}
-// Expose origPOS
-// "global" as in regardless of relation to brackets/parens
-Expr.match.globalPOS = origPOS;
-
-var makeArray = function( array, results ) {
- array = Array.prototype.slice.call( array, 0 );
-
- if ( results ) {
- results.push.apply( results, array );
- return results;
- }
-
- return array;
-};
-
-// Perform a simple check to determine if the browser is capable of
-// converting a NodeList to an array using builtin methods.
-// Also verifies that the returned array holds DOM nodes
-// (which is not the case in the Blackberry browser)
-try {
- Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
-
-// Provide a fallback method if it does not work
-} catch( e ) {
- makeArray = function( array, results ) {
- var i = 0,
- ret = results || [];
-
- if ( toString.call(array) === "[object Array]" ) {
- Array.prototype.push.apply( ret, array );
-
- } else {
- if ( typeof array.length === "number" ) {
- for ( var l = array.length; i < l; i++ ) {
- ret.push( array[i] );
- }
-
- } else {
- for ( ; array[i]; i++ ) {
- ret.push( array[i] );
- }
- }
- }
-
- return ret;
- };
-}
-
-var sortOrder, siblingCheck;
-
-if ( document.documentElement.compareDocumentPosition ) {
- sortOrder = function( a, b ) {
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
- }
-
- if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
- return a.compareDocumentPosition ? -1 : 1;
- }
-
- return a.compareDocumentPosition(b) & 4 ? -1 : 1;
- };
-
-} else {
- sortOrder = function( a, b ) {
- // The nodes are identical, we can exit early
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
-
- // Fallback to using sourceIndex (in IE) if it's available on both nodes
- } else if ( a.sourceIndex && b.sourceIndex ) {
- return a.sourceIndex - b.sourceIndex;
- }
-
- var al, bl,
- ap = [],
- bp = [],
- aup = a.parentNode,
- bup = b.parentNode,
- cur = aup;
-
- // If the nodes are siblings (or identical) we can do a quick check
- if ( aup === bup ) {
- return siblingCheck( a, b );
-
- // If no parents were found then the nodes are disconnected
- } else if ( !aup ) {
- return -1;
-
- } else if ( !bup ) {
- return 1;
- }
-
- // Otherwise they're somewhere else in the tree so we need
- // to build up a full list of the parentNodes for comparison
- while ( cur ) {
- ap.unshift( cur );
- cur = cur.parentNode;
- }
-
- cur = bup;
-
- while ( cur ) {
- bp.unshift( cur );
- cur = cur.parentNode;
- }
-
- al = ap.length;
- bl = bp.length;
-
- // Start walking down the tree looking for a discrepancy
- for ( var i = 0; i < al && i < bl; i++ ) {
- if ( ap[i] !== bp[i] ) {
- return siblingCheck( ap[i], bp[i] );
- }
- }
-
- // We ended someplace up the tree so do a sibling check
- return i === al ?
- siblingCheck( a, bp[i], -1 ) :
- siblingCheck( ap[i], b, 1 );
- };
-
- siblingCheck = function( a, b, ret ) {
- if ( a === b ) {
- return ret;
- }
-
- var cur = a.nextSibling;
-
- while ( cur ) {
- if ( cur === b ) {
- return -1;
- }
-
- cur = cur.nextSibling;
- }
-
- return 1;
- };
-}
-
-// Check to see if the browser returns elements by name when
-// querying by getElementById (and provide a workaround)
-(function(){
- // We're going to inject a fake input element with a specified name
- var form = document.createElement("div"),
- id = "script" + (new Date()).getTime(),
- root = document.documentElement;
-
- form.innerHTML = "<a name='" + id + "'/>";
-
- // Inject it into the root element, check its status, and remove it quickly
- root.insertBefore( form, root.firstChild );
-
- // The workaround has to do additional checks after a getElementById
- // Which slows things down for other browsers (hence the branching)
- if ( document.getElementById( id ) ) {
- Expr.find.ID = function( match, context, isXML ) {
- if ( typeof context.getElementById !== "undefined" && !isXML ) {
- var m = context.getElementById(match[1]);
-
- return m ?
- m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
- [m] :
- undefined :
- [];
- }
- };
-
- Expr.filter.ID = function( elem, match ) {
- var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
-
- return elem.nodeType === 1 && node && node.nodeValue === match;
- };
- }
-
- root.removeChild( form );
-
- // release memory in IE
- root = form = null;
-})();
-
-(function(){
- // Check to see if the browser returns only elements
- // when doing getElementsByTagName("*")
-
- // Create a fake element
- var div = document.createElement("div");
- div.appendChild( document.createComment("") );
-
- // Make sure no comments are found
- if ( div.getElementsByTagName("*").length > 0 ) {
- Expr.find.TAG = function( match, context ) {
- var results = context.getElementsByTagName( match[1] );
-
- // Filter out possible comments
- if ( match[1] === "*" ) {
- var tmp = [];
-
- for ( var i = 0; results[i]; i++ ) {
- if ( results[i].nodeType === 1 ) {
- tmp.push( results[i] );
- }
- }
-
- results = tmp;
- }
-
- return results;
- };
- }
-
- // Check to see if an attribute returns normalized href attributes
- div.innerHTML = "<a href='#'></a>";
-
- if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
- div.firstChild.getAttribute("href") !== "#" ) {
-
- Expr.attrHandle.href = function( elem ) {
- return elem.getAttribute( "href", 2 );
- };
- }
-
- // release memory in IE
- div = null;
-})();
-
-if ( document.querySelectorAll ) {
- (function(){
- var oldSizzle = Sizzle,
- div = document.createElement("div"),
- id = "__sizzle__";
-
- div.innerHTML = "<p class='TEST'></p>";
-
- // Safari can't handle uppercase or unicode characters when
- // in quirks mode.
- if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
- return;
- }
-
- Sizzle = function( query, context, extra, seed ) {
- context = context || document;
-
- // Only use querySelectorAll on non-XML documents
- // (ID selectors don't work in non-HTML documents)
- if ( !seed && !Sizzle.isXML(context) ) {
- // See if we find a selector to speed up
- var match = /^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec( query );
-
- if ( match && (context.nodeType === 1 || context.nodeType === 9) ) {
- // Speed-up: Sizzle("TAG")
- if ( match[1] ) {
- return makeArray( context.getElementsByTagName( query ), extra );
-
- // Speed-up: Sizzle(".CLASS")
- } else if ( match[2] && Expr.find.CLASS && context.getElementsByClassName ) {
- return makeArray( context.getElementsByClassName( match[2] ), extra );
- }
- }
-
- if ( context.nodeType === 9 ) {
- // Speed-up: Sizzle("body")
- // The body element only exists once, optimize finding it
- if ( query === "body" && context.body ) {
- return makeArray( [ context.body ], extra );
-
- // Speed-up: Sizzle("#ID")
- } else if ( match && match[3] ) {
- var elem = context.getElementById( match[3] );
-
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- if ( elem && elem.parentNode ) {
- // Handle the case where IE and Opera return items
- // by name instead of ID
- if ( elem.id === match[3] ) {
- return makeArray( [ elem ], extra );
- }
-
- } else {
- return makeArray( [], extra );
- }
- }
-
- try {
- return makeArray( context.querySelectorAll(query), extra );
- } catch(qsaError) {}
-
- // qSA works strangely on Element-rooted queries
- // We can work around this by specifying an extra ID on the root
- // and working up from there (Thanks to Andrew Dupont for the technique)
- // IE 8 doesn't work on object elements
- } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
- var oldContext = context,
- old = context.getAttribute( "id" ),
- nid = old || id,
- hasParent = context.parentNode,
- relativeHierarchySelector = /^\s*[+~]/.test( query );
-
- if ( !old ) {
- context.setAttribute( "id", nid );
- } else {
- nid = nid.replace( /'/g, "\\$&" );
- }
- if ( relativeHierarchySelector && hasParent ) {
- context = context.parentNode;
- }
-
- try {
- if ( !relativeHierarchySelector || hasParent ) {
- return makeArray( context.querySelectorAll( "[id='" + nid + "'] " + query ), extra );
- }
-
- } catch(pseudoError) {
- } finally {
- if ( !old ) {
- oldContext.removeAttribute( "id" );
- }
- }
- }
- }
-
- return oldSizzle(query, context, extra, seed);
- };
-
- for ( var prop in oldSizzle ) {
- Sizzle[ prop ] = oldSizzle[ prop ];
- }
-
- // release memory in IE
- div = null;
- })();
-}
-
-(function(){
- var html = document.documentElement,
- matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector;
-
- if ( matches ) {
- // Check to see if it's possible to do matchesSelector
- // on a disconnected node (IE 9 fails this)
- var disconnectedMatch = !matches.call( document.createElement( "div" ), "div" ),
- pseudoWorks = false;
-
- try {
- // This should fail with an exception
- // Gecko does not error, returns false instead
- matches.call( document.documentElement, "[test!='']:sizzle" );
-
- } catch( pseudoError ) {
- pseudoWorks = true;
- }
-
- Sizzle.matchesSelector = function( node, expr ) {
- // Make sure that attribute selectors are quoted
- expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
-
- if ( !Sizzle.isXML( node ) ) {
- try {
- if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
- var ret = matches.call( node, expr );
-
- // IE 9's matchesSelector returns false on disconnected nodes
- if ( ret || !disconnectedMatch ||
- // As well, disconnected nodes are said to be in a document
- // fragment in IE 9, so check for that
- node.document && node.document.nodeType !== 11 ) {
- return ret;
- }
- }
- } catch(e) {}
- }
-
- return Sizzle(expr, null, null, [node]).length > 0;
- };
- }
-})();
-
-(function(){
- var div = document.createElement("div");
-
- div.innerHTML = "<div class='test e'></div><div class='test'></div>";
-
- // Opera can't find a second classname (in 9.6)
- // Also, make sure that getElementsByClassName actually exists
- if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
- return;
- }
-
- // Safari caches class attributes, doesn't catch changes (in 3.2)
- div.lastChild.className = "e";
-
- if ( div.getElementsByClassName("e").length === 1 ) {
- return;
- }
-
- Expr.order.splice(1, 0, "CLASS");
- Expr.find.CLASS = function( match, context, isXML ) {
- if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
- return context.getElementsByClassName(match[1]);
- }
- };
-
- // release memory in IE
- div = null;
-})();
-
-function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
- var elem = checkSet[i];
-
- if ( elem ) {
- var match = false;
-
- elem = elem[dir];
-
- while ( elem ) {
- if ( elem[ expando ] === doneName ) {
- match = checkSet[elem.sizset];
- break;
- }
-
- if ( elem.nodeType === 1 && !isXML ){
- elem[ expando ] = doneName;
- elem.sizset = i;
- }
-
- if ( elem.nodeName.toLowerCase() === cur ) {
- match = elem;
- break;
- }
-
- elem = elem[dir];
- }
-
- checkSet[i] = match;
- }
- }
-}
-
-function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
- for ( var i = 0, l = checkSet.length; i < l; i++ ) {
- var elem = checkSet[i];
-
- if ( elem ) {
- var match = false;
-
- elem = elem[dir];
-
- while ( elem ) {
- if ( elem[ expando ] === doneName ) {
- match = checkSet[elem.sizset];
- break;
- }
-
- if ( elem.nodeType === 1 ) {
- if ( !isXML ) {
- elem[ expando ] = doneName;
- elem.sizset = i;
- }
-
- if ( typeof cur !== "string" ) {
- if ( elem === cur ) {
- match = true;
- break;
- }
-
- } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
- match = elem;
- break;
- }
- }
-
- elem = elem[dir];
- }
-
- checkSet[i] = match;
- }
- }
-}
-
-if ( document.documentElement.contains ) {
- Sizzle.contains = function( a, b ) {
- return a !== b && (a.contains ? a.contains(b) : true);
- };
-
-} else if ( document.documentElement.compareDocumentPosition ) {
- Sizzle.contains = function( a, b ) {
- return !!(a.compareDocumentPosition(b) & 16);
- };
-
-} else {
- Sizzle.contains = function() {
- return false;
- };
-}
-
-Sizzle.isXML = function( elem ) {
- // documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
- var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
-
- return documentElement ? documentElement.nodeName !== "HTML" : false;
-};
-
-var posProcess = function( selector, context, seed ) {
- var match,
- tmpSet = [],
- later = "",
- root = context.nodeType ? [context] : context;
-
- // Position selectors must be done after the filter
- // And so must :not(positional) so we move all PSEUDOs to the end
- while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
- later += match[0];
- selector = selector.replace( Expr.match.PSEUDO, "" );
- }
-
- selector = Expr.relative[selector] ? selector + "*" : selector;
-
- for ( var i = 0, l = root.length; i < l; i++ ) {
- Sizzle( selector, root[i], tmpSet, seed );
- }
-
- return Sizzle.filter( later, tmpSet );
-};
-
-// EXPOSE
-// Override sizzle attribute retrieval
-Sizzle.attr = jQuery.attr;
-Sizzle.selectors.attrMap = {};
-jQuery.find = Sizzle;
-jQuery.expr = Sizzle.selectors;
-jQuery.expr[":"] = jQuery.expr.filters;
-jQuery.unique = Sizzle.uniqueSort;
-jQuery.text = Sizzle.getText;
-jQuery.isXMLDoc = Sizzle.isXML;
-jQuery.contains = Sizzle.contains;
-
-
-})();
-
-
-var runtil = /Until$/,
- rparentsprev = /^(?:parents|prevUntil|prevAll)/,
- // Note: This RegExp should be improved, or likely pulled from Sizzle
- rmultiselector = /,/,
- isSimple = /^.[^:#\[\.,]*$/,
- slice = Array.prototype.slice,
- POS = jQuery.expr.match.globalPOS,
- // methods guaranteed to produce a unique set when starting from a unique set
- guaranteedUnique = {
- children: true,
- contents: true,
- next: true,
- prev: true
- };
-
-jQuery.fn.extend({
- find: function( selector ) {
- var self = this,
- i, l;
-
- if ( typeof selector !== "string" ) {
- return jQuery( selector ).filter(function() {
- for ( i = 0, l = self.length; i < l; i++ ) {
- if ( jQuery.contains( self[ i ], this ) ) {
- return true;
- }
- }
- });
- }
-
- var ret = this.pushStack( "", "find", selector ),
- length, n, r;
-
- for ( i = 0, l = this.length; i < l; i++ ) {
- length = ret.length;
- jQuery.find( selector, this[i], ret );
-
- if ( i > 0 ) {
- // Make sure that the results are unique
- for ( n = length; n < ret.length; n++ ) {
- for ( r = 0; r < length; r++ ) {
- if ( ret[r] === ret[n] ) {
- ret.splice(n--, 1);
- break;
- }
- }
- }
- }
- }
-
- return ret;
- },
-
- has: function( target ) {
- var targets = jQuery( target );
- return this.filter(function() {
- for ( var i = 0, l = targets.length; i < l; i++ ) {
- if ( jQuery.contains( this, targets[i] ) ) {
- return true;
- }
- }
- });
- },
-
- not: function( selector ) {
- return this.pushStack( winnow(this, selector, false), "not", selector);
- },
-
- filter: function( selector ) {
- return this.pushStack( winnow(this, selector, true), "filter", selector );
- },
-
- is: function( selector ) {
- return !!selector && (
- typeof selector === "string" ?
- // If this is a positional selector, check membership in the returned set
- // so $("p:first").is("p:last") won't return true for a doc with two "p".
- POS.test( selector ) ?
- jQuery( selector, this.context ).index( this[0] ) >= 0 :
- jQuery.filter( selector, this ).length > 0 :
- this.filter( selector ).length > 0 );
- },
-
- closest: function( selectors, context ) {
- var ret = [], i, l, cur = this[0];
-
- // Array (deprecated as of jQuery 1.7)
- if ( jQuery.isArray( selectors ) ) {
- var level = 1;
-
- while ( cur && cur.ownerDocument && cur !== context ) {
- for ( i = 0; i < selectors.length; i++ ) {
-
- if ( jQuery( cur ).is( selectors[ i ] ) ) {
- ret.push({ selector: selectors[ i ], elem: cur, level: level });
- }
- }
-
- cur = cur.parentNode;
- level++;
- }
-
- return ret;
- }
-
- // String
- var pos = POS.test( selectors ) || typeof selectors !== "string" ?
- jQuery( selectors, context || this.context ) :
- 0;
-
- for ( i = 0, l = this.length; i < l; i++ ) {
- cur = this[i];
-
- while ( cur ) {
- if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
- ret.push( cur );
- break;
-
- } else {
- cur = cur.parentNode;
- if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
- break;
- }
- }
- }
- }
-
- ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
-
- return this.pushStack( ret, "closest", selectors );
- },
-
- // Determine the position of an element within
- // the matched set of elements
- index: function( elem ) {
-
- // No argument, return index in parent
- if ( !elem ) {
- return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1;
- }
-
- // index in selector
- if ( typeof elem === "string" ) {
- return jQuery.inArray( this[0], jQuery( elem ) );
- }
-
- // Locate the position of the desired element
- return jQuery.inArray(
- // If it receives a jQuery object, the first element is used
- elem.jquery ? elem[0] : elem, this );
- },
-
- add: function( selector, context ) {
- var set = typeof selector === "string" ?
- jQuery( selector, context ) :
- jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
- all = jQuery.merge( this.get(), set );
-
- return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
- all :
- jQuery.unique( all ) );
- },
-
- andSelf: function() {
- return this.add( this.prevObject );
- }
-});
-
-// A painfully simple check to see if an element is disconnected
-// from a document (should be improved, where feasible).
-function isDisconnected( node ) {
- return !node || !node.parentNode || node.parentNode.nodeType === 11;
-}
-
-jQuery.each({
- parent: function( elem ) {
- var parent = elem.parentNode;
- return parent && parent.nodeType !== 11 ? parent : null;
- },
- parents: function( elem ) {
- return jQuery.dir( elem, "parentNode" );
- },
- parentsUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "parentNode", until );
- },
- next: function( elem ) {
- return jQuery.nth( elem, 2, "nextSibling" );
- },
- prev: function( elem ) {
- return jQuery.nth( elem, 2, "previousSibling" );
- },
- nextAll: function( elem ) {
- return jQuery.dir( elem, "nextSibling" );
- },
- prevAll: function( elem ) {
- return jQuery.dir( elem, "previousSibling" );
- },
- nextUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "nextSibling", until );
- },
- prevUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "previousSibling", until );
- },
- siblings: function( elem ) {
- return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
- },
- children: function( elem ) {
- return jQuery.sibling( elem.firstChild );
- },
- contents: function( elem ) {
- return jQuery.nodeName( elem, "iframe" ) ?
- elem.contentDocument || elem.contentWindow.document :
- jQuery.makeArray( elem.childNodes );
- }
-}, function( name, fn ) {
- jQuery.fn[ name ] = function( until, selector ) {
- var ret = jQuery.map( this, fn, until );
-
- if ( !runtil.test( name ) ) {
- selector = until;
- }
-
- if ( selector && typeof selector === "string" ) {
- ret = jQuery.filter( selector, ret );
- }
-
- ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;
-
- if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
- ret = ret.reverse();
- }
-
- return this.pushStack( ret, name, slice.call( arguments ).join(",") );
- };
-});
-
-jQuery.extend({
- filter: function( expr, elems, not ) {
- if ( not ) {
- expr = ":not(" + expr + ")";
- }
-
- return elems.length === 1 ?
- jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
- jQuery.find.matches(expr, elems);
- },
-
- dir: function( elem, dir, until ) {
- var matched = [],
- cur = elem[ dir ];
-
- while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
- if ( cur.nodeType === 1 ) {
- matched.push( cur );
- }
- cur = cur[dir];
- }
- return matched;
- },
-
- nth: function( cur, result, dir, elem ) {
- result = result || 1;
- var num = 0;
-
- for ( ; cur; cur = cur[dir] ) {
- if ( cur.nodeType === 1 && ++num === result ) {
- break;
- }
- }
-
- return cur;
- },
-
- sibling: function( n, elem ) {
- var r = [];
-
- for ( ; n; n = n.nextSibling ) {
- if ( n.nodeType === 1 && n !== elem ) {
- r.push( n );
- }
- }
-
- return r;
- }
-});
-
-// Implement the identical functionality for filter and not
-function winnow( elements, qualifier, keep ) {
-
- // Can't pass null or undefined to indexOf in Firefox 4
- // Set to 0 to skip string check
- qualifier = qualifier || 0;
-
- if ( jQuery.isFunction( qualifier ) ) {
- return jQuery.grep(elements, function( elem, i ) {
- var retVal = !!qualifier.call( elem, i, elem );
- return retVal === keep;
- });
-
- } else if ( qualifier.nodeType ) {
- return jQuery.grep(elements, function( elem, i ) {
- return ( elem === qualifier ) === keep;
- });
-
- } else if ( typeof qualifier === "string" ) {
- var filtered = jQuery.grep(elements, function( elem ) {
- return elem.nodeType === 1;
- });
-
- if ( isSimple.test( qualifier ) ) {
- return jQuery.filter(qualifier, filtered, !keep);
- } else {
- qualifier = jQuery.filter( qualifier, filtered );
- }
- }
-
- return jQuery.grep(elements, function( elem, i ) {
- return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
- });
-}
-
-
-
-
-function createSafeFragment( document ) {
- var list = nodeNames.split( "|" ),
- safeFrag = document.createDocumentFragment();
-
- if ( safeFrag.createElement ) {
- while ( list.length ) {
- safeFrag.createElement(
- list.pop()
- );
- }
- }
- return safeFrag;
-}
-
-var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
- "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
- rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
- rleadingWhitespace = /^\s+/,
- rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
- rtagName = /<([\w:]+)/,
- rtbody = /<tbody/i,
- rhtml = /<|&#?\w+;/,
- rnoInnerhtml = /<(?:script|style)/i,
- rnocache = /<(?:script|object|embed|option|style)/i,
- rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
- // checked="checked" or checked
- rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
- rscriptType = /\/(java|ecma)script/i,
- rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)/,
- wrapMap = {
- option: [ 1, "<select multiple='multiple'>", "</select>" ],
- legend: [ 1, "<fieldset>", "</fieldset>" ],
- thead: [ 1, "<table>", "</table>" ],
- tr: [ 2, "<table><tbody>", "</tbody></table>" ],
- td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
- col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
- area: [ 1, "<map>", "</map>" ],
- _default: [ 0, "", "" ]
- },
- safeFragment = createSafeFragment( document );
-
-wrapMap.optgroup = wrapMap.option;
-wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
-wrapMap.th = wrapMap.td;
-
-// IE can't serialize <link> and <script> tags normally
-if ( !jQuery.support.htmlSerialize ) {
- wrapMap._default = [ 1, "div<div>", "</div>" ];
-}
-
-jQuery.fn.extend({
- text: function( value ) {
- return jQuery.access( this, function( value ) {
- return value === undefined ?
- jQuery.text( this ) :
- this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
- }, null, value, arguments.length );
- },
-
- wrapAll: function( html ) {
- if ( jQuery.isFunction( html ) ) {
- return this.each(function(i) {
- jQuery(this).wrapAll( html.call(this, i) );
- });
- }
-
- if ( this[0] ) {
- // The elements to wrap the target around
- var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
-
- if ( this[0].parentNode ) {
- wrap.insertBefore( this[0] );
- }
-
- wrap.map(function() {
- var elem = this;
-
- while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
- elem = elem.firstChild;
- }
-
- return elem;
- }).append( this );
- }
-
- return this;
- },
-
- wrapInner: function( html ) {
- if ( jQuery.isFunction( html ) ) {
- return this.each(function(i) {
- jQuery(this).wrapInner( html.call(this, i) );
- });
- }
-
- return this.each(function() {
- var self = jQuery( this ),
- contents = self.contents();
-
- if ( contents.length ) {
- contents.wrapAll( html );
-
- } else {
- self.append( html );
- }
- });
- },
-
- wrap: function( html ) {
- var isFunction = jQuery.isFunction( html );
-
- return this.each(function(i) {
- jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
- });
- },
-
- unwrap: function() {
- return this.parent().each(function() {
- if ( !jQuery.nodeName( this, "body" ) ) {
- jQuery( this ).replaceWith( this.childNodes );
- }
- }).end();
- },
-
- append: function() {
- return this.domManip(arguments, true, function( elem ) {
- if ( this.nodeType === 1 ) {
- this.appendChild( elem );
- }
- });
- },
-
- prepend: function() {
- return this.domManip(arguments, true, function( elem ) {
- if ( this.nodeType === 1 ) {
- this.insertBefore( elem, this.firstChild );
- }
- });
- },
-
- before: function() {
- if ( this[0] && this[0].parentNode ) {
- return this.domManip(arguments, false, function( elem ) {
- this.parentNode.insertBefore( elem, this );
- });
- } else if ( arguments.length ) {
- var set = jQuery.clean( arguments );
- set.push.apply( set, this.toArray() );
- return this.pushStack( set, "before", arguments );
- }
- },
-
- after: function() {
- if ( this[0] && this[0].parentNode ) {
- return this.domManip(arguments, false, function( elem ) {
- this.parentNode.insertBefore( elem, this.nextSibling );
- });
- } else if ( arguments.length ) {
- var set = this.pushStack( this, "after", arguments );
- set.push.apply( set, jQuery.clean(arguments) );
- return set;
- }
- },
-
- // keepData is for internal use only--do not document
- remove: function( selector, keepData ) {
- for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
- if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
- if ( !keepData && elem.nodeType === 1 ) {
- jQuery.cleanData( elem.getElementsByTagName("*") );
- jQuery.cleanData( [ elem ] );
- }
-
- if ( elem.parentNode ) {
- elem.parentNode.removeChild( elem );
- }
- }
- }
-
- return this;
- },
-
- empty: function() {
- for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
- // Remove element nodes and prevent memory leaks
- if ( elem.nodeType === 1 ) {
- jQuery.cleanData( elem.getElementsByTagName("*") );
- }
-
- // Remove any remaining nodes
- while ( elem.firstChild ) {
- elem.removeChild( elem.firstChild );
- }
- }
-
- return this;
- },
-
- clone: function( dataAndEvents, deepDataAndEvents ) {
- dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
- deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
-
- return this.map( function () {
- return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
- });
- },
-
- html: function( value ) {
- return jQuery.access( this, function( value ) {
- var elem = this[0] || {},
- i = 0,
- l = this.length;
-
- if ( value === undefined ) {
- return elem.nodeType === 1 ?
- elem.innerHTML.replace( rinlinejQuery, "" ) :
- null;
- }
-
-
- if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
- ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
- !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) {
-
- value = value.replace( rxhtmlTag, "<$1></$2>" );
-
- try {
- for (; i < l; i++ ) {
- // Remove element nodes and prevent memory leaks
- elem = this[i] || {};
- if ( elem.nodeType === 1 ) {
- jQuery.cleanData( elem.getElementsByTagName( "*" ) );
- elem.innerHTML = value;
- }
- }
-
- elem = 0;
-
- // If using innerHTML throws an exception, use the fallback method
- } catch(e) {}
- }
-
- if ( elem ) {
- this.empty().append( value );
- }
- }, null, value, arguments.length );
- },
-
- replaceWith: function( value ) {
- if ( this[0] && this[0].parentNode ) {
- // Make sure that the elements are removed from the DOM before they are inserted
- // this can help fix replacing a parent with child elements
- if ( jQuery.isFunction( value ) ) {
- return this.each(function(i) {
- var self = jQuery(this), old = self.html();
- self.replaceWith( value.call( this, i, old ) );
- });
- }
-
- if ( typeof value !== "string" ) {
- value = jQuery( value ).detach();
- }
-
- return this.each(function() {
- var next = this.nextSibling,
- parent = this.parentNode;
-
- jQuery( this ).remove();
-
- if ( next ) {
- jQuery(next).before( value );
- } else {
- jQuery(parent).append( value );
- }
- });
- } else {
- return this.length ?
- this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) :
- this;
- }
- },
-
- detach: function( selector ) {
- return this.remove( selector, true );
- },
-
- domManip: function( args, table, callback ) {
- var results, first, fragment, parent,
- value = args[0],
- scripts = [];
-
- // We can't cloneNode fragments that contain checked, in WebKit
- if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
- return this.each(function() {
- jQuery(this).domManip( args, table, callback, true );
- });
- }
-
- if ( jQuery.isFunction(value) ) {
- return this.each(function(i) {
- var self = jQuery(this);
- args[0] = value.call(this, i, table ? self.html() : undefined);
- self.domManip( args, table, callback );
- });
- }
-
- if ( this[0] ) {
- parent = value && value.parentNode;
-
- // If we're in a fragment, just use that instead of building a new one
- if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
- results = { fragment: parent };
-
- } else {
- results = jQuery.buildFragment( args, this, scripts );
- }
-
- fragment = results.fragment;
-
- if ( fragment.childNodes.length === 1 ) {
- first = fragment = fragment.firstChild;
- } else {
- first = fragment.firstChild;
- }
-
- if ( first ) {
- table = table && jQuery.nodeName( first, "tr" );
-
- for ( var i = 0, l = this.length, lastIndex = l - 1; i < l; i++ ) {
- callback.call(
- table ?
- root(this[i], first) :
- this[i],
- // Make sure that we do not leak memory by inadvertently discarding
- // the original fragment (which might have attached data) instead of
- // using it; in addition, use the original fragment object for the last
- // item instead of first because it can end up being emptied incorrectly
- // in certain situations (Bug #8070).
- // Fragments from the fragment cache must always be cloned and never used
- // in place.
- results.cacheable || ( l > 1 && i < lastIndex ) ?
- jQuery.clone( fragment, true, true ) :
- fragment
- );
- }
- }
-
- if ( scripts.length ) {
- jQuery.each( scripts, function( i, elem ) {
- if ( elem.src ) {
- jQuery.ajax({
- type: "GET",
- global: false,
- url: elem.src,
- async: false,
- dataType: "script"
- });
- } else {
- jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) );
- }
-
- if ( elem.parentNode ) {
- elem.parentNode.removeChild( elem );
- }
- });
- }
- }
-
- return this;
- }
-});
-
-function root( elem, cur ) {
- return jQuery.nodeName(elem, "table") ?
- (elem.getElementsByTagName("tbody")[0] ||
- elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
- elem;
-}
-
-function cloneCopyEvent( src, dest ) {
-
- if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
- return;
- }
-
- var type, i, l,
- oldData = jQuery._data( src ),
- curData = jQuery._data( dest, oldData ),
- events = oldData.events;
-
- if ( events ) {
- delete curData.handle;
- curData.events = {};
-
- for ( type in events ) {
- for ( i = 0, l = events[ type ].length; i < l; i++ ) {
- jQuery.event.add( dest, type, events[ type ][ i ] );
- }
- }
- }
-
- // make the cloned public data object a copy from the original
- if ( curData.data ) {
- curData.data = jQuery.extend( {}, curData.data );
- }
-}
-
-function cloneFixAttributes( src, dest ) {
- var nodeName;
-
- // We do not need to do anything for non-Elements
- if ( dest.nodeType !== 1 ) {
- return;
- }
-
- // clearAttributes removes the attributes, which we don't want,
- // but also removes the attachEvent events, which we *do* want
- if ( dest.clearAttributes ) {
- dest.clearAttributes();
- }
-
- // mergeAttributes, in contrast, only merges back on the
- // original attributes, not the events
- if ( dest.mergeAttributes ) {
- dest.mergeAttributes( src );
- }
-
- nodeName = dest.nodeName.toLowerCase();
-
- // IE6-8 fail to clone children inside object elements that use
- // the proprietary classid attribute value (rather than the type
- // attribute) to identify the type of content to display
- if ( nodeName === "object" ) {
- dest.outerHTML = src.outerHTML;
-
- } else if ( nodeName === "input" && (src.type === "checkbox" || src.type === "radio") ) {
- // IE6-8 fails to persist the checked state of a cloned checkbox
- // or radio button. Worse, IE6-7 fail to give the cloned element
- // a checked appearance if the defaultChecked value isn't also set
- if ( src.checked ) {
- dest.defaultChecked = dest.checked = src.checked;
- }
-
- // IE6-7 get confused and end up setting the value of a cloned
- // checkbox/radio button to an empty string instead of "on"
- if ( dest.value !== src.value ) {
- dest.value = src.value;
- }
-
- // IE6-8 fails to return the selected option to the default selected
- // state when cloning options
- } else if ( nodeName === "option" ) {
- dest.selected = src.defaultSelected;
-
- // IE6-8 fails to set the defaultValue to the correct value when
- // cloning other types of input fields
- } else if ( nodeName === "input" || nodeName === "textarea" ) {
- dest.defaultValue = src.defaultValue;
-
- // IE blanks contents when cloning scripts
- } else if ( nodeName === "script" && dest.text !== src.text ) {
- dest.text = src.text;
- }
-
- // Event data gets referenced instead of copied if the expando
- // gets copied too
- dest.removeAttribute( jQuery.expando );
-
- // Clear flags for bubbling special change/submit events, they must
- // be reattached when the newly cloned events are first activated
- dest.removeAttribute( "_submit_attached" );
- dest.removeAttribute( "_change_attached" );
-}
-
-jQuery.buildFragment = function( args, nodes, scripts ) {
- var fragment, cacheable, cacheresults, doc,
- first = args[ 0 ];
-
- // nodes may contain either an explicit document object,
- // a jQuery collection or context object.
- // If nodes[0] contains a valid object to assign to doc
- if ( nodes && nodes[0] ) {
- doc = nodes[0].ownerDocument || nodes[0];
- }
-
- // Ensure that an attr object doesn't incorrectly stand in as a document object
- // Chrome and Firefox seem to allow this to occur and will throw exception
- // Fixes #8950
- if ( !doc.createDocumentFragment ) {
- doc = document;
- }
-
- // Only cache "small" (1/2 KB) HTML strings that are associated with the main document
- // Cloning options loses the selected state, so don't cache them
- // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
- // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
- // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501
- if ( args.length === 1 && typeof first === "string" && first.length < 512 && doc === document &&
- first.charAt(0) === "<" && !rnocache.test( first ) &&
- (jQuery.support.checkClone || !rchecked.test( first )) &&
- (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) {
-
- cacheable = true;
-
- cacheresults = jQuery.fragments[ first ];
- if ( cacheresults && cacheresults !== 1 ) {
- fragment = cacheresults;
- }
- }
-
- if ( !fragment ) {
- fragment = doc.createDocumentFragment();
- jQuery.clean( args, doc, fragment, scripts );
- }
-
- if ( cacheable ) {
- jQuery.fragments[ first ] = cacheresults ? fragment : 1;
- }
-
- return { fragment: fragment, cacheable: cacheable };
-};
-
-jQuery.fragments = {};
-
-jQuery.each({
- appendTo: "append",
- prependTo: "prepend",
- insertBefore: "before",
- insertAfter: "after",
- replaceAll: "replaceWith"
-}, function( name, original ) {
- jQuery.fn[ name ] = function( selector ) {
- var ret = [],
- insert = jQuery( selector ),
- parent = this.length === 1 && this[0].parentNode;
-
- if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
- insert[ original ]( this[0] );
- return this;
-
- } else {
- for ( var i = 0, l = insert.length; i < l; i++ ) {
- var elems = ( i > 0 ? this.clone(true) : this ).get();
- jQuery( insert[i] )[ original ]( elems );
- ret = ret.concat( elems );
- }
-
- return this.pushStack( ret, name, insert.selector );
- }
- };
-});
-
-function getAll( elem ) {
- if ( typeof elem.getElementsByTagName !== "undefined" ) {
- return elem.getElementsByTagName( "*" );
-
- } else if ( typeof elem.querySelectorAll !== "undefined" ) {
- return elem.querySelectorAll( "*" );
-
- } else {
- return [];
- }
-}
-
-// Used in clean, fixes the defaultChecked property
-function fixDefaultChecked( elem ) {
- if ( elem.type === "checkbox" || elem.type === "radio" ) {
- elem.defaultChecked = elem.checked;
- }
-}
-// Finds all inputs and passes them to fixDefaultChecked
-function findInputs( elem ) {
- var nodeName = ( elem.nodeName || "" ).toLowerCase();
- if ( nodeName === "input" ) {
- fixDefaultChecked( elem );
- // Skip scripts, get other children
- } else if ( nodeName !== "script" && typeof elem.getElementsByTagName !== "undefined" ) {
- jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked );
- }
-}
-
-// Derived From: http://www.iecss.com/shimprove/javascript/shimprove.1-0-1.js
-function shimCloneNode( elem ) {
- var div = document.createElement( "div" );
- safeFragment.appendChild( div );
-
- div.innerHTML = elem.outerHTML;
- return div.firstChild;
-}
-
-jQuery.extend({
- clone: function( elem, dataAndEvents, deepDataAndEvents ) {
- var srcElements,
- destElements,
- i,
- // IE<=8 does not properly clone detached, unknown element nodes
- clone = jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ?
- elem.cloneNode( true ) :
- shimCloneNode( elem );
-
- if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&
- (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
- // IE copies events bound via attachEvent when using cloneNode.
- // Calling detachEvent on the clone will also remove the events
- // from the original. In order to get around this, we use some
- // proprietary methods to clear the events. Thanks to MooTools
- // guys for this hotness.
-
- cloneFixAttributes( elem, clone );
-
- // Using Sizzle here is crazy slow, so we use getElementsByTagName instead
- srcElements = getAll( elem );
- destElements = getAll( clone );
-
- // Weird iteration because IE will replace the length property
- // with an element if you are cloning the body and one of the
- // elements on the page has a name or id of "length"
- for ( i = 0; srcElements[i]; ++i ) {
- // Ensure that the destination node is not null; Fixes #9587
- if ( destElements[i] ) {
- cloneFixAttributes( srcElements[i], destElements[i] );
- }
- }
- }
-
- // Copy the events from the original to the clone
- if ( dataAndEvents ) {
- cloneCopyEvent( elem, clone );
-
- if ( deepDataAndEvents ) {
- srcElements = getAll( elem );
- destElements = getAll( clone );
-
- for ( i = 0; srcElements[i]; ++i ) {
- cloneCopyEvent( srcElements[i], destElements[i] );
- }
- }
- }
-
- srcElements = destElements = null;
-
- // Return the cloned set
- return clone;
- },
-
- clean: function( elems, context, fragment, scripts ) {
- var checkScriptType, script, j,
- ret = [];
-
- context = context || document;
-
- // !context.createElement fails in IE with an error but returns typeof 'object'
- if ( typeof context.createElement === "undefined" ) {
- context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
- }
-
- for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
- if ( typeof elem === "number" ) {
- elem += "";
- }
-
- if ( !elem ) {
- continue;
- }
-
- // Convert html string into DOM nodes
- if ( typeof elem === "string" ) {
- if ( !rhtml.test( elem ) ) {
- elem = context.createTextNode( elem );
- } else {
- // Fix "XHTML"-style tags in all browsers
- elem = elem.replace(rxhtmlTag, "<$1></$2>");
-
- // Trim whitespace, otherwise indexOf won't work as expected
- var tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(),
- wrap = wrapMap[ tag ] || wrapMap._default,
- depth = wrap[0],
- div = context.createElement("div"),
- safeChildNodes = safeFragment.childNodes,
- remove;
-
- // Append wrapper element to unknown element safe doc fragment
- if ( context === document ) {
- // Use the fragment we've already created for this document
- safeFragment.appendChild( div );
- } else {
- // Use a fragment created with the owner document
- createSafeFragment( context ).appendChild( div );
- }
-
- // Go to html and back, then peel off extra wrappers
- div.innerHTML = wrap[1] + elem + wrap[2];
-
- // Move to the right depth
- while ( depth-- ) {
- div = div.lastChild;
- }
-
- // Remove IE's autoinserted <tbody> from table fragments
- if ( !jQuery.support.tbody ) {
-
- // String was a <table>, *may* have spurious <tbody>
- var hasBody = rtbody.test(elem),
- tbody = tag === "table" && !hasBody ?
- div.firstChild && div.firstChild.childNodes :
-
- // String was a bare <thead> or <tfoot>
- wrap[1] === "<table>" && !hasBody ?
- div.childNodes :
- [];
-
- for ( j = tbody.length - 1; j >= 0 ; --j ) {
- if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
- tbody[ j ].parentNode.removeChild( tbody[ j ] );
- }
- }
- }
-
- // IE completely kills leading whitespace when innerHTML is used
- if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
- div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
- }
-
- elem = div.childNodes;
-
- // Clear elements from DocumentFragment (safeFragment or otherwise)
- // to avoid hoarding elements. Fixes #11356
- if ( div ) {
- div.parentNode.removeChild( div );
-
- // Guard against -1 index exceptions in FF3.6
- if ( safeChildNodes.length > 0 ) {
- remove = safeChildNodes[ safeChildNodes.length - 1 ];
-
- if ( remove && remove.parentNode ) {
- remove.parentNode.removeChild( remove );
- }
- }
- }
- }
- }
-
- // Resets defaultChecked for any radios and checkboxes
- // about to be appended to the DOM in IE 6/7 (#8060)
- var len;
- if ( !jQuery.support.appendChecked ) {
- if ( elem[0] && typeof (len = elem.length) === "number" ) {
- for ( j = 0; j < len; j++ ) {
- findInputs( elem[j] );
- }
- } else {
- findInputs( elem );
- }
- }
-
- if ( elem.nodeType ) {
- ret.push( elem );
- } else {
- ret = jQuery.merge( ret, elem );
- }
- }
-
- if ( fragment ) {
- checkScriptType = function( elem ) {
- return !elem.type || rscriptType.test( elem.type );
- };
- for ( i = 0; ret[i]; i++ ) {
- script = ret[i];
- if ( scripts && jQuery.nodeName( script, "script" ) && (!script.type || rscriptType.test( script.type )) ) {
- scripts.push( script.parentNode ? script.parentNode.removeChild( script ) : script );
-
- } else {
- if ( script.nodeType === 1 ) {
- var jsTags = jQuery.grep( script.getElementsByTagName( "script" ), checkScriptType );
-
- ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) );
- }
- fragment.appendChild( script );
- }
- }
- }
-
- return ret;
- },
-
- cleanData: function( elems ) {
- var data, id,
- cache = jQuery.cache,
- special = jQuery.event.special,
- deleteExpando = jQuery.support.deleteExpando;
-
- for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
- if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
- continue;
- }
-
- id = elem[ jQuery.expando ];
-
- if ( id ) {
- data = cache[ id ];
-
- if ( data && data.events ) {
- for ( var type in data.events ) {
- if ( special[ type ] ) {
- jQuery.event.remove( elem, type );
-
- // This is a shortcut to avoid jQuery.event.remove's overhead
- } else {
- jQuery.removeEvent( elem, type, data.handle );
- }
- }
-
- // Null the DOM reference to avoid IE6/7/8 leak (#7054)
- if ( data.handle ) {
- data.handle.elem = null;
- }
- }
-
- if ( deleteExpando ) {
- delete elem[ jQuery.expando ];
-
- } else if ( elem.removeAttribute ) {
- elem.removeAttribute( jQuery.expando );
- }
-
- delete cache[ id ];
- }
- }
- }
-});
-
-
-
-
-var ralpha = /alpha\([^)]*\)/i,
- ropacity = /opacity=([^)]*)/,
- // fixed for IE9, see #8346
- rupper = /([A-Z]|^ms)/g,
- rnum = /^[\-+]?(?:\d*\.)?\d+$/i,
- rnumnonpx = /^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,
- rrelNum = /^([\-+])=([\-+.\de]+)/,
- rmargin = /^margin/,
-
- cssShow = { position: "absolute", visibility: "hidden", display: "block" },
-
- // order is important!
- cssExpand = [ "Top", "Right", "Bottom", "Left" ],
-
- curCSS,
-
- getComputedStyle,
- currentStyle;
-
-jQuery.fn.css = function( name, value ) {
- return jQuery.access( this, function( elem, name, value ) {
- return value !== undefined ?
- jQuery.style( elem, name, value ) :
- jQuery.css( elem, name );
- }, name, value, arguments.length > 1 );
-};
-
-jQuery.extend({
- // Add in style property hooks for overriding the default
- // behavior of getting and setting a style property
- cssHooks: {
- opacity: {
- get: function( elem, computed ) {
- if ( computed ) {
- // We should always get a number back from opacity
- var ret = curCSS( elem, "opacity" );
- return ret === "" ? "1" : ret;
-
- } else {
- return elem.style.opacity;
- }
- }
- }
- },
-
- // Exclude the following css properties to add px
- cssNumber: {
- "fillOpacity": true,
- "fontWeight": true,
- "lineHeight": true,
- "opacity": true,
- "orphans": true,
- "widows": true,
- "zIndex": true,
- "zoom": true
- },
-
- // Add in properties whose names you wish to fix before
- // setting or getting the value
- cssProps: {
- // normalize float css property
- "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
- },
-
- // Get and set the style property on a DOM Node
- style: function( elem, name, value, extra ) {
- // Don't set styles on text and comment nodes
- if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
- return;
- }
-
- // Make sure that we're working with the right name
- var ret, type, origName = jQuery.camelCase( name ),
- style = elem.style, hooks = jQuery.cssHooks[ origName ];
-
- name = jQuery.cssProps[ origName ] || origName;
-
- // Check if we're setting a value
- if ( value !== undefined ) {
- type = typeof value;
-
- // convert relative number strings (+= or -=) to relative numbers. #7345
- if ( type === "string" && (ret = rrelNum.exec( value )) ) {
- value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );
- // Fixes bug #9237
- type = "number";
- }
-
- // Make sure that NaN and null values aren't set. See: #7116
- if ( value == null || type === "number" && isNaN( value ) ) {
- return;
- }
-
- // If a number was passed in, add 'px' to the (except for certain CSS properties)
- if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
- value += "px";
- }
-
- // If a hook was provided, use that value, otherwise just set the specified value
- if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
- // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
- // Fixes bug #5509
- try {
- style[ name ] = value;
- } catch(e) {}
- }
-
- } else {
- // If a hook was provided get the non-computed value from there
- if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
- return ret;
- }
-
- // Otherwise just get the value from the style object
- return style[ name ];
- }
- },
-
- css: function( elem, name, extra ) {
- var ret, hooks;
-
- // Make sure that we're working with the right name
- name = jQuery.camelCase( name );
- hooks = jQuery.cssHooks[ name ];
- name = jQuery.cssProps[ name ] || name;
-
- // cssFloat needs a special treatment
- if ( name === "cssFloat" ) {
- name = "float";
- }
-
- // If a hook was provided get the computed value from there
- if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
- return ret;
-
- // Otherwise, if a way to get the computed value exists, use that
- } else if ( curCSS ) {
- return curCSS( elem, name );
- }
- },
-
- // A method for quickly swapping in/out CSS properties to get correct calculations
- swap: function( elem, options, callback ) {
- var old = {},
- ret, name;
-
- // Remember the old values, and insert the new ones
- for ( name in options ) {
- old[ name ] = elem.style[ name ];
- elem.style[ name ] = options[ name ];
- }
-
- ret = callback.call( elem );
-
- // Revert the old values
- for ( name in options ) {
- elem.style[ name ] = old[ name ];
- }
-
- return ret;
- }
-});
-
-// DEPRECATED in 1.3, Use jQuery.css() instead
-jQuery.curCSS = jQuery.css;
-
-if ( document.defaultView && document.defaultView.getComputedStyle ) {
- getComputedStyle = function( elem, name ) {
- var ret, defaultView, computedStyle, width,
- style = elem.style;
-
- name = name.replace( rupper, "-$1" ).toLowerCase();
-
- if ( (defaultView = elem.ownerDocument.defaultView) &&
- (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
-
- ret = computedStyle.getPropertyValue( name );
- if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
- ret = jQuery.style( elem, name );
- }
- }
-
- // A tribute to the "awesome hack by Dean Edwards"
- // WebKit uses "computed value (percentage if specified)" instead of "used value" for margins
- // which is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
- if ( !jQuery.support.pixelMargin && computedStyle && rmargin.test( name ) && rnumnonpx.test( ret ) ) {
- width = style.width;
- style.width = ret;
- ret = computedStyle.width;
- style.width = width;
- }
-
- return ret;
- };
-}
-
-if ( document.documentElement.currentStyle ) {
- currentStyle = function( elem, name ) {
- var left, rsLeft, uncomputed,
- ret = elem.currentStyle && elem.currentStyle[ name ],
- style = elem.style;
-
- // Avoid setting ret to empty string here
- // so we don't default to auto
- if ( ret == null && style && (uncomputed = style[ name ]) ) {
- ret = uncomputed;
- }
-
- // From the awesome hack by Dean Edwards
- // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
-
- // If we're not dealing with a regular pixel number
- // but a number that has a weird ending, we need to convert it to pixels
- if ( rnumnonpx.test( ret ) ) {
-
- // Remember the original values
- left = style.left;
- rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;
-
- // Put in the new values to get a computed value out
- if ( rsLeft ) {
- elem.runtimeStyle.left = elem.currentStyle.left;
- }
- style.left = name === "fontSize" ? "1em" : ret;
- ret = style.pixelLeft + "px";
-
- // Revert the changed values
- style.left = left;
- if ( rsLeft ) {
- elem.runtimeStyle.left = rsLeft;
- }
- }
-
- return ret === "" ? "auto" : ret;
- };
-}
-
-curCSS = getComputedStyle || currentStyle;
-
-function getWidthOrHeight( elem, name, extra ) {
-
- // Start with offset property
- var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
- i = name === "width" ? 1 : 0,
- len = 4;
-
- if ( val > 0 ) {
- if ( extra !== "border" ) {
- for ( ; i < len; i += 2 ) {
- if ( !extra ) {
- val -= parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;
- }
- if ( extra === "margin" ) {
- val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0;
- } else {
- val -= parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
- }
- }
- }
-
- return val + "px";
- }
-
- // Fall back to computed then uncomputed css if necessary
- val = curCSS( elem, name );
- if ( val < 0 || val == null ) {
- val = elem.style[ name ];
- }
-
- // Computed unit is not pixels. Stop here and return.
- if ( rnumnonpx.test(val) ) {
- return val;
- }
-
- // Normalize "", auto, and prepare for extra
- val = parseFloat( val ) || 0;
-
- // Add padding, border, margin
- if ( extra ) {
- for ( ; i < len; i += 2 ) {
- val += parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;
- if ( extra !== "padding" ) {
- val += parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
- }
- if ( extra === "margin" ) {
- val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ]) ) || 0;
- }
- }
- }
-
- return val + "px";
-}
-
-jQuery.each([ "height", "width" ], function( i, name ) {
- jQuery.cssHooks[ name ] = {
- get: function( elem, computed, extra ) {
- if ( computed ) {
- if ( elem.offsetWidth !== 0 ) {
- return getWidthOrHeight( elem, name, extra );
- } else {
- return jQuery.swap( elem, cssShow, function() {
- return getWidthOrHeight( elem, name, extra );
- });
- }
- }
- },
-
- set: function( elem, value ) {
- return rnum.test( value ) ?
- value + "px" :
- value;
- }
- };
-});
-
-if ( !jQuery.support.opacity ) {
- jQuery.cssHooks.opacity = {
- get: function( elem, computed ) {
- // IE uses filters for opacity
- return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
- ( parseFloat( RegExp.$1 ) / 100 ) + "" :
- computed ? "1" : "";
- },
-
- set: function( elem, value ) {
- var style = elem.style,
- currentStyle = elem.currentStyle,
- opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
- filter = currentStyle && currentStyle.filter || style.filter || "";
-
- // IE has trouble with opacity if it does not have layout
- // Force it by setting the zoom level
- style.zoom = 1;
-
- // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
- if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
-
- // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
- // if "filter:" is present at all, clearType is disabled, we want to avoid this
- // style.removeAttribute is IE Only, but so apparently is this code path...
- style.removeAttribute( "filter" );
-
- // if there there is no filter style applied in a css rule, we are done
- if ( currentStyle && !currentStyle.filter ) {
- return;
- }
- }
-
- // otherwise, set new filter values
- style.filter = ralpha.test( filter ) ?
- filter.replace( ralpha, opacity ) :
- filter + " " + opacity;
- }
- };
-}
-
-jQuery(function() {
- // This hook cannot be added until DOM ready because the support test
- // for it is not run until after DOM ready
- if ( !jQuery.support.reliableMarginRight ) {
- jQuery.cssHooks.marginRight = {
- get: function( elem, computed ) {
- // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
- // Work around by temporarily setting element display to inline-block
- return jQuery.swap( elem, { "display": "inline-block" }, function() {
- if ( computed ) {
- return curCSS( elem, "margin-right" );
- } else {
- return elem.style.marginRight;
- }
- });
- }
- };
- }
-});
-
-if ( jQuery.expr && jQuery.expr.filters ) {
- jQuery.expr.filters.hidden = function( elem ) {
- var width = elem.offsetWidth,
- height = elem.offsetHeight;
-
- return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
- };
-
- jQuery.expr.filters.visible = function( elem ) {
- return !jQuery.expr.filters.hidden( elem );
- };
-}
-
-// These hooks are used by animate to expand properties
-jQuery.each({
- margin: "",
- padding: "",
- border: "Width"
-}, function( prefix, suffix ) {
-
- jQuery.cssHooks[ prefix + suffix ] = {
- expand: function( value ) {
- var i,
-
- // assumes a single number if not a string
- parts = typeof value === "string" ? value.split(" ") : [ value ],
- expanded = {};
-
- for ( i = 0; i < 4; i++ ) {
- expanded[ prefix + cssExpand[ i ] + suffix ] =
- parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
- }
-
- return expanded;
- }
- };
-});
-
-
-
-
-var r20 = /%20/g,
- rbracket = /\[\]$/,
- rCRLF = /\r?\n/g,
- rhash = /#.*$/,
- rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
- rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
- // #7653, #8125, #8152: local protocol detection
- rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,
- rnoContent = /^(?:GET|HEAD)$/,
- rprotocol = /^\/\//,
- rquery = /\?/,
- rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
- rselectTextarea = /^(?:select|textarea)/i,
- rspacesAjax = /\s+/,
- rts = /([?&])_=[^&]*/,
- rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,
-
- // Keep a copy of the old load method
- _load = jQuery.fn.load,
-
- /* Prefilters
- * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
- * 2) These are called:
- * - BEFORE asking for a transport
- * - AFTER param serialization (s.data is a string if s.processData is true)
- * 3) key is the dataType
- * 4) the catchall symbol "*" can be used
- * 5) execution will start with transport dataType and THEN continue down to "*" if needed
- */
- prefilters = {},
-
- /* Transports bindings
- * 1) key is the dataType
- * 2) the catchall symbol "*" can be used
- * 3) selection will start with transport dataType and THEN go to "*" if needed
- */
- transports = {},
-
- // Document location
- ajaxLocation,
-
- // Document location segments
- ajaxLocParts,
-
- // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
- allTypes = ["*/"] + ["*"];
-
-// #8138, IE may throw an exception when accessing
-// a field from window.location if document.domain has been set
-try {
- ajaxLocation = location.href;
-} catch( e ) {
- // Use the href attribute of an A element
- // since IE will modify it given document.location
- ajaxLocation = document.createElement( "a" );
- ajaxLocation.href = "";
- ajaxLocation = ajaxLocation.href;
-}
-
-// Segment location into parts
-ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
-
-// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
-function addToPrefiltersOrTransports( structure ) {
-
- // dataTypeExpression is optional and defaults to "*"
- return function( dataTypeExpression, func ) {
-
- if ( typeof dataTypeExpression !== "string" ) {
- func = dataTypeExpression;
- dataTypeExpression = "*";
- }
-
- if ( jQuery.isFunction( func ) ) {
- var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ),
- i = 0,
- length = dataTypes.length,
- dataType,
- list,
- placeBefore;
-
- // For each dataType in the dataTypeExpression
- for ( ; i < length; i++ ) {
- dataType = dataTypes[ i ];
- // We control if we're asked to add before
- // any existing element
- placeBefore = /^\+/.test( dataType );
- if ( placeBefore ) {
- dataType = dataType.substr( 1 ) || "*";
- }
- list = structure[ dataType ] = structure[ dataType ] || [];
- // then we add to the structure accordingly
- list[ placeBefore ? "unshift" : "push" ]( func );
- }
- }
- };
-}
-
-// Base inspection function for prefilters and transports
-function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR,
- dataType /* internal */, inspected /* internal */ ) {
-
- dataType = dataType || options.dataTypes[ 0 ];
- inspected = inspected || {};
-
- inspected[ dataType ] = true;
-
- var list = structure[ dataType ],
- i = 0,
- length = list ? list.length : 0,
- executeOnly = ( structure === prefilters ),
- selection;
-
- for ( ; i < length && ( executeOnly || !selection ); i++ ) {
- selection = list[ i ]( options, originalOptions, jqXHR );
- // If we got redirected to another dataType
- // we try there if executing only and not done already
- if ( typeof selection === "string" ) {
- if ( !executeOnly || inspected[ selection ] ) {
- selection = undefined;
- } else {
- options.dataTypes.unshift( selection );
- selection = inspectPrefiltersOrTransports(
- structure, options, originalOptions, jqXHR, selection, inspected );
- }
- }
- }
- // If we're only executing or nothing was selected
- // we try the catchall dataType if not done already
- if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) {
- selection = inspectPrefiltersOrTransports(
- structure, options, originalOptions, jqXHR, "*", inspected );
- }
- // unnecessary when only executing (prefilters)
- // but it'll be ignored by the caller in that case
- return selection;
-}
-
-// A special extend for ajax options
-// that takes "flat" options (not to be deep extended)
-// Fixes #9887
-function ajaxExtend( target, src ) {
- var key, deep,
- flatOptions = jQuery.ajaxSettings.flatOptions || {};
- for ( key in src ) {
- if ( src[ key ] !== undefined ) {
- ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
- }
- }
- if ( deep ) {
- jQuery.extend( true, target, deep );
- }
-}
-
-jQuery.fn.extend({
- load: function( url, params, callback ) {
- if ( typeof url !== "string" && _load ) {
- return _load.apply( this, arguments );
-
- // Don't do a request if no elements are being requested
- } else if ( !this.length ) {
- return this;
- }
-
- var off = url.indexOf( " " );
- if ( off >= 0 ) {
- var selector = url.slice( off, url.length );
- url = url.slice( 0, off );
- }
-
- // Default to a GET request
- var type = "GET";
-
- // If the second parameter was provided
- if ( params ) {
- // If it's a function
- if ( jQuery.isFunction( params ) ) {
- // We assume that it's the callback
- callback = params;
- params = undefined;
-
- // Otherwise, build a param string
- } else if ( typeof params === "object" ) {
- params = jQuery.param( params, jQuery.ajaxSettings.traditional );
- type = "POST";
- }
- }
-
- var self = this;
-
- // Request the remote document
- jQuery.ajax({
- url: url,
- type: type,
- dataType: "html",
- data: params,
- // Complete callback (responseText is used internally)
- complete: function( jqXHR, status, responseText ) {
- // Store the response as specified by the jqXHR object
- responseText = jqXHR.responseText;
- // If successful, inject the HTML into all the matched elements
- if ( jqXHR.isResolved() ) {
- // #4825: Get the actual response in case
- // a dataFilter is present in ajaxSettings
- jqXHR.done(function( r ) {
- responseText = r;
- });
- // See if a selector was specified
- self.html( selector ?
- // Create a dummy div to hold the results
- jQuery("<div>")
- // inject the contents of the document in, removing the scripts
- // to avoid any 'Permission Denied' errors in IE
- .append(responseText.replace(rscript, ""))
-
- // Locate the specified elements
- .find(selector) :
-
- // If not, just inject the full result
- responseText );
- }
-
- if ( callback ) {
- self.each( callback, [ responseText, status, jqXHR ] );
- }
- }
- });
-
- return this;
- },
-
- serialize: function() {
- return jQuery.param( this.serializeArray() );
- },
-
- serializeArray: function() {
- return this.map(function(){
- return this.elements ? jQuery.makeArray( this.elements ) : this;
- })
- .filter(function(){
- return this.name && !this.disabled &&
- ( this.checked || rselectTextarea.test( this.nodeName ) ||
- rinput.test( this.type ) );
- })
- .map(function( i, elem ){
- var val = jQuery( this ).val();
-
- return val == null ?
- null :
- jQuery.isArray( val ) ?
- jQuery.map( val, function( val, i ){
- return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
- }) :
- { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
- }).get();
- }
-});
-
-// Attach a bunch of functions for handling common AJAX events
-jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
- jQuery.fn[ o ] = function( f ){
- return this.on( o, f );
- };
-});
-
-jQuery.each( [ "get", "post" ], function( i, method ) {
- jQuery[ method ] = function( url, data, callback, type ) {
- // shift arguments if data argument was omitted
- if ( jQuery.isFunction( data ) ) {
- type = type || callback;
- callback = data;
- data = undefined;
- }
-
- return jQuery.ajax({
- type: method,
- url: url,
- data: data,
- success: callback,
- dataType: type
- });
- };
-});
-
-jQuery.extend({
-
- getScript: function( url, callback ) {
- return jQuery.get( url, undefined, callback, "script" );
- },
-
- getJSON: function( url, data, callback ) {
- return jQuery.get( url, data, callback, "json" );
- },
-
- // Creates a full fledged settings object into target
- // with both ajaxSettings and settings fields.
- // If target is omitted, writes into ajaxSettings.
- ajaxSetup: function( target, settings ) {
- if ( settings ) {
- // Building a settings object
- ajaxExtend( target, jQuery.ajaxSettings );
- } else {
- // Extending ajaxSettings
- settings = target;
- target = jQuery.ajaxSettings;
- }
- ajaxExtend( target, settings );
- return target;
- },
-
- ajaxSettings: {
- url: ajaxLocation,
- isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
- global: true,
- type: "GET",
- contentType: "application/x-www-form-urlencoded; charset=UTF-8",
- processData: true,
- async: true,
- /*
- timeout: 0,
- data: null,
- dataType: null,
- username: null,
- password: null,
- cache: null,
- traditional: false,
- headers: {},
- */
-
- accepts: {
- xml: "application/xml, text/xml",
- html: "text/html",
- text: "text/plain",
- json: "application/json, text/javascript",
- "*": allTypes
- },
-
- contents: {
- xml: /xml/,
- html: /html/,
- json: /json/
- },
-
- responseFields: {
- xml: "responseXML",
- text: "responseText"
- },
-
- // List of data converters
- // 1) key format is "source_type destination_type" (a single space in-between)
- // 2) the catchall symbol "*" can be used for source_type
- converters: {
-
- // Convert anything to text
- "* text": window.String,
-
- // Text to html (true = no transformation)
- "text html": true,
-
- // Evaluate text as a json expression
- "text json": jQuery.parseJSON,
-
- // Parse text as xml
- "text xml": jQuery.parseXML
- },
-
- // For options that shouldn't be deep extended:
- // you can add your own custom options here if
- // and when you create one that shouldn't be
- // deep extended (see ajaxExtend)
- flatOptions: {
- context: true,
- url: true
- }
- },
-
- ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
- ajaxTransport: addToPrefiltersOrTransports( transports ),
-
- // Main method
- ajax: function( url, options ) {
-
- // If url is an object, simulate pre-1.5 signature
- if ( typeof url === "object" ) {
- options = url;
- url = undefined;
- }
-
- // Force options to be an object
- options = options || {};
-
- var // Create the final options object
- s = jQuery.ajaxSetup( {}, options ),
- // Callbacks context
- callbackContext = s.context || s,
- // Context for global events
- // It's the callbackContext if one was provided in the options
- // and if it's a DOM node or a jQuery collection
- globalEventContext = callbackContext !== s &&
- ( callbackContext.nodeType || callbackContext instanceof jQuery ) ?
- jQuery( callbackContext ) : jQuery.event,
- // Deferreds
- deferred = jQuery.Deferred(),
- completeDeferred = jQuery.Callbacks( "once memory" ),
- // Status-dependent callbacks
- statusCode = s.statusCode || {},
- // ifModified key
- ifModifiedKey,
- // Headers (they are sent all at once)
- requestHeaders = {},
- requestHeadersNames = {},
- // Response headers
- responseHeadersString,
- responseHeaders,
- // transport
- transport,
- // timeout handle
- timeoutTimer,
- // Cross-domain detection vars
- parts,
- // The jqXHR state
- state = 0,
- // To know if global events are to be dispatched
- fireGlobals,
- // Loop variable
- i,
- // Fake xhr
- jqXHR = {
-
- readyState: 0,
-
- // Caches the header
- setRequestHeader: function( name, value ) {
- if ( !state ) {
- var lname = name.toLowerCase();
- name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
- requestHeaders[ name ] = value;
- }
- return this;
- },
-
- // Raw string
- getAllResponseHeaders: function() {
- return state === 2 ? responseHeadersString : null;
- },
-
- // Builds headers hashtable if needed
- getResponseHeader: function( key ) {
- var match;
- if ( state === 2 ) {
- if ( !responseHeaders ) {
- responseHeaders = {};
- while( ( match = rheaders.exec( responseHeadersString ) ) ) {
- responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
- }
- }
- match = responseHeaders[ key.toLowerCase() ];
- }
- return match === undefined ? null : match;
- },
-
- // Overrides response content-type header
- overrideMimeType: function( type ) {
- if ( !state ) {
- s.mimeType = type;
- }
- return this;
- },
-
- // Cancel the request
- abort: function( statusText ) {
- statusText = statusText || "abort";
- if ( transport ) {
- transport.abort( statusText );
- }
- done( 0, statusText );
- return this;
- }
- };
-
- // Callback for when everything is done
- // It is defined here because jslint complains if it is declared
- // at the end of the function (which would be more logical and readable)
- function done( status, nativeStatusText, responses, headers ) {
-
- // Called once
- if ( state === 2 ) {
- return;
- }
-
- // State is "done" now
- state = 2;
-
- // Clear timeout if it exists
- if ( timeoutTimer ) {
- clearTimeout( timeoutTimer );
- }
-
- // Dereference transport for early garbage collection
- // (no matter how long the jqXHR object will be used)
- transport = undefined;
-
- // Cache response headers
- responseHeadersString = headers || "";
-
- // Set readyState
- jqXHR.readyState = status > 0 ? 4 : 0;
-
- var isSuccess,
- success,
- error,
- statusText = nativeStatusText,
- response = responses ? ajaxHandleResponses( s, jqXHR, responses ) : undefined,
- lastModified,
- etag;
-
- // If successful, handle type chaining
- if ( status >= 200 && status < 300 || status === 304 ) {
-
- // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
- if ( s.ifModified ) {
-
- if ( ( lastModified = jqXHR.getResponseHeader( "Last-Modified" ) ) ) {
- jQuery.lastModified[ ifModifiedKey ] = lastModified;
- }
- if ( ( etag = jqXHR.getResponseHeader( "Etag" ) ) ) {
- jQuery.etag[ ifModifiedKey ] = etag;
- }
- }
-
- // If not modified
- if ( status === 304 ) {
-
- statusText = "notmodified";
- isSuccess = true;
-
- // If we have data
- } else {
-
- try {
- success = ajaxConvert( s, response );
- statusText = "success";
- isSuccess = true;
- } catch(e) {
- // We have a parsererror
- statusText = "parsererror";
- error = e;
- }
- }
- } else {
- // We extract error from statusText
- // then normalize statusText and status for non-aborts
- error = statusText;
- if ( !statusText || status ) {
- statusText = "error";
- if ( status < 0 ) {
- status = 0;
- }
- }
- }
-
- // Set data for the fake xhr object
- jqXHR.status = status;
- jqXHR.statusText = "" + ( nativeStatusText || statusText );
-
- // Success/Error
- if ( isSuccess ) {
- deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
- } else {
- deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
- }
-
- // Status-dependent callbacks
- jqXHR.statusCode( statusCode );
- statusCode = undefined;
-
- if ( fireGlobals ) {
- globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ),
- [ jqXHR, s, isSuccess ? success : error ] );
- }
-
- // Complete
- completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
-
- if ( fireGlobals ) {
- globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
- // Handle the global AJAX counter
- if ( !( --jQuery.active ) ) {
- jQuery.event.trigger( "ajaxStop" );
- }
- }
- }
-
- // Attach deferreds
- deferred.promise( jqXHR );
- jqXHR.success = jqXHR.done;
- jqXHR.error = jqXHR.fail;
- jqXHR.complete = completeDeferred.add;
-
- // Status-dependent callbacks
- jqXHR.statusCode = function( map ) {
- if ( map ) {
- var tmp;
- if ( state < 2 ) {
- for ( tmp in map ) {
- statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ];
- }
- } else {
- tmp = map[ jqXHR.status ];
- jqXHR.then( tmp, tmp );
- }
- }
- return this;
- };
-
- // Remove hash character (#7531: and string promotion)
- // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
- // We also use the url parameter if available
- s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
-
- // Extract dataTypes list
- s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( rspacesAjax );
-
- // Determine if a cross-domain request is in order
- if ( s.crossDomain == null ) {
- parts = rurl.exec( s.url.toLowerCase() );
- s.crossDomain = !!( parts &&
- ( parts[ 1 ] != ajaxLocParts[ 1 ] || parts[ 2 ] != ajaxLocParts[ 2 ] ||
- ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) !=
- ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) )
- );
- }
-
- // Convert data if not already a string
- if ( s.data && s.processData && typeof s.data !== "string" ) {
- s.data = jQuery.param( s.data, s.traditional );
- }
-
- // Apply prefilters
- inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
-
- // If request was aborted inside a prefilter, stop there
- if ( state === 2 ) {
- return false;
- }
-
- // We can fire global events as of now if asked to
- fireGlobals = s.global;
-
- // Uppercase the type
- s.type = s.type.toUpperCase();
-
- // Determine if request has content
- s.hasContent = !rnoContent.test( s.type );
-
- // Watch for a new set of requests
- if ( fireGlobals && jQuery.active++ === 0 ) {
- jQuery.event.trigger( "ajaxStart" );
- }
-
- // More options handling for requests with no content
- if ( !s.hasContent ) {
-
- // If data is available, append data to url
- if ( s.data ) {
- s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data;
- // #9682: remove data so that it's not used in an eventual retry
- delete s.data;
- }
-
- // Get ifModifiedKey before adding the anti-cache parameter
- ifModifiedKey = s.url;
-
- // Add anti-cache in url if needed
- if ( s.cache === false ) {
-
- var ts = jQuery.now(),
- // try replacing _= if it is there
- ret = s.url.replace( rts, "$1_=" + ts );
-
- // if nothing was replaced, add timestamp to the end
- s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
- }
- }
-
- // Set the correct header, if data is being sent
- if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
- jqXHR.setRequestHeader( "Content-Type", s.contentType );
- }
-
- // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
- if ( s.ifModified ) {
- ifModifiedKey = ifModifiedKey || s.url;
- if ( jQuery.lastModified[ ifModifiedKey ] ) {
- jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] );
- }
- if ( jQuery.etag[ ifModifiedKey ] ) {
- jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] );
- }
- }
-
- // Set the Accepts header for the server, depending on the dataType
- jqXHR.setRequestHeader(
- "Accept",
- s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
- s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
- s.accepts[ "*" ]
- );
-
- // Check for headers option
- for ( i in s.headers ) {
- jqXHR.setRequestHeader( i, s.headers[ i ] );
- }
-
- // Allow custom headers/mimetypes and early abort
- if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
- // Abort if not done already
- jqXHR.abort();
- return false;
-
- }
-
- // Install callbacks on deferreds
- for ( i in { success: 1, error: 1, complete: 1 } ) {
- jqXHR[ i ]( s[ i ] );
- }
-
- // Get transport
- transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
-
- // If no transport, we auto-abort
- if ( !transport ) {
- done( -1, "No Transport" );
- } else {
- jqXHR.readyState = 1;
- // Send global event
- if ( fireGlobals ) {
- globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
- }
- // Timeout
- if ( s.async && s.timeout > 0 ) {
- timeoutTimer = setTimeout( function(){
- jqXHR.abort( "timeout" );
- }, s.timeout );
- }
-
- try {
- state = 1;
- transport.send( requestHeaders, done );
- } catch (e) {
- // Propagate exception as error if not done
- if ( state < 2 ) {
- done( -1, e );
- // Simply rethrow otherwise
- } else {
- throw e;
- }
- }
- }
-
- return jqXHR;
- },
-
- // Serialize an array of form elements or a set of
- // key/values into a query string
- param: function( a, traditional ) {
- var s = [],
- add = function( key, value ) {
- // If value is a function, invoke it and return its value
- value = jQuery.isFunction( value ) ? value() : value;
- s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
- };
-
- // Set traditional to true for jQuery <= 1.3.2 behavior.
- if ( traditional === undefined ) {
- traditional = jQuery.ajaxSettings.traditional;
- }
-
- // If an array was passed in, assume that it is an array of form elements.
- if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
- // Serialize the form elements
- jQuery.each( a, function() {
- add( this.name, this.value );
- });
-
- } else {
- // If traditional, encode the "old" way (the way 1.3.2 or older
- // did it), otherwise encode params recursively.
- for ( var prefix in a ) {
- buildParams( prefix, a[ prefix ], traditional, add );
- }
- }
-
- // Return the resulting serialization
- return s.join( "&" ).replace( r20, "+" );
- }
-});
-
-function buildParams( prefix, obj, traditional, add ) {
- if ( jQuery.isArray( obj ) ) {
- // Serialize array item.
- jQuery.each( obj, function( i, v ) {
- if ( traditional || rbracket.test( prefix ) ) {
- // Treat each array item as a scalar.
- add( prefix, v );
-
- } else {
- // If array item is non-scalar (array or object), encode its
- // numeric index to resolve deserialization ambiguity issues.
- // Note that rack (as of 1.0.0) can't currently deserialize
- // nested arrays properly, and attempting to do so may cause
- // a server error. Possible fixes are to modify rack's
- // deserialization algorithm or to provide an option or flag
- // to force array serialization to be shallow.
- buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
- }
- });
-
- } else if ( !traditional && jQuery.type( obj ) === "object" ) {
- // Serialize object item.
- for ( var name in obj ) {
- buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
- }
-
- } else {
- // Serialize scalar item.
- add( prefix, obj );
- }
-}
-
-// This is still on the jQuery object... for now
-// Want to move this to jQuery.ajax some day
-jQuery.extend({
-
- // Counter for holding the number of active queries
- active: 0,
-
- // Last-Modified header cache for next request
- lastModified: {},
- etag: {}
-
-});
-
-/* Handles responses to an ajax request:
- * - sets all responseXXX fields accordingly
- * - finds the right dataType (mediates between content-type and expected dataType)
- * - returns the corresponding response
- */
-function ajaxHandleResponses( s, jqXHR, responses ) {
-
- var contents = s.contents,
- dataTypes = s.dataTypes,
- responseFields = s.responseFields,
- ct,
- type,
- finalDataType,
- firstDataType;
-
- // Fill responseXXX fields
- for ( type in responseFields ) {
- if ( type in responses ) {
- jqXHR[ responseFields[type] ] = responses[ type ];
- }
- }
-
- // Remove auto dataType and get content-type in the process
- while( dataTypes[ 0 ] === "*" ) {
- dataTypes.shift();
- if ( ct === undefined ) {
- ct = s.mimeType || jqXHR.getResponseHeader( "content-type" );
- }
- }
-
- // Check if we're dealing with a known content-type
- if ( ct ) {
- for ( type in contents ) {
- if ( contents[ type ] && contents[ type ].test( ct ) ) {
- dataTypes.unshift( type );
- break;
- }
- }
- }
-
- // Check to see if we have a response for the expected dataType
- if ( dataTypes[ 0 ] in responses ) {
- finalDataType = dataTypes[ 0 ];
- } else {
- // Try convertible dataTypes
- for ( type in responses ) {
- if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
- finalDataType = type;
- break;
- }
- if ( !firstDataType ) {
- firstDataType = type;
- }
- }
- // Or just use first one
- finalDataType = finalDataType || firstDataType;
- }
-
- // If we found a dataType
- // We add the dataType to the list if needed
- // and return the corresponding response
- if ( finalDataType ) {
- if ( finalDataType !== dataTypes[ 0 ] ) {
- dataTypes.unshift( finalDataType );
- }
- return responses[ finalDataType ];
- }
-}
-
-// Chain conversions given the request and the original response
-function ajaxConvert( s, response ) {
-
- // Apply the dataFilter if provided
- if ( s.dataFilter ) {
- response = s.dataFilter( response, s.dataType );
- }
-
- var dataTypes = s.dataTypes,
- converters = {},
- i,
- key,
- length = dataTypes.length,
- tmp,
- // Current and previous dataTypes
- current = dataTypes[ 0 ],
- prev,
- // Conversion expression
- conversion,
- // Conversion function
- conv,
- // Conversion functions (transitive conversion)
- conv1,
- conv2;
-
- // For each dataType in the chain
- for ( i = 1; i < length; i++ ) {
-
- // Create converters map
- // with lowercased keys
- if ( i === 1 ) {
- for ( key in s.converters ) {
- if ( typeof key === "string" ) {
- converters[ key.toLowerCase() ] = s.converters[ key ];
- }
- }
- }
-
- // Get the dataTypes
- prev = current;
- current = dataTypes[ i ];
-
- // If current is auto dataType, update it to prev
- if ( current === "*" ) {
- current = prev;
- // If no auto and dataTypes are actually different
- } else if ( prev !== "*" && prev !== current ) {
-
- // Get the converter
- conversion = prev + " " + current;
- conv = converters[ conversion ] || converters[ "* " + current ];
-
- // If there is no direct converter, search transitively
- if ( !conv ) {
- conv2 = undefined;
- for ( conv1 in converters ) {
- tmp = conv1.split( " " );
- if ( tmp[ 0 ] === prev || tmp[ 0 ] === "*" ) {
- conv2 = converters[ tmp[1] + " " + current ];
- if ( conv2 ) {
- conv1 = converters[ conv1 ];
- if ( conv1 === true ) {
- conv = conv2;
- } else if ( conv2 === true ) {
- conv = conv1;
- }
- break;
- }
- }
- }
- }
- // If we found no converter, dispatch an error
- if ( !( conv || conv2 ) ) {
- jQuery.error( "No conversion from " + conversion.replace(" "," to ") );
- }
- // If found converter is not an equivalence
- if ( conv !== true ) {
- // Convert with 1 or 2 converters accordingly
- response = conv ? conv( response ) : conv2( conv1(response) );
- }
- }
- }
- return response;
-}
-
-
-
-
-var jsc = jQuery.now(),
- jsre = /(\=)\?(&|$)|\?\?/i;
-
-// Default jsonp settings
-jQuery.ajaxSetup({
- jsonp: "callback",
- jsonpCallback: function() {
- return jQuery.expando + "_" + ( jsc++ );
- }
-});
-
-// Detect, normalize options and install callbacks for jsonp requests
-jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
-
- var inspectData = ( typeof s.data === "string" ) && /^application\/x\-www\-form\-urlencoded/.test( s.contentType );
-
- if ( s.dataTypes[ 0 ] === "jsonp" ||
- s.jsonp !== false && ( jsre.test( s.url ) ||
- inspectData && jsre.test( s.data ) ) ) {
-
- var responseContainer,
- jsonpCallback = s.jsonpCallback =
- jQuery.isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback,
- previous = window[ jsonpCallback ],
- url = s.url,
- data = s.data,
- replace = "$1" + jsonpCallback + "$2";
-
- if ( s.jsonp !== false ) {
- url = url.replace( jsre, replace );
- if ( s.url === url ) {
- if ( inspectData ) {
- data = data.replace( jsre, replace );
- }
- if ( s.data === data ) {
- // Add callback manually
- url += (/\?/.test( url ) ? "&" : "?") + s.jsonp + "=" + jsonpCallback;
- }
- }
- }
-
- s.url = url;
- s.data = data;
-
- // Install callback
- window[ jsonpCallback ] = function( response ) {
- responseContainer = [ response ];
- };
-
- // Clean-up function
- jqXHR.always(function() {
- // Set callback back to previous value
- window[ jsonpCallback ] = previous;
- // Call if it was a function and we have a response
- if ( responseContainer && jQuery.isFunction( previous ) ) {
- window[ jsonpCallback ]( responseContainer[ 0 ] );
- }
- });
-
- // Use data converter to retrieve json after script execution
- s.converters["script json"] = function() {
- if ( !responseContainer ) {
- jQuery.error( jsonpCallback + " was not called" );
- }
- return responseContainer[ 0 ];
- };
-
- // force json dataType
- s.dataTypes[ 0 ] = "json";
-
- // Delegate to script
- return "script";
- }
-});
-
-
-
-
-// Install script dataType
-jQuery.ajaxSetup({
- accepts: {
- script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
- },
- contents: {
- script: /javascript|ecmascript/
- },
- converters: {
- "text script": function( text ) {
- jQuery.globalEval( text );
- return text;
- }
- }
-});
-
-// Handle cache's special case and global
-jQuery.ajaxPrefilter( "script", function( s ) {
- if ( s.cache === undefined ) {
- s.cache = false;
- }
- if ( s.crossDomain ) {
- s.type = "GET";
- s.global = false;
- }
-});
-
-// Bind script tag hack transport
-jQuery.ajaxTransport( "script", function(s) {
-
- // This transport only deals with cross domain requests
- if ( s.crossDomain ) {
-
- var script,
- head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement;
-
- return {
-
- send: function( _, callback ) {
-
- script = document.createElement( "script" );
-
- script.async = "async";
-
- if ( s.scriptCharset ) {
- script.charset = s.scriptCharset;
- }
-
- script.src = s.url;
-
- // Attach handlers for all browsers
- script.onload = script.onreadystatechange = function( _, isAbort ) {
-
- if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
-
- // Handle memory leak in IE
- script.onload = script.onreadystatechange = null;
-
- // Remove the script
- if ( head && script.parentNode ) {
- head.removeChild( script );
- }
-
- // Dereference the script
- script = undefined;
-
- // Callback if not abort
- if ( !isAbort ) {
- callback( 200, "success" );
- }
- }
- };
- // Use insertBefore instead of appendChild to circumvent an IE6 bug.
- // This arises when a base node is used (#2709 and #4378).
- head.insertBefore( script, head.firstChild );
- },
-
- abort: function() {
- if ( script ) {
- script.onload( 0, 1 );
- }
- }
- };
- }
-});
-
-
-
-
-var // #5280: Internet Explorer will keep connections alive if we don't abort on unload
- xhrOnUnloadAbort = window.ActiveXObject ? function() {
- // Abort all pending requests
- for ( var key in xhrCallbacks ) {
- xhrCallbacks[ key ]( 0, 1 );
- }
- } : false,
- xhrId = 0,
- xhrCallbacks;
-
-// Functions to create xhrs
-function createStandardXHR() {
- try {
- return new window.XMLHttpRequest();
- } catch( e ) {}
-}
-
-function createActiveXHR() {
- try {
- return new window.ActiveXObject( "Microsoft.XMLHTTP" );
- } catch( e ) {}
-}
-
-// Create the request object
-// (This is still attached to ajaxSettings for backward compatibility)
-jQuery.ajaxSettings.xhr = window.ActiveXObject ?
- /* Microsoft failed to properly
- * implement the XMLHttpRequest in IE7 (can't request local files),
- * so we use the ActiveXObject when it is available
- * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
- * we need a fallback.
- */
- function() {
- return !this.isLocal && createStandardXHR() || createActiveXHR();
- } :
- // For all other browsers, use the standard XMLHttpRequest object
- createStandardXHR;
-
-// Determine support properties
-(function( xhr ) {
- jQuery.extend( jQuery.support, {
- ajax: !!xhr,
- cors: !!xhr && ( "withCredentials" in xhr )
- });
-})( jQuery.ajaxSettings.xhr() );
-
-// Create transport if the browser can provide an xhr
-if ( jQuery.support.ajax ) {
-
- jQuery.ajaxTransport(function( s ) {
- // Cross domain only allowed if supported through XMLHttpRequest
- if ( !s.crossDomain || jQuery.support.cors ) {
-
- var callback;
-
- return {
- send: function( headers, complete ) {
-
- // Get a new xhr
- var xhr = s.xhr(),
- handle,
- i;
-
- // Open the socket
- // Passing null username, generates a login popup on Opera (#2865)
- if ( s.username ) {
- xhr.open( s.type, s.url, s.async, s.username, s.password );
- } else {
- xhr.open( s.type, s.url, s.async );
- }
-
- // Apply custom fields if provided
- if ( s.xhrFields ) {
- for ( i in s.xhrFields ) {
- xhr[ i ] = s.xhrFields[ i ];
- }
- }
-
- // Override mime type if needed
- if ( s.mimeType && xhr.overrideMimeType ) {
- xhr.overrideMimeType( s.mimeType );
- }
-
- // X-Requested-With header
- // For cross-domain requests, seeing as conditions for a preflight are
- // akin to a jigsaw puzzle, we simply never set it to be sure.
- // (it can always be set on a per-request basis or even using ajaxSetup)
- // For same-domain requests, won't change header if already provided.
- if ( !s.crossDomain && !headers["X-Requested-With"] ) {
- headers[ "X-Requested-With" ] = "XMLHttpRequest";
- }
-
- // Need an extra try/catch for cross domain requests in Firefox 3
- try {
- for ( i in headers ) {
- xhr.setRequestHeader( i, headers[ i ] );
- }
- } catch( _ ) {}
-
- // Do send the request
- // This may raise an exception which is actually
- // handled in jQuery.ajax (so no try/catch here)
- xhr.send( ( s.hasContent && s.data ) || null );
-
- // Listener
- callback = function( _, isAbort ) {
-
- var status,
- statusText,
- responseHeaders,
- responses,
- xml;
-
- // Firefox throws exceptions when accessing properties
- // of an xhr when a network error occured
- // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)
- try {
-
- // Was never called and is aborted or complete
- if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
-
- // Only called once
- callback = undefined;
-
- // Do not keep as active anymore
- if ( handle ) {
- xhr.onreadystatechange = jQuery.noop;
- if ( xhrOnUnloadAbort ) {
- delete xhrCallbacks[ handle ];
- }
- }
-
- // If it's an abort
- if ( isAbort ) {
- // Abort it manually if needed
- if ( xhr.readyState !== 4 ) {
- xhr.abort();
- }
- } else {
- status = xhr.status;
- responseHeaders = xhr.getAllResponseHeaders();
- responses = {};
- xml = xhr.responseXML;
-
- // Construct response list
- if ( xml && xml.documentElement /* #4958 */ ) {
- responses.xml = xml;
- }
-
- // When requesting binary data, IE6-9 will throw an exception
- // on any attempt to access responseText (#11426)
- try {
- responses.text = xhr.responseText;
- } catch( _ ) {
- }
-
- // Firefox throws an exception when accessing
- // statusText for faulty cross-domain requests
- try {
- statusText = xhr.statusText;
- } catch( e ) {
- // We normalize with Webkit giving an empty statusText
- statusText = "";
- }
-
- // Filter status for non standard behaviors
-
- // If the request is local and we have data: assume a success
- // (success with no data won't get notified, that's the best we
- // can do given current implementations)
- if ( !status && s.isLocal && !s.crossDomain ) {
- status = responses.text ? 200 : 404;
- // IE - #1450: sometimes returns 1223 when it should be 204
- } else if ( status === 1223 ) {
- status = 204;
- }
- }
- }
- } catch( firefoxAccessException ) {
- if ( !isAbort ) {
- complete( -1, firefoxAccessException );
- }
- }
-
- // Call complete if needed
- if ( responses ) {
- complete( status, statusText, responses, responseHeaders );
- }
- };
-
- // if we're in sync mode or it's in cache
- // and has been retrieved directly (IE6 & IE7)
- // we need to manually fire the callback
- if ( !s.async || xhr.readyState === 4 ) {
- callback();
- } else {
- handle = ++xhrId;
- if ( xhrOnUnloadAbort ) {
- // Create the active xhrs callbacks list if needed
- // and attach the unload handler
- if ( !xhrCallbacks ) {
- xhrCallbacks = {};
- jQuery( window ).unload( xhrOnUnloadAbort );
- }
- // Add to list of active xhrs callbacks
- xhrCallbacks[ handle ] = callback;
- }
- xhr.onreadystatechange = callback;
- }
- },
-
- abort: function() {
- if ( callback ) {
- callback(0,1);
- }
- }
- };
- }
- });
-}
-
-
-
-
-var elemdisplay = {},
- iframe, iframeDoc,
- rfxtypes = /^(?:toggle|show|hide)$/,
- rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,
- timerId,
- fxAttrs = [
- // height animations
- [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
- // width animations
- [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
- // opacity animations
- [ "opacity" ]
- ],
- fxNow;
-
-jQuery.fn.extend({
- show: function( speed, easing, callback ) {
- var elem, display;
-
- if ( speed || speed === 0 ) {
- return this.animate( genFx("show", 3), speed, easing, callback );
-
- } else {
- for ( var i = 0, j = this.length; i < j; i++ ) {
- elem = this[ i ];
-
- if ( elem.style ) {
- display = elem.style.display;
-
- // Reset the inline display of this element to learn if it is
- // being hidden by cascaded rules or not
- if ( !jQuery._data(elem, "olddisplay") && display === "none" ) {
- display = elem.style.display = "";
- }
-
- // Set elements which have been overridden with display: none
- // in a stylesheet to whatever the default browser style is
- // for such an element
- if ( (display === "" && jQuery.css(elem, "display") === "none") ||
- !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
- jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
- }
- }
- }
-
- // Set the display of most of the elements in a second loop
- // to avoid the constant reflow
- for ( i = 0; i < j; i++ ) {
- elem = this[ i ];
-
- if ( elem.style ) {
- display = elem.style.display;
-
- if ( display === "" || display === "none" ) {
- elem.style.display = jQuery._data( elem, "olddisplay" ) || "";
- }
- }
- }
-
- return this;
- }
- },
-
- hide: function( speed, easing, callback ) {
- if ( speed || speed === 0 ) {
- return this.animate( genFx("hide", 3), speed, easing, callback);
-
- } else {
- var elem, display,
- i = 0,
- j = this.length;
-
- for ( ; i < j; i++ ) {
- elem = this[i];
- if ( elem.style ) {
- display = jQuery.css( elem, "display" );
-
- if ( display !== "none" && !jQuery._data( elem, "olddisplay" ) ) {
- jQuery._data( elem, "olddisplay", display );
- }
- }
- }
-
- // Set the display of the elements in a second loop
- // to avoid the constant reflow
- for ( i = 0; i < j; i++ ) {
- if ( this[i].style ) {
- this[i].style.display = "none";
- }
- }
-
- return this;
- }
- },
-
- // Save the old toggle function
- _toggle: jQuery.fn.toggle,
-
- toggle: function( fn, fn2, callback ) {
- var bool = typeof fn === "boolean";
-
- if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
- this._toggle.apply( this, arguments );
-
- } else if ( fn == null || bool ) {
- this.each(function() {
- var state = bool ? fn : jQuery(this).is(":hidden");
- jQuery(this)[ state ? "show" : "hide" ]();
- });
-
- } else {
- this.animate(genFx("toggle", 3), fn, fn2, callback);
- }
-
- return this;
- },
-
- fadeTo: function( speed, to, easing, callback ) {
- return this.filter(":hidden").css("opacity", 0).show().end()
- .animate({opacity: to}, speed, easing, callback);
- },
-
- animate: function( prop, speed, easing, callback ) {
- var optall = jQuery.speed( speed, easing, callback );
-
- if ( jQuery.isEmptyObject( prop ) ) {
- return this.each( optall.complete, [ false ] );
- }
-
- // Do not change referenced properties as per-property easing will be lost
- prop = jQuery.extend( {}, prop );
-
- function doAnimation() {
- // XXX 'this' does not always have a nodeName when running the
- // test suite
-
- if ( optall.queue === false ) {
- jQuery._mark( this );
- }
-
- var opt = jQuery.extend( {}, optall ),
- isElement = this.nodeType === 1,
- hidden = isElement && jQuery(this).is(":hidden"),
- name, val, p, e, hooks, replace,
- parts, start, end, unit,
- method;
-
- // will store per property easing and be used to determine when an animation is complete
- opt.animatedProperties = {};
-
- // first pass over propertys to expand / normalize
- for ( p in prop ) {
- name = jQuery.camelCase( p );
- if ( p !== name ) {
- prop[ name ] = prop[ p ];
- delete prop[ p ];
- }
-
- if ( ( hooks = jQuery.cssHooks[ name ] ) && "expand" in hooks ) {
- replace = hooks.expand( prop[ name ] );
- delete prop[ name ];
-
- // not quite $.extend, this wont overwrite keys already present.
- // also - reusing 'p' from above because we have the correct "name"
- for ( p in replace ) {
- if ( ! ( p in prop ) ) {
- prop[ p ] = replace[ p ];
- }
- }
- }
- }
-
- for ( name in prop ) {
- val = prop[ name ];
- // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default)
- if ( jQuery.isArray( val ) ) {
- opt.animatedProperties[ name ] = val[ 1 ];
- val = prop[ name ] = val[ 0 ];
- } else {
- opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing';
- }
-
- if ( val === "hide" && hidden || val === "show" && !hidden ) {
- return opt.complete.call( this );
- }
-
- if ( isElement && ( name === "height" || name === "width" ) ) {
- // Make sure that nothing sneaks out
- // Record all 3 overflow attributes because IE does not
- // change the overflow attribute when overflowX and
- // overflowY are set to the same value
- opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
-
- // Set display property to inline-block for height/width
- // animations on inline elements that are having width/height animated
- if ( jQuery.css( this, "display" ) === "inline" &&
- jQuery.css( this, "float" ) === "none" ) {
-
- // inline-level elements accept inline-block;
- // block-level elements need to be inline with layout
- if ( !jQuery.support.inlineBlockNeedsLayout || defaultDisplay( this.nodeName ) === "inline" ) {
- this.style.display = "inline-block";
-
- } else {
- this.style.zoom = 1;
- }
- }
- }
- }
-
- if ( opt.overflow != null ) {
- this.style.overflow = "hidden";
- }
-
- for ( p in prop ) {
- e = new jQuery.fx( this, opt, p );
- val = prop[ p ];
-
- if ( rfxtypes.test( val ) ) {
-
- // Tracks whether to show or hide based on private
- // data attached to the element
- method = jQuery._data( this, "toggle" + p ) || ( val === "toggle" ? hidden ? "show" : "hide" : 0 );
- if ( method ) {
- jQuery._data( this, "toggle" + p, method === "show" ? "hide" : "show" );
- e[ method ]();
- } else {
- e[ val ]();
- }
-
- } else {
- parts = rfxnum.exec( val );
- start = e.cur();
-
- if ( parts ) {
- end = parseFloat( parts[2] );
- unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" );
-
- // We need to compute starting value
- if ( unit !== "px" ) {
- jQuery.style( this, p, (end || 1) + unit);
- start = ( (end || 1) / e.cur() ) * start;
- jQuery.style( this, p, start + unit);
- }
-
- // If a +=/-= token was provided, we're doing a relative animation
- if ( parts[1] ) {
- end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start;
- }
-
- e.custom( start, end, unit );
-
- } else {
- e.custom( start, val, "" );
- }
- }
- }
-
- // For JS strict compliance
- return true;
- }
-
- return optall.queue === false ?
- this.each( doAnimation ) :
- this.queue( optall.queue, doAnimation );
- },
-
- stop: function( type, clearQueue, gotoEnd ) {
- if ( typeof type !== "string" ) {
- gotoEnd = clearQueue;
- clearQueue = type;
- type = undefined;
- }
- if ( clearQueue && type !== false ) {
- this.queue( type || "fx", [] );
- }
-
- return this.each(function() {
- var index,
- hadTimers = false,
- timers = jQuery.timers,
- data = jQuery._data( this );
-
- // clear marker counters if we know they won't be
- if ( !gotoEnd ) {
- jQuery._unmark( true, this );
- }
-
- function stopQueue( elem, data, index ) {
- var hooks = data[ index ];
- jQuery.removeData( elem, index, true );
- hooks.stop( gotoEnd );
- }
-
- if ( type == null ) {
- for ( index in data ) {
- if ( data[ index ] && data[ index ].stop && index.indexOf(".run") === index.length - 4 ) {
- stopQueue( this, data, index );
- }
- }
- } else if ( data[ index = type + ".run" ] && data[ index ].stop ){
- stopQueue( this, data, index );
- }
-
- for ( index = timers.length; index--; ) {
- if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
- if ( gotoEnd ) {
-
- // force the next step to be the last
- timers[ index ]( true );
- } else {
- timers[ index ].saveState();
- }
- hadTimers = true;
- timers.splice( index, 1 );
- }
- }
-
- // start the next in the queue if the last step wasn't forced
- // timers currently will call their complete callbacks, which will dequeue
- // but only if they were gotoEnd
- if ( !( gotoEnd && hadTimers ) ) {
- jQuery.dequeue( this, type );
- }
- });
- }
-
-});
-
-// Animations created synchronously will run synchronously
-function createFxNow() {
- setTimeout( clearFxNow, 0 );
- return ( fxNow = jQuery.now() );
-}
-
-function clearFxNow() {
- fxNow = undefined;
-}
-
-// Generate parameters to create a standard animation
-function genFx( type, num ) {
- var obj = {};
-
- jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice( 0, num )), function() {
- obj[ this ] = type;
- });
-
- return obj;
-}
-
-// Generate shortcuts for custom animations
-jQuery.each({
- slideDown: genFx( "show", 1 ),
- slideUp: genFx( "hide", 1 ),
- slideToggle: genFx( "toggle", 1 ),
- fadeIn: { opacity: "show" },
- fadeOut: { opacity: "hide" },
- fadeToggle: { opacity: "toggle" }
-}, function( name, props ) {
- jQuery.fn[ name ] = function( speed, easing, callback ) {
- return this.animate( props, speed, easing, callback );
- };
-});
-
-jQuery.extend({
- speed: function( speed, easing, fn ) {
- var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
- complete: fn || !fn && easing ||
- jQuery.isFunction( speed ) && speed,
- duration: speed,
- easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
- };
-
- opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
- opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
-
- // normalize opt.queue - true/undefined/null -> "fx"
- if ( opt.queue == null || opt.queue === true ) {
- opt.queue = "fx";
- }
-
- // Queueing
- opt.old = opt.complete;
-
- opt.complete = function( noUnmark ) {
- if ( jQuery.isFunction( opt.old ) ) {
- opt.old.call( this );
- }
-
- if ( opt.queue ) {
- jQuery.dequeue( this, opt.queue );
- } else if ( noUnmark !== false ) {
- jQuery._unmark( this );
- }
- };
-
- return opt;
- },
-
- easing: {
- linear: function( p ) {
- return p;
- },
- swing: function( p ) {
- return ( -Math.cos( p*Math.PI ) / 2 ) + 0.5;
- }
- },
-
- timers: [],
-
- fx: function( elem, options, prop ) {
- this.options = options;
- this.elem = elem;
- this.prop = prop;
-
- options.orig = options.orig || {};
- }
-
-});
-
-jQuery.fx.prototype = {
- // Simple function for setting a style value
- update: function() {
- if ( this.options.step ) {
- this.options.step.call( this.elem, this.now, this );
- }
-
- ( jQuery.fx.step[ this.prop ] || jQuery.fx.step._default )( this );
- },
-
- // Get the current size
- cur: function() {
- if ( this.elem[ this.prop ] != null && (!this.elem.style || this.elem.style[ this.prop ] == null) ) {
- return this.elem[ this.prop ];
- }
-
- var parsed,
- r = jQuery.css( this.elem, this.prop );
- // Empty strings, null, undefined and "auto" are converted to 0,
- // complex values such as "rotate(1rad)" are returned as is,
- // simple values such as "10px" are parsed to Float.
- return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed;
- },
-
- // Start an animation from one number to another
- custom: function( from, to, unit ) {
- var self = this,
- fx = jQuery.fx;
-
- this.startTime = fxNow || createFxNow();
- this.end = to;
- this.now = this.start = from;
- this.pos = this.state = 0;
- this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
-
- function t( gotoEnd ) {
- return self.step( gotoEnd );
- }
-
- t.queue = this.options.queue;
- t.elem = this.elem;
- t.saveState = function() {
- if ( jQuery._data( self.elem, "fxshow" + self.prop ) === undefined ) {
- if ( self.options.hide ) {
- jQuery._data( self.elem, "fxshow" + self.prop, self.start );
- } else if ( self.options.show ) {
- jQuery._data( self.elem, "fxshow" + self.prop, self.end );
- }
- }
- };
-
- if ( t() && jQuery.timers.push(t) && !timerId ) {
- timerId = setInterval( fx.tick, fx.interval );
- }
- },
-
- // Simple 'show' function
- show: function() {
- var dataShow = jQuery._data( this.elem, "fxshow" + this.prop );
-
- // Remember where we started, so that we can go back to it later
- this.options.orig[ this.prop ] = dataShow || jQuery.style( this.elem, this.prop );
- this.options.show = true;
-
- // Begin the animation
- // Make sure that we start at a small width/height to avoid any flash of content
- if ( dataShow !== undefined ) {
- // This show is picking up where a previous hide or show left off
- this.custom( this.cur(), dataShow );
- } else {
- this.custom( this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur() );
- }
-
- // Start by showing the element
- jQuery( this.elem ).show();
- },
-
- // Simple 'hide' function
- hide: function() {
- // Remember where we started, so that we can go back to it later
- this.options.orig[ this.prop ] = jQuery._data( this.elem, "fxshow" + this.prop ) || jQuery.style( this.elem, this.prop );
- this.options.hide = true;
-
- // Begin the animation
- this.custom( this.cur(), 0 );
- },
-
- // Each step of an animation
- step: function( gotoEnd ) {
- var p, n, complete,
- t = fxNow || createFxNow(),
- done = true,
- elem = this.elem,
- options = this.options;
-
- if ( gotoEnd || t >= options.duration + this.startTime ) {
- this.now = this.end;
- this.pos = this.state = 1;
- this.update();
-
- options.animatedProperties[ this.prop ] = true;
-
- for ( p in options.animatedProperties ) {
- if ( options.animatedProperties[ p ] !== true ) {
- done = false;
- }
- }
-
- if ( done ) {
- // Reset the overflow
- if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
-
- jQuery.each( [ "", "X", "Y" ], function( index, value ) {
- elem.style[ "overflow" + value ] = options.overflow[ index ];
- });
- }
-
- // Hide the element if the "hide" operation was done
- if ( options.hide ) {
- jQuery( elem ).hide();
- }
-
- // Reset the properties, if the item has been hidden or shown
- if ( options.hide || options.show ) {
- for ( p in options.animatedProperties ) {
- jQuery.style( elem, p, options.orig[ p ] );
- jQuery.removeData( elem, "fxshow" + p, true );
- // Toggle data is no longer needed
- jQuery.removeData( elem, "toggle" + p, true );
- }
- }
-
- // Execute the complete function
- // in the event that the complete function throws an exception
- // we must ensure it won't be called twice. #5684
-
- complete = options.complete;
- if ( complete ) {
-
- options.complete = false;
- complete.call( elem );
- }
- }
-
- return false;
-
- } else {
- // classical easing cannot be used with an Infinity duration
- if ( options.duration == Infinity ) {
- this.now = t;
- } else {
- n = t - this.startTime;
- this.state = n / options.duration;
-
- // Perform the easing function, defaults to swing
- this.pos = jQuery.easing[ options.animatedProperties[this.prop] ]( this.state, n, 0, 1, options.duration );
- this.now = this.start + ( (this.end - this.start) * this.pos );
- }
- // Perform the next step of the animation
- this.update();
- }
-
- return true;
- }
-};
-
-jQuery.extend( jQuery.fx, {
- tick: function() {
- var timer,
- timers = jQuery.timers,
- i = 0;
-
- for ( ; i < timers.length; i++ ) {
- timer = timers[ i ];
- // Checks the timer has not already been removed
- if ( !timer() && timers[ i ] === timer ) {
- timers.splice( i--, 1 );
- }
- }
-
- if ( !timers.length ) {
- jQuery.fx.stop();
- }
- },
-
- interval: 13,
-
- stop: function() {
- clearInterval( timerId );
- timerId = null;
- },
-
- speeds: {
- slow: 600,
- fast: 200,
- // Default speed
- _default: 400
- },
-
- step: {
- opacity: function( fx ) {
- jQuery.style( fx.elem, "opacity", fx.now );
- },
-
- _default: function( fx ) {
- if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
- fx.elem.style[ fx.prop ] = fx.now + fx.unit;
- } else {
- fx.elem[ fx.prop ] = fx.now;
- }
- }
- }
-});
-
-// Ensure props that can't be negative don't go there on undershoot easing
-jQuery.each( fxAttrs.concat.apply( [], fxAttrs ), function( i, prop ) {
- // exclude marginTop, marginLeft, marginBottom and marginRight from this list
- if ( prop.indexOf( "margin" ) ) {
- jQuery.fx.step[ prop ] = function( fx ) {
- jQuery.style( fx.elem, prop, Math.max(0, fx.now) + fx.unit );
- };
- }
-});
-
-if ( jQuery.expr && jQuery.expr.filters ) {
- jQuery.expr.filters.animated = function( elem ) {
- return jQuery.grep(jQuery.timers, function( fn ) {
- return elem === fn.elem;
- }).length;
- };
-}
-
-// Try to restore the default display value of an element
-function defaultDisplay( nodeName ) {
-
- if ( !elemdisplay[ nodeName ] ) {
-
- var body = document.body,
- elem = jQuery( "<" + nodeName + ">" ).appendTo( body ),
- display = elem.css( "display" );
- elem.remove();
-
- // If the simple way fails,
- // get element's real default display by attaching it to a temp iframe
- if ( display === "none" || display === "" ) {
- // No iframe to use yet, so create it
- if ( !iframe ) {
- iframe = document.createElement( "iframe" );
- iframe.frameBorder = iframe.width = iframe.height = 0;
- }
-
- body.appendChild( iframe );
-
- // Create a cacheable copy of the iframe document on first call.
- // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML
- // document to it; WebKit & Firefox won't allow reusing the iframe document.
- if ( !iframeDoc || !iframe.createElement ) {
- iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document;
- iframeDoc.write( ( jQuery.support.boxModel ? "<!doctype html>" : "" ) + "<html><body>" );
- iframeDoc.close();
- }
-
- elem = iframeDoc.createElement( nodeName );
-
- iframeDoc.body.appendChild( elem );
-
- display = jQuery.css( elem, "display" );
- body.removeChild( iframe );
- }
-
- // Store the correct default display
- elemdisplay[ nodeName ] = display;
- }
-
- return elemdisplay[ nodeName ];
-}
-
-
-
-
-var getOffset,
- rtable = /^t(?:able|d|h)$/i,
- rroot = /^(?:body|html)$/i;
-
-if ( "getBoundingClientRect" in document.documentElement ) {
- getOffset = function( elem, doc, docElem, box ) {
- try {
- box = elem.getBoundingClientRect();
- } catch(e) {}
-
- // Make sure we're not dealing with a disconnected DOM node
- if ( !box || !jQuery.contains( docElem, elem ) ) {
- return box ? { top: box.top, left: box.left } : { top: 0, left: 0 };
- }
-
- var body = doc.body,
- win = getWindow( doc ),
- clientTop = docElem.clientTop || body.clientTop || 0,
- clientLeft = docElem.clientLeft || body.clientLeft || 0,
- scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop,
- scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft,
- top = box.top + scrollTop - clientTop,
- left = box.left + scrollLeft - clientLeft;
-
- return { top: top, left: left };
- };
-
-} else {
- getOffset = function( elem, doc, docElem ) {
- var computedStyle,
- offsetParent = elem.offsetParent,
- prevOffsetParent = elem,
- body = doc.body,
- defaultView = doc.defaultView,
- prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
- top = elem.offsetTop,
- left = elem.offsetLeft;
-
- while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
- if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
- break;
- }
-
- computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
- top -= elem.scrollTop;
- left -= elem.scrollLeft;
-
- if ( elem === offsetParent ) {
- top += elem.offsetTop;
- left += elem.offsetLeft;
-
- if ( jQuery.support.doesNotAddBorder && !(jQuery.support.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
- top += parseFloat( computedStyle.borderTopWidth ) || 0;
- left += parseFloat( computedStyle.borderLeftWidth ) || 0;
- }
-
- prevOffsetParent = offsetParent;
- offsetParent = elem.offsetParent;
- }
-
- if ( jQuery.support.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
- top += parseFloat( computedStyle.borderTopWidth ) || 0;
- left += parseFloat( computedStyle.borderLeftWidth ) || 0;
- }
-
- prevComputedStyle = computedStyle;
- }
-
- if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
- top += body.offsetTop;
- left += body.offsetLeft;
- }
-
- if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) {
- top += Math.max( docElem.scrollTop, body.scrollTop );
- left += Math.max( docElem.scrollLeft, body.scrollLeft );
- }
-
- return { top: top, left: left };
- };
-}
-
-jQuery.fn.offset = function( options ) {
- if ( arguments.length ) {
- return options === undefined ?
- this :
- this.each(function( i ) {
- jQuery.offset.setOffset( this, options, i );
- });
- }
-
- var elem = this[0],
- doc = elem && elem.ownerDocument;
-
- if ( !doc ) {
- return null;
- }
-
- if ( elem === doc.body ) {
- return jQuery.offset.bodyOffset( elem );
- }
-
- return getOffset( elem, doc, doc.documentElement );
-};
-
-jQuery.offset = {
-
- bodyOffset: function( body ) {
- var top = body.offsetTop,
- left = body.offsetLeft;
-
- if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) {
- top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
- left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
- }
-
- return { top: top, left: left };
- },
-
- setOffset: function( elem, options, i ) {
- var position = jQuery.css( elem, "position" );
-
- // set position first, in-case top/left are set even on static elem
- if ( position === "static" ) {
- elem.style.position = "relative";
- }
-
- var curElem = jQuery( elem ),
- curOffset = curElem.offset(),
- curCSSTop = jQuery.css( elem, "top" ),
- curCSSLeft = jQuery.css( elem, "left" ),
- calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1,
- props = {}, curPosition = {}, curTop, curLeft;
-
- // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
- if ( calculatePosition ) {
- curPosition = curElem.position();
- curTop = curPosition.top;
- curLeft = curPosition.left;
- } else {
- curTop = parseFloat( curCSSTop ) || 0;
- curLeft = parseFloat( curCSSLeft ) || 0;
- }
-
- if ( jQuery.isFunction( options ) ) {
- options = options.call( elem, i, curOffset );
- }
-
- if ( options.top != null ) {
- props.top = ( options.top - curOffset.top ) + curTop;
- }
- if ( options.left != null ) {
- props.left = ( options.left - curOffset.left ) + curLeft;
- }
-
- if ( "using" in options ) {
- options.using.call( elem, props );
- } else {
- curElem.css( props );
- }
- }
-};
-
-
-jQuery.fn.extend({
-
- position: function() {
- if ( !this[0] ) {
- return null;
- }
-
- var elem = this[0],
-
- // Get *real* offsetParent
- offsetParent = this.offsetParent(),
-
- // Get correct offsets
- offset = this.offset(),
- parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
-
- // Subtract element margins
- // note: when an element has margin: auto the offsetLeft and marginLeft
- // are the same in Safari causing offset.left to incorrectly be 0
- offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
- offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
-
- // Add offsetParent borders
- parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
- parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
-
- // Subtract the two offsets
- return {
- top: offset.top - parentOffset.top,
- left: offset.left - parentOffset.left
- };
- },
-
- offsetParent: function() {
- return this.map(function() {
- var offsetParent = this.offsetParent || document.body;
- while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
- offsetParent = offsetParent.offsetParent;
- }
- return offsetParent;
- });
- }
-});
-
-
-// Create scrollLeft and scrollTop methods
-jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
- var top = /Y/.test( prop );
-
- jQuery.fn[ method ] = function( val ) {
- return jQuery.access( this, function( elem, method, val ) {
- var win = getWindow( elem );
-
- if ( val === undefined ) {
- return win ? (prop in win) ? win[ prop ] :
- jQuery.support.boxModel && win.document.documentElement[ method ] ||
- win.document.body[ method ] :
- elem[ method ];
- }
-
- if ( win ) {
- win.scrollTo(
- !top ? val : jQuery( win ).scrollLeft(),
- top ? val : jQuery( win ).scrollTop()
- );
-
- } else {
- elem[ method ] = val;
- }
- }, method, val, arguments.length, null );
- };
-});
-
-function getWindow( elem ) {
- return jQuery.isWindow( elem ) ?
- elem :
- elem.nodeType === 9 ?
- elem.defaultView || elem.parentWindow :
- false;
-}
-
-
-
-
-// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods
-jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
- var clientProp = "client" + name,
- scrollProp = "scroll" + name,
- offsetProp = "offset" + name;
-
- // innerHeight and innerWidth
- jQuery.fn[ "inner" + name ] = function() {
- var elem = this[0];
- return elem ?
- elem.style ?
- parseFloat( jQuery.css( elem, type, "padding" ) ) :
- this[ type ]() :
- null;
- };
-
- // outerHeight and outerWidth
- jQuery.fn[ "outer" + name ] = function( margin ) {
- var elem = this[0];
- return elem ?
- elem.style ?
- parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) :
- this[ type ]() :
- null;
- };
-
- jQuery.fn[ type ] = function( value ) {
- return jQuery.access( this, function( elem, type, value ) {
- var doc, docElemProp, orig, ret;
-
- if ( jQuery.isWindow( elem ) ) {
- // 3rd condition allows Nokia support, as it supports the docElem prop but not CSS1Compat
- doc = elem.document;
- docElemProp = doc.documentElement[ clientProp ];
- return jQuery.support.boxModel && docElemProp ||
- doc.body && doc.body[ clientProp ] || docElemProp;
- }
-
- // Get document width or height
- if ( elem.nodeType === 9 ) {
- // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
- doc = elem.documentElement;
-
- // when a window > document, IE6 reports a offset[Width/Height] > client[Width/Height]
- // so we can't use max, as it'll choose the incorrect offset[Width/Height]
- // instead we use the correct client[Width/Height]
- // support:IE6
- if ( doc[ clientProp ] >= doc[ scrollProp ] ) {
- return doc[ clientProp ];
- }
-
- return Math.max(
- elem.body[ scrollProp ], doc[ scrollProp ],
- elem.body[ offsetProp ], doc[ offsetProp ]
- );
- }
-
- // Get width or height on the element
- if ( value === undefined ) {
- orig = jQuery.css( elem, type );
- ret = parseFloat( orig );
- return jQuery.isNumeric( ret ) ? ret : orig;
- }
-
- // Set the width or height on the element
- jQuery( elem ).css( type, value );
- }, type, value, arguments.length, null );
- };
-});
-
-
-
-
-// Expose jQuery to the global object
-window.jQuery = window.$ = jQuery;
-
-// Expose jQuery as an AMD module, but only for AMD loaders that
-// understand the issues with loading multiple versions of jQuery
-// in a page that all might call define(). The loader will indicate
-// they have special allowances for multiple jQuery versions by
-// specifying define.amd.jQuery = true. Register as a named module,
-// since jQuery can be concatenated with other files that may use define,
-// but not use a proper concatenation script that understands anonymous
-// AMD modules. A named AMD is safest and most robust way to register.
-// Lowercase jquery is used because AMD module names are derived from
-// file names, and jQuery is normally delivered in a lowercase file name.
-// Do this after creating the global so that if an AMD module wants to call
-// noConflict to hide this version of jQuery, it will work.
-if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
- define( "jquery", [], function () { return jQuery; } );
-}
-
-
-
-})( window );
diff --git a/tools/infra-dashboard/js/jquery.min.js b/tools/infra-dashboard/js/jquery.min.js
deleted file mode 100644
index fad9ab12..00000000
--- a/tools/infra-dashboard/js/jquery.min.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
-!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b="length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function qa(){}qa.prototype=d.filters=d.pseudos,d.setFilters=new qa,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function ra(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){
-return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=L.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var Q=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,R=["Top","Right","Bottom","Left"],S=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)},T=/^(?:checkbox|radio)$/i;!function(){var a=l.createDocumentFragment(),b=a.appendChild(l.createElement("div")),c=l.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||l,d=c.documentElement,e=c.body,a.pageX=b.clientX+(d&&d.scrollLeft||e&&e.scrollLeft||0)-(d&&d.clientLeft||e&&e.clientLeft||0),a.pageY=b.clientY+(d&&d.scrollTop||e&&e.scrollTop||0)-(d&&d.clientTop||e&&e.clientTop||0)),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},fix:function(a){if(a[n.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=W.test(e)?this.mouseHooks:V.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new n.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=l),3===a.target.nodeType&&(a.target=a.target.parentNode),g.filter?g.filter(a,f):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==_()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===_()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&n.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=n.extend(new n.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?n.event.trigger(e,null,b):n.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?Z:$):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={isDefaultPrevented:$,isPropagationStopped:$,isImmediatePropagationStopped:$,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=Z,a&&a.preventDefault&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=Z,a&&a.stopPropagation&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=Z,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.focusinBubbles||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a),!0)};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=L.access(d,b);e||d.addEventListener(a,c,!0),L.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=L.access(d,b)-1;e?L.access(d,b,e):(d.removeEventListener(a,c,!0),L.remove(d,b))}}}),n.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(g in a)this.on(g,b,c,a[g],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=$;else if(!d)return this;return 1===e&&(f=d,d=function(a){return n().off(a),f.apply(this,arguments)},d.guid=f.guid||(f.guid=n.guid++)),this.each(function(){n.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=$),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var aa=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ia={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1></$2>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=qa[0].contentDocument,b.write(),b.close(),c=sa(a,b),qa.detach()),ra[a]=c),c}var ua=/^margin/,va=new RegExp("^("+Q+")(?!px)[a-z%]+$","i"),wa=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)};function xa(a,b,c){var d,e,f,g,h=a.style;return c=c||wa(a),c&&(g=c.getPropertyValue(b)||c[b]),c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),va.test(g)&&ua.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function ya(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d=l.documentElement,e=l.createElement("div"),f=l.createElement("div");if(f.style){f.style.backgroundClip="content-box",f.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===f.style.backgroundClip,e.style.cssText="border:0;width:0;height:0;top:0;left:-9999px;margin-top:1px;position:absolute",e.appendChild(f);function g(){f.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",f.innerHTML="",d.appendChild(e);var g=a.getComputedStyle(f,null);b="1%"!==g.top,c="4px"===g.width,d.removeChild(e)}a.getComputedStyle&&n.extend(k,{pixelPosition:function(){return g(),b},boxSizingReliable:function(){return null==c&&g(),c},reliableMarginRight:function(){var b,c=f.appendChild(l.createElement("div"));return c.style.cssText=f.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",f.style.width="1px",d.appendChild(e),b=!parseFloat(a.getComputedStyle(c,null).marginRight),d.removeChild(e),f.removeChild(c),b}})}}(),n.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var za=/^(none|table(?!-c[ea]).+)/,Aa=new RegExp("^("+Q+")(.*)$","i"),Ba=new RegExp("^([+-])=("+Q+")","i"),Ca={position:"absolute",visibility:"hidden",display:"block"},Da={letterSpacing:"0",fontWeight:"400"},Ea=["Webkit","O","Moz","ms"];function Fa(a,b){if(b in a)return b;var c=b[0].toUpperCase()+b.slice(1),d=b,e=Ea.length;while(e--)if(b=Ea[e]+c,b in a)return b;return d}function Ga(a,b,c){var d=Aa.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Ha(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+R[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+R[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+R[f]+"Width",!0,e))):(g+=n.css(a,"padding"+R[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+R[f]+"Width",!0,e)));return g}function Ia(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=wa(a),g="border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=xa(a,b,f),(0>e||null==e)&&(e=a.style[b]),va.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Ha(a,b,c||(g?"border":"content"),d,f)+"px"}function Ja(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=L.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&S(d)&&(f[g]=L.access(d,"olddisplay",ta(d.nodeName)))):(e=S(d),"none"===c&&e||L.set(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=xa(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Fa(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=Ba.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(n.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||n.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Fa(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=xa(a,b,d)),"normal"===e&&b in Da&&(e=Da[b]),""===c||c?(f=parseFloat(e),c===!0||n.isNumeric(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?za.test(n.css(a,"display"))&&0===a.offsetWidth?n.swap(a,Ca,function(){return Ia(a,b,d)}):Ia(a,b,d):void 0},set:function(a,c,d){var e=d&&wa(a);return Ga(a,c,d?Ha(a,b,d,"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),n.cssHooks.marginRight=ya(k.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},xa,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+R[d]+b]=f[d]||f[d-2]||f[0];return e}},ua.test(a)||(n.cssHooks[a+b].set=Ga)}),n.fn.extend({css:function(a,b){return J(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=wa(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Ja(this,!0)},hide:function(){return Ja(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){S(this)?n(this).show():n(this).hide()})}});function Ka(a,b,c,d,e){return new Ka.prototype.init(a,b,c,d,e)}n.Tween=Ka,Ka.prototype={constructor:Ka,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=Ka.propHooks[this.prop];return a&&a.get?a.get(this):Ka.propHooks._default.get(this)},run:function(a){var b,c=Ka.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ka.propHooks._default.set(this),this}},Ka.prototype.init.prototype=Ka.prototype,Ka.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[n.cssProps[a.prop]]||n.cssHooks[a.prop])?n.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Ka.propHooks.scrollTop=Ka.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},n.fx=Ka.prototype.init,n.fx.step={};var La,Ma,Na=/^(?:toggle|show|hide)$/,Oa=new RegExp("^(?:([+-])=|)("+Q+")([a-z%]*)$","i"),Pa=/queueHooks$/,Qa=[Va],Ra={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=Oa.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&Oa.exec(n.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,n.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function Sa(){return setTimeout(function(){La=void 0}),La=n.now()}function Ta(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=R[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ua(a,b,c){for(var d,e=(Ra[b]||[]).concat(Ra["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Va(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&S(a),q=L.get(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?L.get(a,"olddisplay")||ta(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Na.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?ta(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=L.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;L.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ua(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function Wa(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function Xa(a,b,c){var d,e,f=0,g=Qa.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=La||Sa(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:La||Sa(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(Wa(k,j.opts.specialEasing);g>f;f++)if(d=Qa[f].call(j,a,k,j.opts))return d;return n.map(k,Ua,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(Xa,{tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],Ra[c]=Ra[c]||[],Ra[c].unshift(b)},prefilter:function(a,b){b?Qa.unshift(a):Qa.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(S).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=Xa(this,n.extend({},a),f);(e||L.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=L.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Pa.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=L.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Ta(b,!0),a,d,e)}}),n.each({slideDown:Ta("show"),slideUp:Ta("hide"),slideToggle:Ta("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(La=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),La=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){Ma||(Ma=setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){clearInterval(Ma),Ma=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(a,b){return a=n.fx?n.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a=l.createElement("input"),b=l.createElement("select"),c=b.appendChild(l.createElement("option"));a.type="checkbox",k.checkOn=""!==a.value,k.optSelected=c.selected,b.disabled=!0,k.optDisabled=!c.disabled,a=l.createElement("input"),a.value="t",a.type="radio",k.radioValue="t"===a.value}();var Ya,Za,$a=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return J(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===U?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?Za:Ya)),
-void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=n.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void n.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),Za={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=$a[b]||n.find.attr;$a[b]=function(a,b,d){var e,f;return d||(f=$a[b],$a[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,$a[b]=f),e}});var _a=/^(?:input|select|textarea|button)$/i;n.fn.extend({prop:function(a,b){return J(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!n.isXMLDoc(a),f&&(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){return a.hasAttribute("tabindex")||_a.test(a.nodeName)||a.href?a.tabIndex:-1}}}}),k.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var ab=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h="string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ab," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=n.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0===arguments.length||"string"==typeof a&&a,i=0,j=this.length;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(h)for(b=(a||"").match(E)||[];j>i;i++)if(c=this[i],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ab," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?n.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(n.isFunction(a)?function(c){n(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=n(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===U||"boolean"===c)&&(this.className&&L.set(this,"__className__",this.className),this.className=this.className||a===!1?"":L.get(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ab," ").indexOf(b)>=0)return!0;return!1}});var bb=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(bb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(d.value,f)>=0)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>=0:void 0}},k.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var cb=n.now(),db=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(a){var b,c;if(!a||"string"!=typeof a)return null;try{c=new DOMParser,b=c.parseFromString(a,"text/xml")}catch(d){b=void 0}return(!b||b.getElementsByTagName("parsererror").length)&&n.error("Invalid XML: "+a),b};var eb=/#.*$/,fb=/([?&])_=[^&]*/,gb=/^(.*?):[ \t]*([^\r\n]*)$/gm,hb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,ib=/^(?:GET|HEAD)$/,jb=/^\/\//,kb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,lb={},mb={},nb="*/".concat("*"),ob=a.location.href,pb=kb.exec(ob.toLowerCase())||[];function qb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function rb(a,b,c,d){var e={},f=a===mb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function sb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function tb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function ub(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:ob,type:"GET",isLocal:hb.test(pb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":nb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?sb(sb(a,n.ajaxSettings),b):sb(n.ajaxSettings,a)},ajaxPrefilter:qb(lb),ajaxTransport:qb(mb),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=n.ajaxSetup({},b),l=k.context||k,m=k.context&&(l.nodeType||l.jquery)?n(l):n.event,o=n.Deferred(),p=n.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!f){f={};while(b=gb.exec(e))f[b[1].toLowerCase()]=b[2]}b=f[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?e:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return c&&c.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||ob)+"").replace(eb,"").replace(jb,pb[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(h=kb.exec(k.url.toLowerCase()),k.crossDomain=!(!h||h[1]===pb[1]&&h[2]===pb[2]&&(h[3]||("http:"===h[1]?"80":"443"))===(pb[3]||("http:"===pb[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),rb(lb,k,b,v),2===t)return v;i=n.event&&k.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!ib.test(k.type),d=k.url,k.hasContent||(k.data&&(d=k.url+=(db.test(d)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=fb.test(d)?d.replace(fb,"$1_="+cb++):d+(db.test(d)?"&":"?")+"_="+cb++)),k.ifModified&&(n.lastModified[d]&&v.setRequestHeader("If-Modified-Since",n.lastModified[d]),n.etag[d]&&v.setRequestHeader("If-None-Match",n.etag[d])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+nb+"; q=0.01":""):k.accepts["*"]);for(j in k.headers)v.setRequestHeader(j,k.headers[j]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(j in{success:1,error:1,complete:1})v[j](k[j]);if(c=rb(mb,k,b,v)){v.readyState=1,i&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,c.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,f,h){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),c=void 0,e=h||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,f&&(u=tb(k,v,f)),u=ub(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[d]=w),w=v.getResponseHeader("etag"),w&&(n.etag[d]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,i&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),i&&(m.trigger("ajaxComplete",[v,k]),--n.active||n.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return this.each(n.isFunction(a)?function(b){n(this).wrapInner(a.call(this,b))}:function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var vb=/%20/g,wb=/\[\]$/,xb=/\r?\n/g,yb=/^(?:submit|button|image|reset|file)$/i,zb=/^(?:input|select|textarea|keygen)/i;function Ab(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||wb.test(a)?d(a,e):Ab(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Ab(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Ab(c,a[c],b,e);return d.join("&").replace(vb,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&zb.test(this.nodeName)&&!yb.test(a)&&(this.checked||!T.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(xb,"\r\n")}}):{name:b.name,value:c.replace(xb,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new XMLHttpRequest}catch(a){}};var Bb=0,Cb={},Db={0:200,1223:204},Eb=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Cb)Cb[a]()}),k.cors=!!Eb&&"withCredentials"in Eb,k.ajax=Eb=!!Eb,n.ajaxTransport(function(a){var b;return k.cors||Eb&&!a.crossDomain?{send:function(c,d){var e,f=a.xhr(),g=++Bb;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)f.setRequestHeader(e,c[e]);b=function(a){return function(){b&&(delete Cb[g],b=f.onload=f.onerror=null,"abort"===a?f.abort():"error"===a?d(f.status,f.statusText):d(Db[f.status]||f.status,f.statusText,"string"==typeof f.responseText?{text:f.responseText}:void 0,f.getAllResponseHeaders()))}},f.onload=b(),f.onerror=b("error"),b=Cb[g]=b("abort");try{f.send(a.hasContent&&a.data||null)}catch(h){if(b)throw h}},abort:function(){b&&b()}}:void 0}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(d,e){b=n("<script>").prop({async:!0,charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&e("error"===a.type?404:200,a.type)}),l.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Fb=[],Gb=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Fb.pop()||n.expando+"_"+cb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Gb.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Gb.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Gb,"$1"+e):b.jsonp!==!1&&(b.url+=(db.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Fb.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||l;var d=v.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=n.buildFragment([a],b,e),e&&e.length&&n(e).remove(),n.merge([],d.childNodes))};var Hb=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&Hb)return Hb.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e,dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,f||[a.responseText,b,a])}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var Ib=a.document.documentElement;function Jb(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(typeof d.getBoundingClientRect!==U&&(e=d.getBoundingClientRect()),c=Jb(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===n.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(d=a.offset()),d.top+=n.css(a[0],"borderTopWidth",!0),d.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-d.top-n.css(c,"marginTop",!0),left:b.left-d.left-n.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||Ib;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Ib})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(b,c){var d="pageYOffset"===c;n.fn[b]=function(e){return J(this,function(b,e,f){var g=Jb(b);return void 0===f?g?g[c]:b[e]:void(g?g.scrollTo(d?a.pageXOffset:f,d?f:a.pageYOffset):b[e]=f)},b,e,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=ya(k.pixelPosition,function(a,c){return c?(c=xa(a,b),va.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return J(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var Kb=a.jQuery,Lb=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Lb),b&&a.jQuery===n&&(a.jQuery=Kb),n},typeof b===U&&(a.jQuery=a.$=n),n});
-//# sourceMappingURL=jquery.min.map \ No newline at end of file
diff --git a/tools/infra-dashboard/js/modernizr.js b/tools/infra-dashboard/js/modernizr.js
deleted file mode 100644
index c3a5741a..00000000
--- a/tools/infra-dashboard/js/modernizr.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/* Modernizr 2.8.3 (Custom Build) | MIT & BSD
- * Build: http://modernizr.com/download/#-svg-shiv-mq-cssclasses-teststyles-load
- */
-;window.Modernizr=function(a,b,c){function x(a){j.cssText=a}function y(a,b){return x(prefixes.join(a+";")+(b||""))}function z(a,b){return typeof a===b}function A(a,b){return!!~(""+a).indexOf(b)}function B(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:z(f,"function")?f.bind(d||b):f}return!1}var d="2.8.3",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m={svg:"http://www.w3.org/2000/svg"},n={},o={},p={},q=[],r=q.slice,s,t=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["&#173;",'<style id="s',h,'">',a,"</style>"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},u=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b)&&c(b).matches||!1;var d;return t("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},v={}.hasOwnProperty,w;!z(v,"undefined")&&!z(v.call,"undefined")?w=function(a,b){return v.call(a,b)}:w=function(a,b){return b in a&&z(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=r.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(r.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(r.call(arguments)))};return e}),n.svg=function(){return!!b.createElementNS&&!!b.createElementNS(m.svg,"svg").createSVGRect};for(var C in n)w(n,C)&&(s=C.toLowerCase(),e[s]=n[C](),q.push((e[s]?"":"no-")+s));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)w(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},x(""),i=k=null,function(a,b){function l(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function m(){var a=s.elements;return typeof a=="string"?a.split(" "):a}function n(a){var b=j[a[h]];return b||(b={},i++,a[h]=i,j[i]=b),b}function o(a,c,d){c||(c=b);if(k)return c.createElement(a);d||(d=n(c));var g;return d.cache[a]?g=d.cache[a].cloneNode():f.test(a)?g=(d.cache[a]=d.createElem(a)).cloneNode():g=d.createElem(a),g.canHaveChildren&&!e.test(a)&&!g.tagUrn?d.frag.appendChild(g):g}function p(a,c){a||(a=b);if(k)return a.createDocumentFragment();c=c||n(a);var d=c.frag.cloneNode(),e=0,f=m(),g=f.length;for(;e<g;e++)d.createElement(f[e]);return d}function q(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return s.shivMethods?o(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(s,b.frag)}function r(a){a||(a=b);var c=n(a);return s.shivCSS&&!g&&!c.hasCSS&&(c.hasCSS=!!l(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),k||q(a,c),a}var c="3.7.0",d=a.html5||{},e=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,f=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,g,h="_html5shiv",i=0,j={},k;(function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",g="hidden"in a,k=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){g=!0,k=!0}})();var s={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:c,shivCSS:d.shivCSS!==!1,supportsUnknownElements:k,shivMethods:d.shivMethods!==!1,type:"default",shivDocument:r,createElement:o,createDocumentFragment:p};a.html5=s,r(b)}(this,b),e._version=d,e.mq=u,e.testStyles=t,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+q.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}}(this,document),Modernizr.load=function(){yepnope.apply(window,[].slice.call(arguments,0))}; \ No newline at end of file
diff --git a/tools/infra-dashboard/js/moment.min.js b/tools/infra-dashboard/js/moment.min.js
deleted file mode 100644
index d301ddbb..00000000
--- a/tools/infra-dashboard/js/moment.min.js
+++ /dev/null
@@ -1,7 +0,0 @@
-//! moment.js
-//! version : 2.13.0
-//! authors : Tim Wood, Iskren Chernev, Moment.js contributors
-//! license : MIT
-//! momentjs.com
-!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.moment=b()}(this,function(){"use strict";function a(){return fd.apply(null,arguments)}function b(a){fd=a}function c(a){return a instanceof Array||"[object Array]"===Object.prototype.toString.call(a)}function d(a){return a instanceof Date||"[object Date]"===Object.prototype.toString.call(a)}function e(a,b){var c,d=[];for(c=0;c<a.length;++c)d.push(b(a[c],c));return d}function f(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function g(a,b){for(var c in b)f(b,c)&&(a[c]=b[c]);return f(b,"toString")&&(a.toString=b.toString),f(b,"valueOf")&&(a.valueOf=b.valueOf),a}function h(a,b,c,d){return Ja(a,b,c,d,!0).utc()}function i(){return{empty:!1,unusedTokens:[],unusedInput:[],overflow:-2,charsLeftOver:0,nullInput:!1,invalidMonth:null,invalidFormat:!1,userInvalidated:!1,iso:!1,parsedDateParts:[],meridiem:null}}function j(a){return null==a._pf&&(a._pf=i()),a._pf}function k(a){if(null==a._isValid){var b=j(a),c=gd.call(b.parsedDateParts,function(a){return null!=a});a._isValid=!isNaN(a._d.getTime())&&b.overflow<0&&!b.empty&&!b.invalidMonth&&!b.invalidWeekday&&!b.nullInput&&!b.invalidFormat&&!b.userInvalidated&&(!b.meridiem||b.meridiem&&c),a._strict&&(a._isValid=a._isValid&&0===b.charsLeftOver&&0===b.unusedTokens.length&&void 0===b.bigHour)}return a._isValid}function l(a){var b=h(NaN);return null!=a?g(j(b),a):j(b).userInvalidated=!0,b}function m(a){return void 0===a}function n(a,b){var c,d,e;if(m(b._isAMomentObject)||(a._isAMomentObject=b._isAMomentObject),m(b._i)||(a._i=b._i),m(b._f)||(a._f=b._f),m(b._l)||(a._l=b._l),m(b._strict)||(a._strict=b._strict),m(b._tzm)||(a._tzm=b._tzm),m(b._isUTC)||(a._isUTC=b._isUTC),m(b._offset)||(a._offset=b._offset),m(b._pf)||(a._pf=j(b)),m(b._locale)||(a._locale=b._locale),hd.length>0)for(c in hd)d=hd[c],e=b[d],m(e)||(a[d]=e);return a}function o(b){n(this,b),this._d=new Date(null!=b._d?b._d.getTime():NaN),id===!1&&(id=!0,a.updateOffset(this),id=!1)}function p(a){return a instanceof o||null!=a&&null!=a._isAMomentObject}function q(a){return 0>a?Math.ceil(a):Math.floor(a)}function r(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=q(b)),c}function s(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;e>d;d++)(c&&a[d]!==b[d]||!c&&r(a[d])!==r(b[d]))&&g++;return g+f}function t(b){a.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+b)}function u(b,c){var d=!0;return g(function(){return null!=a.deprecationHandler&&a.deprecationHandler(null,b),d&&(t(b+"\nArguments: "+Array.prototype.slice.call(arguments).join(", ")+"\n"+(new Error).stack),d=!1),c.apply(this,arguments)},c)}function v(b,c){null!=a.deprecationHandler&&a.deprecationHandler(b,c),jd[b]||(t(c),jd[b]=!0)}function w(a){return a instanceof Function||"[object Function]"===Object.prototype.toString.call(a)}function x(a){return"[object Object]"===Object.prototype.toString.call(a)}function y(a){var b,c;for(c in a)b=a[c],w(b)?this[c]=b:this["_"+c]=b;this._config=a,this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)}function z(a,b){var c,d=g({},a);for(c in b)f(b,c)&&(x(a[c])&&x(b[c])?(d[c]={},g(d[c],a[c]),g(d[c],b[c])):null!=b[c]?d[c]=b[c]:delete d[c]);return d}function A(a){null!=a&&this.set(a)}function B(a){return a?a.toLowerCase().replace("_","-"):a}function C(a){for(var b,c,d,e,f=0;f<a.length;){for(e=B(a[f]).split("-"),b=e.length,c=B(a[f+1]),c=c?c.split("-"):null;b>0;){if(d=D(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&s(e,c,!0)>=b-1)break;b--}f++}return null}function D(a){var b=null;if(!nd[a]&&"undefined"!=typeof module&&module&&module.exports)try{b=ld._abbr,require("./locale/"+a),E(b)}catch(c){}return nd[a]}function E(a,b){var c;return a&&(c=m(b)?H(a):F(a,b),c&&(ld=c)),ld._abbr}function F(a,b){return null!==b?(b.abbr=a,null!=nd[a]?(v("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale"),b=z(nd[a]._config,b)):null!=b.parentLocale&&(null!=nd[b.parentLocale]?b=z(nd[b.parentLocale]._config,b):v("parentLocaleUndefined","specified parentLocale is not defined yet")),nd[a]=new A(b),E(a),nd[a]):(delete nd[a],null)}function G(a,b){if(null!=b){var c;null!=nd[a]&&(b=z(nd[a]._config,b)),c=new A(b),c.parentLocale=nd[a],nd[a]=c,E(a)}else null!=nd[a]&&(null!=nd[a].parentLocale?nd[a]=nd[a].parentLocale:null!=nd[a]&&delete nd[a]);return nd[a]}function H(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return ld;if(!c(a)){if(b=D(a))return b;a=[a]}return C(a)}function I(){return kd(nd)}function J(a,b){var c=a.toLowerCase();od[c]=od[c+"s"]=od[b]=a}function K(a){return"string"==typeof a?od[a]||od[a.toLowerCase()]:void 0}function L(a){var b,c,d={};for(c in a)f(a,c)&&(b=K(c),b&&(d[b]=a[c]));return d}function M(b,c){return function(d){return null!=d?(O(this,b,d),a.updateOffset(this,c),this):N(this,b)}}function N(a,b){return a.isValid()?a._d["get"+(a._isUTC?"UTC":"")+b]():NaN}function O(a,b,c){a.isValid()&&a._d["set"+(a._isUTC?"UTC":"")+b](c)}function P(a,b){var c;if("object"==typeof a)for(c in a)this.set(c,a[c]);else if(a=K(a),w(this[a]))return this[a](b);return this}function Q(a,b,c){var d=""+Math.abs(a),e=b-d.length,f=a>=0;return(f?c?"+":"":"-")+Math.pow(10,Math.max(0,e)).toString().substr(1)+d}function R(a,b,c,d){var e=d;"string"==typeof d&&(e=function(){return this[d]()}),a&&(sd[a]=e),b&&(sd[b[0]]=function(){return Q(e.apply(this,arguments),b[1],b[2])}),c&&(sd[c]=function(){return this.localeData().ordinal(e.apply(this,arguments),a)})}function S(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function T(a){var b,c,d=a.match(pd);for(b=0,c=d.length;c>b;b++)sd[d[b]]?d[b]=sd[d[b]]:d[b]=S(d[b]);return function(b){var e,f="";for(e=0;c>e;e++)f+=d[e]instanceof Function?d[e].call(b,a):d[e];return f}}function U(a,b){return a.isValid()?(b=V(b,a.localeData()),rd[b]=rd[b]||T(b),rd[b](a)):a.localeData().invalidDate()}function V(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(qd.lastIndex=0;d>=0&&qd.test(a);)a=a.replace(qd,c),qd.lastIndex=0,d-=1;return a}function W(a,b,c){Kd[a]=w(b)?b:function(a,d){return a&&c?c:b}}function X(a,b){return f(Kd,a)?Kd[a](b._strict,b._locale):new RegExp(Y(a))}function Y(a){return Z(a.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e}))}function Z(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function $(a,b){var c,d=b;for("string"==typeof a&&(a=[a]),"number"==typeof b&&(d=function(a,c){c[b]=r(a)}),c=0;c<a.length;c++)Ld[a[c]]=d}function _(a,b){$(a,function(a,c,d,e){d._w=d._w||{},b(a,d._w,d,e)})}function aa(a,b,c){null!=b&&f(Ld,a)&&Ld[a](b,c._a,c,a)}function ba(a,b){return new Date(Date.UTC(a,b+1,0)).getUTCDate()}function ca(a,b){return c(this._months)?this._months[a.month()]:this._months[Vd.test(b)?"format":"standalone"][a.month()]}function da(a,b){return c(this._monthsShort)?this._monthsShort[a.month()]:this._monthsShort[Vd.test(b)?"format":"standalone"][a.month()]}function ea(a,b,c){var d,e,f,g=a.toLocaleLowerCase();if(!this._monthsParse)for(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[],d=0;12>d;++d)f=h([2e3,d]),this._shortMonthsParse[d]=this.monthsShort(f,"").toLocaleLowerCase(),this._longMonthsParse[d]=this.months(f,"").toLocaleLowerCase();return c?"MMM"===b?(e=md.call(this._shortMonthsParse,g),-1!==e?e:null):(e=md.call(this._longMonthsParse,g),-1!==e?e:null):"MMM"===b?(e=md.call(this._shortMonthsParse,g),-1!==e?e:(e=md.call(this._longMonthsParse,g),-1!==e?e:null)):(e=md.call(this._longMonthsParse,g),-1!==e?e:(e=md.call(this._shortMonthsParse,g),-1!==e?e:null))}function fa(a,b,c){var d,e,f;if(this._monthsParseExact)return ea.call(this,a,b,c);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),d=0;12>d;d++){if(e=h([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}}function ga(a,b){var c;if(!a.isValid())return a;if("string"==typeof b)if(/^\d+$/.test(b))b=r(b);else if(b=a.localeData().monthsParse(b),"number"!=typeof b)return a;return c=Math.min(a.date(),ba(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a}function ha(b){return null!=b?(ga(this,b),a.updateOffset(this,!0),this):N(this,"Month")}function ia(){return ba(this.year(),this.month())}function ja(a){return this._monthsParseExact?(f(this,"_monthsRegex")||la.call(this),a?this._monthsShortStrictRegex:this._monthsShortRegex):this._monthsShortStrictRegex&&a?this._monthsShortStrictRegex:this._monthsShortRegex}function ka(a){return this._monthsParseExact?(f(this,"_monthsRegex")||la.call(this),a?this._monthsStrictRegex:this._monthsRegex):this._monthsStrictRegex&&a?this._monthsStrictRegex:this._monthsRegex}function la(){function a(a,b){return b.length-a.length}var b,c,d=[],e=[],f=[];for(b=0;12>b;b++)c=h([2e3,b]),d.push(this.monthsShort(c,"")),e.push(this.months(c,"")),f.push(this.months(c,"")),f.push(this.monthsShort(c,""));for(d.sort(a),e.sort(a),f.sort(a),b=0;12>b;b++)d[b]=Z(d[b]),e[b]=Z(e[b]),f[b]=Z(f[b]);this._monthsRegex=new RegExp("^("+f.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+e.join("|")+")","i"),this._monthsShortStrictRegex=new RegExp("^("+d.join("|")+")","i")}function ma(a){var b,c=a._a;return c&&-2===j(a).overflow&&(b=c[Nd]<0||c[Nd]>11?Nd:c[Od]<1||c[Od]>ba(c[Md],c[Nd])?Od:c[Pd]<0||c[Pd]>24||24===c[Pd]&&(0!==c[Qd]||0!==c[Rd]||0!==c[Sd])?Pd:c[Qd]<0||c[Qd]>59?Qd:c[Rd]<0||c[Rd]>59?Rd:c[Sd]<0||c[Sd]>999?Sd:-1,j(a)._overflowDayOfYear&&(Md>b||b>Od)&&(b=Od),j(a)._overflowWeeks&&-1===b&&(b=Td),j(a)._overflowWeekday&&-1===b&&(b=Ud),j(a).overflow=b),a}function na(a){var b,c,d,e,f,g,h=a._i,i=$d.exec(h)||_d.exec(h);if(i){for(j(a).iso=!0,b=0,c=be.length;c>b;b++)if(be[b][1].exec(i[1])){e=be[b][0],d=be[b][2]!==!1;break}if(null==e)return void(a._isValid=!1);if(i[3]){for(b=0,c=ce.length;c>b;b++)if(ce[b][1].exec(i[3])){f=(i[2]||" ")+ce[b][0];break}if(null==f)return void(a._isValid=!1)}if(!d&&null!=f)return void(a._isValid=!1);if(i[4]){if(!ae.exec(i[4]))return void(a._isValid=!1);g="Z"}a._f=e+(f||"")+(g||""),Ca(a)}else a._isValid=!1}function oa(b){var c=de.exec(b._i);return null!==c?void(b._d=new Date(+c[1])):(na(b),void(b._isValid===!1&&(delete b._isValid,a.createFromInputFallback(b))))}function pa(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 100>a&&a>=0&&isFinite(h.getFullYear())&&h.setFullYear(a),h}function qa(a){var b=new Date(Date.UTC.apply(null,arguments));return 100>a&&a>=0&&isFinite(b.getUTCFullYear())&&b.setUTCFullYear(a),b}function ra(a){return sa(a)?366:365}function sa(a){return a%4===0&&a%100!==0||a%400===0}function ta(){return sa(this.year())}function ua(a,b,c){var d=7+b-c,e=(7+qa(a,0,d).getUTCDay()-b)%7;return-e+d-1}function va(a,b,c,d,e){var f,g,h=(7+c-d)%7,i=ua(a,d,e),j=1+7*(b-1)+h+i;return 0>=j?(f=a-1,g=ra(f)+j):j>ra(a)?(f=a+1,g=j-ra(a)):(f=a,g=j),{year:f,dayOfYear:g}}function wa(a,b,c){var d,e,f=ua(a.year(),b,c),g=Math.floor((a.dayOfYear()-f-1)/7)+1;return 1>g?(e=a.year()-1,d=g+xa(e,b,c)):g>xa(a.year(),b,c)?(d=g-xa(a.year(),b,c),e=a.year()+1):(e=a.year(),d=g),{week:d,year:e}}function xa(a,b,c){var d=ua(a,b,c),e=ua(a+1,b,c);return(ra(a)-d+e)/7}function ya(a,b,c){return null!=a?a:null!=b?b:c}function za(b){var c=new Date(a.now());return b._useUTC?[c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate()]:[c.getFullYear(),c.getMonth(),c.getDate()]}function Aa(a){var b,c,d,e,f=[];if(!a._d){for(d=za(a),a._w&&null==a._a[Od]&&null==a._a[Nd]&&Ba(a),a._dayOfYear&&(e=ya(a._a[Md],d[Md]),a._dayOfYear>ra(e)&&(j(a)._overflowDayOfYear=!0),c=qa(e,0,a._dayOfYear),a._a[Nd]=c.getUTCMonth(),a._a[Od]=c.getUTCDate()),b=0;3>b&&null==a._a[b];++b)a._a[b]=f[b]=d[b];for(;7>b;b++)a._a[b]=f[b]=null==a._a[b]?2===b?1:0:a._a[b];24===a._a[Pd]&&0===a._a[Qd]&&0===a._a[Rd]&&0===a._a[Sd]&&(a._nextDay=!0,a._a[Pd]=0),a._d=(a._useUTC?qa:pa).apply(null,f),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[Pd]=24)}}function Ba(a){var b,c,d,e,f,g,h,i;b=a._w,null!=b.GG||null!=b.W||null!=b.E?(f=1,g=4,c=ya(b.GG,a._a[Md],wa(Ka(),1,4).year),d=ya(b.W,1),e=ya(b.E,1),(1>e||e>7)&&(i=!0)):(f=a._locale._week.dow,g=a._locale._week.doy,c=ya(b.gg,a._a[Md],wa(Ka(),f,g).year),d=ya(b.w,1),null!=b.d?(e=b.d,(0>e||e>6)&&(i=!0)):null!=b.e?(e=b.e+f,(b.e<0||b.e>6)&&(i=!0)):e=f),1>d||d>xa(c,f,g)?j(a)._overflowWeeks=!0:null!=i?j(a)._overflowWeekday=!0:(h=va(c,d,e,f,g),a._a[Md]=h.year,a._dayOfYear=h.dayOfYear)}function Ca(b){if(b._f===a.ISO_8601)return void na(b);b._a=[],j(b).empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,k=0;for(e=V(b._f,b._locale).match(pd)||[],c=0;c<e.length;c++)f=e[c],d=(h.match(X(f,b))||[])[0],d&&(g=h.substr(0,h.indexOf(d)),g.length>0&&j(b).unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),k+=d.length),sd[f]?(d?j(b).empty=!1:j(b).unusedTokens.push(f),aa(f,d,b)):b._strict&&!d&&j(b).unusedTokens.push(f);j(b).charsLeftOver=i-k,h.length>0&&j(b).unusedInput.push(h),j(b).bigHour===!0&&b._a[Pd]<=12&&b._a[Pd]>0&&(j(b).bigHour=void 0),j(b).parsedDateParts=b._a.slice(0),j(b).meridiem=b._meridiem,b._a[Pd]=Da(b._locale,b._a[Pd],b._meridiem),Aa(b),ma(b)}function Da(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&12>b&&(b+=12),d||12!==b||(b=0),b):b}function Ea(a){var b,c,d,e,f;if(0===a._f.length)return j(a).invalidFormat=!0,void(a._d=new Date(NaN));for(e=0;e<a._f.length;e++)f=0,b=n({},a),null!=a._useUTC&&(b._useUTC=a._useUTC),b._f=a._f[e],Ca(b),k(b)&&(f+=j(b).charsLeftOver,f+=10*j(b).unusedTokens.length,j(b).score=f,(null==d||d>f)&&(d=f,c=b));g(a,c||b)}function Fa(a){if(!a._d){var b=L(a._i);a._a=e([b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],function(a){return a&&parseInt(a,10)}),Aa(a)}}function Ga(a){var b=new o(ma(Ha(a)));return b._nextDay&&(b.add(1,"d"),b._nextDay=void 0),b}function Ha(a){var b=a._i,e=a._f;return a._locale=a._locale||H(a._l),null===b||void 0===e&&""===b?l({nullInput:!0}):("string"==typeof b&&(a._i=b=a._locale.preparse(b)),p(b)?new o(ma(b)):(c(e)?Ea(a):e?Ca(a):d(b)?a._d=b:Ia(a),k(a)||(a._d=null),a))}function Ia(b){var f=b._i;void 0===f?b._d=new Date(a.now()):d(f)?b._d=new Date(f.valueOf()):"string"==typeof f?oa(b):c(f)?(b._a=e(f.slice(0),function(a){return parseInt(a,10)}),Aa(b)):"object"==typeof f?Fa(b):"number"==typeof f?b._d=new Date(f):a.createFromInputFallback(b)}function Ja(a,b,c,d,e){var f={};return"boolean"==typeof c&&(d=c,c=void 0),f._isAMomentObject=!0,f._useUTC=f._isUTC=e,f._l=c,f._i=a,f._f=b,f._strict=d,Ga(f)}function Ka(a,b,c,d){return Ja(a,b,c,d,!1)}function La(a,b){var d,e;if(1===b.length&&c(b[0])&&(b=b[0]),!b.length)return Ka();for(d=b[0],e=1;e<b.length;++e)(!b[e].isValid()||b[e][a](d))&&(d=b[e]);return d}function Ma(){var a=[].slice.call(arguments,0);return La("isBefore",a)}function Na(){var a=[].slice.call(arguments,0);return La("isAfter",a)}function Oa(a){var b=L(a),c=b.year||0,d=b.quarter||0,e=b.month||0,f=b.week||0,g=b.day||0,h=b.hour||0,i=b.minute||0,j=b.second||0,k=b.millisecond||0;this._milliseconds=+k+1e3*j+6e4*i+1e3*h*60*60,this._days=+g+7*f,this._months=+e+3*d+12*c,this._data={},this._locale=H(),this._bubble()}function Pa(a){return a instanceof Oa}function Qa(a,b){R(a,0,0,function(){var a=this.utcOffset(),c="+";return 0>a&&(a=-a,c="-"),c+Q(~~(a/60),2)+b+Q(~~a%60,2)})}function Ra(a,b){var c=(b||"").match(a)||[],d=c[c.length-1]||[],e=(d+"").match(ie)||["-",0,0],f=+(60*e[1])+r(e[2]);return"+"===e[0]?f:-f}function Sa(b,c){var e,f;return c._isUTC?(e=c.clone(),f=(p(b)||d(b)?b.valueOf():Ka(b).valueOf())-e.valueOf(),e._d.setTime(e._d.valueOf()+f),a.updateOffset(e,!1),e):Ka(b).local()}function Ta(a){return 15*-Math.round(a._d.getTimezoneOffset()/15)}function Ua(b,c){var d,e=this._offset||0;return this.isValid()?null!=b?("string"==typeof b?b=Ra(Hd,b):Math.abs(b)<16&&(b=60*b),!this._isUTC&&c&&(d=Ta(this)),this._offset=b,this._isUTC=!0,null!=d&&this.add(d,"m"),e!==b&&(!c||this._changeInProgress?jb(this,db(b-e,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?e:Ta(this):null!=b?this:NaN}function Va(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}function Wa(a){return this.utcOffset(0,a)}function Xa(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(Ta(this),"m")),this}function Ya(){return this._tzm?this.utcOffset(this._tzm):"string"==typeof this._i&&this.utcOffset(Ra(Gd,this._i)),this}function Za(a){return this.isValid()?(a=a?Ka(a).utcOffset():0,(this.utcOffset()-a)%60===0):!1}function $a(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function _a(){if(!m(this._isDSTShifted))return this._isDSTShifted;var a={};if(n(a,this),a=Ha(a),a._a){var b=a._isUTC?h(a._a):Ka(a._a);this._isDSTShifted=this.isValid()&&s(a._a,b.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function ab(){return this.isValid()?!this._isUTC:!1}function bb(){return this.isValid()?this._isUTC:!1}function cb(){return this.isValid()?this._isUTC&&0===this._offset:!1}function db(a,b){var c,d,e,g=a,h=null;return Pa(a)?g={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(g={},b?g[b]=a:g.milliseconds=a):(h=je.exec(a))?(c="-"===h[1]?-1:1,g={y:0,d:r(h[Od])*c,h:r(h[Pd])*c,m:r(h[Qd])*c,s:r(h[Rd])*c,ms:r(h[Sd])*c}):(h=ke.exec(a))?(c="-"===h[1]?-1:1,g={y:eb(h[2],c),M:eb(h[3],c),w:eb(h[4],c),d:eb(h[5],c),h:eb(h[6],c),m:eb(h[7],c),s:eb(h[8],c)}):null==g?g={}:"object"==typeof g&&("from"in g||"to"in g)&&(e=gb(Ka(g.from),Ka(g.to)),g={},g.ms=e.milliseconds,g.M=e.months),d=new Oa(g),Pa(a)&&f(a,"_locale")&&(d._locale=a._locale),d}function eb(a,b){var c=a&&parseFloat(a.replace(",","."));return(isNaN(c)?0:c)*b}function fb(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function gb(a,b){var c;return a.isValid()&&b.isValid()?(b=Sa(b,a),a.isBefore(b)?c=fb(a,b):(c=fb(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c):{milliseconds:0,months:0}}function hb(a){return 0>a?-1*Math.round(-1*a):Math.round(a)}function ib(a,b){return function(c,d){var e,f;return null===d||isNaN(+d)||(v(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period)."),f=c,c=d,d=f),c="string"==typeof c?+c:c,e=db(c,d),jb(this,e,a),this}}function jb(b,c,d,e){var f=c._milliseconds,g=hb(c._days),h=hb(c._months);b.isValid()&&(e=null==e?!0:e,f&&b._d.setTime(b._d.valueOf()+f*d),g&&O(b,"Date",N(b,"Date")+g*d),h&&ga(b,N(b,"Month")+h*d),e&&a.updateOffset(b,g||h))}function kb(a,b){var c=a||Ka(),d=Sa(c,this).startOf("day"),e=this.diff(d,"days",!0),f=-6>e?"sameElse":-1>e?"lastWeek":0>e?"lastDay":1>e?"sameDay":2>e?"nextDay":7>e?"nextWeek":"sameElse",g=b&&(w(b[f])?b[f]():b[f]);return this.format(g||this.localeData().calendar(f,this,Ka(c)))}function lb(){return new o(this)}function mb(a,b){var c=p(a)?a:Ka(a);return this.isValid()&&c.isValid()?(b=K(m(b)?"millisecond":b),"millisecond"===b?this.valueOf()>c.valueOf():c.valueOf()<this.clone().startOf(b).valueOf()):!1}function nb(a,b){var c=p(a)?a:Ka(a);return this.isValid()&&c.isValid()?(b=K(m(b)?"millisecond":b),"millisecond"===b?this.valueOf()<c.valueOf():this.clone().endOf(b).valueOf()<c.valueOf()):!1}function ob(a,b,c,d){return d=d||"()",("("===d[0]?this.isAfter(a,c):!this.isBefore(a,c))&&(")"===d[1]?this.isBefore(b,c):!this.isAfter(b,c))}function pb(a,b){var c,d=p(a)?a:Ka(a);return this.isValid()&&d.isValid()?(b=K(b||"millisecond"),"millisecond"===b?this.valueOf()===d.valueOf():(c=d.valueOf(),this.clone().startOf(b).valueOf()<=c&&c<=this.clone().endOf(b).valueOf())):!1}function qb(a,b){return this.isSame(a,b)||this.isAfter(a,b)}function rb(a,b){return this.isSame(a,b)||this.isBefore(a,b)}function sb(a,b,c){var d,e,f,g;return this.isValid()?(d=Sa(a,this),d.isValid()?(e=6e4*(d.utcOffset()-this.utcOffset()),b=K(b),"year"===b||"month"===b||"quarter"===b?(g=tb(this,d),"quarter"===b?g/=3:"year"===b&&(g/=12)):(f=this-d,g="second"===b?f/1e3:"minute"===b?f/6e4:"hour"===b?f/36e5:"day"===b?(f-e)/864e5:"week"===b?(f-e)/6048e5:f),c?g:q(g)):NaN):NaN}function tb(a,b){var c,d,e=12*(b.year()-a.year())+(b.month()-a.month()),f=a.clone().add(e,"months");return 0>b-f?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)||0}function ub(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function vb(){var a=this.clone().utc();return 0<a.year()&&a.year()<=9999?w(Date.prototype.toISOString)?this.toDate().toISOString():U(a,"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]"):U(a,"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]")}function wb(b){b||(b=this.isUtc()?a.defaultFormatUtc:a.defaultFormat);var c=U(this,b);return this.localeData().postformat(c)}function xb(a,b){return this.isValid()&&(p(a)&&a.isValid()||Ka(a).isValid())?db({to:this,from:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function yb(a){return this.from(Ka(),a)}function zb(a,b){return this.isValid()&&(p(a)&&a.isValid()||Ka(a).isValid())?db({from:this,to:a}).locale(this.locale()).humanize(!b):this.localeData().invalidDate()}function Ab(a){return this.to(Ka(),a)}function Bb(a){var b;return void 0===a?this._locale._abbr:(b=H(a),null!=b&&(this._locale=b),this)}function Cb(){return this._locale}function Db(a){switch(a=K(a)){case"year":this.month(0);case"quarter":case"month":this.date(1);case"week":case"isoWeek":case"day":case"date":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return"week"===a&&this.weekday(0),"isoWeek"===a&&this.isoWeekday(1),"quarter"===a&&this.month(3*Math.floor(this.month()/3)),this}function Eb(a){return a=K(a),void 0===a||"millisecond"===a?this:("date"===a&&(a="day"),this.startOf(a).add(1,"isoWeek"===a?"week":a).subtract(1,"ms"))}function Fb(){return this._d.valueOf()-6e4*(this._offset||0)}function Gb(){return Math.floor(this.valueOf()/1e3)}function Hb(){return this._offset?new Date(this.valueOf()):this._d}function Ib(){var a=this;return[a.year(),a.month(),a.date(),a.hour(),a.minute(),a.second(),a.millisecond()]}function Jb(){var a=this;return{years:a.year(),months:a.month(),date:a.date(),hours:a.hours(),minutes:a.minutes(),seconds:a.seconds(),milliseconds:a.milliseconds()}}function Kb(){return this.isValid()?this.toISOString():null}function Lb(){return k(this)}function Mb(){return g({},j(this))}function Nb(){return j(this).overflow}function Ob(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}}function Pb(a,b){R(0,[a,a.length],0,b)}function Qb(a){return Ub.call(this,a,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)}function Rb(a){return Ub.call(this,a,this.isoWeek(),this.isoWeekday(),1,4)}function Sb(){return xa(this.year(),1,4)}function Tb(){var a=this.localeData()._week;return xa(this.year(),a.dow,a.doy)}function Ub(a,b,c,d,e){var f;return null==a?wa(this,d,e).year:(f=xa(a,d,e),b>f&&(b=f),Vb.call(this,a,b,c,d,e))}function Vb(a,b,c,d,e){var f=va(a,b,c,d,e),g=qa(f.year,0,f.dayOfYear);return this.year(g.getUTCFullYear()),this.month(g.getUTCMonth()),this.date(g.getUTCDate()),this}function Wb(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)}function Xb(a){return wa(a,this._week.dow,this._week.doy).week}function Yb(){return this._week.dow}function Zb(){return this._week.doy}function $b(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")}function _b(a){var b=wa(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")}function ac(a,b){return"string"!=typeof a?a:isNaN(a)?(a=b.weekdaysParse(a),"number"==typeof a?a:null):parseInt(a,10)}function bc(a,b){return c(this._weekdays)?this._weekdays[a.day()]:this._weekdays[this._weekdays.isFormat.test(b)?"format":"standalone"][a.day()]}function cc(a){return this._weekdaysShort[a.day()]}function dc(a){return this._weekdaysMin[a.day()]}function ec(a,b,c){var d,e,f,g=a.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],d=0;7>d;++d)f=h([2e3,1]).day(d),this._minWeekdaysParse[d]=this.weekdaysMin(f,"").toLocaleLowerCase(),this._shortWeekdaysParse[d]=this.weekdaysShort(f,"").toLocaleLowerCase(),this._weekdaysParse[d]=this.weekdays(f,"").toLocaleLowerCase();return c?"dddd"===b?(e=md.call(this._weekdaysParse,g),-1!==e?e:null):"ddd"===b?(e=md.call(this._shortWeekdaysParse,g),-1!==e?e:null):(e=md.call(this._minWeekdaysParse,g),-1!==e?e:null):"dddd"===b?(e=md.call(this._weekdaysParse,g),-1!==e?e:(e=md.call(this._shortWeekdaysParse,g),-1!==e?e:(e=md.call(this._minWeekdaysParse,g),-1!==e?e:null))):"ddd"===b?(e=md.call(this._shortWeekdaysParse,g),-1!==e?e:(e=md.call(this._weekdaysParse,g),-1!==e?e:(e=md.call(this._minWeekdaysParse,g),-1!==e?e:null))):(e=md.call(this._minWeekdaysParse,g),-1!==e?e:(e=md.call(this._weekdaysParse,g),-1!==e?e:(e=md.call(this._shortWeekdaysParse,g),-1!==e?e:null)))}function fc(a,b,c){var d,e,f;if(this._weekdaysParseExact)return ec.call(this,a,b,c);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),d=0;7>d;d++){if(e=h([2e3,1]).day(d),c&&!this._fullWeekdaysParse[d]&&(this._fullWeekdaysParse[d]=new RegExp("^"+this.weekdays(e,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[d]=new RegExp("^"+this.weekdaysShort(e,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[d]=new RegExp("^"+this.weekdaysMin(e,"").replace(".",".?")+"$","i")),this._weekdaysParse[d]||(f="^"+this.weekdays(e,"")+"|^"+this.weekdaysShort(e,"")+"|^"+this.weekdaysMin(e,""),this._weekdaysParse[d]=new RegExp(f.replace(".",""),"i")),c&&"dddd"===b&&this._fullWeekdaysParse[d].test(a))return d;if(c&&"ddd"===b&&this._shortWeekdaysParse[d].test(a))return d;if(c&&"dd"===b&&this._minWeekdaysParse[d].test(a))return d;if(!c&&this._weekdaysParse[d].test(a))return d}}function gc(a){if(!this.isValid())return null!=a?this:NaN;var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=ac(a,this.localeData()),this.add(a-b,"d")):b}function hc(a){if(!this.isValid())return null!=a?this:NaN;var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")}function ic(a){return this.isValid()?null==a?this.day()||7:this.day(this.day()%7?a:a-7):null!=a?this:NaN}function jc(a){return this._weekdaysParseExact?(f(this,"_weekdaysRegex")||mc.call(this),a?this._weekdaysStrictRegex:this._weekdaysRegex):this._weekdaysStrictRegex&&a?this._weekdaysStrictRegex:this._weekdaysRegex}function kc(a){return this._weekdaysParseExact?(f(this,"_weekdaysRegex")||mc.call(this),a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):this._weekdaysShortStrictRegex&&a?this._weekdaysShortStrictRegex:this._weekdaysShortRegex}function lc(a){return this._weekdaysParseExact?(f(this,"_weekdaysRegex")||mc.call(this),a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):this._weekdaysMinStrictRegex&&a?this._weekdaysMinStrictRegex:this._weekdaysMinRegex}function mc(){function a(a,b){return b.length-a.length}var b,c,d,e,f,g=[],i=[],j=[],k=[];for(b=0;7>b;b++)c=h([2e3,1]).day(b),d=this.weekdaysMin(c,""),e=this.weekdaysShort(c,""),f=this.weekdays(c,""),g.push(d),i.push(e),j.push(f),k.push(d),k.push(e),k.push(f);for(g.sort(a),i.sort(a),j.sort(a),k.sort(a),b=0;7>b;b++)i[b]=Z(i[b]),j[b]=Z(j[b]),k[b]=Z(k[b]);this._weekdaysRegex=new RegExp("^("+k.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+j.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+i.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+g.join("|")+")","i")}function nc(a){var b=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")}function oc(){return this.hours()%12||12}function pc(){return this.hours()||24}function qc(a,b){R(a,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),b)})}function rc(a,b){return b._meridiemParse}function sc(a){return"p"===(a+"").toLowerCase().charAt(0)}function tc(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"}function uc(a,b){b[Sd]=r(1e3*("0."+a))}function vc(){return this._isUTC?"UTC":""}function wc(){return this._isUTC?"Coordinated Universal Time":""}function xc(a){return Ka(1e3*a)}function yc(){return Ka.apply(null,arguments).parseZone()}function zc(a,b,c){var d=this._calendar[a];return w(d)?d.call(b,c):d}function Ac(a){var b=this._longDateFormat[a],c=this._longDateFormat[a.toUpperCase()];return b||!c?b:(this._longDateFormat[a]=c.replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a])}function Bc(){return this._invalidDate}function Cc(a){return this._ordinal.replace("%d",a)}function Dc(a){return a}function Ec(a,b,c,d){var e=this._relativeTime[c];return w(e)?e(a,b,c,d):e.replace(/%d/i,a)}function Fc(a,b){var c=this._relativeTime[a>0?"future":"past"];return w(c)?c(b):c.replace(/%s/i,b)}function Gc(a,b,c,d){var e=H(),f=h().set(d,b);return e[c](f,a)}function Hc(a,b,c){if("number"==typeof a&&(b=a,a=void 0),a=a||"",null!=b)return Gc(a,b,c,"month");var d,e=[];for(d=0;12>d;d++)e[d]=Gc(a,d,c,"month");return e}function Ic(a,b,c,d){"boolean"==typeof a?("number"==typeof b&&(c=b,b=void 0),b=b||""):(b=a,c=b,a=!1,"number"==typeof b&&(c=b,b=void 0),b=b||"");var e=H(),f=a?e._week.dow:0;if(null!=c)return Gc(b,(c+f)%7,d,"day");var g,h=[];for(g=0;7>g;g++)h[g]=Gc(b,(g+f)%7,d,"day");return h}function Jc(a,b){return Hc(a,b,"months")}function Kc(a,b){return Hc(a,b,"monthsShort")}function Lc(a,b,c){return Ic(a,b,c,"weekdays")}function Mc(a,b,c){return Ic(a,b,c,"weekdaysShort")}function Nc(a,b,c){return Ic(a,b,c,"weekdaysMin")}function Oc(){var a=this._data;return this._milliseconds=Le(this._milliseconds),this._days=Le(this._days),this._months=Le(this._months),a.milliseconds=Le(a.milliseconds),a.seconds=Le(a.seconds),a.minutes=Le(a.minutes),a.hours=Le(a.hours),a.months=Le(a.months),a.years=Le(a.years),this}function Pc(a,b,c,d){var e=db(b,c);return a._milliseconds+=d*e._milliseconds,a._days+=d*e._days,a._months+=d*e._months,a._bubble()}function Qc(a,b){return Pc(this,a,b,1)}function Rc(a,b){return Pc(this,a,b,-1)}function Sc(a){return 0>a?Math.floor(a):Math.ceil(a)}function Tc(){var a,b,c,d,e,f=this._milliseconds,g=this._days,h=this._months,i=this._data;return f>=0&&g>=0&&h>=0||0>=f&&0>=g&&0>=h||(f+=864e5*Sc(Vc(h)+g),g=0,h=0),i.milliseconds=f%1e3,a=q(f/1e3),i.seconds=a%60,b=q(a/60),i.minutes=b%60,c=q(b/60),i.hours=c%24,g+=q(c/24),e=q(Uc(g)),h+=e,g-=Sc(Vc(e)),d=q(h/12),h%=12,i.days=g,i.months=h,i.years=d,this}function Uc(a){return 4800*a/146097}function Vc(a){return 146097*a/4800}function Wc(a){var b,c,d=this._milliseconds;if(a=K(a),"month"===a||"year"===a)return b=this._days+d/864e5,c=this._months+Uc(b),"month"===a?c:c/12;switch(b=this._days+Math.round(Vc(this._months)),a){case"week":return b/7+d/6048e5;case"day":return b+d/864e5;case"hour":return 24*b+d/36e5;case"minute":return 1440*b+d/6e4;case"second":return 86400*b+d/1e3;case"millisecond":return Math.floor(864e5*b)+d;default:throw new Error("Unknown unit "+a)}}function Xc(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*r(this._months/12)}function Yc(a){return function(){return this.as(a)}}function Zc(a){
-return a=K(a),this[a+"s"]()}function $c(a){return function(){return this._data[a]}}function _c(){return q(this.days()/7)}function ad(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function bd(a,b,c){var d=db(a).abs(),e=_e(d.as("s")),f=_e(d.as("m")),g=_e(d.as("h")),h=_e(d.as("d")),i=_e(d.as("M")),j=_e(d.as("y")),k=e<af.s&&["s",e]||1>=f&&["m"]||f<af.m&&["mm",f]||1>=g&&["h"]||g<af.h&&["hh",g]||1>=h&&["d"]||h<af.d&&["dd",h]||1>=i&&["M"]||i<af.M&&["MM",i]||1>=j&&["y"]||["yy",j];return k[2]=b,k[3]=+a>0,k[4]=c,ad.apply(null,k)}function cd(a,b){return void 0===af[a]?!1:void 0===b?af[a]:(af[a]=b,!0)}function dd(a){var b=this.localeData(),c=bd(this,!a,b);return a&&(c=b.pastFuture(+this,c)),b.postformat(c)}function ed(){var a,b,c,d=bf(this._milliseconds)/1e3,e=bf(this._days),f=bf(this._months);a=q(d/60),b=q(a/60),d%=60,a%=60,c=q(f/12),f%=12;var g=c,h=f,i=e,j=b,k=a,l=d,m=this.asSeconds();return m?(0>m?"-":"")+"P"+(g?g+"Y":"")+(h?h+"M":"")+(i?i+"D":"")+(j||k||l?"T":"")+(j?j+"H":"")+(k?k+"M":"")+(l?l+"S":""):"P0D"}var fd,gd;gd=Array.prototype.some?Array.prototype.some:function(a){for(var b=Object(this),c=b.length>>>0,d=0;c>d;d++)if(d in b&&a.call(this,b[d],d,b))return!0;return!1};var hd=a.momentProperties=[],id=!1,jd={};a.suppressDeprecationWarnings=!1,a.deprecationHandler=null;var kd;kd=Object.keys?Object.keys:function(a){var b,c=[];for(b in a)f(a,b)&&c.push(b);return c};var ld,md,nd={},od={},pd=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,qd=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,rd={},sd={},td=/\d/,ud=/\d\d/,vd=/\d{3}/,wd=/\d{4}/,xd=/[+-]?\d{6}/,yd=/\d\d?/,zd=/\d\d\d\d?/,Ad=/\d\d\d\d\d\d?/,Bd=/\d{1,3}/,Cd=/\d{1,4}/,Dd=/[+-]?\d{1,6}/,Ed=/\d+/,Fd=/[+-]?\d+/,Gd=/Z|[+-]\d\d:?\d\d/gi,Hd=/Z|[+-]\d\d(?::?\d\d)?/gi,Id=/[+-]?\d+(\.\d{1,3})?/,Jd=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,Kd={},Ld={},Md=0,Nd=1,Od=2,Pd=3,Qd=4,Rd=5,Sd=6,Td=7,Ud=8;md=Array.prototype.indexOf?Array.prototype.indexOf:function(a){var b;for(b=0;b<this.length;++b)if(this[b]===a)return b;return-1},R("M",["MM",2],"Mo",function(){return this.month()+1}),R("MMM",0,0,function(a){return this.localeData().monthsShort(this,a)}),R("MMMM",0,0,function(a){return this.localeData().months(this,a)}),J("month","M"),W("M",yd),W("MM",yd,ud),W("MMM",function(a,b){return b.monthsShortRegex(a)}),W("MMMM",function(a,b){return b.monthsRegex(a)}),$(["M","MM"],function(a,b){b[Nd]=r(a)-1}),$(["MMM","MMMM"],function(a,b,c,d){var e=c._locale.monthsParse(a,d,c._strict);null!=e?b[Nd]=e:j(c).invalidMonth=a});var Vd=/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/,Wd="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),Xd="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),Yd=Jd,Zd=Jd,$d=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,_d=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,ae=/Z|[+-]\d\d(?::?\d\d)?/,be=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],ce=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],de=/^\/?Date\((\-?\d+)/i;a.createFromInputFallback=u("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),R("Y",0,0,function(){var a=this.year();return 9999>=a?""+a:"+"+a}),R(0,["YY",2],0,function(){return this.year()%100}),R(0,["YYYY",4],0,"year"),R(0,["YYYYY",5],0,"year"),R(0,["YYYYYY",6,!0],0,"year"),J("year","y"),W("Y",Fd),W("YY",yd,ud),W("YYYY",Cd,wd),W("YYYYY",Dd,xd),W("YYYYYY",Dd,xd),$(["YYYYY","YYYYYY"],Md),$("YYYY",function(b,c){c[Md]=2===b.length?a.parseTwoDigitYear(b):r(b)}),$("YY",function(b,c){c[Md]=a.parseTwoDigitYear(b)}),$("Y",function(a,b){b[Md]=parseInt(a,10)}),a.parseTwoDigitYear=function(a){return r(a)+(r(a)>68?1900:2e3)};var ee=M("FullYear",!0);a.ISO_8601=function(){};var fe=u("moment().min is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(){var a=Ka.apply(null,arguments);return this.isValid()&&a.isValid()?this>a?this:a:l()}),ge=u("moment().max is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(){var a=Ka.apply(null,arguments);return this.isValid()&&a.isValid()?a>this?this:a:l()}),he=function(){return Date.now?Date.now():+new Date};Qa("Z",":"),Qa("ZZ",""),W("Z",Hd),W("ZZ",Hd),$(["Z","ZZ"],function(a,b,c){c._useUTC=!0,c._tzm=Ra(Hd,a)});var ie=/([\+\-]|\d\d)/gi;a.updateOffset=function(){};var je=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?\d*)?$/,ke=/^(-)?P(?:(-?[0-9,.]*)Y)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)W)?(?:(-?[0-9,.]*)D)?(?:T(?:(-?[0-9,.]*)H)?(?:(-?[0-9,.]*)M)?(?:(-?[0-9,.]*)S)?)?$/;db.fn=Oa.prototype;var le=ib(1,"add"),me=ib(-1,"subtract");a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ",a.defaultFormatUtc="YYYY-MM-DDTHH:mm:ss[Z]";var ne=u("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(a){return void 0===a?this.localeData():this.locale(a)});R(0,["gg",2],0,function(){return this.weekYear()%100}),R(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Pb("gggg","weekYear"),Pb("ggggg","weekYear"),Pb("GGGG","isoWeekYear"),Pb("GGGGG","isoWeekYear"),J("weekYear","gg"),J("isoWeekYear","GG"),W("G",Fd),W("g",Fd),W("GG",yd,ud),W("gg",yd,ud),W("GGGG",Cd,wd),W("gggg",Cd,wd),W("GGGGG",Dd,xd),W("ggggg",Dd,xd),_(["gggg","ggggg","GGGG","GGGGG"],function(a,b,c,d){b[d.substr(0,2)]=r(a)}),_(["gg","GG"],function(b,c,d,e){c[e]=a.parseTwoDigitYear(b)}),R("Q",0,"Qo","quarter"),J("quarter","Q"),W("Q",td),$("Q",function(a,b){b[Nd]=3*(r(a)-1)}),R("w",["ww",2],"wo","week"),R("W",["WW",2],"Wo","isoWeek"),J("week","w"),J("isoWeek","W"),W("w",yd),W("ww",yd,ud),W("W",yd),W("WW",yd,ud),_(["w","ww","W","WW"],function(a,b,c,d){b[d.substr(0,1)]=r(a)});var oe={dow:0,doy:6};R("D",["DD",2],"Do","date"),J("date","D"),W("D",yd),W("DD",yd,ud),W("Do",function(a,b){return a?b._ordinalParse:b._ordinalParseLenient}),$(["D","DD"],Od),$("Do",function(a,b){b[Od]=r(a.match(yd)[0],10)});var pe=M("Date",!0);R("d",0,"do","day"),R("dd",0,0,function(a){return this.localeData().weekdaysMin(this,a)}),R("ddd",0,0,function(a){return this.localeData().weekdaysShort(this,a)}),R("dddd",0,0,function(a){return this.localeData().weekdays(this,a)}),R("e",0,0,"weekday"),R("E",0,0,"isoWeekday"),J("day","d"),J("weekday","e"),J("isoWeekday","E"),W("d",yd),W("e",yd),W("E",yd),W("dd",function(a,b){return b.weekdaysMinRegex(a)}),W("ddd",function(a,b){return b.weekdaysShortRegex(a)}),W("dddd",function(a,b){return b.weekdaysRegex(a)}),_(["dd","ddd","dddd"],function(a,b,c,d){var e=c._locale.weekdaysParse(a,d,c._strict);null!=e?b.d=e:j(c).invalidWeekday=a}),_(["d","e","E"],function(a,b,c,d){b[d]=r(a)});var qe="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),re="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),se="Su_Mo_Tu_We_Th_Fr_Sa".split("_"),te=Jd,ue=Jd,ve=Jd;R("DDD",["DDDD",3],"DDDo","dayOfYear"),J("dayOfYear","DDD"),W("DDD",Bd),W("DDDD",vd),$(["DDD","DDDD"],function(a,b,c){c._dayOfYear=r(a)}),R("H",["HH",2],0,"hour"),R("h",["hh",2],0,oc),R("k",["kk",2],0,pc),R("hmm",0,0,function(){return""+oc.apply(this)+Q(this.minutes(),2)}),R("hmmss",0,0,function(){return""+oc.apply(this)+Q(this.minutes(),2)+Q(this.seconds(),2)}),R("Hmm",0,0,function(){return""+this.hours()+Q(this.minutes(),2)}),R("Hmmss",0,0,function(){return""+this.hours()+Q(this.minutes(),2)+Q(this.seconds(),2)}),qc("a",!0),qc("A",!1),J("hour","h"),W("a",rc),W("A",rc),W("H",yd),W("h",yd),W("HH",yd,ud),W("hh",yd,ud),W("hmm",zd),W("hmmss",Ad),W("Hmm",zd),W("Hmmss",Ad),$(["H","HH"],Pd),$(["a","A"],function(a,b,c){c._isPm=c._locale.isPM(a),c._meridiem=a}),$(["h","hh"],function(a,b,c){b[Pd]=r(a),j(c).bigHour=!0}),$("hmm",function(a,b,c){var d=a.length-2;b[Pd]=r(a.substr(0,d)),b[Qd]=r(a.substr(d)),j(c).bigHour=!0}),$("hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[Pd]=r(a.substr(0,d)),b[Qd]=r(a.substr(d,2)),b[Rd]=r(a.substr(e)),j(c).bigHour=!0}),$("Hmm",function(a,b,c){var d=a.length-2;b[Pd]=r(a.substr(0,d)),b[Qd]=r(a.substr(d))}),$("Hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[Pd]=r(a.substr(0,d)),b[Qd]=r(a.substr(d,2)),b[Rd]=r(a.substr(e))});var we=/[ap]\.?m?\.?/i,xe=M("Hours",!0);R("m",["mm",2],0,"minute"),J("minute","m"),W("m",yd),W("mm",yd,ud),$(["m","mm"],Qd);var ye=M("Minutes",!1);R("s",["ss",2],0,"second"),J("second","s"),W("s",yd),W("ss",yd,ud),$(["s","ss"],Rd);var ze=M("Seconds",!1);R("S",0,0,function(){return~~(this.millisecond()/100)}),R(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),R(0,["SSS",3],0,"millisecond"),R(0,["SSSS",4],0,function(){return 10*this.millisecond()}),R(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),R(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),R(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),R(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),R(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),J("millisecond","ms"),W("S",Bd,td),W("SS",Bd,ud),W("SSS",Bd,vd);var Ae;for(Ae="SSSS";Ae.length<=9;Ae+="S")W(Ae,Ed);for(Ae="S";Ae.length<=9;Ae+="S")$(Ae,uc);var Be=M("Milliseconds",!1);R("z",0,0,"zoneAbbr"),R("zz",0,0,"zoneName");var Ce=o.prototype;Ce.add=le,Ce.calendar=kb,Ce.clone=lb,Ce.diff=sb,Ce.endOf=Eb,Ce.format=wb,Ce.from=xb,Ce.fromNow=yb,Ce.to=zb,Ce.toNow=Ab,Ce.get=P,Ce.invalidAt=Nb,Ce.isAfter=mb,Ce.isBefore=nb,Ce.isBetween=ob,Ce.isSame=pb,Ce.isSameOrAfter=qb,Ce.isSameOrBefore=rb,Ce.isValid=Lb,Ce.lang=ne,Ce.locale=Bb,Ce.localeData=Cb,Ce.max=ge,Ce.min=fe,Ce.parsingFlags=Mb,Ce.set=P,Ce.startOf=Db,Ce.subtract=me,Ce.toArray=Ib,Ce.toObject=Jb,Ce.toDate=Hb,Ce.toISOString=vb,Ce.toJSON=Kb,Ce.toString=ub,Ce.unix=Gb,Ce.valueOf=Fb,Ce.creationData=Ob,Ce.year=ee,Ce.isLeapYear=ta,Ce.weekYear=Qb,Ce.isoWeekYear=Rb,Ce.quarter=Ce.quarters=Wb,Ce.month=ha,Ce.daysInMonth=ia,Ce.week=Ce.weeks=$b,Ce.isoWeek=Ce.isoWeeks=_b,Ce.weeksInYear=Tb,Ce.isoWeeksInYear=Sb,Ce.date=pe,Ce.day=Ce.days=gc,Ce.weekday=hc,Ce.isoWeekday=ic,Ce.dayOfYear=nc,Ce.hour=Ce.hours=xe,Ce.minute=Ce.minutes=ye,Ce.second=Ce.seconds=ze,Ce.millisecond=Ce.milliseconds=Be,Ce.utcOffset=Ua,Ce.utc=Wa,Ce.local=Xa,Ce.parseZone=Ya,Ce.hasAlignedHourOffset=Za,Ce.isDST=$a,Ce.isDSTShifted=_a,Ce.isLocal=ab,Ce.isUtcOffset=bb,Ce.isUtc=cb,Ce.isUTC=cb,Ce.zoneAbbr=vc,Ce.zoneName=wc,Ce.dates=u("dates accessor is deprecated. Use date instead.",pe),Ce.months=u("months accessor is deprecated. Use month instead",ha),Ce.years=u("years accessor is deprecated. Use year instead",ee),Ce.zone=u("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",Va);var De=Ce,Ee={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},Fe={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},Ge="Invalid date",He="%d",Ie=/\d{1,2}/,Je={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},Ke=A.prototype;Ke._calendar=Ee,Ke.calendar=zc,Ke._longDateFormat=Fe,Ke.longDateFormat=Ac,Ke._invalidDate=Ge,Ke.invalidDate=Bc,Ke._ordinal=He,Ke.ordinal=Cc,Ke._ordinalParse=Ie,Ke.preparse=Dc,Ke.postformat=Dc,Ke._relativeTime=Je,Ke.relativeTime=Ec,Ke.pastFuture=Fc,Ke.set=y,Ke.months=ca,Ke._months=Wd,Ke.monthsShort=da,Ke._monthsShort=Xd,Ke.monthsParse=fa,Ke._monthsRegex=Zd,Ke.monthsRegex=ka,Ke._monthsShortRegex=Yd,Ke.monthsShortRegex=ja,Ke.week=Xb,Ke._week=oe,Ke.firstDayOfYear=Zb,Ke.firstDayOfWeek=Yb,Ke.weekdays=bc,Ke._weekdays=qe,Ke.weekdaysMin=dc,Ke._weekdaysMin=se,Ke.weekdaysShort=cc,Ke._weekdaysShort=re,Ke.weekdaysParse=fc,Ke._weekdaysRegex=te,Ke.weekdaysRegex=jc,Ke._weekdaysShortRegex=ue,Ke.weekdaysShortRegex=kc,Ke._weekdaysMinRegex=ve,Ke.weekdaysMinRegex=lc,Ke.isPM=sc,Ke._meridiemParse=we,Ke.meridiem=tc,E("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===r(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),a.lang=u("moment.lang is deprecated. Use moment.locale instead.",E),a.langData=u("moment.langData is deprecated. Use moment.localeData instead.",H);var Le=Math.abs,Me=Yc("ms"),Ne=Yc("s"),Oe=Yc("m"),Pe=Yc("h"),Qe=Yc("d"),Re=Yc("w"),Se=Yc("M"),Te=Yc("y"),Ue=$c("milliseconds"),Ve=$c("seconds"),We=$c("minutes"),Xe=$c("hours"),Ye=$c("days"),Ze=$c("months"),$e=$c("years"),_e=Math.round,af={s:45,m:45,h:22,d:26,M:11},bf=Math.abs,cf=Oa.prototype;cf.abs=Oc,cf.add=Qc,cf.subtract=Rc,cf.as=Wc,cf.asMilliseconds=Me,cf.asSeconds=Ne,cf.asMinutes=Oe,cf.asHours=Pe,cf.asDays=Qe,cf.asWeeks=Re,cf.asMonths=Se,cf.asYears=Te,cf.valueOf=Xc,cf._bubble=Tc,cf.get=Zc,cf.milliseconds=Ue,cf.seconds=Ve,cf.minutes=We,cf.hours=Xe,cf.days=Ye,cf.weeks=_c,cf.months=Ze,cf.years=$e,cf.humanize=dd,cf.toISOString=ed,cf.toString=ed,cf.toJSON=ed,cf.locale=Bb,cf.localeData=Cb,cf.toIsoString=u("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",ed),cf.lang=ne,R("X",0,0,"unix"),R("x",0,0,"valueOf"),W("x",Fd),W("X",Id),$("X",function(a,b,c){c._d=new Date(1e3*parseFloat(a,10))}),$("x",function(a,b,c){c._d=new Date(r(a))}),a.version="2.13.0",b(Ka),a.fn=De,a.min=Ma,a.max=Na,a.now=he,a.utc=h,a.unix=xc,a.months=Jc,a.isDate=d,a.locale=E,a.invalid=l,a.duration=db,a.isMoment=p,a.weekdays=Lc,a.parseZone=yc,a.localeData=H,a.isDuration=Pa,a.monthsShort=Kc,a.weekdaysMin=Nc,a.defineLocale=F,a.updateLocale=G,a.locales=I,a.weekdaysShort=Mc,a.normalizeUnits=K,a.relativeTimeThreshold=cd,a.prototype=De;var df=a;return df}); \ No newline at end of file
diff --git a/tools/infra-dashboard/js/script.js b/tools/infra-dashboard/js/script.js
deleted file mode 100644
index 07c832a2..00000000
--- a/tools/infra-dashboard/js/script.js
+++ /dev/null
@@ -1,27 +0,0 @@
-jQuery(document).ready(function () {
- // If svg is not supported
- if (!Modernizr.svg) {
- jQuery('img[src$=".svg"]').each(function() {
- jQuery(this).attr('src', jQuery(this).attr('src').replace('.svg', '.png'));
- });
- }
- // If media queries are not supported
- if(!Modernizr.mq('only all')) {
- jQuery('head').append('<link id="no-mq" rel="stylesheet" type="text/css">');
- jQuery("link#no-mq").attr("href", "/joomla/media/templates/highsoft_bootstrap/css/ie.css");
- }
- // Sidebar click animation
- jQuery('.nav-sidebar > li').click(function () {
- if (!jQuery(this).hasClass("active")) {
- jQuery('.nav-sidebar > li.active > div.active').removeClass('active');
- jQuery('.nav-sidebar > li.active > ul').slideUp("slow");
- jQuery('.nav-sidebar > li.active').removeClass('active');
- jQuery(this).addClass("active");
- jQuery('.nav-sidebar > li.active > ul').slideDown("slow");
- jQuery('.nav-sidebar > li.active > div').addClass('active');
- }
- });
- jQuery("#sidebar-toggle").click(function (e) {
- jQuery("#wrap").toggleClass("toggled");
- });
-}); \ No newline at end of file
diff --git a/tools/infra-dashboard/js/test_graph.js b/tools/infra-dashboard/js/test_graph.js
deleted file mode 100644
index 1d1d5e43..00000000
--- a/tools/infra-dashboard/js/test_graph.js
+++ /dev/null
@@ -1,108 +0,0 @@
-$(function () {
-
- // Get the CSV and create the chart
- $.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=analytics.csv&callback=?', function (csv) {
-
- $('#container').highcharts({
-
- data: {
- csv: csv
- },
-
- title: {
- text: 'Daily visits at www.highcharts.com'
- },
-
- subtitle: {
- text: 'Source: Google Analytics'
- },
-
- xAxis: {
- tickInterval: 7 * 24 * 3600 * 1000, // one week
- tickWidth: 0,
- gridLineWidth: 1,
- labels: {
- align: 'left',
- x: 3,
- y: -3
- }
- },
-
- yAxis: [{ // left y axis
- title: {
- text: null
- },
- labels: {
- align: 'left',
- x: 3,
- y: 16,
- format: '{value:.,0f}'
- },
- showFirstLabel: false
- }, { // right y axis
- linkedTo: 0,
- gridLineWidth: 0,
- opposite: true,
- title: {
- text: null
- },
- labels: {
- align: 'right',
- x: -3,
- y: 16,
- format: '{value:.,0f}'
- },
- showFirstLabel: false
- }],
-
- legend: {
- align: 'left',
- verticalAlign: 'top',
- y: 20,
- floating: true,
- borderWidth: 0
- },
-
- tooltip: {
- shared: true,
- crosshairs: true
- },
-
- plotOptions: {
- series: {
- cursor: 'pointer',
- point: {
- events: {
- click: function (e) {
- hs.htmlExpand(null, {
- pageOrigin: {
- x: e.pageX || e.clientX,
- y: e.pageY || e.clientY
- },
- headingText: this.series.name,
- maincontentText: Highcharts.dateFormat('%A, %b %e, %Y', this.x) + ':<br/> ' +
- this.y + ' visits',
- width: 200
- });
- }
- }
- },
- marker: {
- lineWidth: 1
- }
- }
- },
-
- series: [{
- name: 'All visits',
- lineWidth: 4,
- marker: {
- radius: 4
- }
- }, {
- name: 'New visitors'
- }]
- });
- });
-
-});
diff --git a/tools/infra-dashboard/media/ajax-loader.gif b/tools/infra-dashboard/media/ajax-loader.gif
deleted file mode 100644
index 3c2f7c05..00000000
--- a/tools/infra-dashboard/media/ajax-loader.gif
+++ /dev/null
Binary files differ
diff --git a/tools/infra-dashboard/media/collaborative-projects-logo.png b/tools/infra-dashboard/media/collaborative-projects-logo.png
deleted file mode 100644
index 195ad081..00000000
--- a/tools/infra-dashboard/media/collaborative-projects-logo.png
+++ /dev/null
Binary files differ
diff --git a/tools/infra-dashboard/media/diagonal-white.png b/tools/infra-dashboard/media/diagonal-white.png
deleted file mode 100644
index 9772997c..00000000
--- a/tools/infra-dashboard/media/diagonal-white.png
+++ /dev/null
Binary files differ
diff --git a/tools/infra-dashboard/media/favicon_400x400.jpg b/tools/infra-dashboard/media/favicon_400x400.jpg
deleted file mode 100644
index a45d1bf2..00000000
--- a/tools/infra-dashboard/media/favicon_400x400.jpg
+++ /dev/null
Binary files differ
diff --git a/tools/infra-dashboard/media/loader.white.gif b/tools/infra-dashboard/media/loader.white.gif
deleted file mode 100644
index f2a1bc0c..00000000
--- a/tools/infra-dashboard/media/loader.white.gif
+++ /dev/null
Binary files differ
diff --git a/tools/infra-dashboard/media/opnfvlogo.JPG b/tools/infra-dashboard/media/opnfvlogo.JPG
deleted file mode 100644
index ef3fe355..00000000
--- a/tools/infra-dashboard/media/opnfvlogo.JPG
+++ /dev/null
Binary files differ
diff --git a/tools/infra-dashboard/pages/ci_pods.php b/tools/infra-dashboard/pages/ci_pods.php
deleted file mode 100644
index 5f51530d..00000000
--- a/tools/infra-dashboard/pages/ci_pods.php
+++ /dev/null
@@ -1,91 +0,0 @@
-<script type="text/javascript">
- $(document).ready(function() {
- $('#example').DataTable( {
- "order": [[ 3, "desc" ],[ 2, "desc" ]]
- } );
- } );
-</script>
-
-<?php
- include '../utils/jenkinsAdapter.php';
- include '../utils/database.php';
-
- connectDB();
- $result = mysql_query("SELECT * FROM resource, pod WHERE resource.resource_id=pod.resource_id;");
- closeDB();
-
- echo '<table id="example" class="table table-striped table-bordered" cellspacing="0" width="100%">';
- echo "<thead>";
- echo "<tr>";
- echo "<th>Name</th>";
- echo "<th>Slave Name</th>";
- echo "<th>Status</th>";
- echo "<th>Installer</th>";
- echo "<th>Scenario</th>";
- echo "<th>Branch</th>";
- echo "<th>Job</th>";
- echo "</tr>";
- echo "</thead>";
- echo "<tbody>";
-
- while ($row = mysql_fetch_array($result)) {
- $slave = $row{'slavename'};
- if (! isCiPod($slave)) continue;
-
- $slave_url = getSlaveUrl($slave);
- $status = getSlaveStatus($slave);
-
- $job_name = "";
- $job_installer = "";
- $job_branch = "";
- $job_url = "";
- $job_scenario = "";
- $job_type = "";
-
- if ($status == 'online'){
- $job_params = getJJob($slave);
- $job_name = $job_params['name'];
- $job_installer = $job_params['installer'];
- $job_branch = $job_params['branch'];
- $job_url = $job_params['url']."lastBuild/consoleFull";
- $job_scenario = $job_params['scenario'];
- $job_type = $job_params['type'];
- }
-
- echo "<tr>";
- echo "<th><a target='_blank' href='".$row{'link'}."'>".$row{'name'}."</a></th>";
- echo "<th><a target='_blank' href='".$slave_url."'>".$slave."</a></th>";
- if ($status == "online") $color = "#BEFAAA";
- else $color = "#FAAAAB";
- echo "<th style='background-color: ".$color.";'>".$status."</th>";
- if ($job_type == "0") $class = "blink_me";
- else $class="";
- echo "<th class='".$class."'>".$job_installer."</th>";
- echo "<th class='".$class."'>".$job_scenario."</th>";
- echo "<th class='".$class."'>".$job_branch."</th>";
- $green = '#33cc00';
- $grey = '#646F73';
- $red = '#FF5555';
- $orange = '#EDD62B';
- if ($job_type == "0") { // job running
- echo "<th><a class='blink_me' style='font-size:12px;color:".$grey.";' target='_blank' href='".$job_url."'>".$job_name."</a></th>";
- }
- else if ($job_type == "1") {// last job successful
- echo "<th><a style='font-size:12px;color:".$green.";' target='_blank' href='".$job_url."'>".$job_name."</a></th>";
- }
- else if ($job_type == "2") {// last job failed
- echo "<th><a style='font-size:12px;color:".$red."' target='_blank' href='".$job_url."'>".$job_name."</a></th>";
- }
- else if ($job_type == "3") {// last job is unstable
- echo "<th><a style='font-size:12px;color:".$orange."' target='_blank' href='".$job_url."'>".$job_name."</a></th>";
- }
- else {
- echo "<th><a style='font-size:12px;' target='_blank' href='".$job_url."'>".$job_name."</a></th>";
- }
- echo "</tr>";
- }
- echo '</tbody>';
- echo '</table>';
-
-
-?>
diff --git a/tools/infra-dashboard/pages/dev_pods.php b/tools/infra-dashboard/pages/dev_pods.php
deleted file mode 100644
index 144504b5..00000000
--- a/tools/infra-dashboard/pages/dev_pods.php
+++ /dev/null
@@ -1,342 +0,0 @@
-<?php
- // trick for the calendar object, if we use always the same id name, it doesn't work properly
- $random = time();
- $calendar_id = "calendar_".$random;
-?>
-
-
-<script type="text/javascript">
- $(document).ready(function() {
- $('#example').DataTable( {
- "order": [[ 2, "desc" ],[ 5, "desc"]]
- } );
- var date = new Date();
- var d = date.getDate();
- var m = date.getMonth();
- var y = date.getFullYear();
- } );
-
- $(function() {
- var dialog, form,
-
- // From http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#e-mail-state-%28type=email%29
- emailRegex = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
- email = $( "#email" ),
- password = $( "#password" ),
- allFields = $( [] ).add( email ).add( password ),
- tips = $( ".validateTips" );
-
- function updateTips( t ) {
- tips
- .text( t )
- .addClass( "ui-state-highlight" );
- setTimeout(function() {
- tips.removeClass( "ui-state-highlight", 1500 );
- }, 500 );
- }
-
- function checkLength( o, n, min, max ) {
- if ( o.val().length > max || o.val().length < min ) {
- o.addClass( "ui-state-error" );
- updateTips( "Length of " + n + " must be between " +
- min + " and " + max + "." );
- return false;
- } else {
- return true;
- }
- }
-
- function checkRegexp( o, regexp, n ) {
- if ( !( regexp.test( o.val() ) ) ) {
- o.addClass( "ui-state-error" );
- updateTips( n );
- return false;
- } else {
- return true;
- }
- }
-
- function bookResource() {
- var user_id = $('#hd_user_id').val();
- if (user_id == "") {
- alert ("Only registered users can book.");
- return;
- }
- var resource_id = $('#resource_id').val();
- var resource_name = $('#resource_name').val();
- var purpose = $('#purpose').val();
- var starttime = $('#starttime').val();
- var endtime = $('#endtime').val();
- $.ajax({
- type: 'POST',
- url: "utils/book.php",
- data: {action: 'book', resource_id: resource_id, resource_name: resource_name, user_id: user_id, start: starttime, end: endtime, purpose: purpose, start: starttime, end: endtime},
- success: function(data){
- if (data == "1") alert("Booking not possible (your account is not associated with a role). Please contact the administrator.");
- else if (data == "2") alert("You are not allowed to book this resource.");
- else {
- alert(data)
- //location.reload();
- var href = document.location.protocol +"//"+ document.location.hostname + document.location.pathname
- location.href = href + "?page=devpods"
- }
- },
- errpr: function(data){
- alert("error")
- }
-
- });
-
- dialog.dialog( "close" );
- return true;
- }
-
- dialog = $( "#dialog-form" ).dialog({
- autoOpen: false,
- height: 800,
- width: 900,
- modal: true,
- resizable:false,
- buttons: {
- "Book": bookResource,
- Cancel: function() {
- dialog.dialog( "close" );
- $('#starttime').attr('value', "");
- $('#endtime').attr('value', "");
- $('#purpose').attr('value', "");
- $(".ui-dialog-buttonpane button:contains('Book')").attr("disabled", true)
- .addClass("ui-state-disabled");
- }
- },
- close: function() {
- form[ 0 ].reset();
- allFields.removeClass( "ui-state-error" );
- }
- });
-
- form = dialog.find( "form" ).on( "submit", function( event ) {
- event.preventDefault();
- bookResource();
- });
-
- $(".ui-dialog-buttonpane button:contains('Book')").attr("disabled", true)
- .addClass("ui-state-disabled");
- dialog_event = $( "#dialog_event" ).dialog({
- autoOpen: false,
- height: 400,
- width: 420,
- modal: true,
- resizable:false,
- buttons: {
- Close: function() {
- dialog_event.dialog( "close" );
- },
- "Release": function() {
- alert("Not working yet.");
- }
- },
- });
-
-
- $( ".btn-book" ).button().on( "click", function() {
- var resource_id = $(this).attr('id');
- var resource_name = $(this).attr('value');
- $('#resource_id').attr('value', resource_id);
- $('#resource_name').attr('value', resource_name);
- var title = "Book resource: ".concat(resource_name);
- var calendar_id = '<?=$calendar_id?>';
- $('#<?=$calendar_id?>').fullCalendar( 'destroy' );
- $.ajax({
- type: 'POST',
- url: "utils/book.php",
- data: {action: 'getBookedDates', resource_id: resource_id},
-
- success: function(data){
- //if (data != "") {
- var calendarOptions = {
- height: 660,
- header: {
- left: 'prev,next today',
- center: 'title',
- right: 'agendaWeek,month'
- },
- defaultView: 'agendaWeek',
- slotDuration: '00:60:00',
- slotLabelFormat:"HH:mm",
- firstDay: 1,
- nowIndicator: true,
- allDaySlot: false,
- selectOverlap: false,
- selectable: true,
- selectHelper: true,
- editable: false,
- timezone: 'UTC',
- eventStartEditable: false,
- eventDurationEditable: false,
- events: jQuery.parseJSON( data ),
- select: function(start, end) {
- var view = $('#<?=$calendar_id?>').fullCalendar('getView');
- if (view.name == "month") return
- var title = prompt('Purpose of this booking:');
- var eventData;
- var provisional_id = "537818F62BC63518ECE15338FB86C8BE";
- if (title) {
- $('#<?=$calendar_id?>').fullCalendar('removeEvents',provisional_id);
- eventData = {
- id: provisional_id,
- title: title,
- start: start,
- end: end
- };
- start=moment(start).format('YYYY-MM-DD HH:mm:ss');
- end=moment(end).format('YYYY-MM-DD HH:mm:ss');
- $('#<?=$calendar_id?>').fullCalendar('renderEvent', eventData, true); // stick? = true
- $('#starttime').attr('value', start);
- $('#endtime').attr('value', end);
- $('#purpose').attr('value', title);
- $(".ui-dialog-buttonpane button:contains('Book')").attr("disabled", false)
- .removeClass("ui-state-disabled");
- }
- $('#<?=$calendar_id?>').fullCalendar('unselect');
-
- },
- eventLimit: true, // allow "more" link when too many events
- timeFormat: 'H(:mm)', // uppercase H for 24-hour clock
- eventClick: function(event) {
- $('#dg-start').text(event.start);
- $('#dg-end').text(event.end);
- $('#dg-booker-email').text(event.booker_email);
- $('#dg-purpose').text(event.title);
- dialog_event.dialog( "open" );
- }
- }
- $('#<?=$calendar_id?>').fullCalendar(calendarOptions);
- $('#<?=$calendar_id?>').fullCalendar('render');
- //}
- //else {
- // if first time (it has never been booked)
- // $('#<?=$calendar_id?>').fullCalendar('removeEventSource');
- //}
- },
- error: function(data){
- alert("error getting booked dates.");
- }
-
- });
- dialog.dialog( 'option', 'title', title);
- dialog.dialog( "open" );
- ///$('#<?=$calendar_id?>').fullCalendar( 'rerenderEvents' )
- });
- });
-</script>
-
-<style>
- .fc-divider {
- display:none !important;
- }
-</style>
-
-<?php
-
- include '../utils/jenkinsAdapter.php';
- include '../utils/database.php';
-
- connectDB();
- //$q = "select r.ID,r.NAME,r.LINK,r.DESCR,r.ACTIVE,b.BOOKEDBY,b.BOOKEDFROM,b.BOOKEDUNTIL,b.PURPOSE from resource r left join booking b on r.ID = b.RES_Id and now() between b.BOOKEDFROM and b.BOOKEDUNTIL where r.TYPE=2;";
- $q = "SELECT r.resource_id,r.name as resname,r.slavename, r.link,u.user_id,u.name as username,u.email,b.starttime,b.endtime,b.purpose from resource r LEFT JOIN pod p LEFT JOIN booking b INNER JOIN user u ON u.user_id = b.user_id ON b.resource_id = p.resource_id AND now() > b.starttime AND now() <= b.endtime ON r.resource_id = p.resource_id;";
- $result = mysql_query($q);
-
- //SELECT r.name as resname,r.slavename, r.link, r.resource_id,u.user_id,u.name as username,u.email,b.starttime,b.endtime,b.purpose from resource r LEFT JOIN pod p LEFT JOIN booking b INNER JOIN user u ON u.user_id = b.user_id ON b.resource_id = p.resource_id AND now() > b.starttime AND now() <= b.endtime ON r.resource_id = p.resource_id WHERE type_id=2;
- closeDB();
-
- echo '<table id="example" class="table table-striped table-bordered" cellspacing="0" width="100%">';
- echo "<thead>";
- echo "<tr>";
- echo "<th>Name</th>";
- echo "<th>Slave Name</th>";
- echo "<th>Booked by</th>";
- echo "<th>Booked until</th>";
- echo "<th>Purpose</th>";
- echo "<th>Status</th>";
- echo "<th></th>";
- echo "</tr>";
- echo "</thead>";
- echo "<tbody>";
-
- while ($row = mysql_fetch_array($result)) {
- $slave = $row{'slavename'};
- if (! isDevPod($slave)) continue;
-
- $slave_url = getSlaveUrl($slave);
- $status = getSlaveStatus($slave);
- echo "<tr>";
- echo "<th><a target='_blank' href='".$row{'link'}."'>".$row{'resname'}."</a></th>";
- echo "<th><a target='_blank' href='".$slave_url."'>".$slave."</a></th>";
- if ($row{'username'} != "") $booker = $row{'username'};
- else $booker="-";
- echo "<th>".$booker."</th>";
-
- if ($row{'endtime'} != "") {
- $until = strtotime($row{'endtime'});
- echo "<th>".date('d/M/Y', $until)."</th>";
- //$until = $row{'endtime'};
- } else {
- $until="-";
- echo "<th>".$until."</th>";
- }
- if ($row{'purpose'} != "") $purpose = $row{'purpose'};
- else $purpose="-";
- echo "<th>".$purpose."</th>";
- $active = 'true';
- if ($status == "online") $color = "#BEFAAA";
- else $color = "#FAAAAB";
- echo "<th style='background-color: ".$color.";'>".$status."</th>";
-
- echo "<th><button id='".$row{'resource_id'}."' value='".$row{'slavename'}."' class='btn-book' type='button'>Book</button></th>";
- echo "</tr>";
- }
- echo '</tbody>';
- echo '</table>';
-?>
-
-
-<div id="dialog-form" title="Book resource">
- <form>
- <div id='<?=$calendar_id?>' style="margin-top:10px"></div>
- <input type="submit" tabindex="-1" style="position:absolute; top:-100px"/>
- </form>
-</div>
-
-
-<div id="dialog_event" title="event">
- <table>
- <tr>
- <td style="width:100px">Booked by:</td>
- <td><p id="dg-booker-email"></p></td>
- </tr>
- <tr>
- <td>Start:</td>
- <td><p id="dg-start"></p></td>
- </tr>
- <tr>
- <td>End:</td>
- <td><p id="dg-end"></p></td>
- </tr>
- <tr>
- <td>Purpose:</td>
- <td><p id="dg-purpose"></p></td>
- </tr>
- <table>
-</div>
-
-
-
-<input type="hidden" id="resource_id" name="resource_id" value="10"/>
-<input type="hidden" id="resource_name" name="resource_name"/>
-<input type="hidden" id="starttime" value=""/>
-<input type="hidden" id="endtime" value=""/>
-<input type="hidden" id="purpose" value=""/>
-<input type="hidden" id="event_id" value=""/>
-
-
-
diff --git a/tools/infra-dashboard/pages/slaves.php b/tools/infra-dashboard/pages/slaves.php
deleted file mode 100644
index 25fafd26..00000000
--- a/tools/infra-dashboard/pages/slaves.php
+++ /dev/null
@@ -1,58 +0,0 @@
-<script type="text/javascript">
- $(document).ready(function() {
- $('#example').DataTable( {
- "order": [[ 2, "desc" ], [ 1, "desc" ]]
- } );
- } );
-</script>
-
-<?php
- include '../utils/jenkinsAdapter.php';
- $array = $SLAVES->xpath('computer');
-
- echo '<table id="example" class="table table-striped table-bordered" cellspacing="0" width="100%">';
- echo "<thead>";
- echo "<tr>";
- echo "<th>Slave name</th>";
- echo "<th>Status</th>";
- echo "<th>Current build</th>";
- echo "</tr>";
- echo "</thead>";
- echo "<tbody>";
- foreach ($array as &$value) {
-
- $slave = $value->displayName;
- $idle = $value->idle;
- $slave_url = getSlaveUrl($slave);
- $status = getSlaveStatus($slave);
-
- if ($status == "online" and $idle == "true") {
- $status = "online / idle";
- $color = "#C8D6C3";
- }
- else if ($status == "online") $color = "#BEFAAA";
- else $color = "#FAAAAB";
-
- $job_name = "";
- $job_url = "";
- $job_scenario = "";
-
-
- if ($status == 'online') {
- $job_params = getJJob($slave);
- $job_name = $job_params['name'];
- $job_url = $job_params['url'];
- $job_scenario = $job_params['scenario'];
- }
-
- echo "<tr>";
- echo "<th><a target='_blank' href='".$slave_url."'>".$slave."</a></th>";
-
- echo "<th style='background-color: ".$color.";'>".$status."</th>";
- echo "<th><a class='blink_me' style='font-size:12px;color:#33cc00;' target='_blank' href='".$job_url."'>".$job_name."</a></th>";
-
- echo "</tr>";
- }
- echo '</tbody>';
- echo '</table>';
-?>
diff --git a/tools/infra-dashboard/populateDB.txt b/tools/infra-dashboard/populateDB.txt
deleted file mode 100644
index d3f8f5e4..00000000
--- a/tools/infra-dashboard/populateDB.txt
+++ /dev/null
@@ -1,203 +0,0 @@
-
-CREATE DATABASE opnfv_pharos;
-USE opnfv_pharos;
-SHOW TABLES;
-use opnfv_pharos;
-
-DROP TABLE resource;
-CREATE TABLE resource (
- resource_id INT UNSIGNED AUTO_INCREMENT,
- name VARCHAR(100) NOT NULL,
- slavename VARCHAR(50),
- description VARCHAR(300),
- link VARCHAR(100),
- bookable BOOLEAN DEFAULT false,
- active BOOLEAN DEFAULT true,
- PRIMARY KEY (resource_id)
-);
-
-DROP TABLE server;
-CREATE TABLE server (
- server_id INT UNSIGNED AUTO_INCREMENT,
- resource_id INT NOT NULL,
- model VARCHAR(200),
- cpu VARCHAR(200),
- ram VARCHAR(200),
- storage VARCHAR(200),
- count INT DEFAULT 1,
- PRIMARY KEY (server_id)
-);
-
-DROP TABLE pod;
-CREATE TABLE pod (
- pod_id INT UNSIGNED AUTO_INCREMENT,
- resource_id INT NOT NULL,
- chassis VARCHAR(500),
- PRIMARY KEY (pod_id)
-);
-
-DROP TABLE user;
-CREATE TABLE user(
- user_id INT UNSIGNED AUTO_INCREMENT,
- name VARCHAR(100) NOT NULL,
- email VARCHAR(100) NOT NULL UNIQUE,
- password VARCHAR(100) NOT NULL,
- company VARCHAR(100),
- creation TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
- PRIMARY KEY (user_id)
-);
-
-DROP TABLE role;
-CREATE TABLE role (
- role_id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
- name VARCHAR(30),
- description VARCHAR(300)
-);
-
-DROP TABLE user_role;
-CREATE TABLE user_role (
- user_id INT NOT NULL,
- role_id INT NOT NULL,
- description VARCHAR(300),
- PRIMARY KEY (user_id, role_id)
-);
-
-
-DROP TABLE user_resource;
-CREATE TABLE user_resource (
- user_id INT NOT NULL,
- resource_id INT NOT NULL,
- PRIMARY KEY (user_id, resource_id)
-);
-
-
-
-DROP TABLE booking;
-CREATE TABLE booking(
- booking_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
- resource_id INT NOT NULL,
- user_id INT NOT NULL,
- starttime DATETIME NOT NULL,
- endtime DATETIME NOT NULL,
- creation TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
- purpose VARCHAR(300)
-);
-
-/*
-describe resource;
-describe server;
-describe pod;
-describe pod_type;
-describe user;
-describe role;
-describe user_role;
-describe user_resource;
-describe booking;
-*/
-
-/* POD TYPES */
-INSERT INTO pod_type (name, description) VALUES ("ci_pod", "PODS for CI usage only");
-INSERT INTO pod_type (name, description) VALUES ("dev_pod", "PODS development");
-
-
-/* CI PODS */
-INSERT INTO resource (name, slavename, description, link) VALUES ("Linux Foundation POD 1", "lf-pod1", "Some description", "https://wiki.opnfv.org/display/pharos/Lf+Lab");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='lf-pod1';
-
-INSERT INTO resource (name, slavename, description, link) VALUES ("Linux Foundation POD 2", "lf-pod2", "Some description", "https://wiki.opnfv.org/display/pharos/Lf+Lab");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='lf-pod2';
-
-INSERT INTO resource (name, slavename, description, link) VALUES ("Ericsson POD 2", "ericsson-pod2", "Some description", "https://wiki.opnfv.org/display/pharos/Ericsson+Hosting+and+Request+Process");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='ericsson-pod2';
-
-INSERT INTO resource (name, slavename, description, link) VALUES ("Intel POD 2", "intel-pod2", "Some description", "https://wiki.opnfv.org/display/pharos/Intel+Pod2");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='intel-pod2';
-
-INSERT INTO resource (name, slavename, description, link) VALUES ("Intel POD 5", "intel-pod5", "Some description", "https://wiki.opnfv.org/display/pharos/Intel+Pod5");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='intel-pod5';
-
-INSERT INTO resource (name, slavename, description, link) VALUES ("Intel POD 6", "intel-pod6", "Some description", "https://wiki.opnfv.org/display/pharos/Intel+Pod6");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='intel-pod6';
-
-INSERT INTO resource (name, slavename, description, link) VALUES ("Intel POD 8", "intel-pod8", "Some description", "https://wiki.opnfv.org/display/pharos/Intel+Pod8");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='intel-pod8';
-
-INSERT INTO resource (name, slavename, description, link) VALUES ("Huawei POD 1", "huawei-pod1", "Some description", "https://wiki.opnfv.org/display/pharos/Huawei+Hosting");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='huawei-pod1';
-
-
-
-
-
-/* SOME DEV PODS */
-
-
-
-INSERT INTO resource (name, slavename, description, bookable, link) VALUES ("Intel POD 3", "intel-pod3", "Some description", true, "https://wiki.opnfv.org/display/pharos/Intel+Pod3");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='intel-pod3';
-
-INSERT INTO resource (name, slavename, description, bookable, link) VALUES ("Dell POD 1", "dell-pod1", "Some description", true, "https://wiki.opnfv.org/display/pharos/Dell+Hosting");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='dell-pod1';
-
-INSERT INTO resource (name, slavename, description, bookable, link) VALUES ("Dell POD 2", "dell-pod2", "Some description", true, "https://wiki.opnfv.org/display/pharos/Dell+Hosting");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='dell-pod2';
-
-INSERT INTO resource (name, slavename, description, bookable, link) VALUES ("Orange POD 2", "orange-pod2", "Some description", true, "https://wiki.opnfv.org/display/pharos/Opnfv-orange-pod2");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='orange-pod2';
-
-INSERT INTO resource (name, slavename, description, bookable, link) VALUES ("Arm POD 1", "arm-build1", "Some description", true, "https://wiki.opnfv.org/display/pharos/Enea-pharos-lab");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='arm-build1';
-
-INSERT INTO resource (name, slavename, description, bookable, link) VALUES ("Ericsson POD 1", "ericsson-pod1", "Some description", true, "https://wiki.opnfv.org/display/pharos/Ericsson+Hosting+and+Request+Process");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='ericsson-pod1';
-
-INSERT INTO resource (name, slavename, description, bookable,link) VALUES ("Huawei POD 2", "huawei-pod2", "Some description", true, "https://wiki.opnfv.org/display/pharos/Huawei+Hosting");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='huawei-pod2';
-
-INSERT INTO resource (name, slavename, description, bookable,link) VALUES ("Huawei POD 3", "huawei-pod3", "Some description", true, "https://wiki.opnfv.org/display/pharos/Huawei+Hosting");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='huawei-pod3';
-
-INSERT INTO resource (name, slavename, description, bookable, link) VALUES ("Huawei POD 4", "huawei-pod4", "Some description", true, "https://wiki.opnfv.org/display/pharos/Huawei+Hosting");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='huawei-pod4';
-
-INSERT INTO resource (name, slavename, description, bookable, link) VALUES ("Intel POD 9", "intel-pod9", "Some description", true, "https://wiki.opnfv.org/display/pharos/Intel+Pod9");
-INSERT INTO pod (resource_id) SELECT resource_id FROM resource where slavename='intel-pod9';
-
-
-SELECT * FROM resource;
-SELECT * FROM pod;
-
-
-INSERT INTO role (name, description) VALUES ("admin", "Administrator of the system");
-INSERT INTO role (name, description) VALUES ("lab_owner", "Owner of a lab.");
-INSERT INTO role (name, description) VALUES ("troubleshooter", "A person who can book a pod for troubleshooting.");
-SELECT * FROM role;
-
-INSERT INTO user (name, password, email, company) VALUES ("Jose Lausuch", md5("opnfv"), "jose.lausuch@ericsson.com", "Ericsson");
-INSERT INTO user (name, password, email, company) VALUES ("Daniel Smith", md5("opnfv"), "daniel.smith@ericsson.com", "Ericsson");
-INSERT INTO user (name, password, email, company) VALUES ("Jack Morgan", md5("opnfv"), "jack.morgan@intel.com", "Intel");
-INSERT INTO user (name, password, email, company) VALUES ("Fatih Degirmenci", md5("opnfv"), "fatih.degirmenci@ericsson.com", "Ericsson");
-INSERT INTO user (name, password, email, company) VALUES ("Trevor Cooper", md5("opnfv"), "trevor.cooper@intel.com", "Intel");
-SELECT * FROM user;
-
-INSERT INTO user_role (user_id, role_id) SELECT user_id,role_id FROM user,role WHERE email="jose.lausuch@ericsson.com" AND role.name="admin";
-INSERT INTO user_role (user_id, role_id) SELECT user_id,role_id FROM user,role WHERE email="daniel.smith@ericsson.com" AND role.name="lab_owner";
-INSERT INTO user_role (user_id, role_id) SELECT user_id,role_id FROM user,role WHERE email="jack.morgan@intel.com" AND role.name="lab_owner";
-INSERT INTO user_role (user_id, role_id) SELECT user_id,role_id FROM user,role WHERE email="jack.morgan@intel.com" AND role.name="troubleshooter";
-INSERT INTO user_role (user_id, role_id) SELECT user_id,role_id FROM user,role WHERE email="fatih.degirmenci@ericsson.com" AND role.name="troubleshooter";
-INSERT INTO user_role (user_id, role_id) SELECT user_id,role_id FROM user,role WHERE email="trevor.cooper@intel.com" AND role.name="troubleshooter";
-SELECT * FROM user_role;
-
-INSERT INTO user_resource (user_id, resource_id) SELECT user_id,resource_id FROM user,resource WHERE email="daniel.smith@ericsson.com" and slavename="ericsson-pod1";
-INSERT INTO user_resource (user_id, resource_id) SELECT user_id,resource_id FROM user,resource WHERE email="daniel.smith@ericsson.com" and slavename="ericsson-pod2";
-INSERT INTO user_resource (user_id, resource_id) SELECT user_id,resource_id FROM user,resource WHERE email="jack.morgan@intel.com" and slavename="intel-pod2";
-INSERT INTO user_resource (user_id, resource_id) SELECT user_id,resource_id FROM user,resource WHERE email="jack.morgan@intel.com" and slavename="intel-pod3";
-INSERT INTO user_resource (user_id, resource_id) SELECT user_id,resource_id FROM user,resource WHERE email="jack.morgan@intel.com" and slavename="intel-pod5";
-INSERT INTO user_resource (user_id, resource_id) SELECT user_id,resource_id FROM user,resource WHERE email="jack.morgan@intel.com" and slavename="intel-pod6";
-INSERT INTO user_resource (user_id, resource_id) SELECT user_id,resource_id FROM user,resource WHERE email="jack.morgan@intel.com" and slavename="intel-pod8";
-INSERT INTO user_resource (user_id, resource_id) SELECT user_id,resource_id FROM user,resource WHERE email="jack.morgan@intel.com" and slavename="intel-pod9";
-SELECT * FROM user_resource;
-
-
-
-
diff --git a/tools/infra-dashboard/utils/book.php b/tools/infra-dashboard/utils/book.php
deleted file mode 100644
index 6d4c5b20..00000000
--- a/tools/infra-dashboard/utils/book.php
+++ /dev/null
@@ -1,82 +0,0 @@
-<?php
-
- include 'database.php';
-
- function book() {
- $resource_id = $_POST['resource_id'];
- $resource_name = $_POST['resource_name'];
- $user_id = $_POST['user_id'];
- $start = $_POST['start'];
- $end = $_POST['end'];
- $purpose = $_POST['purpose'];
-
- $query = "select role.name as rolename from user, role, user_role where user.user_id = ".$user_id." and role.role_id=user_role.role_id and user_role.user_id=user.user_id;";
- $result = mysql_query($query);
-
- if(mysql_num_rows($result) == 0) {
- echo "1"; //return a code instead of a meesage. Display the message later in javascript according to the returned code.
- //echo "Booking not possible (your account is not associated with a role). Please contact the administrator.";
- exit;
- }
- $is_only_lab_owner = true;
- while ($row = mysql_fetch_array($result)) {
- $rolename = $row['rolename'];
- if ($rolename != "lab_owner") $is_only_lab_owner = false;
- }
- if ($is_only_lab_owner) {
- $query = "select * from user u inner join user_resource r on r.user_id=u.user_id and u.user_id=".$user_id." and r.resource_id=".$resource_id.";";
- $result = mysql_query($query);
- if(mysql_num_rows($result) == 0) {
- echo "2";
- //echo "You are not allowed to book this resource. ";
- exit;
- }
- }
- $query = "INSERT INTO booking (resource_id, user_id, starttime, endtime, purpose) VALUES (".$resource_id.",".$user_id.",'".$start."','".$end."', '".$purpose."');";
- $result = mysql_query($query);
- if(mysql_insert_id()>0){
- echo "Booking successful. The resource '".$resource_name."' is booked from ".$start." to ".$end.".";
- }
- else{
- echo "Mysql Error : ".mysql_error().". Query = ".$query;
- }
-
- }
-
- function getBookedDates() {
- $resource_id = $_POST['resource_id'];
- $query = "SELECT b.booking_id, b.resource_id,u.name as username,u.email,b.starttime,b.endtime,b.creation,b.purpose FROM booking as b,user as u WHERE b.resource_id=".$resource_id." AND b.user_id=u.user_id;";
- $result = mysql_query($query);
-
- $events = array();
- while ($row = mysql_fetch_array($result)) {
- $e = array();
- $e['id'] = $row['booking_id'];
- $e['booker_name'] = $row['username'];
- $e['booker_email'] = $row['email'];
- $e['title'] = $row['purpose'];
- $e['start'] = $row['starttime'];
- $e['end'] = $row['endtime'];
- $e['bookdate'] = $row['creation'];
-
- // Merge the event array into the return array
- array_push($events, $e);
- }
-
- echo json_encode($events);
- }
-
-
-
- $action = $_POST['action'];
-
- connectDB();
- if ($action == "book") {
- book();
- } elseif ($action == "getBookedDates" ) {
- getBookedDates();
- } else {
- echo "Invalid POST action.";
- }
- closeDB();
-?>
diff --git a/tools/infra-dashboard/utils/database.php b/tools/infra-dashboard/utils/database.php
deleted file mode 100644
index b72c3d12..00000000
--- a/tools/infra-dashboard/utils/database.php
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php
- include '../../../../auth-db.php';
- date_default_timezone_set('UTC');
- function connectDB() {
- global $username;
- global $password;
- global $hostname;
- global $dbname;
-
- $dbhandle = mysql_connect($hostname, $username, $password)
- or die("Unable to connect to MySQL.".mysql_error());
- $selected = mysql_select_db($dbname,$dbhandle)
- or die("Could not select opnfv_pharos DB.");
- }
-
- function closeDB(){
- mysql_connect($dbhandle);
- }
-
-?>
diff --git a/tools/infra-dashboard/utils/jenkinsAdapter.php b/tools/infra-dashboard/utils/jenkinsAdapter.php
deleted file mode 100644
index c238feb7..00000000
--- a/tools/infra-dashboard/utils/jenkinsAdapter.php
+++ /dev/null
@@ -1,204 +0,0 @@
-<?php
-
- function getSlaves() {
- $query="https://build.opnfv.org/ci/computer/api/xml?tree=computer[displayName,offline,idle]";
- $output = file_get_contents($query);
- $xml = simplexml_load_string($output);
- if ($xml) return $xml;
- else return "";
- }
-
- function getCiSlaves(){
- $query="https://build.opnfv.org/ci/label/ci-pod/api/xml?xpath=labelAtom/node[nodeName]&wrapper=nodes";
- $output = file_get_contents($query);
- $xml = simplexml_load_string($output);
- if ($xml) return $xml;
- else return "";
- }
-
- function getAllBuilds(){
- $query="https://build.opnfv.org/ci/api/xml?tree=jobs[displayName,url,lastBuild[fullDisplayName,building,builtOn,timestamp,result]]";
- $output = file_get_contents($query);
- $xml = simplexml_load_string($output);
- if ($xml) return $xml;
- else return "";
- }
-
- $SLAVES = getSlaves();
- $CI_PODS = getCiSlaves();
- $ALL_BUILDS = getAllBuilds();
-
- function getActiveBuilds() {
- global $ALL_BUILDS;
- //$query="https://build.opnfv.org/ci/api/xml?tree=jobs[displayName,url,lastBuild[fullDisplayName,building,builtOn,timestamp]]&xpath=hudson/job[lastBuild/building=%27true%27]&wrapper=hudson";
- $xml = $ALL_BUILDS->xpath('job[lastBuild/building="true"]');
- if ($xml) return $xml;
- else return "";
- }
-
- $ACTIVE_BUILDS = getActiveBuilds();
-
- function slaveExists($slave) {
- global $SLAVES;
- $slave = $SLAVES->xpath('computer[displayName="'.$slave.'"]');
- if ($slave) return true;
- else return false;
- }
-
- function getSlaveStatus($slave) {
- global $SLAVES;
- $status = "unknown";
- if (!slaveExists($slave)) return $status;
- $slave = $SLAVES->xpath('computer[displayName="'.$slave.'"]');
- $offline = $slave[0]->offline;
-
- if ($offline == "true") $status = "offline";
- else $status = "online";
- return $status;
- }
-
- function getSlaveUrl($slave) {
- if (slaveExists($slave)) return "https://build.opnfv.org/ci/computer/".$slave;
- else return "";
- }
-
-
- function isCiPod($slave) {
- global $CI_PODS;
- $result = $CI_PODS->xpath('node[nodeName="'.$slave.'"]');
- if ($result) return true;
- else return false;
- }
-
- function isDevPod($slave) {
- global $CI_PODS;
- if (isCiPod($slave)) return false;
- else if (strpos($slave, 'pod') !== false) return true;
- else return false;
- }
-
- function parseJobString($str) {
- $scenario = '';
- $installer = '';
- $branch = '';
- $installers = array("fuel", "joid", "apex", "compass");
- $branches = array("master","arno", "brahmaputra", "colorado");
- $arr = split ('[ -]', $str);
- for($x = 0; $x < count($arr); $x++) {
- if (strcmp($arr[$x],"os") == 0) //all the scenarios start with 'os'
- $scenario = $arr[$x].'-'.$arr[$x+1].'-'.$arr[$x+2].'-'.$arr[$x+3];
- else if (in_array($arr[$x], $installers))
- $installer = $arr[$x];
- else if (in_array($arr[$x], $branches))
- $branch = $arr[$x];
- }
- $arr2 = explode(' ', $str);
- $jobname = $arr2[0]; //take first word as job name
-
- return array(
- "jobname"=>$jobname,
- "installer"=>$installer,
- "branch"=>$branch,
- "scenario"=>$scenario
- );
- }
-
-
- function getJJob($slave) {
- global $ALL_BUILDS;
- if (!slaveExists($slave)) return "";
-
- //$builds = $ALL_BUILDS;
- //$xml = $ALL_BUILDS->xpath('job[lastBuild/building="true"][lastBuild/builtOn="'.$slave.'"]');
- $builds = $ALL_BUILDS->xpath('job[lastBuild/builtOn="'.$slave.'"]');
- if (! $builds) { //the slave does not have jobs in building state
- //echo "NO JOBS FOUND";
- return "";
- }
- else {
- //is there any active build?
- $builds = $ALL_BUILDS->xpath('job[lastBuild/building="true"][lastBuild/builtOn="'.$slave.'"]');
- if ($builds) { // there are active builds for this slave
- //print_r($builds);
-
- $child_job = simplexml_import_dom($builds[0]);
- foreach ($builds as &$build) {
- $int1 = intval($build->lastBuild->timestamp);
- $int2 = intval($child_job->lastBuild->timestamp);
- if ($int1 > $int2) {
- $child_job = simplexml_import_dom($build);
- }
- }
- $url = strval($child_job->url);
- $fullDisplayName = $child_job->lastBuild->fullDisplayName;
- //echo $fullDisplayName."<br>";
-
- $params = parseJobString($fullDisplayName);
-
- $type = 0; // type=0 means the job is running
- $job_params = array(
- "name"=>$params['jobname'],
- "url"=>$url,
- "scenario"=>$params['scenario'],
- "installer"=>$params['installer'],
- "branch"=>$params['branch'],
- "type"=>$type
- );
- //print_r($job_params);
- return $job_params;
-
- }
- else { // there are NO active builds for this slave, we take the latest build
- //echo "NO Active builds";
- $builds = $ALL_BUILDS->xpath('job[lastBuild/building="false"][lastBuild/builtOn="'.$slave.'"]');
- $last_job = simplexml_import_dom($builds[0]);
- //print_r($last_job);
- foreach ($builds as &$build) {
- $int1 = intval($build->lastBuild->timestamp);
- $int2 = intval($last_job->lastBuild->timestamp);
- if ($int1 > $int2) {
- $last_job = simplexml_import_dom($build);
- }
- }
- $url = strval($last_job->url);
- $result = strval($last_job->lastBuild->result);
- $fullDisplayName = $last_job->lastBuild->fullDisplayName;
-
- $params = parseJobString($fullDisplayName);
-
- $type = 3;
- if ($result == "SUCCESS") $type = 1; // type=1 means it's the last job and it succeded
- if ($result == "FAILURE") $type = 2; // type=2 means it's the last job and it failed
- if ($result == "UNSTABLE") $type = 3; // type=3 means it's the last job is unstable
-
- $job_params = array(
- "name"=>$params['jobname'],
- "url"=>$url,
- "scenario"=>$params['scenario'],
- "installer"=>$params['installer'],
- "branch"=>$params['branch'],
- "type"=>$type
- );
-
- return $job_params;
- //print_r($job_params);
- }
-
- }
- }
-
- /*
- $slave = "lf-pod2";
- $job_params = getJJob($slave);
-
- $status = getSlaveStatus($slave);
- echo "Status slave ".$slave.": ".$status."<br>";
- echo "Job: ".$job_params['name']."<br>";
- echo "URL: ".$job_params['url']."<br>";
- echo "Scenario: ".$job_params['scenario']."<br>";
- echo "Installer: ".$job_params['installer']."<br>";
- echo "Branch: ".$job_params['branch']."<br>";
- echo "Type: ".$job_params['type']."<br>";
- */
-
-?>
diff --git a/tools/infra-dashboard/utils/login.php b/tools/infra-dashboard/utils/login.php
deleted file mode 100644
index 2ac7101d..00000000
--- a/tools/infra-dashboard/utils/login.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-
- include 'database.php';
-
-
- function login(){
- $email = $_POST['email'];
- $password = $_POST['password'];
-
- $query = "SELECT * FROM user where EMAIL='".$email."';";
- $result = mysql_query($query);
-
- $user = array();
- if(mysql_num_rows($result) > 0) {
- $query = "SELECT * FROM user where email='".$email."' and password='".$password."';";
- $result = mysql_query($query);
- if(mysql_num_rows($result) > 0) {
- while($row = mysql_fetch_assoc($result)) {
- $user = $row;
- $user["result"] = 0;
-
- $_SESSION['user_id'] = $user['user_id'];
- $_SESSION['user_name'] = $user['name'];
- $_SESSION['user_email'] = $user['email'];
- }
- } else {
- $user["result"] = 1; //wrong password
- }
- } else {
- $user["result"] = 2; //user not registered
- }
- echo json_encode($user);
-
- }
-
-
- $action = $_POST['action'];
-
- connectDB();
- session_start();
-
- if ($action == "login") {
- login();
- } else if ($action == "logout") {
- unset($_SESSION['user_id']);
- unset($_SESSION['user_name']);
- unset($_SESSION['user_email']);
- session_destroy();
- } else {
- echo "Invalid POST action.";
- }
- closeDB();
-
-?>
-
-