.\n\n.list-group {\n // No need to set list-style: none; since .list-group-item is block level\n margin-bottom: 20px;\n padding-left: 0; // reset padding because ul and ol\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n // Place the border on the list items and negative margin up for better styling\n margin-bottom: -1px;\n background-color: @list-group-bg;\n border: 1px solid @list-group-border;\n\n // Round the first and last items\n &:first-child {\n .border-top-radius(@list-group-border-radius);\n }\n &:last-child {\n margin-bottom: 0;\n .border-bottom-radius(@list-group-border-radius);\n }\n}\n\n\n// Linked list items\n//\n// Use anchor elements instead of `li`s or `div`s to create linked list items.\n// Includes an extra `.active` modifier class for showing selected items.\n\na.list-group-item {\n color: @list-group-link-color;\n\n .list-group-item-heading {\n color: @list-group-link-heading-color;\n }\n\n // Hover state\n &:hover,\n &:focus {\n text-decoration: none;\n color: @list-group-link-hover-color;\n background-color: @list-group-hover-bg;\n }\n}\n\n.list-group-item {\n // Disabled state\n &.disabled,\n &.disabled:hover,\n &.disabled:focus {\n background-color: @list-group-disabled-bg;\n color: @list-group-disabled-color;\n cursor: @cursor-disabled;\n\n // Force color to inherit for custom content\n .list-group-item-heading {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-disabled-text-color;\n }\n }\n\n // Active class on item itself, not parent\n &.active,\n &.active:hover,\n &.active:focus {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: @list-group-active-color;\n background-color: @list-group-active-bg;\n border-color: @list-group-active-border;\n\n // Force color to inherit for custom content\n .list-group-item-heading,\n .list-group-item-heading > small,\n .list-group-item-heading > .small {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-active-text-color;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n.list-group-item-variant(success; @state-success-bg; @state-success-text);\n.list-group-item-variant(info; @state-info-bg; @state-info-text);\n.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);\n.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);\n\n\n// Custom content options\n//\n// Extra classes for creating well-formatted content within `.list-group-item`s.\n\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n","// List Groups\n\n.list-group-item-variant(@state; @background; @color) {\n .list-group-item-@{state} {\n color: @color;\n background-color: @background;\n\n a& {\n color: @color;\n\n .list-group-item-heading {\n color: inherit;\n }\n\n &:hover,\n &:focus {\n color: @color;\n background-color: darken(@background, 5%);\n }\n &.active,\n &.active:hover,\n &.active:focus {\n color: #fff;\n background-color: @color;\n border-color: @color;\n }\n }\n }\n}\n","//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n margin-bottom: @line-height-computed;\n background-color: @panel-bg;\n border: 1px solid transparent;\n border-radius: @panel-border-radius;\n .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n padding: @panel-body-padding;\n &:extend(.clearfix all);\n}\n\n// Optional heading\n.panel-heading {\n padding: @panel-heading-padding;\n border-bottom: 1px solid transparent;\n .border-top-radius((@panel-border-radius - 1));\n\n > .dropdown .dropdown-toggle {\n color: inherit;\n }\n}\n\n// Within heading, strip any `h*` tag of its default margins for spacing.\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: ceil((@font-size-base * 1.125));\n color: inherit;\n\n > a {\n color: inherit;\n }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n padding: @panel-footer-padding;\n background-color: @panel-footer-bg;\n border-top: 1px solid @panel-inner-border;\n .border-bottom-radius((@panel-border-radius - 1));\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n > .list-group,\n > .panel-collapse > .list-group {\n margin-bottom: 0;\n\n .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n }\n\n // Add border top radius for first one\n &:first-child {\n .list-group-item:first-child {\n border-top: 0;\n .border-top-radius((@panel-border-radius - 1));\n }\n }\n // Add border bottom radius for last one\n &:last-child {\n .list-group-item:last-child {\n border-bottom: 0;\n .border-bottom-radius((@panel-border-radius - 1));\n }\n }\n }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n .list-group-item:first-child {\n border-top-width: 0;\n }\n}\n.list-group + .panel-footer {\n border-top-width: 0;\n}\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n > .table,\n > .table-responsive > .table,\n > .panel-collapse > .table {\n margin-bottom: 0;\n\n caption {\n padding-left: @panel-body-padding;\n padding-right: @panel-body-padding;\n }\n }\n // Add border top radius for first one\n > .table:first-child,\n > .table-responsive:first-child > .table:first-child {\n .border-top-radius((@panel-border-radius - 1));\n\n > thead:first-child,\n > tbody:first-child {\n > tr:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n border-top-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-top-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n // Add border bottom radius for last one\n > .table:last-child,\n > .table-responsive:last-child > .table:last-child {\n .border-bottom-radius((@panel-border-radius - 1));\n\n > tbody:last-child,\n > tfoot:last-child {\n > tr:last-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n border-bottom-right-radius: (@panel-border-radius - 1);\n\n td:first-child,\n th:first-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-bottom-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n > .panel-body + .table,\n > .panel-body + .table-responsive,\n > .table + .panel-body,\n > .table-responsive + .panel-body {\n border-top: 1px solid @table-border-color;\n }\n > .table > tbody:first-child > tr:first-child th,\n > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n }\n > .table-bordered,\n > .table-responsive > .table-bordered {\n border: 0;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n > thead,\n > tbody {\n > tr:first-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n > tbody,\n > tfoot {\n > tr:last-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n }\n > .table-responsive {\n border: 0;\n margin-bottom: 0;\n }\n}\n\n\n// Collapsable panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n margin-bottom: @line-height-computed;\n\n // Tighten up margin so it's only between panels\n .panel {\n margin-bottom: 0;\n border-radius: @panel-border-radius;\n\n + .panel {\n margin-top: 5px;\n }\n }\n\n .panel-heading {\n border-bottom: 0;\n\n + .panel-collapse > .panel-body,\n + .panel-collapse > .list-group {\n border-top: 1px solid @panel-inner-border;\n }\n }\n\n .panel-footer {\n border-top: 0;\n + .panel-collapse .panel-body {\n border-bottom: 1px solid @panel-inner-border;\n }\n }\n}\n\n\n// Contextual variations\n.panel-default {\n .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-info {\n .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n.panel-warning {\n .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n","// Panels\n\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n border-color: @border;\n\n & > .panel-heading {\n color: @heading-text-color;\n background-color: @heading-bg-color;\n border-color: @heading-border;\n\n + .panel-collapse > .panel-body {\n border-top-color: @border;\n }\n .badge {\n color: @heading-bg-color;\n background-color: @heading-text-color;\n }\n }\n & > .panel-footer {\n + .panel-collapse > .panel-body {\n border-bottom-color: @border;\n }\n }\n}\n","// Embeds responsive\n//\n// Credit: Nicolas Gallagher and SUIT CSS.\n\n.embed-responsive {\n position: relative;\n display: block;\n height: 0;\n padding: 0;\n overflow: hidden;\n\n .embed-responsive-item,\n iframe,\n embed,\n object,\n video {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n height: 100%;\n width: 100%;\n border: 0;\n }\n\n // Modifier class for 16:9 aspect ratio\n &.embed-responsive-16by9 {\n padding-bottom: 56.25%;\n }\n\n // Modifier class for 4:3 aspect ratio\n &.embed-responsive-4by3 {\n padding-bottom: 75%;\n }\n}\n","//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: @well-bg;\n border: 1px solid @well-border;\n border-radius: @border-radius-base;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n blockquote {\n border-color: #ddd;\n border-color: rgba(0,0,0,.15);\n }\n}\n\n// Sizes\n.well-lg {\n padding: 24px;\n border-radius: @border-radius-large;\n}\n.well-sm {\n padding: 9px;\n border-radius: @border-radius-small;\n}\n","//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n float: right;\n font-size: (@font-size-base * 1.5);\n font-weight: @close-font-weight;\n line-height: 1;\n color: @close-color;\n text-shadow: @close-text-shadow;\n .opacity(.2);\n\n &:hover,\n &:focus {\n color: @close-color;\n text-decoration: none;\n cursor: pointer;\n .opacity(.5);\n }\n\n // Additional properties for button version\n // iOS requires the button element instead of an anchor tag.\n // If you want the anchor version, it requires `href=\"#\"`.\n button& {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n }\n}\n","//\n// Modals\n// --------------------------------------------------\n\n// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n display: none;\n overflow: hidden;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal;\n -webkit-overflow-scrolling: touch;\n\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n\n // When fading in the modal, animate it to slide down\n &.fade .modal-dialog {\n .translate(0, -25%);\n .transition-transform(~\"0.3s ease-out\");\n }\n &.in .modal-dialog { .translate(0, 0) }\n}\n.modal-open .modal {\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n background-color: @modal-content-bg;\n border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n border: 1px solid @modal-content-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 3px 9px rgba(0,0,0,.5));\n background-clip: padding-box;\n // Remove focus outline from opened modal\n outline: 0;\n}\n\n// Modal background\n.modal-backdrop {\n position: absolute;\n top: 0;\n right: 0;\n left: 0;\n background-color: @modal-backdrop-bg;\n // Fade for backdrop\n &.fade { .opacity(0); }\n &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n padding: @modal-title-padding;\n border-bottom: 1px solid @modal-header-border-color;\n min-height: (@modal-title-padding + @modal-title-line-height);\n}\n// Close icon\n.modal-header .close {\n margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n margin: 0;\n line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n padding: @modal-inner-padding;\n text-align: right; // right align buttons\n border-top: 1px solid @modal-footer-border-color;\n &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n // Properly space out buttons\n .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n }\n // but override that for button groups\n .btn-group .btn + .btn {\n margin-left: -1px;\n }\n // and override it for block buttons as well\n .btn-block + .btn-block {\n margin-left: 0;\n }\n}\n\n// Measure scrollbar width for padding body during modal show/hide\n.modal-scrollbar-measure {\n position: absolute;\n top: -9999px;\n width: 50px;\n height: 50px;\n overflow: scroll;\n}\n\n// Scale up the modal\n@media (min-width: @screen-sm-min) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n width: @modal-md;\n margin: 30px auto;\n }\n .modal-content {\n .box-shadow(0 5px 15px rgba(0,0,0,.5));\n }\n\n // Modal sizes\n .modal-sm { width: @modal-sm; }\n}\n\n@media (min-width: @screen-md-min) {\n .modal-lg { width: @modal-lg; }\n}\n","//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n position: absolute;\n z-index: @zindex-tooltip;\n display: block;\n visibility: visible;\n // Reset font and text propertes given new insertion method\n font-family: @font-family-base;\n font-size: @font-size-small;\n font-weight: normal;\n line-height: 1.4;\n .opacity(0);\n\n &.in { .opacity(@tooltip-opacity); }\n &.top { margin-top: -3px; padding: @tooltip-arrow-width 0; }\n &.right { margin-left: 3px; padding: 0 @tooltip-arrow-width; }\n &.bottom { margin-top: 3px; padding: @tooltip-arrow-width 0; }\n &.left { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: @tooltip-max-width;\n padding: 3px 8px;\n color: @tooltip-color;\n text-align: center;\n text-decoration: none;\n background-color: @tooltip-bg;\n border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n// Note: Deprecated .top-left, .top-right, .bottom-left, and .bottom-right as of v3.3.1\n.tooltip {\n &.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-left .tooltip-arrow {\n bottom: 0;\n right: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-right .tooltip-arrow {\n bottom: 0;\n left: @tooltip-arrow-width;\n margin-bottom: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n border-right-color: @tooltip-arrow-color;\n }\n &.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-left-color: @tooltip-arrow-color;\n }\n &.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-left .tooltip-arrow {\n top: 0;\n right: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-right .tooltip-arrow {\n top: 0;\n left: @tooltip-arrow-width;\n margin-top: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n}\n","//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: @zindex-popover;\n display: none;\n max-width: @popover-max-width;\n padding: 1px;\n // Reset font and text propertes given new insertion method\n font-family: @font-family-base;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: @line-height-base;\n text-align: left;\n background-color: @popover-bg;\n background-clip: padding-box;\n border: 1px solid @popover-fallback-border-color;\n border: 1px solid @popover-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n // Overrides for proper insertion\n white-space: normal;\n\n // Offset the popover to account for the popover arrow\n &.top { margin-top: -@popover-arrow-width; }\n &.right { margin-left: @popover-arrow-width; }\n &.bottom { margin-top: @popover-arrow-width; }\n &.left { margin-left: -@popover-arrow-width; }\n}\n\n.popover-title {\n margin: 0; // reset heading margin\n padding: 8px 14px;\n font-size: @font-size-base;\n background-color: @popover-title-bg;\n border-bottom: 1px solid darken(@popover-title-bg, 5%);\n border-radius: (@border-radius-large - 1) (@border-radius-large - 1) 0 0;\n}\n\n.popover-content {\n padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover > .arrow {\n &,\n &:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n }\n}\n.popover > .arrow {\n border-width: @popover-arrow-outer-width;\n}\n.popover > .arrow:after {\n border-width: @popover-arrow-width;\n content: \"\";\n}\n\n.popover {\n &.top > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-top-color: @popover-arrow-outer-color;\n bottom: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n bottom: 1px;\n margin-left: -@popover-arrow-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-color;\n }\n }\n &.right > .arrow {\n top: 50%;\n left: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-right-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n left: 1px;\n bottom: -@popover-arrow-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-color;\n }\n }\n &.bottom > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-bottom-color: @popover-arrow-outer-color;\n top: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n top: 1px;\n margin-left: -@popover-arrow-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-color;\n }\n }\n\n &.left > .arrow {\n top: 50%;\n right: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-right-width: 0;\n border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-left-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: @popover-arrow-color;\n bottom: -@popover-arrow-width;\n }\n }\n}\n","//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n position: relative;\n}\n\n.carousel-inner {\n position: relative;\n overflow: hidden;\n width: 100%;\n\n > .item {\n display: none;\n position: relative;\n .transition(.6s ease-in-out left);\n\n // Account for jankitude on images\n > img,\n > a > img {\n &:extend(.img-responsive);\n line-height: 1;\n }\n\n // WebKit CSS3 transforms for supported devices\n @media all and (transform-3d), (-webkit-transform-3d) {\n transition: transform .6s ease-in-out;\n backface-visibility: hidden;\n perspective: 1000;\n\n &.next,\n &.active.right {\n transform: translate3d(100%, 0, 0);\n left: 0;\n }\n &.prev,\n &.active.left {\n transform: translate3d(-100%, 0, 0);\n left: 0;\n }\n &.next.left,\n &.prev.right,\n &.active {\n transform: translate3d(0, 0, 0);\n left: 0;\n }\n }\n }\n\n > .active,\n > .next,\n > .prev {\n display: block;\n }\n\n > .active {\n left: 0;\n }\n\n > .next,\n > .prev {\n position: absolute;\n top: 0;\n width: 100%;\n }\n\n > .next {\n left: 100%;\n }\n > .prev {\n left: -100%;\n }\n > .next.left,\n > .prev.right {\n left: 0;\n }\n\n > .active.left {\n left: -100%;\n }\n > .active.right {\n left: 100%;\n }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: @carousel-control-width;\n .opacity(@carousel-control-opacity);\n font-size: @carousel-control-font-size;\n color: @carousel-control-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n // We can't have this transition here because WebKit cancels the carousel\n // animation if you trip this while in the middle of another animation.\n\n // Set gradients for backgrounds\n &.left {\n #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n }\n &.right {\n left: auto;\n right: 0;\n #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n }\n\n // Hover/focus state\n &:hover,\n &:focus {\n outline: 0;\n color: @carousel-control-color;\n text-decoration: none;\n .opacity(.9);\n }\n\n // Toggles\n .icon-prev,\n .icon-next,\n .glyphicon-chevron-left,\n .glyphicon-chevron-right {\n position: absolute;\n top: 50%;\n z-index: 5;\n display: inline-block;\n }\n .icon-prev,\n .glyphicon-chevron-left {\n left: 50%;\n margin-left: -10px;\n }\n .icon-next,\n .glyphicon-chevron-right {\n right: 50%;\n margin-right: -10px;\n }\n .icon-prev,\n .icon-next {\n width: 20px;\n height: 20px;\n margin-top: -10px;\n font-family: serif;\n }\n\n\n .icon-prev {\n &:before {\n content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n }\n }\n .icon-next {\n &:before {\n content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n }\n }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n position: absolute;\n bottom: 10px;\n left: 50%;\n z-index: 15;\n width: 60%;\n margin-left: -30%;\n padding-left: 0;\n list-style: none;\n text-align: center;\n\n li {\n display: inline-block;\n width: 10px;\n height: 10px;\n margin: 1px;\n text-indent: -999px;\n border: 1px solid @carousel-indicator-border-color;\n border-radius: 10px;\n cursor: pointer;\n\n // IE8-9 hack for event handling\n //\n // Internet Explorer 8-9 does not support clicks on elements without a set\n // `background-color`. We cannot use `filter` since that's not viewed as a\n // background color by the browser. Thus, a hack is needed.\n //\n // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n // set alpha transparency for the best results possible.\n background-color: #000 \\9; // IE8\n background-color: rgba(0,0,0,0); // IE9\n }\n .active {\n margin: 0;\n width: 12px;\n height: 12px;\n background-color: @carousel-indicator-active-bg;\n }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n position: absolute;\n left: 15%;\n right: 15%;\n bottom: 20px;\n z-index: 10;\n padding-top: 20px;\n padding-bottom: 20px;\n color: @carousel-caption-color;\n text-align: center;\n text-shadow: @carousel-text-shadow;\n & .btn {\n text-shadow: none; // No shadow for button elements in carousel-caption\n }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-sm-min) {\n\n // Scale up the controls a smidge\n .carousel-control {\n .glyphicon-chevron-left,\n .glyphicon-chevron-right,\n .icon-prev,\n .icon-next {\n width: 30px;\n height: 30px;\n margin-top: -15px;\n font-size: 30px;\n }\n .glyphicon-chevron-left,\n .icon-prev {\n margin-left: -15px;\n }\n .glyphicon-chevron-right,\n .icon-next {\n margin-right: -15px;\n }\n }\n\n // Show and left align the captions\n .carousel-caption {\n left: 20%;\n right: 20%;\n padding-bottom: 30px;\n }\n\n // Move up the indicators\n .carousel-indicators {\n bottom: 20px;\n }\n}\n","// Clearfix\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n// contenteditable attribute is included anywhere else in the document.\n// Otherwise it causes space to appear at the top and bottom of elements\n// that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n// `:before` to contain the top-margins of child elements.\n//\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n\n.clearfix() {\n &:before,\n &:after {\n content: \" \"; // 1\n display: table; // 2\n }\n &:after {\n clear: both;\n }\n}\n","// Center-align a block level element\n\n.center-block() {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n","// CSS image replacement\n//\n// Heads up! v3 launched with with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (will be removed in v4)\n.hide-text() {\n font: ~\"0/0\" a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n\n// New mixin to use as of v3.0.1\n.text-hide() {\n .hide-text();\n}\n","//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#support-ie10-width\n// Source: http://timkadlec.com/2013/01/windows-phone-8-and-device-width/\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n width: device-width;\n}\n\n\n// Visibility utilities\n// Note: Deprecated .visible-xs, .visible-sm, .visible-md, and .visible-lg as of v3.2.0\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n .responsive-invisibility();\n}\n\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n display: none !important;\n}\n\n.visible-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-visibility();\n }\n}\n.visible-xs-block {\n @media (max-width: @screen-xs-max) {\n display: block !important;\n }\n}\n.visible-xs-inline {\n @media (max-width: @screen-xs-max) {\n display: inline !important;\n }\n}\n.visible-xs-inline-block {\n @media (max-width: @screen-xs-max) {\n display: inline-block !important;\n }\n}\n\n.visible-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-visibility();\n }\n}\n.visible-sm-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: block !important;\n }\n}\n.visible-sm-inline {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline !important;\n }\n}\n.visible-sm-inline-block {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n display: inline-block !important;\n }\n}\n\n.visible-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-visibility();\n }\n}\n.visible-md-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: block !important;\n }\n}\n.visible-md-inline {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline !important;\n }\n}\n.visible-md-inline-block {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n display: inline-block !important;\n }\n}\n\n.visible-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-visibility();\n }\n}\n.visible-lg-block {\n @media (min-width: @screen-lg-min) {\n display: block !important;\n }\n}\n.visible-lg-inline {\n @media (min-width: @screen-lg-min) {\n display: inline !important;\n }\n}\n.visible-lg-inline-block {\n @media (min-width: @screen-lg-min) {\n display: inline-block !important;\n }\n}\n\n.hidden-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-invisibility();\n }\n}\n.hidden-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-invisibility();\n }\n}\n.hidden-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-invisibility();\n }\n}\n.hidden-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-invisibility();\n }\n}\n\n\n// Print utilities\n//\n// Media queries are placed on the inside to be mixin-friendly.\n\n// Note: Deprecated .visible-print as of v3.2.0\n.visible-print {\n .responsive-invisibility();\n\n @media print {\n .responsive-visibility();\n }\n}\n.visible-print-block {\n display: none !important;\n\n @media print {\n display: block !important;\n }\n}\n.visible-print-inline {\n display: none !important;\n\n @media print {\n display: inline !important;\n }\n}\n.visible-print-inline-block {\n display: none !important;\n\n @media print {\n display: inline-block !important;\n }\n}\n\n.hidden-print {\n @media print {\n .responsive-invisibility();\n }\n}\n","// Responsive utilities\n\n//\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n display: block !important;\n table& { display: table; }\n tr& { display: table-row !important; }\n th&,\n td& { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n display: none !important;\n}\n"]}
\ No newline at end of file
diff --git a/index/css/bootstrap.min.css b/index/css/bootstrap.min.css
new file mode 100644
index 0000000..b6fe4e0
--- /dev/null
+++ b/index/css/bootstrap.min.css
@@ -0,0 +1,5 @@
+/*!
+ * Bootstrap v3.3.1 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}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{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:before,:after{color:#000!important;text-shadow:none!important;background:transparent!important;-webkit-box-shadow:none!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:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:hover,a:focus{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px}input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{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}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{position:absolute;margin-top:4px \9;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],input[type=radio].disabled,input[type=checkbox].disabled,fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm,.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm,select.form-group-sm .form-control{height:30px;line-height:30px}textarea.input-sm,textarea.form-group-sm .form-control,select[multiple].input-sm,select[multiple].form-group-sm .form-control{height:auto}.input-lg,.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg,select.form-group-lg .form-control{height:46px;line-height:46px}textarea.input-lg,textarea.form-group-lg .form-control,select[multiple].input-lg,select[multiple].form-group-lg .form-control{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.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;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.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;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.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;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;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{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default.focus,.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary:hover,.btn-primary:focus,.btn-primary.focus,.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success.focus,.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info.focus,.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning.focus,.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger.focus,.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.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{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.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-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.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 .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width: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}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.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-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.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-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;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=radio],[data-toggle=buttons]>.btn-group>.btn input[type=radio],[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left: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 16px;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}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].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:12px;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}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control: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 12px;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:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{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:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-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:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-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+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#337ab7}.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:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.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:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.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:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important;visibility:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius: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;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;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}@media (min-width:768px){.navbar-toggle{display:none}}.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;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-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)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-top-left-radius:4px;border-top-right-radius:4px;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-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{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:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{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:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{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:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}@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:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{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]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.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}}@-o-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;overflow:hidden;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:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-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}.progress-striped .progress-bar,.progress-bar-striped{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);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-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-success{background-color:#5cb85c}.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);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-info{background-color:#5bc0de}.progress-striped .progress-bar-info{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)}.progress-bar-warning{background-color:#f0ad4e}.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);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{margin-top:15px}.media:first-child{margin-top:0}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#c7ddef}.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:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{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:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{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:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{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:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.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-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.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,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-right:15px;padding-left:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.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 td:first-child,.panel>.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 td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th: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 th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.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 td:last-child,.panel>.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 td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th: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 th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.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 td:first-child,.panel>.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 td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.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 td:last-child,.panel>.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 td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.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,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border: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{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{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:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.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;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height: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{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(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;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:absolute;top:0;right:0;left:0;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.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}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.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;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:400;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.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{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.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{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:400;line-height:1.42857143;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;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)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;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}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";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;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.next,.carousel-inner>.item.active.right{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.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;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.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:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;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:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{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%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{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{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{display:table;content:" "}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}}
\ No newline at end of file
diff --git a/index/css/fontAwesome.css b/index/css/fontAwesome.css
new file mode 100644
index 0000000..b5f5435
--- /dev/null
+++ b/index/css/fontAwesome.css
@@ -0,0 +1,2337 @@
+/*!
+ * Font Awesome 4.7.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.7.0');
+ src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.7.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;
+}
+/* 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;
+}
+.fa-pull-left {
+ float: left;
+}
+.fa-pull-right {
+ float: right;
+}
+.fa.fa-pull-left {
+ margin-right: .3em;
+}
+.fa.fa-pull-right {
+ margin-left: .3em;
+}
+/* Deprecated as of 4.4.0 */
+.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 {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
+ -webkit-transform: rotate(90deg);
+ -ms-transform: rotate(90deg);
+ transform: rotate(90deg);
+}
+.fa-rotate-180 {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
+ -webkit-transform: rotate(180deg);
+ -ms-transform: rotate(180deg);
+ transform: rotate(180deg);
+}
+.fa-rotate-270 {
+ -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
+ -webkit-transform: rotate(270deg);
+ -ms-transform: rotate(270deg);
+ transform: rotate(270deg);
+}
+.fa-flip-horizontal {
+ -ms-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 {
+ -ms-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-feed:before,
+.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-pp: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-resistance: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-y-combinator-square:before,
+.fa-yc-square:before,
+.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-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-intersex:before,
+.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-genderless:before {
+ content: "\f22d";
+}
+.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";
+}
+.fa-yc:before,
+.fa-y-combinator:before {
+ content: "\f23b";
+}
+.fa-optin-monster:before {
+ content: "\f23c";
+}
+.fa-opencart:before {
+ content: "\f23d";
+}
+.fa-expeditedssl:before {
+ content: "\f23e";
+}
+.fa-battery-4:before,
+.fa-battery:before,
+.fa-battery-full:before {
+ content: "\f240";
+}
+.fa-battery-3:before,
+.fa-battery-three-quarters:before {
+ content: "\f241";
+}
+.fa-battery-2:before,
+.fa-battery-half:before {
+ content: "\f242";
+}
+.fa-battery-1:before,
+.fa-battery-quarter:before {
+ content: "\f243";
+}
+.fa-battery-0:before,
+.fa-battery-empty:before {
+ content: "\f244";
+}
+.fa-mouse-pointer:before {
+ content: "\f245";
+}
+.fa-i-cursor:before {
+ content: "\f246";
+}
+.fa-object-group:before {
+ content: "\f247";
+}
+.fa-object-ungroup:before {
+ content: "\f248";
+}
+.fa-sticky-note:before {
+ content: "\f249";
+}
+.fa-sticky-note-o:before {
+ content: "\f24a";
+}
+.fa-cc-jcb:before {
+ content: "\f24b";
+}
+.fa-cc-diners-club:before {
+ content: "\f24c";
+}
+.fa-clone:before {
+ content: "\f24d";
+}
+.fa-balance-scale:before {
+ content: "\f24e";
+}
+.fa-hourglass-o:before {
+ content: "\f250";
+}
+.fa-hourglass-1:before,
+.fa-hourglass-start:before {
+ content: "\f251";
+}
+.fa-hourglass-2:before,
+.fa-hourglass-half:before {
+ content: "\f252";
+}
+.fa-hourglass-3:before,
+.fa-hourglass-end:before {
+ content: "\f253";
+}
+.fa-hourglass:before {
+ content: "\f254";
+}
+.fa-hand-grab-o:before,
+.fa-hand-rock-o:before {
+ content: "\f255";
+}
+.fa-hand-stop-o:before,
+.fa-hand-paper-o:before {
+ content: "\f256";
+}
+.fa-hand-scissors-o:before {
+ content: "\f257";
+}
+.fa-hand-lizard-o:before {
+ content: "\f258";
+}
+.fa-hand-spock-o:before {
+ content: "\f259";
+}
+.fa-hand-pointer-o:before {
+ content: "\f25a";
+}
+.fa-hand-peace-o:before {
+ content: "\f25b";
+}
+.fa-trademark:before {
+ content: "\f25c";
+}
+.fa-registered:before {
+ content: "\f25d";
+}
+.fa-creative-commons:before {
+ content: "\f25e";
+}
+.fa-gg:before {
+ content: "\f260";
+}
+.fa-gg-circle:before {
+ content: "\f261";
+}
+.fa-tripadvisor:before {
+ content: "\f262";
+}
+.fa-odnoklassniki:before {
+ content: "\f263";
+}
+.fa-odnoklassniki-square:before {
+ content: "\f264";
+}
+.fa-get-pocket:before {
+ content: "\f265";
+}
+.fa-wikipedia-w:before {
+ content: "\f266";
+}
+.fa-safari:before {
+ content: "\f267";
+}
+.fa-chrome:before {
+ content: "\f268";
+}
+.fa-firefox:before {
+ content: "\f269";
+}
+.fa-opera:before {
+ content: "\f26a";
+}
+.fa-internet-explorer:before {
+ content: "\f26b";
+}
+.fa-tv:before,
+.fa-television:before {
+ content: "\f26c";
+}
+.fa-contao:before {
+ content: "\f26d";
+}
+.fa-500px:before {
+ content: "\f26e";
+}
+.fa-amazon:before {
+ content: "\f270";
+}
+.fa-calendar-plus-o:before {
+ content: "\f271";
+}
+.fa-calendar-minus-o:before {
+ content: "\f272";
+}
+.fa-calendar-times-o:before {
+ content: "\f273";
+}
+.fa-calendar-check-o:before {
+ content: "\f274";
+}
+.fa-industry:before {
+ content: "\f275";
+}
+.fa-map-pin:before {
+ content: "\f276";
+}
+.fa-map-signs:before {
+ content: "\f277";
+}
+.fa-map-o:before {
+ content: "\f278";
+}
+.fa-map:before {
+ content: "\f279";
+}
+.fa-commenting:before {
+ content: "\f27a";
+}
+.fa-commenting-o:before {
+ content: "\f27b";
+}
+.fa-houzz:before {
+ content: "\f27c";
+}
+.fa-vimeo:before {
+ content: "\f27d";
+}
+.fa-black-tie:before {
+ content: "\f27e";
+}
+.fa-fonticons:before {
+ content: "\f280";
+}
+.fa-reddit-alien:before {
+ content: "\f281";
+}
+.fa-edge:before {
+ content: "\f282";
+}
+.fa-credit-card-alt:before {
+ content: "\f283";
+}
+.fa-codiepie:before {
+ content: "\f284";
+}
+.fa-modx:before {
+ content: "\f285";
+}
+.fa-fort-awesome:before {
+ content: "\f286";
+}
+.fa-usb:before {
+ content: "\f287";
+}
+.fa-product-hunt:before {
+ content: "\f288";
+}
+.fa-mixcloud:before {
+ content: "\f289";
+}
+.fa-scribd:before {
+ content: "\f28a";
+}
+.fa-pause-circle:before {
+ content: "\f28b";
+}
+.fa-pause-circle-o:before {
+ content: "\f28c";
+}
+.fa-stop-circle:before {
+ content: "\f28d";
+}
+.fa-stop-circle-o:before {
+ content: "\f28e";
+}
+.fa-shopping-bag:before {
+ content: "\f290";
+}
+.fa-shopping-basket:before {
+ content: "\f291";
+}
+.fa-hashtag:before {
+ content: "\f292";
+}
+.fa-bluetooth:before {
+ content: "\f293";
+}
+.fa-bluetooth-b:before {
+ content: "\f294";
+}
+.fa-percent:before {
+ content: "\f295";
+}
+.fa-gitlab:before {
+ content: "\f296";
+}
+.fa-wpbeginner:before {
+ content: "\f297";
+}
+.fa-wpforms:before {
+ content: "\f298";
+}
+.fa-envira:before {
+ content: "\f299";
+}
+.fa-universal-access:before {
+ content: "\f29a";
+}
+.fa-wheelchair-alt:before {
+ content: "\f29b";
+}
+.fa-question-circle-o:before {
+ content: "\f29c";
+}
+.fa-blind:before {
+ content: "\f29d";
+}
+.fa-audio-description:before {
+ content: "\f29e";
+}
+.fa-volume-control-phone:before {
+ content: "\f2a0";
+}
+.fa-braille:before {
+ content: "\f2a1";
+}
+.fa-assistive-listening-systems:before {
+ content: "\f2a2";
+}
+.fa-asl-interpreting:before,
+.fa-american-sign-language-interpreting:before {
+ content: "\f2a3";
+}
+.fa-deafness:before,
+.fa-hard-of-hearing:before,
+.fa-deaf:before {
+ content: "\f2a4";
+}
+.fa-glide:before {
+ content: "\f2a5";
+}
+.fa-glide-g:before {
+ content: "\f2a6";
+}
+.fa-signing:before,
+.fa-sign-language:before {
+ content: "\f2a7";
+}
+.fa-low-vision:before {
+ content: "\f2a8";
+}
+.fa-viadeo:before {
+ content: "\f2a9";
+}
+.fa-viadeo-square:before {
+ content: "\f2aa";
+}
+.fa-snapchat:before {
+ content: "\f2ab";
+}
+.fa-snapchat-ghost:before {
+ content: "\f2ac";
+}
+.fa-snapchat-square:before {
+ content: "\f2ad";
+}
+.fa-pied-piper:before {
+ content: "\f2ae";
+}
+.fa-first-order:before {
+ content: "\f2b0";
+}
+.fa-yoast:before {
+ content: "\f2b1";
+}
+.fa-themeisle:before {
+ content: "\f2b2";
+}
+.fa-google-plus-circle:before,
+.fa-google-plus-official:before {
+ content: "\f2b3";
+}
+.fa-fa:before,
+.fa-font-awesome:before {
+ content: "\f2b4";
+}
+.fa-handshake-o:before {
+ content: "\f2b5";
+}
+.fa-envelope-open:before {
+ content: "\f2b6";
+}
+.fa-envelope-open-o:before {
+ content: "\f2b7";
+}
+.fa-linode:before {
+ content: "\f2b8";
+}
+.fa-address-book:before {
+ content: "\f2b9";
+}
+.fa-address-book-o:before {
+ content: "\f2ba";
+}
+.fa-vcard:before,
+.fa-address-card:before {
+ content: "\f2bb";
+}
+.fa-vcard-o:before,
+.fa-address-card-o:before {
+ content: "\f2bc";
+}
+.fa-user-circle:before {
+ content: "\f2bd";
+}
+.fa-user-circle-o:before {
+ content: "\f2be";
+}
+.fa-user-o:before {
+ content: "\f2c0";
+}
+.fa-id-badge:before {
+ content: "\f2c1";
+}
+.fa-drivers-license:before,
+.fa-id-card:before {
+ content: "\f2c2";
+}
+.fa-drivers-license-o:before,
+.fa-id-card-o:before {
+ content: "\f2c3";
+}
+.fa-quora:before {
+ content: "\f2c4";
+}
+.fa-free-code-camp:before {
+ content: "\f2c5";
+}
+.fa-telegram:before {
+ content: "\f2c6";
+}
+.fa-thermometer-4:before,
+.fa-thermometer:before,
+.fa-thermometer-full:before {
+ content: "\f2c7";
+}
+.fa-thermometer-3:before,
+.fa-thermometer-three-quarters:before {
+ content: "\f2c8";
+}
+.fa-thermometer-2:before,
+.fa-thermometer-half:before {
+ content: "\f2c9";
+}
+.fa-thermometer-1:before,
+.fa-thermometer-quarter:before {
+ content: "\f2ca";
+}
+.fa-thermometer-0:before,
+.fa-thermometer-empty:before {
+ content: "\f2cb";
+}
+.fa-shower:before {
+ content: "\f2cc";
+}
+.fa-bathtub:before,
+.fa-s15:before,
+.fa-bath:before {
+ content: "\f2cd";
+}
+.fa-podcast:before {
+ content: "\f2ce";
+}
+.fa-window-maximize:before {
+ content: "\f2d0";
+}
+.fa-window-minimize:before {
+ content: "\f2d1";
+}
+.fa-window-restore:before {
+ content: "\f2d2";
+}
+.fa-times-rectangle:before,
+.fa-window-close:before {
+ content: "\f2d3";
+}
+.fa-times-rectangle-o:before,
+.fa-window-close-o:before {
+ content: "\f2d4";
+}
+.fa-bandcamp:before {
+ content: "\f2d5";
+}
+.fa-grav:before {
+ content: "\f2d6";
+}
+.fa-etsy:before {
+ content: "\f2d7";
+}
+.fa-imdb:before {
+ content: "\f2d8";
+}
+.fa-ravelry:before {
+ content: "\f2d9";
+}
+.fa-eercast:before {
+ content: "\f2da";
+}
+.fa-microchip:before {
+ content: "\f2db";
+}
+.fa-snowflake-o:before {
+ content: "\f2dc";
+}
+.fa-superpowers:before {
+ content: "\f2dd";
+}
+.fa-wpexplorer:before {
+ content: "\f2de";
+}
+.fa-meetup:before {
+ content: "\f2e0";
+}
+.sr-only {
+ position: absolute;
+ width: 1px;
+ height: 1px;
+ padding: 0;
+ margin: -1px;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
+ border: 0;
+}
+.sr-only-focusable:active,
+.sr-only-focusable:focus {
+ position: static;
+ width: auto;
+ height: auto;
+ margin: 0;
+ overflow: visible;
+ clip: auto;
+}
\ No newline at end of file
diff --git a/index/css/fonts/flexslider-icon.eot b/index/css/fonts/flexslider-icon.eot
new file mode 100644
index 0000000..97c4196
Binary files /dev/null and b/index/css/fonts/flexslider-icon.eot differ
diff --git a/index/css/fonts/flexslider-icon.svg b/index/css/fonts/flexslider-icon.svg
new file mode 100644
index 0000000..89fd1ab
--- /dev/null
+++ b/index/css/fonts/flexslider-icon.svg
@@ -0,0 +1,19 @@
+
+
+
+
+This is a custom SVG font generated by IcoMoon.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/index/css/fonts/flexslider-icon.ttf b/index/css/fonts/flexslider-icon.ttf
new file mode 100644
index 0000000..0543298
Binary files /dev/null and b/index/css/fonts/flexslider-icon.ttf differ
diff --git a/index/css/fonts/flexslider-icon.woff b/index/css/fonts/flexslider-icon.woff
new file mode 100644
index 0000000..10c4eeb
Binary files /dev/null and b/index/css/fonts/flexslider-icon.woff differ
diff --git a/index/css/light-box.css b/index/css/light-box.css
new file mode 100644
index 0000000..b5136e0
--- /dev/null
+++ b/index/css/light-box.css
@@ -0,0 +1,216 @@
+/* LIGHT BOX */
+
+body:after {
+ content: url(../img/close.png) url(../img/loading.gif) url(../img/prev.png) url(../img/next.png);
+ display: none;
+}
+
+body.lb-disable-scrolling {
+ overflow: hidden;
+}
+
+.lightboxOverlay {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 99999;
+ background-color: black;
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
+ opacity: 0.8;
+ display: none;
+}
+
+.lightbox {
+ position: absolute;
+ margin-top: 0%;
+ left: 0;
+ width: 100%;
+ z-index: 100000;
+ text-align: center;
+ line-height: 0;
+ font-weight: normal;
+}
+
+.lightbox .lb-image {
+ display: block;
+ height: auto;
+ max-width: inherit;
+ max-height: none;
+ border-radius: 5px;
+
+ /* Image border */
+ border: 10px solid white;
+}
+
+.lightbox a img {
+ border: none;
+}
+
+.lb-outerContainer {
+ position: relative;
+ *zoom: 1;
+ width: 250px;
+ height: 250px;
+ margin: 0 auto;
+ border-radius: 4px;
+
+ /* Background color behind image.
+ This is visible during transitions. */
+ background-color: white;
+}
+
+.lb-outerContainer:after {
+ content: "";
+ display: table;
+ clear: both;
+}
+
+.lb-loader {
+ position: absolute;
+ top: 43%;
+ left: 0;
+ height: 25%;
+ width: 100%;
+ text-align: center;
+ line-height: 0;
+}
+
+.lb-cancel {
+ display: block;
+ width: 32px;
+ height: 32px;
+ margin: 0 auto;
+ background: url(../img/loading.gif) no-repeat;
+}
+
+.lb-nav {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ width: 100%;
+ z-index: 10;
+}
+
+.lb-container > .nav {
+ left: 0;
+}
+
+.lb-nav a {
+ outline: none;
+ background-image: url('data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==');
+}
+
+.lb-prev, .lb-next {
+ height: 100%;
+ cursor: pointer;
+ display: block;
+}
+
+.lb-nav a.lb-prev {
+ width: 34%;
+ left: 0;
+ float: left;
+ background: url(../img/prev.png) left 48% no-repeat;
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
+ opacity: 0;
+ -webkit-transition: opacity 0.6s;
+ -moz-transition: opacity 0.6s;
+ -o-transition: opacity 0.6s;
+ transition: opacity 0.6s;
+}
+
+.lb-nav a.lb-prev:hover {
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
+ opacity: 1;
+}
+
+.lb-nav a.lb-next {
+ width: 64%;
+ right: 0;
+ float: right;
+ background: url(../img/next.png) right 48% no-repeat;
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
+ opacity: 0;
+ -webkit-transition: opacity 0.6s;
+ -moz-transition: opacity 0.6s;
+ -o-transition: opacity 0.6s;
+ transition: opacity 0.6s;
+}
+
+.lb-nav a.lb-next:hover {
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
+ opacity: 1;
+}
+
+.lb-dataContainer {
+ margin: 0 auto;
+ padding-top: 5px;
+ *zoom: 1;
+ width: 100%;
+ -moz-border-radius-bottomleft: 4px;
+ -webkit-border-bottom-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+ -moz-border-radius-bottomright: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+}
+
+.lb-dataContainer:after {
+ content: "";
+ display: table;
+ clear: both;
+}
+
+.lb-data {
+ padding: 0 4px;
+ color: #ccc;
+}
+
+.lb-data .lb-details {
+ width: 85%;
+ float: left;
+ text-align: left;
+ line-height: 1.1em;
+}
+
+.lb-data .lb-caption {
+ font-size: 13px;
+ font-weight: bold;
+ line-height: 1em;
+}
+
+.lb-data .lb-caption a {
+ color: #4ae;
+}
+
+.lb-data .lb-number {
+ margin-top: 15px;
+ display: block;
+ clear: left;
+ padding-bottom: 1em;
+ font-size: 13px;
+ color: #999999;
+}
+
+.lb-data .lb-close {
+ display: block;
+ float: right;
+ width: 30px;
+ height: 30px;
+ background: url(../img/close.png) top right no-repeat;
+ text-align: right;
+ outline: none;
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70);
+ opacity: 0.7;
+ -webkit-transition: opacity 0.2s;
+ -moz-transition: opacity 0.2s;
+ -o-transition: opacity 0.2s;
+ transition: opacity 0.2s;
+}
+
+.lb-data .lb-close:hover {
+ cursor: pointer;
+ filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
+ opacity: 1;
+}
\ No newline at end of file
diff --git a/index/css/owl-carousel.css b/index/css/owl-carousel.css
new file mode 100644
index 0000000..7dc7bdc
--- /dev/null
+++ b/index/css/owl-carousel.css
@@ -0,0 +1,181 @@
+/**
+ * Owl Carousel v2.3.1
+ * Copyright 2013-2018 David Deutsch
+ * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
+ */
+/*
+ * Owl Carousel - Core
+ */
+.owl-carousel {
+ display: none;
+ width: 100%;
+ -webkit-tap-highlight-color: transparent;
+ /* position relative and z-index fix webkit rendering fonts issue */
+ position: relative;
+ z-index: 1; }
+ .owl-carousel .owl-stage {
+ position: relative;
+ -ms-touch-action: pan-Y;
+ touch-action: manipulation;
+ -moz-backface-visibility: hidden;
+ /* fix firefox animation glitch */ }
+ .owl-carousel .owl-stage:after {
+ content: ".";
+ display: block;
+ clear: both;
+ visibility: hidden;
+ line-height: 0;
+ height: 0; }
+ .owl-carousel .owl-stage-outer {
+ position: relative;
+ overflow: hidden;
+ /* fix for flashing background */
+ -webkit-transform: translate3d(0px, 0px, 0px); }
+ .owl-carousel .owl-wrapper,
+ .owl-carousel .owl-item {
+ -webkit-backface-visibility: hidden;
+ -moz-backface-visibility: hidden;
+ -ms-backface-visibility: hidden;
+ -webkit-transform: translate3d(0, 0, 0);
+ -moz-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0); }
+ .owl-carousel .owl-item {
+ position: relative;
+ min-height: 1px;
+ float: left;
+ -webkit-backface-visibility: hidden;
+ -webkit-tap-highlight-color: transparent;
+ -webkit-touch-callout: none; }
+ .owl-carousel .owl-item img {
+ display: block;
+ width: 100%; }
+ .owl-carousel .owl-nav.disabled,
+ .owl-carousel .owl-dots.disabled {
+ display: none; }
+ .owl-carousel .owl-nav .owl-prev,
+ .owl-carousel .owl-nav .owl-next,
+ .owl-carousel .owl-dot {
+ cursor: pointer;
+ cursor: hand;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none; }
+ .owl-carousel .owl-nav button.owl-prev,
+ .owl-carousel .owl-nav button.owl-next,
+ .owl-carousel button.owl-dot {
+ background: none;
+ color: inherit;
+ border: none;
+ padding: 0 !important;
+ font: inherit; }
+ .owl-carousel.owl-loaded {
+ display: block; }
+ .owl-carousel.owl-loading {
+ opacity: 0;
+ display: block; }
+ .owl-carousel.owl-hidden {
+ opacity: 0; }
+ .owl-carousel.owl-refresh .owl-item {
+ visibility: hidden; }
+ .owl-carousel.owl-drag .owl-item {
+ -ms-touch-action: none;
+ touch-action: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none; }
+ .owl-carousel.owl-grab {
+ cursor: move;
+ cursor: grab; }
+ .owl-carousel.owl-rtl {
+ direction: rtl; }
+ .owl-carousel.owl-rtl .owl-item {
+ float: right; }
+
+/* No Js */
+.no-js .owl-carousel {
+ display: block; }
+
+/*
+ * Owl Carousel - Animate Plugin
+ */
+.owl-carousel .animated {
+ animation-duration: 1000ms;
+ animation-fill-mode: both; }
+
+.owl-carousel .owl-animated-in {
+ z-index: 0; }
+
+.owl-carousel .owl-animated-out {
+ z-index: 1; }
+
+.owl-carousel .fadeOut {
+ animation-name: fadeOut; }
+
+@keyframes fadeOut {
+ 0% {
+ opacity: 1; }
+ 100% {
+ opacity: 0; } }
+
+/*
+ * Owl Carousel - Auto Height Plugin
+ */
+.owl-height {
+ transition: height 500ms ease-in-out; }
+
+/*
+ * Owl Carousel - Lazy Load Plugin
+ */
+.owl-carousel .owl-item .owl-lazy {
+ opacity: 0;
+ transition: opacity 400ms ease; }
+
+.owl-carousel .owl-item img.owl-lazy {
+ transform-style: preserve-3d; }
+
+/*
+ * Owl Carousel - Video Plugin
+ */
+.owl-carousel .owl-video-wrapper {
+ position: relative;
+ height: 100%;
+ background: #000; }
+
+.owl-carousel .owl-video-play-icon {
+ position: absolute;
+ height: 80px;
+ width: 80px;
+ left: 50%;
+ top: 50%;
+ margin-left: -40px;
+ margin-top: -40px;
+ background: url("../../css/owl.video.play.png") no-repeat;
+ cursor: pointer;
+ z-index: 1;
+ -webkit-backface-visibility: hidden;
+ transition: transform 100ms ease; }
+
+.owl-carousel .owl-video-play-icon:hover {
+ -ms-transform: scale(1.3, 1.3);
+ transform: scale(1.3, 1.3); }
+
+.owl-carousel .owl-video-playing .owl-video-tn,
+.owl-carousel .owl-video-playing .owl-video-play-icon {
+ display: none; }
+
+.owl-carousel .owl-video-tn {
+ opacity: 0;
+ height: 100%;
+ background-position: center center;
+ background-repeat: no-repeat;
+ background-size: contain;
+ transition: opacity 400ms ease; }
+
+.owl-carousel .owl-video-frame {
+ position: relative;
+ z-index: 1;
+ height: 100%;
+ width: 100%; }
\ No newline at end of file
diff --git a/index/css/templatemo-style.css b/index/css/templatemo-style.css
new file mode 100644
index 0000000..b69f5d1
--- /dev/null
+++ b/index/css/templatemo-style.css
@@ -0,0 +1,1068 @@
+body {
+ font-family: 'Open Sans', sans-serif;
+}
+
+p {
+ font-size: 13px;
+ color: #7a7a7a;
+ line-height: 24px;
+}
+
+.page-content {
+ width: 77.5%;
+ float: right;
+}
+
+.content-section {
+ padding-top: 80px;
+ position: relative;
+ width: 100%;
+ display: inline-block;
+ height: auto;
+ left: 50%;
+ text-align: center;
+ -webkit-transform: translateX(-50%);
+ -moz-transform: translateX(-50%);
+ -ms-transform: translateX(-50%);
+ -o-transform: translateX(-50%);
+ transform: translateX(-50%);
+}
+
+.section-heading {
+ text-align: left;
+ position: relative;
+ margin-bottom: 60px;
+}
+
+.section-heading h1 {
+ margin-top: 0px;
+ font-size: 32px;
+ color: #232323;
+ display: inline-block;
+ margin-right: 50px;
+}
+.tlinks{text-indent:-9999px;height:0;line-height:0;font-size:0;overflow:hidden;}
+.section-heading em {
+ font-style: normal;
+ font-weight: 700;
+ color: #45489a;
+}
+
+.section-heading p {
+ display: inline-block;
+ font-size: 15px;
+ line-height: 26px;
+ color: #343434;
+ position: absolute;
+ top: 12.5px;
+}
+
+.white-button a {
+ font-size: 13px;
+ font-weight: 600;
+ color: #45489a;
+ text-transform: capitalize;
+ background-color: #fff;
+ display: inline-block;
+ height: 44px;
+ line-height: 44px;
+ padding: 0px 25px;
+ letter-spacing: 0.25px;
+ text-decoration: none;
+ transition: all 0.3s;
+}
+
+.white-button a:hover {
+ background-color: #45489a;
+ color: #fff;
+}
+
+.accent-button a {
+ font-size: 13px;
+ font-weight: 600;
+ color: #fff;
+ text-transform: capitalize;
+ background-color: #45489a;
+ display: inline-block;
+ height: 44px;
+ line-height: 44px;
+ padding: 0px 25px;
+ letter-spacing: 0.25px;
+ text-decoration: none;
+ transition: all 0.3s;
+}
+
+.accent-button a:hover {
+ background-color: #fff;
+ color: #45489a;
+}
+
+header {
+ position: fixed;
+ top: 0;
+ transition: top 0.3s ease-in-out;
+ width: 100%;
+}
+
+.nav-up {
+ top: -75px;
+}
+
+/* Responsive Navigation */
+
+.responsive-nav {
+ position: fixed;
+ z-index: 10;
+ width: 100%;
+ height: 80px;
+ background-color: rgba(250,250,250,.95);
+ box-shadow: 0px 5px 15px rgba(0,0,0,0.2);
+}
+
+.navbar-toggle {
+ position: absolute;
+ top: 40%;
+ left: 50%;
+ display: inline-block;
+ -webkit-transform: translateX(-50%) translateY(-50%);
+ -moz-transform: translateX(-50%) translateY(-50%);
+ -ms-transform: translateX(-50%) translateY(-50%);
+ -o-transform: translateX(-50%) translateY(-50%);
+ transform: translateX(-50%) translateY(-50%);
+}
+
+.navbar-nav {
+ margin: 0;
+ border: none;
+}
+
+#main-nav ul {
+ text-align: center;
+ background-color: rgba(0,0,0,0.9);
+ margin-top: 59px;
+ width: 100%;
+}
+#main-nav ul li {
+ margin: 15px 0px;
+}
+#main-nav ul li:hover {
+ background-color: transparent;
+}
+#main-nav ul li a {
+ font-size: 15px;
+ text-transform: capitalize;
+ color: #fff;
+ box-shadow: none;
+ border: none;
+}
+
+#main-nav ul li a:hover {
+ opacity: 0.5;
+ background-color: transparent;
+}
+
+.navbar-toggle span {
+ background-color: #232323;
+}
+
+
+/* Sidebar Style */
+
+.sidebar-navigation {
+ width: 22.5%;
+ float: left;
+ height: 100%;
+ position: fixed;
+ background-color: rgba(12,12,12,0.9);
+ z-index: 10;
+}
+
+.sidebar-navigation .logo {
+ position: absolute;
+ width: 100%;
+ height: 140px;
+ line-height: 100px;
+ background-color: #45489a;
+ padding: 20px;
+ text-align: center;
+}
+
+.sidebar-navigation .logo a {
+ text-decoration: none;
+ color: #fff;
+ font-size: 24px;
+ font-weight: 700;
+ text-transform: uppercase;
+ letter-spacing: 0.5px;
+ height: 100px;
+ width: 100%;
+ display: inline-block;
+ border: 1px solid rgba(250,250,250,0.5);
+}
+
+.sidebar-navigation .logo em {
+ font-style: normal;
+ font-weight: 300;
+}
+
+.sidebar-navigation nav {
+ position: relative;
+ top: 60%;
+ left: 60%;
+ -webkit-transform: translateX(-60%) translateY(-60%);
+ -moz-transform: translateX(-60%) translateY(-60%);
+ -ms-transform: translateX(-60%) translateY(-60%);
+ -o-transform: translateX(-60%) translateY(-60%);
+ transform: translateX(-60%) translateY(-60%);
+}
+
+.sidebar-navigation ul {
+ margin-left: 45px;
+ list-style: none;
+ padding: 0;
+}
+.sidebar-navigation li{
+ padding: 10px 0;
+}
+.sidebar-navigation span{
+ display: inline-block;
+ position:relative;
+}
+.sidebar-navigation nav a{
+ display: inline-block;
+ color: #fff;
+ margin-top: 5px;
+ text-decoration: none!important;
+ font-size: 15px;
+ letter-spacing: 0.5px;
+ text-transform: capitalize;
+}
+.circle{
+ margin-right: 5px;
+ height: 10px;
+ width: 10px;
+ left: 0px;
+ top: -1px;
+ border-radius: 50%;
+ background-color: transparent;
+ border: 2px solid #fff;
+ transition: all 0.3s;
+}
+.rect{
+ height: 1px;
+ width: 0px;
+ left: 0;
+ bottom: 5.5px;
+ background-color: #fff;
+ -webkit-transition: -webkit-transform 0.1s, width 0.6s;
+ -moz-transition: -webkit-transform 0.1s, width 0.6s;
+ transition: transform 0.1s, width 0.6s;
+}
+.sidebar-navigation nav a:focus {
+ color: #fff;
+}
+.sidebar-navigation nav a:hover, nav .active-section {
+ color: #fff;
+}
+.sidebar-navigation nav a:hover span, nav .active-section span{
+ background-color: #ddd;
+}
+.sidebar-navigation nav .active-section .rect{
+ width: 30px;
+}
+.sidebar-navigation nav .active-section .circle{
+ background-color: #fff;
+}
+
+.sidebar-navigation .social-icons {
+ position: absolute;
+ width: 100%;
+ bottom: 10px;
+ padding: 0;
+ margin: 0;
+ text-align: center;
+}
+
+.sidebar-navigation .social-icons li {
+ display: inline-block;
+ margin-right: 15px;
+ margin-top: 0px;
+ margin-bottom: 0px;
+}
+.sidebar-navigation .social-icons li:last-child {
+ margin-right: 0px;
+}
+
+.sidebar-navigation .social-icons li a {
+ font-size: 18px;
+ color: #fff;
+ transition: all 0.5s;
+}
+
+.sidebar-navigation .social-icons li a:hover {
+ color: #45489a;
+}
+
+
+/* Slider Style */
+
+.slider .content-section {
+ padding-top: 0px;
+ min-width: 100%;
+ min-height: 100vh;
+ width: 100%;
+ height: 100vh;
+ text-align: center;
+}
+
+.slider p a {
+ color: #FFF;
+}
+.slider p a:hover {
+ color: #FF0;
+ text-decoration: none;
+}
+
+.Modern-Slider .info {
+ text-align: right;
+ position: absolute;
+ z-index: 10;
+ top: 50%;
+ right: 60px;
+ -webkit-transform: translateY(-50%);
+ -moz-transform: translateY(-50%);
+ -ms-transform: translateY(-50%);
+ -o-transform: translateY(-50%);
+ transform: translateY(-50%);
+ display: inline-block;
+}
+
+.Modern-Slider .info h1 {
+ margin-top: 0px;
+ margin-bottom: 15px;
+ font-size: 48px;
+ color: #fff;
+ font-weight: 700;
+}
+
+.Modern-Slider .info p {
+ font-size: 15px;
+ color: #fff;
+}
+
+.Modern-Slider .info .white-button {
+ margin-top: 30px;
+}
+
+.Modern-Slider .info .white-button a:focus {
+ outline: none;
+}
+
+.Modern-Slider .slick-dots {
+ opacity: 0;
+}
+
+.Modern-Slider .NextArrow{
+ outline: none;
+ display: none;
+ position:absolute;
+ top:60px;
+ right:60px;
+ width:50px;
+ height:50px;
+ background:rgba(0,0,0,.50);
+ border:0 none;
+ margin-top:-22.5px;
+ text-align:center;
+ font:32px/50px FontAwesome;
+ color:#FFF;
+ z-index:5;
+}
+
+.Modern-Slider .NextArrow:before{content:'\f105';}
+
+.Modern-Slider .PrevArrow{
+ outline: none;
+ position:absolute;
+ top:60px;
+ right: 120px;
+ width:50px;
+ height:50px;
+ background:rgba(0,0,0,.50);
+ border:0 none;
+ margin-top:-22.5px;
+ text-align:center;
+ font:32px/50px FontAwesome;
+ color:#FFF;
+ z-index:5;
+}
+
+.Modern-Slider .item .image {
+ width: 100%;
+ height: 100vh;
+ background-position: center center;
+ background-size: cover;
+ display: block;
+}
+
+.Modern-Slider .item-1 .image {
+ background-image: url(../img/slide_1.jpg);
+}
+
+.Modern-Slider .item-2 .image {
+ background-image: url(../img/slide_2.jpg);
+}
+
+.Modern-Slider .item-3 .image {
+ background-image: url(../img/slide_3.jpg);
+}
+
+.Modern-Slider .PrevArrow:before{content:'\f104';}
+
+.Modern-Slider .item .image {
+ animation: zoomin 12s ease-in-out infinite alternate;
+ -webkit-animation: zoomin 12s ease-in-out infinite alternate;
+}
+
+@keyframes zoomin {
+ 0% {-webkit-transform: scale(1);}
+ 100% {-webkit-transform: scale(1.2);}
+}
+
+.Modern-Slider {background:transparent;}
+
+/* ==== Slick Slider Css Ruls === */
+.slick-slider{position:relative;display:block;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-touch-callout:none;-khtml-user-select:none;-ms-touch-action:pan-y;touch-action:pan-y;-webkit-tap-highlight-color:transparent}
+.slick-list{position:relative;display:block;overflow:hidden;margin:0;padding:0}
+.slick-list:focus{outline:none}.slick-list.dragging{cursor:hand}
+.slick-slider .slick-track,.slick-slider .slick-list{-webkit-transform:translate3d(0,0,0);-ms-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}
+.slick-track{position:relative;top:0;left:0;display:block}
+.slick-track:before,.slick-track:after{display:table;content:''}.slick-track:after{clear:both}
+.slick-loading .slick-track{visibility:hidden}
+.slick-slide{display:none;float:left /* If RTL Make This Right */ ;height:100%;min-height:1px}
+.slick-slide.dragging img{pointer-events:none}
+.slick-initialized .slick-slide{display:block}
+.slick-loading .slick-slide{visibility:hidden}
+.slick-vertical .slick-slide{display:block;height:auto;border:1px solid transparent}
+
+
+/* Featured Style */
+
+#featured {
+ padding-left: 60px;
+ padding-right: 60px;
+ padding-bottom: 80px;
+ border-bottom: 1px solid #eee;
+}
+
+#featured .section-heading {
+ margin-right: 20%;
+}
+
+#featured .content-section {
+ display: inline-block;
+ position: relative;
+}
+
+#featured .owl-dots {
+ margin-top: 40px;
+}
+
+#featured .owl-dots .owl-dot span {
+ width: 12px;
+ height: 12px;
+ background-color: #cdcdcd!important;
+ display: inline-block;
+ border-radius: 50%;
+ margin: 0 3px;
+}
+
+#featured .owl-dots .active span {
+ background-color: #45489a!important;
+}
+
+#featured .owl-dots button {
+ outline: none;
+}
+
+#featured .owl-nav {
+ position: absolute;
+ display: inline-block;
+ top: -110px;
+ right: 0;
+}
+
+#featured .owl-nav button:focus {
+ outline: none;
+}
+
+#featured .owl-nav .owl-prev span {
+ margin-right: 10px;
+}
+
+#featured .owl-nav .owl-next span, #featured .owl-nav .owl-prev span {
+ outline: none;
+ width: 50px;
+ height: 50px;
+ display: inline-block;
+ text-align: center;
+ line-height: 42px;
+ background-color: #eee;
+ color: #232323;
+ font-size: 42px;
+ transition: all 0.5s;
+}
+
+#featured .owl-nav span:hover {
+ background-color: #45489a;
+ color: #fff;
+}
+
+#featured .item {
+ text-align: left;
+ position: relative;
+ z-index: 10;
+}
+
+#featured .item .image {
+ position: relative;
+}
+
+#featured .item .image img {
+ width: 100%;
+ overflow: hidden;
+}
+
+#featured .item .image .featured-button a {
+ font-size: 13px;
+ font-weight: 600;
+ color: #fff;
+ text-align: center;
+ text-transform: capitalize;
+ background-color: rgba(69,72,154, 0.9);
+ display: inline-block;
+ height: 44px;
+ line-height: 44px;
+ width: 100%;
+ letter-spacing: 0.25px;
+ text-decoration: none;
+ transition: all 0.5s;
+ position: absolute;
+ z-index: 9;
+ bottom: -44px;
+ opacity: 0;
+}
+
+#featured .item:hover .featured-button a {
+ bottom: 0;
+ opacity: 1;
+}
+
+#featured .item .text-content {
+ padding-top: 20px;
+ background-color: #fff;
+ position: relative;
+ z-index: 10;
+}
+
+#featured .item .text-content h4 {
+ margin-top: 0px;
+ margin-bottom: 5px;
+ font-size: 21px;
+ font-weight: 600;
+ color: #232323;
+ letter-spacing: 0.5px;
+}
+
+#featured .item .text-content span {
+ display: inline-block;
+ font-size: 15px;
+ font-weight: 600;
+ color: #7a7a7a;
+ letter-spacing: 0.5px;
+ margin-bottom: 12.5px;
+}
+
+
+
+/* Projects Style */
+
+#projects {
+ padding-left: 60px;
+ padding-right: 60px;
+ padding-bottom: 50px;
+}
+
+#projects .masonry {
+ position: relative;
+ width: 100%;
+}
+
+#projects .masonry .item img {
+ transition: all 1s;
+ width: 100%;
+ overflow: hidden;
+ margin-bottom: 30px;
+}
+
+#projects .masonry .item img:hover {
+ opacity: 0.5;
+}
+
+
+
+/* Video Presentation Style */
+
+#video {
+ text-align: center;
+ background-color: #f4f4f4;
+ padding: 100px 60px;
+}
+
+#video .section-heading {
+ margin-bottom: 30px;
+ text-align: center;
+}
+
+#video .section-heading h1 {
+ display: block;
+ margin: 0px;
+}
+
+#video .section-heading p {
+ position: relative;
+ margin: 0px;
+}
+
+#video .accent-button {
+ margin-top: 30px;
+}
+
+.box-video{
+ width: 100%;
+ position: relative;
+ margin-top: 30px;
+ cursor: pointer;
+ overflow: hidden;
+}
+
+.box-video .bg-video{
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: cover;
+ z-index: 2;
+}
+
+.box-video .video-container{
+ position: relative;
+ margin: 0;
+ z-index: 1;
+}
+
+.box-video .bt-play {
+ position: absolute;
+ top:50%;
+ left:50%;
+ margin:-30px 0 0 -30px;
+ display: inline-block;
+ width: 60px;
+ height: 60px;
+ background:#fff;
+ border-radius: 50%;
+ text-indent: -999em;
+ cursor: pointer;
+ z-index:2;
+ -webkit-transition: all .3s ease-out;
+ transition: all .3s ease-out;
+}
+.box-video .bt-play:after {
+ content: '';
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ height: 0;
+ width: 0;
+ margin: -12px 0 0 -6px;
+ border: solid transparent;
+ border-left-color: #000;
+ border-width: 12px 20px;
+ -webkit-transition: all .3s ease-out;
+ transition: all .3s ease-out;
+}
+.box-video:hover .bt-play {
+ transform: scale(1.1);
+}
+
+.box-video.open .bg-video{
+ visibility: hidden;
+ opacity: 0;
+ -webkit-transition: all .6s .8s;
+ transition: all .6s .8s;
+}
+.box-video.open .video-container{
+ opacity: 1;
+ -webkit-transition: all .6s .8s;
+ transition: all .6s .8s;
+}
+
+
+
+
+/* Blog Style */
+
+#blog {
+ padding-left: 60px;
+ padding-right: 60px;
+ padding-bottom: 80px;
+}
+
+#blog .tabs {
+ list-style: none;
+ margin: 0px;
+ padding: 0px;
+ height: 90px;
+ width: 100%;
+ background-color: #eee;
+ border-bottom: 10px solid #45489a;
+}
+
+#blog .tabs li {
+ display: inline-block;
+ text-align: center;
+ width: 25%;
+ float: left;
+ margin: 0;
+ padding: 0;
+}
+
+#blog .tabs a {
+ display: block;
+ text-align: center;
+ text-decoration: none;
+ text-transform: capitalize;
+ letter-spacing: 0.5px;
+ color: #232323;
+ font-size: 19px;
+ line-height: 80px;
+ font-weight: 600;
+ transition: 0.5s;
+}
+
+#blog .tabs a:hover {
+ color: #45489a;
+}
+
+
+#blog .tabs .active:hover {
+ color: #fff;
+}
+
+#blog .tabs .active {
+ background-color: #45489a;
+ color: #fff;
+}
+
+.tabgroup {
+ background-color: #f4f4f4;
+ padding: 20px 30px;
+}
+
+.clearfix:after {
+ content:"";
+ display:table;
+ clear:both;
+}
+
+#blog .tabgroup ul {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+
+#blog .tabgroup ul li {
+ display: inline-block;
+ text-align: left;
+ margin-bottom: 10px;
+ padding-bottom: 20px;
+ border-bottom: 1px solid #ddd;
+}
+
+#blog .tabgroup ul li:last-child {
+ border-bottom: none;
+ margin-bottom: 0px;
+ padding-bottom: 10px;
+}
+
+#blog .tabgroup ul li img {
+ float: left;
+ margin-right: 30px;
+ max-width: 100%;
+ overflow: hidden;
+}
+#blog .tabgroup ul li .text-content {
+ display: inline;
+}
+
+#blog .item .text-content h4 {
+ padding-top: 7.5px;
+ margin-top: 0px;
+ margin-bottom: 5px;
+ font-size: 21px;
+ font-weight: 600;
+ color: #232323;
+ letter-spacing: 0.5px;
+}
+
+#blog .item .text-content span {
+ display: inline-block;
+ font-size: 15px;
+ font-weight: 600;
+ color: #7a7a7a;
+ letter-spacing: 0.5px;
+ margin-bottom: 15px;
+}
+
+#blog .item .text-content .accent-button {
+ margin-top: 25px;
+}
+
+
+
+
+/* Contact Style */
+
+#contact {
+ padding-top: 0px;
+}
+
+#contact-content {
+ padding: 80px 60px;
+}
+
+#contact input {
+ border-radius: 0px;
+ padding-left: 15px;
+ font-size: 13px;
+ color: #aaa;
+ background-color: #f4f4f4;
+ border: 1px solid #eee;
+ outline: none;
+ box-shadow: none;
+ line-height: 40px;
+ height: 40px;
+ width: 100%;
+ margin-bottom: 25px;
+}
+
+#contact textarea {
+ border-radius: 0px;
+ padding-left: 15px;
+ padding-top: 10px;
+ font-size: 13px;
+ color: #aaa;
+ background-color: #f4f4f4;
+ border: 1px solid #eee;
+ outline: none;
+ box-shadow: none;
+ height: 200px;
+ max-height: 250px;
+ width: 100%;
+ max-width: 100%;
+ margin-bottom: 25px;
+}
+
+#contact button {
+ font-size: 13px;
+ border-radius: 0px;
+ font-weight: 600;
+ color: #fff;
+ text-transform: capitalize;
+ background-color: #45489a;
+ display: inline-block;
+ height: 44px;
+ line-height: 24px;
+ outline: none;
+ box-shadow: none;
+ width: 100%;
+ letter-spacing: 0.25px;
+ text-decoration: none;
+ transition: all 0.3s;
+}
+
+#contact button:hover {
+ color: #232323;
+ background-color: #f4f4f4;
+}
+
+
+
+/* Footer Style */
+
+.footer {
+ background-color: rgba(12,12,12,0.9);
+ height: 80px;
+ line-height: 80px;
+ display: inline-block;
+ text-align: center;
+ width: 100%;
+}
+
+.footer p {
+ margin-bottom: 0px;
+ font-size: 13px;
+ line-height: 80px;
+ color: #fff;
+ letter-spacing: 0.5px;
+ font-weight: 300;
+}
+
+.footer p a {
+ text-decoration: none;
+ color: #fff;
+ font-weight: 600;
+}
+
+
+
+/* Responsive Style */
+
+@media (max-width: 992px) {
+
+ .responsive-nav {
+ display: none;
+ }
+
+ .sidebar-navigation .logo a {
+ font-size: 18px;
+ }
+
+ .sidebar-navigation nav a {
+ font-size: 13px;
+ }
+
+ .sidebar-navigation nav ul {
+ margin-left: 30px;
+ }
+
+ .sidebar-navigation .social-icons li a {
+ font-size: 15px;
+ }
+
+}
+
+
+@media (max-width: 767px) {
+
+ .responsive-nav {
+ display: block;
+ height: 60px;
+ }
+
+ .page-content {
+ width: 100%;
+ }
+
+ .Modern-Slider .info {
+ text-align: center;
+ right: 0px;
+ padding: 0px 30px;
+ }
+
+ .Modern-Slider .NextArrow{
+ outline: none;
+ display: none;
+ position:absolute;
+ top:120px;
+ right: 50%;
+ transform: translateX(50%);
+ margin-right: -30px;
+ width:50px;
+ height:50px;
+ background:rgba(0,0,0,.50);
+ border:0 none;
+ text-align:center;
+ font:32px/50px FontAwesome;
+ color:#FFF;
+ z-index:5;
+ }
+
+ .Modern-Slider .NextArrow:before{content:'\f105';}
+
+ .Modern-Slider .PrevArrow{
+ outline: none;
+ position:absolute;
+ top:120px;
+ left: 50%;
+ transform: translateX(-50%);
+ margin-left: -30px;
+ width:50px;
+ height:50px;
+ background:rgba(0,0,0,.50);
+ border:0 none;
+ text-align:center;
+ font:32px/50px FontAwesome;
+ color:#FFF;
+ z-index:5;
+ }
+
+
+
+}
+
+@media (max-width: 690px) {
+
+ .section-heading p {
+ position: relative;
+ }
+
+ #featured {
+ padding-left: 15px;
+ padding-right: 15px;
+ }
+
+ #featured .owl-nav {
+ position: absolute;
+ display: inline-block;
+ top: -220px;
+ right: 0;
+ }
+
+ #projects {
+ padding-left: 15px;
+ padding-right: 15px;
+ }
+
+ #video {
+ padding-left: 15px;
+ padding-right: 15px;
+ }
+
+ #blog {
+ padding-left: 15px;
+ padding-right: 15px;
+ }
+
+ #blog .tabs a {
+ font-size: 13px;
+ }
+
+ #blog .tabgroup ul li img {
+ float: none;
+ width: 100%;
+ margin-bottom: 15px;
+ }
+ #blog .tabgroup ul li .text-content {
+ display: block;
+ }
+
+ #contact-content {
+ padding-left: 15px;
+ padding-right: 15px;
+ }
+
+}
\ No newline at end of file
diff --git a/index/fonts/FontAwesome.otf b/index/fonts/FontAwesome.otf
new file mode 100644
index 0000000..401ec0f
Binary files /dev/null and b/index/fonts/FontAwesome.otf differ
diff --git a/index/fonts/fontawesome-webfont.eot b/index/fonts/fontawesome-webfont.eot
new file mode 100644
index 0000000..e9f60ca
Binary files /dev/null and b/index/fonts/fontawesome-webfont.eot differ
diff --git a/index/fonts/fontawesome-webfont.svg b/index/fonts/fontawesome-webfont.svg
new file mode 100644
index 0000000..855c845
--- /dev/null
+++ b/index/fonts/fontawesome-webfont.svg
@@ -0,0 +1,2671 @@
+
+
+
+
+Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016
+ By ,,,
+Copyright Dave Gandy 2016. All rights reserved.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/index/fonts/fontawesome-webfont.ttf b/index/fonts/fontawesome-webfont.ttf
new file mode 100644
index 0000000..35acda2
Binary files /dev/null and b/index/fonts/fontawesome-webfont.ttf differ
diff --git a/index/fonts/fontawesome-webfont.woff b/index/fonts/fontawesome-webfont.woff
new file mode 100644
index 0000000..400014a
Binary files /dev/null and b/index/fonts/fontawesome-webfont.woff differ
diff --git a/index/fonts/fontawesome-webfont.woff2 b/index/fonts/fontawesome-webfont.woff2
new file mode 100644
index 0000000..4d13fc6
Binary files /dev/null and b/index/fonts/fontawesome-webfont.woff2 differ
diff --git a/index/fonts/glyphicons-halflings-regular.eot b/index/fonts/glyphicons-halflings-regular.eot
new file mode 100644
index 0000000..4a4ca86
Binary files /dev/null and b/index/fonts/glyphicons-halflings-regular.eot differ
diff --git a/index/fonts/glyphicons-halflings-regular.svg b/index/fonts/glyphicons-halflings-regular.svg
new file mode 100644
index 0000000..25691af
--- /dev/null
+++ b/index/fonts/glyphicons-halflings-regular.svg
@@ -0,0 +1,229 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/index/fonts/glyphicons-halflings-regular.ttf b/index/fonts/glyphicons-halflings-regular.ttf
new file mode 100644
index 0000000..67fa00b
Binary files /dev/null and b/index/fonts/glyphicons-halflings-regular.ttf differ
diff --git a/index/fonts/glyphicons-halflings-regular.woff b/index/fonts/glyphicons-halflings-regular.woff
new file mode 100644
index 0000000..8c54182
Binary files /dev/null and b/index/fonts/glyphicons-halflings-regular.woff differ
diff --git a/index/img/blog_1.jpg b/index/img/blog_1.jpg
new file mode 100644
index 0000000..90a7883
Binary files /dev/null and b/index/img/blog_1.jpg differ
diff --git a/index/img/blog_2.jpg b/index/img/blog_2.jpg
new file mode 100644
index 0000000..819480f
Binary files /dev/null and b/index/img/blog_2.jpg differ
diff --git a/index/img/blog_3.jpg b/index/img/blog_3.jpg
new file mode 100644
index 0000000..8f0702c
Binary files /dev/null and b/index/img/blog_3.jpg differ
diff --git a/index/img/close.png b/index/img/close.png
new file mode 100644
index 0000000..20baa1d
Binary files /dev/null and b/index/img/close.png differ
diff --git a/index/img/featured_1.jpg b/index/img/featured_1.jpg
new file mode 100644
index 0000000..2cf1216
Binary files /dev/null and b/index/img/featured_1.jpg differ
diff --git a/index/img/featured_2.jpg b/index/img/featured_2.jpg
new file mode 100644
index 0000000..6c1995c
Binary files /dev/null and b/index/img/featured_2.jpg differ
diff --git a/index/img/featured_3.jpg b/index/img/featured_3.jpg
new file mode 100644
index 0000000..6d9955f
Binary files /dev/null and b/index/img/featured_3.jpg differ
diff --git a/index/img/loading.gif b/index/img/loading.gif
new file mode 100644
index 0000000..5087c2a
Binary files /dev/null and b/index/img/loading.gif differ
diff --git a/index/img/next.png b/index/img/next.png
new file mode 100644
index 0000000..08365ac
Binary files /dev/null and b/index/img/next.png differ
diff --git a/index/img/portfolio_1.jpg b/index/img/portfolio_1.jpg
new file mode 100644
index 0000000..2a253eb
Binary files /dev/null and b/index/img/portfolio_1.jpg differ
diff --git a/index/img/portfolio_2.jpg b/index/img/portfolio_2.jpg
new file mode 100644
index 0000000..40078ff
Binary files /dev/null and b/index/img/portfolio_2.jpg differ
diff --git a/index/img/portfolio_3.jpg b/index/img/portfolio_3.jpg
new file mode 100644
index 0000000..978898e
Binary files /dev/null and b/index/img/portfolio_3.jpg differ
diff --git a/index/img/portfolio_4.jpg b/index/img/portfolio_4.jpg
new file mode 100644
index 0000000..0014803
Binary files /dev/null and b/index/img/portfolio_4.jpg differ
diff --git a/index/img/portfolio_5.jpg b/index/img/portfolio_5.jpg
new file mode 100644
index 0000000..124d5d8
Binary files /dev/null and b/index/img/portfolio_5.jpg differ
diff --git a/index/img/portfolio_big_1.jpg b/index/img/portfolio_big_1.jpg
new file mode 100644
index 0000000..32e9ec9
Binary files /dev/null and b/index/img/portfolio_big_1.jpg differ
diff --git a/index/img/portfolio_big_2.jpg b/index/img/portfolio_big_2.jpg
new file mode 100644
index 0000000..2b1b6db
Binary files /dev/null and b/index/img/portfolio_big_2.jpg differ
diff --git a/index/img/portfolio_big_3.jpg b/index/img/portfolio_big_3.jpg
new file mode 100644
index 0000000..c311205
Binary files /dev/null and b/index/img/portfolio_big_3.jpg differ
diff --git a/index/img/portfolio_big_4.jpg b/index/img/portfolio_big_4.jpg
new file mode 100644
index 0000000..5ca0faf
Binary files /dev/null and b/index/img/portfolio_big_4.jpg differ
diff --git a/index/img/portfolio_big_5.jpg b/index/img/portfolio_big_5.jpg
new file mode 100644
index 0000000..661f3c9
Binary files /dev/null and b/index/img/portfolio_big_5.jpg differ
diff --git a/index/img/prev.png b/index/img/prev.png
new file mode 100644
index 0000000..329fa98
Binary files /dev/null and b/index/img/prev.png differ
diff --git a/index/img/slide_1.jpg b/index/img/slide_1.jpg
new file mode 100644
index 0000000..0d3942f
Binary files /dev/null and b/index/img/slide_1.jpg differ
diff --git a/index/img/slide_2.jpg b/index/img/slide_2.jpg
new file mode 100644
index 0000000..a44cd96
Binary files /dev/null and b/index/img/slide_2.jpg differ
diff --git a/index/img/slide_3.jpg b/index/img/slide_3.jpg
new file mode 100644
index 0000000..72a0dc5
Binary files /dev/null and b/index/img/slide_3.jpg differ
diff --git a/index/js/main.js b/index/js/main.js
new file mode 100644
index 0000000..8c94672
--- /dev/null
+++ b/index/js/main.js
@@ -0,0 +1,117 @@
+jQuery(document).ready(function($) {
+
+ 'use strict';
+
+
+ $(".Modern-Slider").slick({
+ autoplay:true,
+ speed:1000,
+ slidesToShow:1,
+ slidesToScroll:1,
+ pauseOnHover:false,
+ dots:true,
+ fade: true,
+ pauseOnDotsHover:true,
+ cssEase:'linear',
+ // fade:true,
+ draggable:false,
+ prevArrow:'
',
+ nextArrow:'
',
+ });
+
+ $('#nav-toggle').on('click', function (event) {
+ event.preventDefault();
+ $('#main-nav').toggleClass("open");
+ });
+
+
+ $('.tabgroup > div').hide();
+ $('.tabgroup > div:first-of-type').show();
+ $('.tabs a').click(function(e){
+ e.preventDefault();
+ var $this = $(this),
+ tabgroup = '#'+$this.parents('.tabs').data('tabgroup'),
+ others = $this.closest('li').siblings().children('a'),
+ target = $this.attr('href');
+ others.removeClass('active');
+ $this.addClass('active');
+ $(tabgroup).children('div').hide();
+ $(target).show();
+
+ })
+
+
+
+ $(".box-video").click(function(){
+ $('iframe',this)[0].src += "&autoplay=1";
+ $(this).addClass('open');
+ });
+
+ $('.owl-carousel').owlCarousel({
+ loop:true,
+ margin:30,
+ responsiveClass:true,
+ responsive:{
+ 0:{
+ items:1,
+ nav:true
+ },
+ 600:{
+ items:2,
+ nav:false
+ },
+ 1000:{
+ items:3,
+ nav:true,
+ loop:false
+ }
+ }
+ })
+
+
+
+ var contentSection = $('.content-section, .main-banner');
+ var navigation = $('nav');
+
+ //when a nav link is clicked, smooth scroll to the section
+ navigation.on('click', 'a', function(event){
+ event.preventDefault(); //prevents previous event
+ smoothScroll($(this.hash));
+ });
+
+ //update navigation on scroll...
+ $(window).on('scroll', function(){
+ updateNavigation();
+ })
+ //...and when the page starts
+ updateNavigation();
+
+ /////FUNCTIONS
+ function updateNavigation(){
+ contentSection.each(function(){
+ var sectionName = $(this).attr('id');
+ var navigationMatch = $('nav a[href="#' + sectionName + '"]');
+ if( ($(this).offset().top - $(window).height()/2 < $(window).scrollTop()) &&
+ ($(this).offset().top + $(this).height() - $(window).height()/2 > $(window).scrollTop()))
+ {
+ navigationMatch.addClass('active-section');
+ }
+ else {
+ navigationMatch.removeClass('active-section');
+ }
+ });
+ }
+ function smoothScroll(target){
+ $('body,html').animate({
+ scrollTop: target.offset().top
+ }, 800);
+ }
+
+
+ $('.button a[href*=#]').on('click', function(e) {
+ e.preventDefault();
+ $('html, body').animate({ scrollTop: $($(this).attr('href')).offset().top -0 }, 500, 'linear');
+ });
+
+
+});
\ No newline at end of file
diff --git a/index/js/plugins.js b/index/js/plugins.js
new file mode 100644
index 0000000..c127260
--- /dev/null
+++ b/index/js/plugins.js
@@ -0,0 +1,6749 @@
+/*
+ _ _ _ _
+ ___| (_) ___| | __ (_)___
+/ __| | |/ __| |/ / | / __|
+\__ \ | | (__| < _ | \__ \
+|___/_|_|\___|_|\_(_)/ |___/
+ |__/
+
+ Version: 1.8.0
+ Author: Ken Wheeler
+ Website: http://kenwheeler.github.io
+ Docs: http://kenwheeler.github.io/slick
+ Repo: http://github.com/kenwheeler/slick
+ Issues: http://github.com/kenwheeler/slick/issues
+
+ */
+/* global window, document, define, jQuery, setInterval, clearInterval */
+(function(factory) {
+ 'use strict';
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof exports !== 'undefined') {
+ module.exports = factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+
+}(function($) {
+ 'use strict';
+ var Slick = window.Slick || {};
+
+ Slick = (function() {
+
+ var instanceUid = 0;
+
+ function Slick(element, settings) {
+
+ var _ = this, dataSettings;
+
+ _.defaults = {
+ accessibility: true,
+ adaptiveHeight: false,
+ appendArrows: $(element),
+ appendDots: $(element),
+ arrows: true,
+ asNavFor: null,
+ prevArrow: '
Previous ',
+ nextArrow: '
Next ',
+ autoplay: false,
+ autoplaySpeed: 3000,
+ centerMode: false,
+ centerPadding: '50px',
+ cssEase: 'ease',
+ customPaging: function(slider, i) {
+ return $('
').text(i + 1);
+ },
+ dots: false,
+ dotsClass: 'slick-dots',
+ draggable: true,
+ easing: 'linear',
+ edgeFriction: 0.35,
+ fade: false,
+ focusOnSelect: false,
+ infinite: true,
+ initialSlide: 0,
+ lazyLoad: 'ondemand',
+ mobileFirst: false,
+ pauseOnHover: true,
+ pauseOnFocus: true,
+ pauseOnDotsHover: false,
+ respondTo: 'window',
+ responsive: null,
+ rows: 1,
+ rtl: false,
+ slide: '',
+ slidesPerRow: 1,
+ slidesToShow: 1,
+ slidesToScroll: 1,
+ speed: 500,
+ swipe: true,
+ swipeToSlide: false,
+ touchMove: true,
+ touchThreshold: 5,
+ useCSS: true,
+ useTransform: true,
+ variableWidth: false,
+ vertical: false,
+ verticalSwiping: false,
+ waitForAnimate: true,
+ zIndex: 1000
+ };
+
+ _.initials = {
+ animating: false,
+ dragging: false,
+ autoPlayTimer: null,
+ currentDirection: 0,
+ currentLeft: null,
+ currentSlide: 0,
+ direction: 1,
+ $dots: null,
+ listWidth: null,
+ listHeight: null,
+ loadIndex: 0,
+ $nextArrow: null,
+ $prevArrow: null,
+ slideCount: null,
+ slideWidth: null,
+ $slideTrack: null,
+ $slides: null,
+ sliding: false,
+ slideOffset: 0,
+ swipeLeft: null,
+ $list: null,
+ touchObject: {},
+ transformsEnabled: false,
+ unslicked: false
+ };
+
+ $.extend(_, _.initials);
+
+ _.activeBreakpoint = null;
+ _.animType = null;
+ _.animProp = null;
+ _.breakpoints = [];
+ _.breakpointSettings = [];
+ _.cssTransitions = false;
+ _.focussed = false;
+ _.interrupted = false;
+ _.hidden = 'hidden';
+ _.paused = true;
+ _.positionProp = null;
+ _.respondTo = null;
+ _.rowCount = 1;
+ _.shouldClick = true;
+ _.$slider = $(element);
+ _.$slidesCache = null;
+ _.transformType = null;
+ _.transitionType = null;
+ _.visibilityChange = 'visibilitychange';
+ _.windowWidth = 0;
+ _.windowTimer = null;
+
+ dataSettings = $(element).data('slick') || {};
+
+ _.options = $.extend({}, _.defaults, settings, dataSettings);
+
+ _.currentSlide = _.options.initialSlide;
+
+ _.originalSettings = _.options;
+
+ if (typeof document.mozHidden !== 'undefined') {
+ _.hidden = 'mozHidden';
+ _.visibilityChange = 'mozvisibilitychange';
+ } else if (typeof document.webkitHidden !== 'undefined') {
+ _.hidden = 'webkitHidden';
+ _.visibilityChange = 'webkitvisibilitychange';
+ }
+
+ _.autoPlay = $.proxy(_.autoPlay, _);
+ _.autoPlayClear = $.proxy(_.autoPlayClear, _);
+ _.autoPlayIterator = $.proxy(_.autoPlayIterator, _);
+ _.changeSlide = $.proxy(_.changeSlide, _);
+ _.clickHandler = $.proxy(_.clickHandler, _);
+ _.selectHandler = $.proxy(_.selectHandler, _);
+ _.setPosition = $.proxy(_.setPosition, _);
+ _.swipeHandler = $.proxy(_.swipeHandler, _);
+ _.dragHandler = $.proxy(_.dragHandler, _);
+ _.keyHandler = $.proxy(_.keyHandler, _);
+
+ _.instanceUid = instanceUid++;
+
+ // A simple way to check for HTML strings
+ // Strict HTML recognition (must start with <)
+ // Extracted from jQuery v1.11 source
+ _.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/;
+
+
+ _.registerBreakpoints();
+ _.init(true);
+
+ }
+
+ return Slick;
+
+ }());
+
+ Slick.prototype.activateADA = function() {
+ var _ = this;
+
+ _.$slideTrack.find('.slick-active').attr({
+ 'aria-hidden': 'false'
+ }).find('a, input, button, select').attr({
+ 'tabindex': '0'
+ });
+
+ };
+
+ Slick.prototype.addSlide = Slick.prototype.slickAdd = function(markup, index, addBefore) {
+
+ var _ = this;
+
+ if (typeof(index) === 'boolean') {
+ addBefore = index;
+ index = null;
+ } else if (index < 0 || (index >= _.slideCount)) {
+ return false;
+ }
+
+ _.unload();
+
+ if (typeof(index) === 'number') {
+ if (index === 0 && _.$slides.length === 0) {
+ $(markup).appendTo(_.$slideTrack);
+ } else if (addBefore) {
+ $(markup).insertBefore(_.$slides.eq(index));
+ } else {
+ $(markup).insertAfter(_.$slides.eq(index));
+ }
+ } else {
+ if (addBefore === true) {
+ $(markup).prependTo(_.$slideTrack);
+ } else {
+ $(markup).appendTo(_.$slideTrack);
+ }
+ }
+
+ _.$slides = _.$slideTrack.children(this.options.slide);
+
+ _.$slideTrack.children(this.options.slide).detach();
+
+ _.$slideTrack.append(_.$slides);
+
+ _.$slides.each(function(index, element) {
+ $(element).attr('data-slick-index', index);
+ });
+
+ _.$slidesCache = _.$slides;
+
+ _.reinit();
+
+ };
+
+ Slick.prototype.animateHeight = function() {
+ var _ = this;
+ if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
+ var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
+ _.$list.animate({
+ height: targetHeight
+ }, _.options.speed);
+ }
+ };
+
+ Slick.prototype.animateSlide = function(targetLeft, callback) {
+
+ var animProps = {},
+ _ = this;
+
+ _.animateHeight();
+
+ if (_.options.rtl === true && _.options.vertical === false) {
+ targetLeft = -targetLeft;
+ }
+ if (_.transformsEnabled === false) {
+ if (_.options.vertical === false) {
+ _.$slideTrack.animate({
+ left: targetLeft
+ }, _.options.speed, _.options.easing, callback);
+ } else {
+ _.$slideTrack.animate({
+ top: targetLeft
+ }, _.options.speed, _.options.easing, callback);
+ }
+
+ } else {
+
+ if (_.cssTransitions === false) {
+ if (_.options.rtl === true) {
+ _.currentLeft = -(_.currentLeft);
+ }
+ $({
+ animStart: _.currentLeft
+ }).animate({
+ animStart: targetLeft
+ }, {
+ duration: _.options.speed,
+ easing: _.options.easing,
+ step: function(now) {
+ now = Math.ceil(now);
+ if (_.options.vertical === false) {
+ animProps[_.animType] = 'translate(' +
+ now + 'px, 0px)';
+ _.$slideTrack.css(animProps);
+ } else {
+ animProps[_.animType] = 'translate(0px,' +
+ now + 'px)';
+ _.$slideTrack.css(animProps);
+ }
+ },
+ complete: function() {
+ if (callback) {
+ callback.call();
+ }
+ }
+ });
+
+ } else {
+
+ _.applyTransition();
+ targetLeft = Math.ceil(targetLeft);
+
+ if (_.options.vertical === false) {
+ animProps[_.animType] = 'translate3d(' + targetLeft + 'px, 0px, 0px)';
+ } else {
+ animProps[_.animType] = 'translate3d(0px,' + targetLeft + 'px, 0px)';
+ }
+ _.$slideTrack.css(animProps);
+
+ if (callback) {
+ setTimeout(function() {
+
+ _.disableTransition();
+
+ callback.call();
+ }, _.options.speed);
+ }
+
+ }
+
+ }
+
+ };
+
+ Slick.prototype.getNavTarget = function() {
+
+ var _ = this,
+ asNavFor = _.options.asNavFor;
+
+ if ( asNavFor && asNavFor !== null ) {
+ asNavFor = $(asNavFor).not(_.$slider);
+ }
+
+ return asNavFor;
+
+ };
+
+ Slick.prototype.asNavFor = function(index) {
+
+ var _ = this,
+ asNavFor = _.getNavTarget();
+
+ if ( asNavFor !== null && typeof asNavFor === 'object' ) {
+ asNavFor.each(function() {
+ var target = $(this).slick('getSlick');
+ if(!target.unslicked) {
+ target.slideHandler(index, true);
+ }
+ });
+ }
+
+ };
+
+ Slick.prototype.applyTransition = function(slide) {
+
+ var _ = this,
+ transition = {};
+
+ if (_.options.fade === false) {
+ transition[_.transitionType] = _.transformType + ' ' + _.options.speed + 'ms ' + _.options.cssEase;
+ } else {
+ transition[_.transitionType] = 'opacity ' + _.options.speed + 'ms ' + _.options.cssEase;
+ }
+
+ if (_.options.fade === false) {
+ _.$slideTrack.css(transition);
+ } else {
+ _.$slides.eq(slide).css(transition);
+ }
+
+ };
+
+ Slick.prototype.autoPlay = function() {
+
+ var _ = this;
+
+ _.autoPlayClear();
+
+ if ( _.slideCount > _.options.slidesToShow ) {
+ _.autoPlayTimer = setInterval( _.autoPlayIterator, _.options.autoplaySpeed );
+ }
+
+ };
+
+ Slick.prototype.autoPlayClear = function() {
+
+ var _ = this;
+
+ if (_.autoPlayTimer) {
+ clearInterval(_.autoPlayTimer);
+ }
+
+ };
+
+ Slick.prototype.autoPlayIterator = function() {
+
+ var _ = this,
+ slideTo = _.currentSlide + _.options.slidesToScroll;
+
+ if ( !_.paused && !_.interrupted && !_.focussed ) {
+
+ if ( _.options.infinite === false ) {
+
+ if ( _.direction === 1 && ( _.currentSlide + 1 ) === ( _.slideCount - 1 )) {
+ _.direction = 0;
+ }
+
+ else if ( _.direction === 0 ) {
+
+ slideTo = _.currentSlide - _.options.slidesToScroll;
+
+ if ( _.currentSlide - 1 === 0 ) {
+ _.direction = 1;
+ }
+
+ }
+
+ }
+
+ _.slideHandler( slideTo );
+
+ }
+
+ };
+
+ Slick.prototype.buildArrows = function() {
+
+ var _ = this;
+
+ if (_.options.arrows === true ) {
+
+ _.$prevArrow = $(_.options.prevArrow).addClass('slick-arrow');
+ _.$nextArrow = $(_.options.nextArrow).addClass('slick-arrow');
+
+ if( _.slideCount > _.options.slidesToShow ) {
+
+ _.$prevArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
+ _.$nextArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
+
+ if (_.htmlExpr.test(_.options.prevArrow)) {
+ _.$prevArrow.prependTo(_.options.appendArrows);
+ }
+
+ if (_.htmlExpr.test(_.options.nextArrow)) {
+ _.$nextArrow.appendTo(_.options.appendArrows);
+ }
+
+ if (_.options.infinite !== true) {
+ _.$prevArrow
+ .addClass('slick-disabled')
+ .attr('aria-disabled', 'true');
+ }
+
+ } else {
+
+ _.$prevArrow.add( _.$nextArrow )
+
+ .addClass('slick-hidden')
+ .attr({
+ 'aria-disabled': 'true',
+ 'tabindex': '-1'
+ });
+
+ }
+
+ }
+
+ };
+
+ Slick.prototype.buildDots = function() {
+
+ var _ = this,
+ i, dot;
+
+ if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
+
+ _.$slider.addClass('slick-dotted');
+
+ dot = $('
').addClass(_.options.dotsClass);
+
+ for (i = 0; i <= _.getDotCount(); i += 1) {
+ dot.append($('
').append(_.options.customPaging.call(this, _, i)));
+ }
+
+ _.$dots = dot.appendTo(_.options.appendDots);
+
+ _.$dots.find('li').first().addClass('slick-active').attr('aria-hidden', 'false');
+
+ }
+
+ };
+
+ Slick.prototype.buildOut = function() {
+
+ var _ = this;
+
+ _.$slides =
+ _.$slider
+ .children( _.options.slide + ':not(.slick-cloned)')
+ .addClass('slick-slide');
+
+ _.slideCount = _.$slides.length;
+
+ _.$slides.each(function(index, element) {
+ $(element)
+ .attr('data-slick-index', index)
+ .data('originalStyling', $(element).attr('style') || '');
+ });
+
+ _.$slider.addClass('slick-slider');
+
+ _.$slideTrack = (_.slideCount === 0) ?
+ $('
').appendTo(_.$slider) :
+ _.$slides.wrapAll('
').parent();
+
+ _.$list = _.$slideTrack.wrap(
+ '
').parent();
+ _.$slideTrack.css('opacity', 0);
+
+ if (_.options.centerMode === true || _.options.swipeToSlide === true) {
+ _.options.slidesToScroll = 1;
+ }
+
+ $('img[data-lazy]', _.$slider).not('[src]').addClass('slick-loading');
+
+ _.setupInfinite();
+
+ _.buildArrows();
+
+ _.buildDots();
+
+ _.updateDots();
+
+
+ _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
+
+ if (_.options.draggable === true) {
+ _.$list.addClass('draggable');
+ }
+
+ };
+
+ Slick.prototype.buildRows = function() {
+
+ var _ = this, a, b, c, newSlides, numOfSlides, originalSlides,slidesPerSection;
+
+ newSlides = document.createDocumentFragment();
+ originalSlides = _.$slider.children();
+
+ if(_.options.rows > 1) {
+
+ slidesPerSection = _.options.slidesPerRow * _.options.rows;
+ numOfSlides = Math.ceil(
+ originalSlides.length / slidesPerSection
+ );
+
+ for(a = 0; a < numOfSlides; a++){
+ var slide = document.createElement('div');
+ for(b = 0; b < _.options.rows; b++) {
+ var row = document.createElement('div');
+ for(c = 0; c < _.options.slidesPerRow; c++) {
+ var target = (a * slidesPerSection + ((b * _.options.slidesPerRow) + c));
+ if (originalSlides.get(target)) {
+ row.appendChild(originalSlides.get(target));
+ }
+ }
+ slide.appendChild(row);
+ }
+ newSlides.appendChild(slide);
+ }
+
+ _.$slider.empty().append(newSlides);
+ _.$slider.children().children().children()
+ .css({
+ 'width':(100 / _.options.slidesPerRow) + '%',
+ 'display': 'inline-block'
+ });
+
+ }
+
+ };
+
+ Slick.prototype.checkResponsive = function(initial, forceUpdate) {
+
+ var _ = this,
+ breakpoint, targetBreakpoint, respondToWidth, triggerBreakpoint = false;
+ var sliderWidth = _.$slider.width();
+ var windowWidth = window.innerWidth || $(window).width();
+
+ if (_.respondTo === 'window') {
+ respondToWidth = windowWidth;
+ } else if (_.respondTo === 'slider') {
+ respondToWidth = sliderWidth;
+ } else if (_.respondTo === 'min') {
+ respondToWidth = Math.min(windowWidth, sliderWidth);
+ }
+
+ if ( _.options.responsive &&
+ _.options.responsive.length &&
+ _.options.responsive !== null) {
+
+ targetBreakpoint = null;
+
+ for (breakpoint in _.breakpoints) {
+ if (_.breakpoints.hasOwnProperty(breakpoint)) {
+ if (_.originalSettings.mobileFirst === false) {
+ if (respondToWidth < _.breakpoints[breakpoint]) {
+ targetBreakpoint = _.breakpoints[breakpoint];
+ }
+ } else {
+ if (respondToWidth > _.breakpoints[breakpoint]) {
+ targetBreakpoint = _.breakpoints[breakpoint];
+ }
+ }
+ }
+ }
+
+ if (targetBreakpoint !== null) {
+ if (_.activeBreakpoint !== null) {
+ if (targetBreakpoint !== _.activeBreakpoint || forceUpdate) {
+ _.activeBreakpoint =
+ targetBreakpoint;
+ if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
+ _.unslick(targetBreakpoint);
+ } else {
+ _.options = $.extend({}, _.originalSettings,
+ _.breakpointSettings[
+ targetBreakpoint]);
+ if (initial === true) {
+ _.currentSlide = _.options.initialSlide;
+ }
+ _.refresh(initial);
+ }
+ triggerBreakpoint = targetBreakpoint;
+ }
+ } else {
+ _.activeBreakpoint = targetBreakpoint;
+ if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
+ _.unslick(targetBreakpoint);
+ } else {
+ _.options = $.extend({}, _.originalSettings,
+ _.breakpointSettings[
+ targetBreakpoint]);
+ if (initial === true) {
+ _.currentSlide = _.options.initialSlide;
+ }
+ _.refresh(initial);
+ }
+ triggerBreakpoint = targetBreakpoint;
+ }
+ } else {
+ if (_.activeBreakpoint !== null) {
+ _.activeBreakpoint = null;
+ _.options = _.originalSettings;
+ if (initial === true) {
+ _.currentSlide = _.options.initialSlide;
+ }
+ _.refresh(initial);
+ triggerBreakpoint = targetBreakpoint;
+ }
+ }
+
+ // only trigger breakpoints during an actual break. not on initialize.
+ if( !initial && triggerBreakpoint !== false ) {
+ _.$slider.trigger('breakpoint', [_, triggerBreakpoint]);
+ }
+ }
+
+ };
+
+ Slick.prototype.changeSlide = function(event, dontAnimate) {
+
+ var _ = this,
+ $target = $(event.currentTarget),
+ indexOffset, slideOffset, unevenOffset;
+
+ // If target is a link, prevent default action.
+ if($target.is('a')) {
+ event.preventDefault();
+ }
+
+ // If target is not the
element (ie: a child), find the .
+ if(!$target.is('li')) {
+ $target = $target.closest('li');
+ }
+
+ unevenOffset = (_.slideCount % _.options.slidesToScroll !== 0);
+ indexOffset = unevenOffset ? 0 : (_.slideCount - _.currentSlide) % _.options.slidesToScroll;
+
+ switch (event.data.message) {
+
+ case 'previous':
+ slideOffset = indexOffset === 0 ? _.options.slidesToScroll : _.options.slidesToShow - indexOffset;
+ if (_.slideCount > _.options.slidesToShow) {
+ _.slideHandler(_.currentSlide - slideOffset, false, dontAnimate);
+ }
+ break;
+
+ case 'next':
+ slideOffset = indexOffset === 0 ? _.options.slidesToScroll : indexOffset;
+ if (_.slideCount > _.options.slidesToShow) {
+ _.slideHandler(_.currentSlide + slideOffset, false, dontAnimate);
+ }
+ break;
+
+ case 'index':
+ var index = event.data.index === 0 ? 0 :
+ event.data.index || $target.index() * _.options.slidesToScroll;
+
+ _.slideHandler(_.checkNavigable(index), false, dontAnimate);
+ $target.children().trigger('focus');
+ break;
+
+ default:
+ return;
+ }
+
+ };
+
+ Slick.prototype.checkNavigable = function(index) {
+
+ var _ = this,
+ navigables, prevNavigable;
+
+ navigables = _.getNavigableIndexes();
+ prevNavigable = 0;
+ if (index > navigables[navigables.length - 1]) {
+ index = navigables[navigables.length - 1];
+ } else {
+ for (var n in navigables) {
+ if (index < navigables[n]) {
+ index = prevNavigable;
+ break;
+ }
+ prevNavigable = navigables[n];
+ }
+ }
+
+ return index;
+ };
+
+ Slick.prototype.cleanUpEvents = function() {
+
+ var _ = this;
+
+ if (_.options.dots && _.$dots !== null) {
+
+ $('li', _.$dots)
+ .off('click.slick', _.changeSlide)
+ .off('mouseenter.slick', $.proxy(_.interrupt, _, true))
+ .off('mouseleave.slick', $.proxy(_.interrupt, _, false));
+
+ }
+
+ _.$slider.off('focus.slick blur.slick');
+
+ if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
+ _.$prevArrow && _.$prevArrow.off('click.slick', _.changeSlide);
+ _.$nextArrow && _.$nextArrow.off('click.slick', _.changeSlide);
+ }
+
+ _.$list.off('touchstart.slick mousedown.slick', _.swipeHandler);
+ _.$list.off('touchmove.slick mousemove.slick', _.swipeHandler);
+ _.$list.off('touchend.slick mouseup.slick', _.swipeHandler);
+ _.$list.off('touchcancel.slick mouseleave.slick', _.swipeHandler);
+
+ _.$list.off('click.slick', _.clickHandler);
+
+ $(document).off(_.visibilityChange, _.visibility);
+
+ _.cleanUpSlideEvents();
+
+ if (_.options.accessibility === true) {
+ _.$list.off('keydown.slick', _.keyHandler);
+ }
+
+ if (_.options.focusOnSelect === true) {
+ $(_.$slideTrack).children().off('click.slick', _.selectHandler);
+ }
+
+ $(window).off('orientationchange.slick.slick-' + _.instanceUid, _.orientationChange);
+
+ $(window).off('resize.slick.slick-' + _.instanceUid, _.resize);
+
+ $('[draggable!=true]', _.$slideTrack).off('dragstart', _.preventDefault);
+
+ $(window).off('load.slick.slick-' + _.instanceUid, _.setPosition);
+ $(document).off('ready.slick.slick-' + _.instanceUid, _.setPosition);
+
+ };
+
+ Slick.prototype.cleanUpSlideEvents = function() {
+
+ var _ = this;
+
+ _.$list.off('mouseenter.slick', $.proxy(_.interrupt, _, true));
+ _.$list.off('mouseleave.slick', $.proxy(_.interrupt, _, false));
+
+ };
+
+ Slick.prototype.cleanUpRows = function() {
+
+ var _ = this, originalSlides;
+
+ if(_.options.rows > 1) {
+ originalSlides = _.$slides.children().children();
+ originalSlides.removeAttr('style');
+ _.$slider.empty().append(originalSlides);
+ }
+
+ };
+
+ Slick.prototype.clickHandler = function(event) {
+
+ var _ = this;
+
+ if (_.shouldClick === false) {
+ event.stopImmediatePropagation();
+ event.stopPropagation();
+ event.preventDefault();
+ }
+
+ };
+
+ Slick.prototype.destroy = function(refresh) {
+
+ var _ = this;
+
+ _.autoPlayClear();
+
+ _.touchObject = {};
+
+ _.cleanUpEvents();
+
+ $('.slick-cloned', _.$slider).detach();
+
+ if (_.$dots) {
+ _.$dots.remove();
+ }
+
+
+ if ( _.$prevArrow && _.$prevArrow.length ) {
+
+ _.$prevArrow
+ .removeClass('slick-disabled slick-arrow slick-hidden')
+ .removeAttr('aria-hidden aria-disabled tabindex')
+ .css('display','');
+
+ if ( _.htmlExpr.test( _.options.prevArrow )) {
+ _.$prevArrow.remove();
+ }
+ }
+
+ if ( _.$nextArrow && _.$nextArrow.length ) {
+
+ _.$nextArrow
+ .removeClass('slick-disabled slick-arrow slick-hidden')
+ .removeAttr('aria-hidden aria-disabled tabindex')
+ .css('display','');
+
+ if ( _.htmlExpr.test( _.options.nextArrow )) {
+ _.$nextArrow.remove();
+ }
+
+ }
+
+
+ if (_.$slides) {
+
+ _.$slides
+ .removeClass('slick-slide slick-active slick-center slick-visible slick-current')
+ .removeAttr('aria-hidden')
+ .removeAttr('data-slick-index')
+ .each(function(){
+ $(this).attr('style', $(this).data('originalStyling'));
+ });
+
+ _.$slideTrack.children(this.options.slide).detach();
+
+ _.$slideTrack.detach();
+
+ _.$list.detach();
+
+ _.$slider.append(_.$slides);
+ }
+
+ _.cleanUpRows();
+
+ _.$slider.removeClass('slick-slider');
+ _.$slider.removeClass('slick-initialized');
+ _.$slider.removeClass('slick-dotted');
+
+ _.unslicked = true;
+
+ if(!refresh) {
+ _.$slider.trigger('destroy', [_]);
+ }
+
+ };
+
+ Slick.prototype.disableTransition = function(slide) {
+
+ var _ = this,
+ transition = {};
+
+ transition[_.transitionType] = '';
+
+ if (_.options.fade === false) {
+ _.$slideTrack.css(transition);
+ } else {
+ _.$slides.eq(slide).css(transition);
+ }
+
+ };
+
+ Slick.prototype.fadeSlide = function(slideIndex, callback) {
+
+ var _ = this;
+
+ if (_.cssTransitions === false) {
+
+ _.$slides.eq(slideIndex).css({
+ zIndex: _.options.zIndex
+ });
+
+ _.$slides.eq(slideIndex).animate({
+ opacity: 1
+ }, _.options.speed, _.options.easing, callback);
+
+ } else {
+
+ _.applyTransition(slideIndex);
+
+ _.$slides.eq(slideIndex).css({
+ opacity: 1,
+ zIndex: _.options.zIndex
+ });
+
+ if (callback) {
+ setTimeout(function() {
+
+ _.disableTransition(slideIndex);
+
+ callback.call();
+ }, _.options.speed);
+ }
+
+ }
+
+ };
+
+ Slick.prototype.fadeSlideOut = function(slideIndex) {
+
+ var _ = this;
+
+ if (_.cssTransitions === false) {
+
+ _.$slides.eq(slideIndex).animate({
+ opacity: 0,
+ zIndex: _.options.zIndex - 2
+ }, _.options.speed, _.options.easing);
+
+ } else {
+
+ _.applyTransition(slideIndex);
+
+ _.$slides.eq(slideIndex).css({
+ opacity: 0,
+ zIndex: _.options.zIndex - 2
+ });
+
+ }
+
+ };
+
+ Slick.prototype.filterSlides = Slick.prototype.slickFilter = function(filter) {
+
+ var _ = this;
+
+ if (filter !== null) {
+
+ _.$slidesCache = _.$slides;
+
+ _.unload();
+
+ _.$slideTrack.children(this.options.slide).detach();
+
+ _.$slidesCache.filter(filter).appendTo(_.$slideTrack);
+
+ _.reinit();
+
+ }
+
+ };
+
+ Slick.prototype.focusHandler = function() {
+
+ var _ = this;
+
+ _.$slider
+ .off('focus.slick blur.slick')
+ .on('focus.slick blur.slick',
+ '*:not(.slick-arrow)', function(event) {
+
+ event.stopImmediatePropagation();
+ var $sf = $(this);
+
+ setTimeout(function() {
+
+ if( _.options.pauseOnFocus ) {
+ _.focussed = $sf.is(':focus');
+ _.autoPlay();
+ }
+
+ }, 0);
+
+ });
+ };
+
+ Slick.prototype.getCurrent = Slick.prototype.slickCurrentSlide = function() {
+
+ var _ = this;
+ return _.currentSlide;
+
+ };
+
+ Slick.prototype.getDotCount = function() {
+
+ var _ = this;
+
+ var breakPoint = 0;
+ var counter = 0;
+ var pagerQty = 0;
+
+ if (_.options.infinite === true) {
+ while (breakPoint < _.slideCount) {
+ ++pagerQty;
+ breakPoint = counter + _.options.slidesToScroll;
+ counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
+ }
+ } else if (_.options.centerMode === true) {
+ pagerQty = _.slideCount;
+ } else if(!_.options.asNavFor) {
+ pagerQty = 1 + Math.ceil((_.slideCount - _.options.slidesToShow) / _.options.slidesToScroll);
+ }else {
+ while (breakPoint < _.slideCount) {
+ ++pagerQty;
+ breakPoint = counter + _.options.slidesToScroll;
+ counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
+ }
+ }
+
+ return pagerQty - 1;
+
+ };
+
+ Slick.prototype.getLeft = function(slideIndex) {
+
+ var _ = this,
+ targetLeft,
+ verticalHeight,
+ verticalOffset = 0,
+ targetSlide;
+
+ _.slideOffset = 0;
+ verticalHeight = _.$slides.first().outerHeight(true);
+
+ if (_.options.infinite === true) {
+ if (_.slideCount > _.options.slidesToShow) {
+ _.slideOffset = (_.slideWidth * _.options.slidesToShow) * -1;
+ verticalOffset = (verticalHeight * _.options.slidesToShow) * -1;
+ }
+ if (_.slideCount % _.options.slidesToScroll !== 0) {
+ if (slideIndex + _.options.slidesToScroll > _.slideCount && _.slideCount > _.options.slidesToShow) {
+ if (slideIndex > _.slideCount) {
+ _.slideOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * _.slideWidth) * -1;
+ verticalOffset = ((_.options.slidesToShow - (slideIndex - _.slideCount)) * verticalHeight) * -1;
+ } else {
+ _.slideOffset = ((_.slideCount % _.options.slidesToScroll) * _.slideWidth) * -1;
+ verticalOffset = ((_.slideCount % _.options.slidesToScroll) * verticalHeight) * -1;
+ }
+ }
+ }
+ } else {
+ if (slideIndex + _.options.slidesToShow > _.slideCount) {
+ _.slideOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * _.slideWidth;
+ verticalOffset = ((slideIndex + _.options.slidesToShow) - _.slideCount) * verticalHeight;
+ }
+ }
+
+ if (_.slideCount <= _.options.slidesToShow) {
+ _.slideOffset = 0;
+ verticalOffset = 0;
+ }
+
+ if (_.options.centerMode === true && _.options.infinite === true) {
+ _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2) - _.slideWidth;
+ } else if (_.options.centerMode === true) {
+ _.slideOffset = 0;
+ _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2);
+ }
+
+ if (_.options.vertical === false) {
+ targetLeft = ((slideIndex * _.slideWidth) * -1) + _.slideOffset;
+ } else {
+ targetLeft = ((slideIndex * verticalHeight) * -1) + verticalOffset;
+ }
+
+ if (_.options.variableWidth === true) {
+
+ if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
+ targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
+ } else {
+ targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow);
+ }
+
+ if (_.options.rtl === true) {
+ if (targetSlide[0]) {
+ targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
+ } else {
+ targetLeft = 0;
+ }
+ } else {
+ targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
+ }
+
+ if (_.options.centerMode === true) {
+ if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
+ targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
+ } else {
+ targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow + 1);
+ }
+
+ if (_.options.rtl === true) {
+ if (targetSlide[0]) {
+ targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
+ } else {
+ targetLeft = 0;
+ }
+ } else {
+ targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
+ }
+
+ targetLeft += (_.$list.width() - targetSlide.outerWidth()) / 2;
+ }
+ }
+
+ return targetLeft;
+
+ };
+
+ Slick.prototype.getOption = Slick.prototype.slickGetOption = function(option) {
+
+ var _ = this;
+
+ return _.options[option];
+
+ };
+
+ Slick.prototype.getNavigableIndexes = function() {
+
+ var _ = this,
+ breakPoint = 0,
+ counter = 0,
+ indexes = [],
+ max;
+
+ if (_.options.infinite === false) {
+ max = _.slideCount;
+ } else {
+ breakPoint = _.options.slidesToScroll * -1;
+ counter = _.options.slidesToScroll * -1;
+ max = _.slideCount * 2;
+ }
+
+ while (breakPoint < max) {
+ indexes.push(breakPoint);
+ breakPoint = counter + _.options.slidesToScroll;
+ counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
+ }
+
+ return indexes;
+
+ };
+
+ Slick.prototype.getSlick = function() {
+
+ return this;
+
+ };
+
+ Slick.prototype.getSlideCount = function() {
+
+ var _ = this,
+ slidesTraversed, swipedSlide, centerOffset;
+
+ centerOffset = _.options.centerMode === true ? _.slideWidth * Math.floor(_.options.slidesToShow / 2) : 0;
+
+ if (_.options.swipeToSlide === true) {
+ _.$slideTrack.find('.slick-slide').each(function(index, slide) {
+ if (slide.offsetLeft - centerOffset + ($(slide).outerWidth() / 2) > (_.swipeLeft * -1)) {
+ swipedSlide = slide;
+ return false;
+ }
+ });
+
+ slidesTraversed = Math.abs($(swipedSlide).attr('data-slick-index') - _.currentSlide) || 1;
+
+ return slidesTraversed;
+
+ } else {
+ return _.options.slidesToScroll;
+ }
+
+ };
+
+ Slick.prototype.goTo = Slick.prototype.slickGoTo = function(slide, dontAnimate) {
+
+ var _ = this;
+
+ _.changeSlide({
+ data: {
+ message: 'index',
+ index: parseInt(slide)
+ }
+ }, dontAnimate);
+
+ };
+
+ Slick.prototype.init = function(creation) {
+
+ var _ = this;
+
+ if (!$(_.$slider).hasClass('slick-initialized')) {
+
+ $(_.$slider).addClass('slick-initialized');
+
+ _.buildRows();
+ _.buildOut();
+ _.setProps();
+ _.startLoad();
+ _.loadSlider();
+ _.initializeEvents();
+ _.updateArrows();
+ _.updateDots();
+ _.checkResponsive(true);
+ _.focusHandler();
+
+ }
+
+ if (creation) {
+ _.$slider.trigger('init', [_]);
+ }
+
+ if (_.options.accessibility === true) {
+ _.initADA();
+ }
+
+ if ( _.options.autoplay ) {
+
+ _.paused = false;
+ _.autoPlay();
+
+ }
+
+ };
+
+ Slick.prototype.initADA = function() {
+ var _ = this;
+ _.$slides.add(_.$slideTrack.find('.slick-cloned')).attr({
+ 'aria-hidden': 'true',
+ 'tabindex': '-1'
+ }).find('a, input, button, select').attr({
+ 'tabindex': '-1'
+ });
+
+ _.$slideTrack.attr('role', 'listbox');
+
+ _.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function(i) {
+ $(this).attr({
+ 'role': 'option',
+ 'aria-describedby': 'slick-slide' + _.instanceUid + i + ''
+ });
+ });
+
+ if (_.$dots !== null) {
+ _.$dots.attr('role', 'tablist').find('li').each(function(i) {
+ $(this).attr({
+ 'role': 'presentation',
+ 'aria-selected': 'false',
+ 'aria-controls': 'navigation' + _.instanceUid + i + '',
+ 'id': 'slick-slide' + _.instanceUid + i + ''
+ });
+ })
+ .first().attr('aria-selected', 'true').end()
+ .find('button').attr('role', 'button').end()
+ .closest('div').attr('role', 'toolbar');
+ }
+ _.activateADA();
+
+ };
+
+ Slick.prototype.initArrowEvents = function() {
+
+ var _ = this;
+
+ if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
+ _.$prevArrow
+ .off('click.slick')
+ .on('click.slick', {
+ message: 'previous'
+ }, _.changeSlide);
+ _.$nextArrow
+ .off('click.slick')
+ .on('click.slick', {
+ message: 'next'
+ }, _.changeSlide);
+ }
+
+ };
+
+ Slick.prototype.initDotEvents = function() {
+
+ var _ = this;
+
+ if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
+ $('li', _.$dots).on('click.slick', {
+ message: 'index'
+ }, _.changeSlide);
+ }
+
+ if ( _.options.dots === true && _.options.pauseOnDotsHover === true ) {
+
+ $('li', _.$dots)
+ .on('mouseenter.slick', $.proxy(_.interrupt, _, true))
+ .on('mouseleave.slick', $.proxy(_.interrupt, _, false));
+
+ }
+
+ };
+
+ Slick.prototype.initSlideEvents = function() {
+
+ var _ = this;
+
+ if ( _.options.pauseOnHover ) {
+
+ _.$list.on('mouseenter.slick', $.proxy(_.interrupt, _, true));
+ _.$list.on('mouseleave.slick', $.proxy(_.interrupt, _, false));
+
+ }
+
+ };
+
+ Slick.prototype.initializeEvents = function() {
+
+ var _ = this;
+
+ _.initArrowEvents();
+
+ _.initDotEvents();
+ _.initSlideEvents();
+
+ _.$list.on('touchstart.slick mousedown.slick', {
+ action: 'start'
+ }, _.swipeHandler);
+ _.$list.on('touchmove.slick mousemove.slick', {
+ action: 'move'
+ }, _.swipeHandler);
+ _.$list.on('touchend.slick mouseup.slick', {
+ action: 'end'
+ }, _.swipeHandler);
+ _.$list.on('touchcancel.slick mouseleave.slick', {
+ action: 'end'
+ }, _.swipeHandler);
+
+ _.$list.on('click.slick', _.clickHandler);
+
+ $(document).on(_.visibilityChange, $.proxy(_.visibility, _));
+
+ if (_.options.accessibility === true) {
+ _.$list.on('keydown.slick', _.keyHandler);
+ }
+
+ if (_.options.focusOnSelect === true) {
+ $(_.$slideTrack).children().on('click.slick', _.selectHandler);
+ }
+
+ $(window).on('orientationchange.slick.slick-' + _.instanceUid, $.proxy(_.orientationChange, _));
+
+ $(window).on('resize.slick.slick-' + _.instanceUid, $.proxy(_.resize, _));
+
+ $('[draggable!=true]', _.$slideTrack).on('dragstart', _.preventDefault);
+
+ $(window).on('load.slick.slick-' + _.instanceUid, _.setPosition);
+ $(document).on('ready.slick.slick-' + _.instanceUid, _.setPosition);
+
+ };
+
+ Slick.prototype.initUI = function() {
+
+ var _ = this;
+
+ if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
+
+ _.$prevArrow.show();
+ _.$nextArrow.show();
+
+ }
+
+ if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
+
+ _.$dots.show();
+
+ }
+
+ };
+
+ Slick.prototype.keyHandler = function(event) {
+
+ var _ = this;
+ //Dont slide if the cursor is inside the form fields and arrow keys are pressed
+ if(!event.target.tagName.match('TEXTAREA|INPUT|SELECT')) {
+ if (event.keyCode === 37 && _.options.accessibility === true) {
+ _.changeSlide({
+ data: {
+ message: _.options.rtl === true ? 'next' : 'previous'
+ }
+ });
+ } else if (event.keyCode === 39 && _.options.accessibility === true) {
+ _.changeSlide({
+ data: {
+ message: _.options.rtl === true ? 'previous' : 'next'
+ }
+ });
+ }
+ }
+
+ };
+
+ Slick.prototype.lazyLoad = function() {
+
+ var _ = this,
+ loadRange, cloneRange, rangeStart, rangeEnd;
+
+ function loadImages(imagesScope) {
+
+ $('img[data-lazy]', imagesScope).each(function() {
+
+ var image = $(this),
+ imageSource = $(this).attr('data-lazy'),
+ imageToLoad = document.createElement('img');
+
+ imageToLoad.onload = function() {
+
+ image
+ .animate({ opacity: 0 }, 100, function() {
+ image
+ .attr('src', imageSource)
+ .animate({ opacity: 1 }, 200, function() {
+ image
+ .removeAttr('data-lazy')
+ .removeClass('slick-loading');
+ });
+ _.$slider.trigger('lazyLoaded', [_, image, imageSource]);
+ });
+
+ };
+
+ imageToLoad.onerror = function() {
+
+ image
+ .removeAttr( 'data-lazy' )
+ .removeClass( 'slick-loading' )
+ .addClass( 'slick-lazyload-error' );
+
+ _.$slider.trigger('lazyLoadError', [ _, image, imageSource ]);
+
+ };
+
+ imageToLoad.src = imageSource;
+
+ });
+
+ }
+
+ if (_.options.centerMode === true) {
+ if (_.options.infinite === true) {
+ rangeStart = _.currentSlide + (_.options.slidesToShow / 2 + 1);
+ rangeEnd = rangeStart + _.options.slidesToShow + 2;
+ } else {
+ rangeStart = Math.max(0, _.currentSlide - (_.options.slidesToShow / 2 + 1));
+ rangeEnd = 2 + (_.options.slidesToShow / 2 + 1) + _.currentSlide;
+ }
+ } else {
+ rangeStart = _.options.infinite ? _.options.slidesToShow + _.currentSlide : _.currentSlide;
+ rangeEnd = Math.ceil(rangeStart + _.options.slidesToShow);
+ if (_.options.fade === true) {
+ if (rangeStart > 0) rangeStart--;
+ if (rangeEnd <= _.slideCount) rangeEnd++;
+ }
+ }
+
+ loadRange = _.$slider.find('.slick-slide').slice(rangeStart, rangeEnd);
+ loadImages(loadRange);
+
+ if (_.slideCount <= _.options.slidesToShow) {
+ cloneRange = _.$slider.find('.slick-slide');
+ loadImages(cloneRange);
+ } else
+ if (_.currentSlide >= _.slideCount - _.options.slidesToShow) {
+ cloneRange = _.$slider.find('.slick-cloned').slice(0, _.options.slidesToShow);
+ loadImages(cloneRange);
+ } else if (_.currentSlide === 0) {
+ cloneRange = _.$slider.find('.slick-cloned').slice(_.options.slidesToShow * -1);
+ loadImages(cloneRange);
+ }
+
+ };
+
+ Slick.prototype.loadSlider = function() {
+
+ var _ = this;
+
+ _.setPosition();
+
+ _.$slideTrack.css({
+ opacity: 1
+ });
+
+ _.$slider.removeClass('slick-loading');
+
+ _.initUI();
+
+ if (_.options.lazyLoad === 'progressive') {
+ _.progressiveLazyLoad();
+ }
+
+ };
+
+ Slick.prototype.next = Slick.prototype.slickNext = function() {
+
+ var _ = this;
+
+ _.changeSlide({
+ data: {
+ message: 'next'
+ }
+ });
+
+ };
+
+ Slick.prototype.orientationChange = function() {
+
+ var _ = this;
+
+ _.checkResponsive();
+ _.setPosition();
+
+ };
+
+ Slick.prototype.pause = Slick.prototype.slickPause = function() {
+
+ var _ = this;
+
+ _.autoPlayClear();
+ _.paused = true;
+
+ };
+
+ Slick.prototype.play = Slick.prototype.slickPlay = function() {
+
+ var _ = this;
+
+ _.autoPlay();
+ _.options.autoplay = true;
+ _.paused = false;
+ _.focussed = false;
+ _.interrupted = false;
+
+ };
+
+ Slick.prototype.postSlide = function(index) {
+
+ var _ = this;
+
+ if( !_.unslicked ) {
+
+ _.$slider.trigger('afterChange', [_, index]);
+
+ _.animating = false;
+
+ _.setPosition();
+
+ _.swipeLeft = null;
+
+ if ( _.options.autoplay ) {
+ _.autoPlay();
+ }
+
+ if (_.options.accessibility === true) {
+ _.initADA();
+ }
+
+ }
+
+ };
+
+ Slick.prototype.prev = Slick.prototype.slickPrev = function() {
+
+ var _ = this;
+
+ _.changeSlide({
+ data: {
+ message: 'previous'
+ }
+ });
+
+ };
+
+ Slick.prototype.preventDefault = function(event) {
+
+ event.preventDefault();
+
+ };
+
+ Slick.prototype.progressiveLazyLoad = function( tryCount ) {
+
+ tryCount = tryCount || 1;
+
+ var _ = this,
+ $imgsToLoad = $( 'img[data-lazy]', _.$slider ),
+ image,
+ imageSource,
+ imageToLoad;
+
+ if ( $imgsToLoad.length ) {
+
+ image = $imgsToLoad.first();
+ imageSource = image.attr('data-lazy');
+ imageToLoad = document.createElement('img');
+
+ imageToLoad.onload = function() {
+
+ image
+ .attr( 'src', imageSource )
+ .removeAttr('data-lazy')
+ .removeClass('slick-loading');
+
+ if ( _.options.adaptiveHeight === true ) {
+ _.setPosition();
+ }
+
+ _.$slider.trigger('lazyLoaded', [ _, image, imageSource ]);
+ _.progressiveLazyLoad();
+
+ };
+
+ imageToLoad.onerror = function() {
+
+ if ( tryCount < 3 ) {
+
+ /**
+ * try to load the image 3 times,
+ * leave a slight delay so we don't get
+ * servers blocking the request.
+ */
+ setTimeout( function() {
+ _.progressiveLazyLoad( tryCount + 1 );
+ }, 500 );
+
+ } else {
+
+ image
+ .removeAttr( 'data-lazy' )
+ .removeClass( 'slick-loading' )
+ .addClass( 'slick-lazyload-error' );
+
+ _.$slider.trigger('lazyLoadError', [ _, image, imageSource ]);
+
+ _.progressiveLazyLoad();
+
+ }
+
+ };
+
+ imageToLoad.src = imageSource;
+
+ } else {
+
+ _.$slider.trigger('allImagesLoaded', [ _ ]);
+
+ }
+
+ };
+
+ Slick.prototype.refresh = function( initializing ) {
+
+ var _ = this, currentSlide, lastVisibleIndex;
+
+ lastVisibleIndex = _.slideCount - _.options.slidesToShow;
+
+ // in non-infinite sliders, we don't want to go past the
+ // last visible index.
+ if( !_.options.infinite && ( _.currentSlide > lastVisibleIndex )) {
+ _.currentSlide = lastVisibleIndex;
+ }
+
+ // if less slides than to show, go to start.
+ if ( _.slideCount <= _.options.slidesToShow ) {
+ _.currentSlide = 0;
+
+ }
+
+ currentSlide = _.currentSlide;
+
+ _.destroy(true);
+
+ $.extend(_, _.initials, { currentSlide: currentSlide });
+
+ _.init();
+
+ if( !initializing ) {
+
+ _.changeSlide({
+ data: {
+ message: 'index',
+ index: currentSlide
+ }
+ }, false);
+
+ }
+
+ };
+
+ Slick.prototype.registerBreakpoints = function() {
+
+ var _ = this, breakpoint, currentBreakpoint, l,
+ responsiveSettings = _.options.responsive || null;
+
+ if ( $.type(responsiveSettings) === 'array' && responsiveSettings.length ) {
+
+ _.respondTo = _.options.respondTo || 'window';
+
+ for ( breakpoint in responsiveSettings ) {
+
+ l = _.breakpoints.length-1;
+ currentBreakpoint = responsiveSettings[breakpoint].breakpoint;
+
+ if (responsiveSettings.hasOwnProperty(breakpoint)) {
+
+ // loop through the breakpoints and cut out any existing
+ // ones with the same breakpoint number, we don't want dupes.
+ while( l >= 0 ) {
+ if( _.breakpoints[l] && _.breakpoints[l] === currentBreakpoint ) {
+ _.breakpoints.splice(l,1);
+ }
+ l--;
+ }
+
+ _.breakpoints.push(currentBreakpoint);
+ _.breakpointSettings[currentBreakpoint] = responsiveSettings[breakpoint].settings;
+
+ }
+
+ }
+
+ _.breakpoints.sort(function(a, b) {
+ return ( _.options.mobileFirst ) ? a-b : b-a;
+ });
+
+ }
+
+ };
+
+ Slick.prototype.reinit = function() {
+
+ var _ = this;
+
+ _.$slides =
+ _.$slideTrack
+ .children(_.options.slide)
+ .addClass('slick-slide');
+
+ _.slideCount = _.$slides.length;
+
+ if (_.currentSlide >= _.slideCount && _.currentSlide !== 0) {
+ _.currentSlide = _.currentSlide - _.options.slidesToScroll;
+ }
+
+ if (_.slideCount <= _.options.slidesToShow) {
+ _.currentSlide = 0;
+ }
+
+ _.registerBreakpoints();
+
+ _.setProps();
+ _.setupInfinite();
+ _.buildArrows();
+ _.updateArrows();
+ _.initArrowEvents();
+ _.buildDots();
+ _.updateDots();
+ _.initDotEvents();
+ _.cleanUpSlideEvents();
+ _.initSlideEvents();
+
+ _.checkResponsive(false, true);
+
+ if (_.options.focusOnSelect === true) {
+ $(_.$slideTrack).children().on('click.slick', _.selectHandler);
+ }
+
+ _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);
+
+ _.setPosition();
+ _.focusHandler();
+
+ _.paused = !_.options.autoplay;
+ _.autoPlay();
+
+ _.$slider.trigger('reInit', [_]);
+
+ };
+
+ Slick.prototype.resize = function() {
+
+ var _ = this;
+
+ if ($(window).width() !== _.windowWidth) {
+ clearTimeout(_.windowDelay);
+ _.windowDelay = window.setTimeout(function() {
+ _.windowWidth = $(window).width();
+ _.checkResponsive();
+ if( !_.unslicked ) { _.setPosition(); }
+ }, 50);
+ }
+ };
+
+ Slick.prototype.removeSlide = Slick.prototype.slickRemove = function(index, removeBefore, removeAll) {
+
+ var _ = this;
+
+ if (typeof(index) === 'boolean') {
+ removeBefore = index;
+ index = removeBefore === true ? 0 : _.slideCount - 1;
+ } else {
+ index = removeBefore === true ? --index : index;
+ }
+
+ if (_.slideCount < 1 || index < 0 || index > _.slideCount - 1) {
+ return false;
+ }
+
+ _.unload();
+
+ if (removeAll === true) {
+ _.$slideTrack.children().remove();
+ } else {
+ _.$slideTrack.children(this.options.slide).eq(index).remove();
+ }
+
+ _.$slides = _.$slideTrack.children(this.options.slide);
+
+ _.$slideTrack.children(this.options.slide).detach();
+
+ _.$slideTrack.append(_.$slides);
+
+ _.$slidesCache = _.$slides;
+
+ _.reinit();
+
+ };
+
+ Slick.prototype.setCSS = function(position) {
+
+ var _ = this,
+ positionProps = {},
+ x, y;
+
+ if (_.options.rtl === true) {
+ position = -position;
+ }
+ x = _.positionProp == 'left' ? Math.ceil(position) + 'px' : '0px';
+ y = _.positionProp == 'top' ? Math.ceil(position) + 'px' : '0px';
+
+ positionProps[_.positionProp] = position;
+
+ if (_.transformsEnabled === false) {
+ _.$slideTrack.css(positionProps);
+ } else {
+ positionProps = {};
+ if (_.cssTransitions === false) {
+ positionProps[_.animType] = 'translate(' + x + ', ' + y + ')';
+ _.$slideTrack.css(positionProps);
+ } else {
+ positionProps[_.animType] = 'translate3d(' + x + ', ' + y + ', 0px)';
+ _.$slideTrack.css(positionProps);
+ }
+ }
+
+ };
+
+ Slick.prototype.setDimensions = function() {
+
+ var _ = this;
+
+ if (_.options.vertical === false) {
+ if (_.options.centerMode === true) {
+ _.$list.css({
+ padding: ('0px ' + _.options.centerPadding)
+ });
+ }
+ } else {
+ _.$list.height(_.$slides.first().outerHeight(true) * _.options.slidesToShow);
+ if (_.options.centerMode === true) {
+ _.$list.css({
+ padding: (_.options.centerPadding + ' 0px')
+ });
+ }
+ }
+
+ _.listWidth = _.$list.width();
+ _.listHeight = _.$list.height();
+
+
+ if (_.options.vertical === false && _.options.variableWidth === false) {
+ _.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow);
+ _.$slideTrack.width(Math.ceil((_.slideWidth * _.$slideTrack.children('.slick-slide').length)));
+
+ } else if (_.options.variableWidth === true) {
+ _.$slideTrack.width(5000 * _.slideCount);
+ } else {
+ _.slideWidth = Math.ceil(_.listWidth);
+ _.$slideTrack.height(Math.ceil((_.$slides.first().outerHeight(true) * _.$slideTrack.children('.slick-slide').length)));
+ }
+
+ var offset = _.$slides.first().outerWidth(true) - _.$slides.first().width();
+ if (_.options.variableWidth === false) _.$slideTrack.children('.slick-slide').width(_.slideWidth - offset);
+
+ };
+
+ Slick.prototype.setFade = function() {
+
+ var _ = this,
+ targetLeft;
+
+ _.$slides.each(function(index, element) {
+ targetLeft = (_.slideWidth * index) * -1;
+ if (_.options.rtl === true) {
+ $(element).css({
+ position: 'relative',
+ right: targetLeft,
+ top: 0,
+ zIndex: _.options.zIndex - 2,
+ opacity: 0
+ });
+ } else {
+ $(element).css({
+ position: 'relative',
+ left: targetLeft,
+ top: 0,
+ zIndex: _.options.zIndex - 2,
+ opacity: 0
+ });
+ }
+ });
+
+ _.$slides.eq(_.currentSlide).css({
+ zIndex: _.options.zIndex - 1,
+ opacity: 1
+ });
+
+ };
+
+ Slick.prototype.setHeight = function() {
+
+ var _ = this;
+
+ if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
+ var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
+ _.$list.css('height', targetHeight);
+ }
+
+ };
+
+ Slick.prototype.setOption =
+ Slick.prototype.slickSetOption = function() {
+
+ /**
+ * accepts arguments in format of:
+ *
+ * - for changing a single option's value:
+ * .slick("setOption", option, value, refresh )
+ *
+ * - for changing a set of responsive options:
+ * .slick("setOption", 'responsive', [{}, ...], refresh )
+ *
+ * - for updating multiple values at once (not responsive)
+ * .slick("setOption", { 'option': value, ... }, refresh )
+ */
+
+ var _ = this, l, item, option, value, refresh = false, type;
+
+ if( $.type( arguments[0] ) === 'object' ) {
+
+ option = arguments[0];
+ refresh = arguments[1];
+ type = 'multiple';
+
+ } else if ( $.type( arguments[0] ) === 'string' ) {
+
+ option = arguments[0];
+ value = arguments[1];
+ refresh = arguments[2];
+
+ if ( arguments[0] === 'responsive' && $.type( arguments[1] ) === 'array' ) {
+
+ type = 'responsive';
+
+ } else if ( typeof arguments[1] !== 'undefined' ) {
+
+ type = 'single';
+
+ }
+
+ }
+
+ if ( type === 'single' ) {
+
+ _.options[option] = value;
+
+
+ } else if ( type === 'multiple' ) {
+
+ $.each( option , function( opt, val ) {
+
+ _.options[opt] = val;
+
+ });
+
+
+ } else if ( type === 'responsive' ) {
+
+ for ( item in value ) {
+
+ if( $.type( _.options.responsive ) !== 'array' ) {
+
+ _.options.responsive = [ value[item] ];
+
+ } else {
+
+ l = _.options.responsive.length-1;
+
+ // loop through the responsive object and splice out duplicates.
+ while( l >= 0 ) {
+
+ if( _.options.responsive[l].breakpoint === value[item].breakpoint ) {
+
+ _.options.responsive.splice(l,1);
+
+ }
+
+ l--;
+
+ }
+
+ _.options.responsive.push( value[item] );
+
+ }
+
+ }
+
+ }
+
+ if ( refresh ) {
+
+ _.unload();
+ _.reinit();
+
+ }
+
+ };
+
+ Slick.prototype.setPosition = function() {
+
+ var _ = this;
+
+ _.setDimensions();
+
+ _.setHeight();
+
+ if (_.options.fade === false) {
+ _.setCSS(_.getLeft(_.currentSlide));
+ } else {
+ _.setFade();
+ }
+
+ _.$slider.trigger('setPosition', [_]);
+
+ };
+
+ Slick.prototype.setProps = function() {
+
+ var _ = this,
+ bodyStyle = document.body.style;
+
+ _.positionProp = _.options.vertical === true ? 'top' : 'left';
+
+ if (_.positionProp === 'top') {
+ _.$slider.addClass('slick-vertical');
+ } else {
+ _.$slider.removeClass('slick-vertical');
+ }
+
+ if (bodyStyle.WebkitTransition !== undefined ||
+ bodyStyle.MozTransition !== undefined ||
+ bodyStyle.msTransition !== undefined) {
+ if (_.options.useCSS === true) {
+ _.cssTransitions = true;
+ }
+ }
+
+ if ( _.options.fade ) {
+ if ( typeof _.options.zIndex === 'number' ) {
+ if( _.options.zIndex < 3 ) {
+ _.options.zIndex = 3;
+ }
+ } else {
+ _.options.zIndex = _.defaults.zIndex;
+ }
+ }
+
+ if (bodyStyle.OTransform !== undefined) {
+ _.animType = 'OTransform';
+ _.transformType = '-o-transform';
+ _.transitionType = 'OTransition';
+ if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
+ }
+ if (bodyStyle.MozTransform !== undefined) {
+ _.animType = 'MozTransform';
+ _.transformType = '-moz-transform';
+ _.transitionType = 'MozTransition';
+ if (bodyStyle.perspectiveProperty === undefined && bodyStyle.MozPerspective === undefined) _.animType = false;
+ }
+ if (bodyStyle.webkitTransform !== undefined) {
+ _.animType = 'webkitTransform';
+ _.transformType = '-webkit-transform';
+ _.transitionType = 'webkitTransition';
+ if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
+ }
+ if (bodyStyle.msTransform !== undefined) {
+ _.animType = 'msTransform';
+ _.transformType = '-ms-transform';
+ _.transitionType = 'msTransition';
+ if (bodyStyle.msTransform === undefined) _.animType = false;
+ }
+ if (bodyStyle.transform !== undefined && _.animType !== false) {
+ _.animType = 'transform';
+ _.transformType = 'transform';
+ _.transitionType = 'transition';
+ }
+ _.transformsEnabled = _.options.useTransform && (_.animType !== null && _.animType !== false);
+ };
+
+
+ Slick.prototype.setSlideClasses = function(index) {
+
+ var _ = this,
+ centerOffset, allSlides, indexOffset, remainder;
+
+ allSlides = _.$slider
+ .find('.slick-slide')
+ .removeClass('slick-active slick-center slick-current')
+ .attr('aria-hidden', 'true');
+
+ _.$slides
+ .eq(index)
+ .addClass('slick-current');
+
+ if (_.options.centerMode === true) {
+
+ centerOffset = Math.floor(_.options.slidesToShow / 2);
+
+ if (_.options.infinite === true) {
+
+ if (index >= centerOffset && index <= (_.slideCount - 1) - centerOffset) {
+
+ _.$slides
+ .slice(index - centerOffset, index + centerOffset + 1)
+ .addClass('slick-active')
+ .attr('aria-hidden', 'false');
+
+ } else {
+
+ indexOffset = _.options.slidesToShow + index;
+ allSlides
+ .slice(indexOffset - centerOffset + 1, indexOffset + centerOffset + 2)
+ .addClass('slick-active')
+ .attr('aria-hidden', 'false');
+
+ }
+
+ if (index === 0) {
+
+ allSlides
+ .eq(allSlides.length - 1 - _.options.slidesToShow)
+ .addClass('slick-center');
+
+ } else if (index === _.slideCount - 1) {
+
+ allSlides
+ .eq(_.options.slidesToShow)
+ .addClass('slick-center');
+
+ }
+
+ }
+
+ _.$slides
+ .eq(index)
+ .addClass('slick-center');
+
+ } else {
+
+ if (index >= 0 && index <= (_.slideCount - _.options.slidesToShow)) {
+
+ _.$slides
+ .slice(index, index + _.options.slidesToShow)
+ .addClass('slick-active')
+ .attr('aria-hidden', 'false');
+
+ } else if (allSlides.length <= _.options.slidesToShow) {
+
+ allSlides
+ .addClass('slick-active')
+ .attr('aria-hidden', 'false');
+
+ } else {
+
+ remainder = _.slideCount % _.options.slidesToShow;
+ indexOffset = _.options.infinite === true ? _.options.slidesToShow + index : index;
+
+ if (_.options.slidesToShow == _.options.slidesToScroll && (_.slideCount - index) < _.options.slidesToShow) {
+
+ allSlides
+ .slice(indexOffset - (_.options.slidesToShow - remainder), indexOffset + remainder)
+ .addClass('slick-active')
+ .attr('aria-hidden', 'false');
+
+ } else {
+
+ allSlides
+ .slice(indexOffset, indexOffset + _.options.slidesToShow)
+ .addClass('slick-active')
+ .attr('aria-hidden', 'false');
+
+ }
+
+ }
+
+ }
+
+ if (_.options.lazyLoad === 'ondemand') {
+ _.lazyLoad();
+ }
+
+ };
+
+ Slick.prototype.setupInfinite = function() {
+
+ var _ = this,
+ i, slideIndex, infiniteCount;
+
+ if (_.options.fade === true) {
+ _.options.centerMode = false;
+ }
+
+ if (_.options.infinite === true && _.options.fade === false) {
+
+ slideIndex = null;
+
+ if (_.slideCount > _.options.slidesToShow) {
+
+ if (_.options.centerMode === true) {
+ infiniteCount = _.options.slidesToShow + 1;
+ } else {
+ infiniteCount = _.options.slidesToShow;
+ }
+
+ for (i = _.slideCount; i > (_.slideCount -
+ infiniteCount); i -= 1) {
+ slideIndex = i - 1;
+ $(_.$slides[slideIndex]).clone(true).attr('id', '')
+ .attr('data-slick-index', slideIndex - _.slideCount)
+ .prependTo(_.$slideTrack).addClass('slick-cloned');
+ }
+ for (i = 0; i < infiniteCount; i += 1) {
+ slideIndex = i;
+ $(_.$slides[slideIndex]).clone(true).attr('id', '')
+ .attr('data-slick-index', slideIndex + _.slideCount)
+ .appendTo(_.$slideTrack).addClass('slick-cloned');
+ }
+ _.$slideTrack.find('.slick-cloned').find('[id]').each(function() {
+ $(this).attr('id', '');
+ });
+
+ }
+
+ }
+
+ };
+
+ Slick.prototype.interrupt = function( toggle ) {
+
+ var _ = this;
+
+ if( !toggle ) {
+ _.autoPlay();
+ }
+ _.interrupted = toggle;
+
+ };
+
+ Slick.prototype.selectHandler = function(event) {
+
+ var _ = this;
+
+ var targetElement =
+ $(event.target).is('.slick-slide') ?
+ $(event.target) :
+ $(event.target).parents('.slick-slide');
+
+ var index = parseInt(targetElement.attr('data-slick-index'));
+
+ if (!index) index = 0;
+
+ if (_.slideCount <= _.options.slidesToShow) {
+
+ _.setSlideClasses(index);
+ _.asNavFor(index);
+ return;
+
+ }
+
+ _.slideHandler(index);
+
+ };
+
+ Slick.prototype.slideHandler = function(index, sync, dontAnimate) {
+
+ var targetSlide, animSlide, oldSlide, slideLeft, targetLeft = null,
+ _ = this, navTarget;
+
+ sync = sync || false;
+
+ if (_.animating === true && _.options.waitForAnimate === true) {
+ return;
+ }
+
+ if (_.options.fade === true && _.currentSlide === index) {
+ return;
+ }
+
+ if (_.slideCount <= _.options.slidesToShow) {
+ return;
+ }
+
+ if (sync === false) {
+ _.asNavFor(index);
+ }
+
+ targetSlide = index;
+ targetLeft = _.getLeft(targetSlide);
+ slideLeft = _.getLeft(_.currentSlide);
+
+ _.currentLeft = _.swipeLeft === null ? slideLeft : _.swipeLeft;
+
+ if (_.options.infinite === false && _.options.centerMode === false && (index < 0 || index > _.getDotCount() * _.options.slidesToScroll)) {
+ if (_.options.fade === false) {
+ targetSlide = _.currentSlide;
+ if (dontAnimate !== true) {
+ _.animateSlide(slideLeft, function() {
+ _.postSlide(targetSlide);
+ });
+ } else {
+ _.postSlide(targetSlide);
+ }
+ }
+ return;
+ } else if (_.options.infinite === false && _.options.centerMode === true && (index < 0 || index > (_.slideCount - _.options.slidesToScroll))) {
+ if (_.options.fade === false) {
+ targetSlide = _.currentSlide;
+ if (dontAnimate !== true) {
+ _.animateSlide(slideLeft, function() {
+ _.postSlide(targetSlide);
+ });
+ } else {
+ _.postSlide(targetSlide);
+ }
+ }
+ return;
+ }
+
+ if ( _.options.autoplay ) {
+ clearInterval(_.autoPlayTimer);
+ }
+
+ if (targetSlide < 0) {
+ if (_.slideCount % _.options.slidesToScroll !== 0) {
+ animSlide = _.slideCount - (_.slideCount % _.options.slidesToScroll);
+ } else {
+ animSlide = _.slideCount + targetSlide;
+ }
+ } else if (targetSlide >= _.slideCount) {
+ if (_.slideCount % _.options.slidesToScroll !== 0) {
+ animSlide = 0;
+ } else {
+ animSlide = targetSlide - _.slideCount;
+ }
+ } else {
+ animSlide = targetSlide;
+ }
+
+ _.animating = true;
+
+ _.$slider.trigger('beforeChange', [_, _.currentSlide, animSlide]);
+
+ oldSlide = _.currentSlide;
+ _.currentSlide = animSlide;
+
+ _.setSlideClasses(_.currentSlide);
+
+ if ( _.options.asNavFor ) {
+
+ navTarget = _.getNavTarget();
+ navTarget = navTarget.slick('getSlick');
+
+ if ( navTarget.slideCount <= navTarget.options.slidesToShow ) {
+ navTarget.setSlideClasses(_.currentSlide);
+ }
+
+ }
+
+ _.updateDots();
+ _.updateArrows();
+
+ if (_.options.fade === true) {
+ if (dontAnimate !== true) {
+
+ _.fadeSlideOut(oldSlide);
+
+ _.fadeSlide(animSlide, function() {
+ _.postSlide(animSlide);
+ });
+
+ } else {
+ _.postSlide(animSlide);
+ }
+ _.animateHeight();
+ return;
+ }
+
+ if (dontAnimate !== true) {
+ _.animateSlide(targetLeft, function() {
+ _.postSlide(animSlide);
+ });
+ } else {
+ _.postSlide(animSlide);
+ }
+
+ };
+
+ Slick.prototype.startLoad = function() {
+
+ var _ = this;
+
+ if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
+
+ _.$prevArrow.hide();
+ _.$nextArrow.hide();
+
+ }
+
+ if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
+
+ _.$dots.hide();
+
+ }
+
+ _.$slider.addClass('slick-loading');
+
+ };
+
+ Slick.prototype.swipeDirection = function() {
+
+ var xDist, yDist, r, swipeAngle, _ = this;
+
+ xDist = _.touchObject.startX - _.touchObject.curX;
+ yDist = _.touchObject.startY - _.touchObject.curY;
+ r = Math.atan2(yDist, xDist);
+
+ swipeAngle = Math.round(r * 180 / Math.PI);
+ if (swipeAngle < 0) {
+ swipeAngle = 360 - Math.abs(swipeAngle);
+ }
+
+ if ((swipeAngle <= 45) && (swipeAngle >= 0)) {
+ return (_.options.rtl === false ? 'left' : 'right');
+ }
+ if ((swipeAngle <= 360) && (swipeAngle >= 315)) {
+ return (_.options.rtl === false ? 'left' : 'right');
+ }
+ if ((swipeAngle >= 135) && (swipeAngle <= 225)) {
+ return (_.options.rtl === false ? 'right' : 'left');
+ }
+ if (_.options.verticalSwiping === true) {
+ if ((swipeAngle >= 35) && (swipeAngle <= 135)) {
+ return 'down';
+ } else {
+ return 'up';
+ }
+ }
+
+ return 'vertical';
+
+ };
+
+ Slick.prototype.swipeEnd = function(event) {
+
+ var _ = this,
+ slideCount,
+ direction;
+
+ _.dragging = false;
+ _.interrupted = false;
+ _.shouldClick = ( _.touchObject.swipeLength > 10 ) ? false : true;
+
+ if ( _.touchObject.curX === undefined ) {
+ return false;
+ }
+
+ if ( _.touchObject.edgeHit === true ) {
+ _.$slider.trigger('edge', [_, _.swipeDirection() ]);
+ }
+
+ if ( _.touchObject.swipeLength >= _.touchObject.minSwipe ) {
+
+ direction = _.swipeDirection();
+
+ switch ( direction ) {
+
+ case 'left':
+ case 'down':
+
+ slideCount =
+ _.options.swipeToSlide ?
+ _.checkNavigable( _.currentSlide + _.getSlideCount() ) :
+ _.currentSlide + _.getSlideCount();
+
+ _.currentDirection = 0;
+
+ break;
+
+ case 'right':
+ case 'up':
+
+ slideCount =
+ _.options.swipeToSlide ?
+ _.checkNavigable( _.currentSlide - _.getSlideCount() ) :
+ _.currentSlide - _.getSlideCount();
+
+ _.currentDirection = 1;
+
+ break;
+
+ default:
+
+
+ }
+
+ if( direction != 'vertical' ) {
+
+ _.slideHandler( slideCount );
+ _.touchObject = {};
+ _.$slider.trigger('swipe', [_, direction ]);
+
+ }
+
+ } else {
+
+ if ( _.touchObject.startX !== _.touchObject.curX ) {
+
+ _.slideHandler( _.currentSlide );
+ _.touchObject = {};
+
+ }
+
+ }
+
+ };
+
+ Slick.prototype.swipeHandler = function(event) {
+
+ var _ = this;
+
+ if ((_.options.swipe === false) || ('ontouchend' in document && _.options.swipe === false)) {
+ return;
+ } else if (_.options.draggable === false && event.type.indexOf('mouse') !== -1) {
+ return;
+ }
+
+ _.touchObject.fingerCount = event.originalEvent && event.originalEvent.touches !== undefined ?
+ event.originalEvent.touches.length : 1;
+
+ _.touchObject.minSwipe = _.listWidth / _.options
+ .touchThreshold;
+
+ if (_.options.verticalSwiping === true) {
+ _.touchObject.minSwipe = _.listHeight / _.options
+ .touchThreshold;
+ }
+
+ switch (event.data.action) {
+
+ case 'start':
+ _.swipeStart(event);
+ break;
+
+ case 'move':
+ _.swipeMove(event);
+ break;
+
+ case 'end':
+ _.swipeEnd(event);
+ break;
+
+ }
+
+ };
+
+ Slick.prototype.swipeMove = function(event) {
+
+ var _ = this,
+ edgeWasHit = false,
+ curLeft, swipeDirection, swipeLength, positionOffset, touches;
+
+ touches = event.originalEvent !== undefined ? event.originalEvent.touches : null;
+
+ if (!_.dragging || touches && touches.length !== 1) {
+ return false;
+ }
+
+ curLeft = _.getLeft(_.currentSlide);
+
+ _.touchObject.curX = touches !== undefined ? touches[0].pageX : event.clientX;
+ _.touchObject.curY = touches !== undefined ? touches[0].pageY : event.clientY;
+
+ _.touchObject.swipeLength = Math.round(Math.sqrt(
+ Math.pow(_.touchObject.curX - _.touchObject.startX, 2)));
+
+ if (_.options.verticalSwiping === true) {
+ _.touchObject.swipeLength = Math.round(Math.sqrt(
+ Math.pow(_.touchObject.curY - _.touchObject.startY, 2)));
+ }
+
+ swipeDirection = _.swipeDirection();
+
+ if (swipeDirection === 'vertical') {
+ return;
+ }
+
+ if (event.originalEvent !== undefined && _.touchObject.swipeLength > 4) {
+ event.preventDefault();
+ }
+
+ positionOffset = (_.options.rtl === false ? 1 : -1) * (_.touchObject.curX > _.touchObject.startX ? 1 : -1);
+ if (_.options.verticalSwiping === true) {
+ positionOffset = _.touchObject.curY > _.touchObject.startY ? 1 : -1;
+ }
+
+
+ swipeLength = _.touchObject.swipeLength;
+
+ _.touchObject.edgeHit = false;
+
+ if (_.options.infinite === false) {
+ if ((_.currentSlide === 0 && swipeDirection === 'right') || (_.currentSlide >= _.getDotCount() && swipeDirection === 'left')) {
+ swipeLength = _.touchObject.swipeLength * _.options.edgeFriction;
+ _.touchObject.edgeHit = true;
+ }
+ }
+
+ if (_.options.vertical === false) {
+ _.swipeLeft = curLeft + swipeLength * positionOffset;
+ } else {
+ _.swipeLeft = curLeft + (swipeLength * (_.$list.height() / _.listWidth)) * positionOffset;
+ }
+ if (_.options.verticalSwiping === true) {
+ _.swipeLeft = curLeft + swipeLength * positionOffset;
+ }
+
+ if (_.options.fade === true || _.options.touchMove === false) {
+ return false;
+ }
+
+ if (_.animating === true) {
+ _.swipeLeft = null;
+ return false;
+ }
+
+ _.setCSS(_.swipeLeft);
+
+ };
+
+ Slick.prototype.swipeStart = function(event) {
+
+ var _ = this,
+ touches;
+
+ _.interrupted = true;
+
+ if (_.touchObject.fingerCount !== 1 || _.slideCount <= _.options.slidesToShow) {
+ _.touchObject = {};
+ return false;
+ }
+
+ if (event.originalEvent !== undefined && event.originalEvent.touches !== undefined) {
+ touches = event.originalEvent.touches[0];
+ }
+
+ _.touchObject.startX = _.touchObject.curX = touches !== undefined ? touches.pageX : event.clientX;
+ _.touchObject.startY = _.touchObject.curY = touches !== undefined ? touches.pageY : event.clientY;
+
+ _.dragging = true;
+
+ };
+
+ Slick.prototype.unfilterSlides = Slick.prototype.slickUnfilter = function() {
+
+ var _ = this;
+
+ if (_.$slidesCache !== null) {
+
+ _.unload();
+
+ _.$slideTrack.children(this.options.slide).detach();
+
+ _.$slidesCache.appendTo(_.$slideTrack);
+
+ _.reinit();
+
+ }
+
+ };
+
+ Slick.prototype.unload = function() {
+
+ var _ = this;
+
+ $('.slick-cloned', _.$slider).remove();
+
+ if (_.$dots) {
+ _.$dots.remove();
+ }
+
+ if (_.$prevArrow && _.htmlExpr.test(_.options.prevArrow)) {
+ _.$prevArrow.remove();
+ }
+
+ if (_.$nextArrow && _.htmlExpr.test(_.options.nextArrow)) {
+ _.$nextArrow.remove();
+ }
+
+ _.$slides
+ .removeClass('slick-slide slick-active slick-visible slick-current')
+ .attr('aria-hidden', 'true')
+ .css('width', '');
+
+ };
+
+ Slick.prototype.unslick = function(fromBreakpoint) {
+
+ var _ = this;
+ _.$slider.trigger('unslick', [_, fromBreakpoint]);
+ _.destroy();
+
+ };
+
+ Slick.prototype.updateArrows = function() {
+
+ var _ = this,
+ centerOffset;
+
+ centerOffset = Math.floor(_.options.slidesToShow / 2);
+
+ if ( _.options.arrows === true &&
+ _.slideCount > _.options.slidesToShow &&
+ !_.options.infinite ) {
+
+ _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
+ _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
+
+ if (_.currentSlide === 0) {
+
+ _.$prevArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
+ _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
+
+ } else if (_.currentSlide >= _.slideCount - _.options.slidesToShow && _.options.centerMode === false) {
+
+ _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
+ _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
+
+ } else if (_.currentSlide >= _.slideCount - 1 && _.options.centerMode === true) {
+
+ _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
+ _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
+
+ }
+
+ }
+
+ };
+
+ Slick.prototype.updateDots = function() {
+
+ var _ = this;
+
+ if (_.$dots !== null) {
+
+ _.$dots
+ .find('li')
+ .removeClass('slick-active')
+ .attr('aria-hidden', 'true');
+
+ _.$dots
+ .find('li')
+ .eq(Math.floor(_.currentSlide / _.options.slidesToScroll))
+ .addClass('slick-active')
+ .attr('aria-hidden', 'false');
+
+ }
+
+ };
+
+ Slick.prototype.visibility = function() {
+
+ var _ = this;
+
+ if ( _.options.autoplay ) {
+
+ if ( document[_.hidden] ) {
+
+ _.interrupted = true;
+
+ } else {
+
+ _.interrupted = false;
+
+ }
+
+ }
+
+ };
+
+ $.fn.slick = function() {
+ var _ = this,
+ opt = arguments[0],
+ args = Array.prototype.slice.call(arguments, 1),
+ l = _.length,
+ i,
+ ret;
+ for (i = 0; i < l; i++) {
+ if (typeof opt == 'object' || typeof opt == 'undefined')
+ _[i].slick = new Slick(_[i], opt);
+ else
+ ret = _[i].slick[opt].apply(_[i].slick, args);
+ if (typeof ret != 'undefined') return ret;
+ }
+ return _;
+ };
+
+}));
+/*!
+ * Lightbox v2.10.0
+ * by Lokesh Dhakar
+ *
+ * More info:
+ * http://lokeshdhakar.com/projects/lightbox2/
+ *
+ * Copyright 2007, 2018 Lokesh Dhakar
+ * Released under the MIT license
+ * https://github.com/lokesh/lightbox2/blob/master/LICENSE
+ *
+ * @preserve
+ */
+
+// Uses Node, AMD or browser globals to create a module.
+(function (root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['jquery'], factory);
+ } else if (typeof exports === 'object') {
+ // Node. Does not work with strict CommonJS, but
+ // only CommonJS-like environments that support module.exports,
+ // like Node.
+ module.exports = factory(require('jquery'));
+ } else {
+ // Browser globals (root is window)
+ root.lightbox = factory(root.jQuery);
+ }
+}(this, function ($) {
+
+ function Lightbox(options) {
+ this.album = [];
+ this.currentImageIndex = void 0;
+ this.init();
+
+ // options
+ this.options = $.extend({}, this.constructor.defaults);
+ this.option(options);
+ }
+
+ // Descriptions of all options available on the demo site:
+ // http://lokeshdhakar.com/projects/lightbox2/index.html#options
+ Lightbox.defaults = {
+ albumLabel: 'Image %1 of %2',
+ alwaysShowNavOnTouchDevices: false,
+ fadeDuration: 600,
+ fitImagesInViewport: true,
+ imageFadeDuration: 600,
+ // maxWidth: 800,
+ // maxHeight: 600,
+ positionFromTop: 50,
+ resizeDuration: 700,
+ showImageNumberLabel: true,
+ wrapAround: false,
+ disableScrolling: false,
+ /*
+ Sanitize Title
+ If the caption data is trusted, for example you are hardcoding it in, then leave this to false.
+ This will free you to add html tags, such as links, in the caption.
+
+ If the caption data is user submitted or from some other untrusted source, then set this to true
+ to prevent xss and other injection attacks.
+ */
+ sanitizeTitle: false
+ };
+
+ Lightbox.prototype.option = function(options) {
+ $.extend(this.options, options);
+ };
+
+ Lightbox.prototype.imageCountLabel = function(currentImageNum, totalImages) {
+ return this.options.albumLabel.replace(/%1/g, currentImageNum).replace(/%2/g, totalImages);
+ };
+
+ Lightbox.prototype.init = function() {
+ var self = this;
+ // Both enable and build methods require the body tag to be in the DOM.
+ $(document).ready(function() {
+ self.enable();
+ self.build();
+ });
+ };
+
+ // Loop through anchors and areamaps looking for either data-lightbox attributes or rel attributes
+ // that contain 'lightbox'. When these are clicked, start lightbox.
+ Lightbox.prototype.enable = function() {
+ var self = this;
+ $('body').on('click', 'a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]', function(event) {
+ self.start($(event.currentTarget));
+ return false;
+ });
+ };
+
+ // Build html for the lightbox and the overlay.
+ // Attach event handlers to the new DOM elements. click click click
+ Lightbox.prototype.build = function() {
+ if ($('#lightbox').length > 0) {
+ return;
+ }
+
+ var self = this;
+ $('
').appendTo($('body'));
+
+ // Cache jQuery objects
+ this.$lightbox = $('#lightbox');
+ this.$overlay = $('#lightboxOverlay');
+ this.$outerContainer = this.$lightbox.find('.lb-outerContainer');
+ this.$container = this.$lightbox.find('.lb-container');
+ this.$image = this.$lightbox.find('.lb-image');
+ this.$nav = this.$lightbox.find('.lb-nav');
+
+ // Store css values for future lookup
+ this.containerPadding = {
+ top: parseInt(this.$container.css('padding-top'), 10),
+ right: parseInt(this.$container.css('padding-right'), 10),
+ bottom: parseInt(this.$container.css('padding-bottom'), 10),
+ left: parseInt(this.$container.css('padding-left'), 10)
+ };
+
+ this.imageBorderWidth = {
+ top: parseInt(this.$image.css('border-top-width'), 10),
+ right: parseInt(this.$image.css('border-right-width'), 10),
+ bottom: parseInt(this.$image.css('border-bottom-width'), 10),
+ left: parseInt(this.$image.css('border-left-width'), 10)
+ };
+
+ // Attach event handlers to the newly minted DOM elements
+ this.$overlay.hide().on('click', function() {
+ self.end();
+ return false;
+ });
+
+ this.$lightbox.hide().on('click', function(event) {
+ if ($(event.target).attr('id') === 'lightbox') {
+ self.end();
+ }
+ return false;
+ });
+
+ this.$outerContainer.on('click', function(event) {
+ if ($(event.target).attr('id') === 'lightbox') {
+ self.end();
+ }
+ return false;
+ });
+
+ this.$lightbox.find('.lb-prev').on('click', function() {
+ if (self.currentImageIndex === 0) {
+ self.changeImage(self.album.length - 1);
+ } else {
+ self.changeImage(self.currentImageIndex - 1);
+ }
+ return false;
+ });
+
+ this.$lightbox.find('.lb-next').on('click', function() {
+ if (self.currentImageIndex === self.album.length - 1) {
+ self.changeImage(0);
+ } else {
+ self.changeImage(self.currentImageIndex + 1);
+ }
+ return false;
+ });
+
+ /*
+ Show context menu for image on right-click
+
+ There is a div containing the navigation that spans the entire image and lives above of it. If
+ you right-click, you are right clicking this div and not the image. This prevents users from
+ saving the image or using other context menu actions with the image.
+
+ To fix this, when we detect the right mouse button is pressed down, but not yet clicked, we
+ set pointer-events to none on the nav div. This is so that the upcoming right-click event on
+ the next mouseup will bubble down to the image. Once the right-click/contextmenu event occurs
+ we set the pointer events back to auto for the nav div so it can capture hover and left-click
+ events as usual.
+ */
+ this.$nav.on('mousedown', function(event) {
+ if (event.which === 3) {
+ self.$nav.css('pointer-events', 'none');
+
+ self.$lightbox.one('contextmenu', function() {
+ setTimeout(function() {
+ this.$nav.css('pointer-events', 'auto');
+ }.bind(self), 0);
+ });
+ }
+ });
+
+
+ this.$lightbox.find('.lb-loader, .lb-close').on('click', function() {
+ self.end();
+ return false;
+ });
+ };
+
+ // Show overlay and lightbox. If the image is part of a set, add siblings to album array.
+ Lightbox.prototype.start = function($link) {
+ var self = this;
+ var $window = $(window);
+
+ $window.on('resize', $.proxy(this.sizeOverlay, this));
+
+ $('select, object, embed').css({
+ visibility: 'hidden'
+ });
+
+ this.sizeOverlay();
+
+ this.album = [];
+ var imageNumber = 0;
+
+ function addToAlbum($link) {
+ self.album.push({
+ alt: $link.attr('data-alt'),
+ link: $link.attr('href'),
+ title: $link.attr('data-title') || $link.attr('title')
+ });
+ }
+
+ // Support both data-lightbox attribute and rel attribute implementations
+ var dataLightboxValue = $link.attr('data-lightbox');
+ var $links;
+
+ if (dataLightboxValue) {
+ $links = $($link.prop('tagName') + '[data-lightbox="' + dataLightboxValue + '"]');
+ for (var i = 0; i < $links.length; i = ++i) {
+ addToAlbum($($links[i]));
+ if ($links[i] === $link[0]) {
+ imageNumber = i;
+ }
+ }
+ } else {
+ if ($link.attr('rel') === 'lightbox') {
+ // If image is not part of a set
+ addToAlbum($link);
+ } else {
+ // If image is part of a set
+ $links = $($link.prop('tagName') + '[rel="' + $link.attr('rel') + '"]');
+ for (var j = 0; j < $links.length; j = ++j) {
+ addToAlbum($($links[j]));
+ if ($links[j] === $link[0]) {
+ imageNumber = j;
+ }
+ }
+ }
+ }
+
+ // Position Lightbox
+ var top = $window.scrollTop() + this.options.positionFromTop;
+ var left = $window.scrollLeft();
+ this.$lightbox.css({
+ top: top + 'px',
+ left: left + 'px'
+ }).fadeIn(this.options.fadeDuration);
+
+ // Disable scrolling of the page while open
+ if (this.options.disableScrolling) {
+ $('html').addClass('lb-disable-scrolling');
+ }
+
+ this.changeImage(imageNumber);
+ };
+
+ // Hide most UI elements in preparation for the animated resizing of the lightbox.
+ Lightbox.prototype.changeImage = function(imageNumber) {
+ var self = this;
+
+ this.disableKeyboardNav();
+ var $image = this.$lightbox.find('.lb-image');
+
+ this.$overlay.fadeIn(this.options.fadeDuration);
+
+ $('.lb-loader').fadeIn('slow');
+ this.$lightbox.find('.lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption').hide();
+
+ this.$outerContainer.addClass('animating');
+
+ // When image to show is preloaded, we send the width and height to sizeContainer()
+ var preloader = new Image();
+ preloader.onload = function() {
+ var $preloader;
+ var imageHeight;
+ var imageWidth;
+ var maxImageHeight;
+ var maxImageWidth;
+ var windowHeight;
+ var windowWidth;
+
+ $image.attr({
+ 'alt': self.album[imageNumber].alt,
+ 'src': self.album[imageNumber].link
+ });
+
+ $preloader = $(preloader);
+
+ $image.width(preloader.width);
+ $image.height(preloader.height);
+
+ if (self.options.fitImagesInViewport) {
+ // Fit image inside the viewport.
+ // Take into account the border around the image and an additional 10px gutter on each side.
+
+ windowWidth = $(window).width();
+ windowHeight = $(window).height();
+ maxImageWidth = windowWidth - self.containerPadding.left - self.containerPadding.right - self.imageBorderWidth.left - self.imageBorderWidth.right - 20;
+ maxImageHeight = windowHeight - self.containerPadding.top - self.containerPadding.bottom - self.imageBorderWidth.top - self.imageBorderWidth.bottom - 120;
+
+ // Check if image size is larger then maxWidth|maxHeight in settings
+ if (self.options.maxWidth && self.options.maxWidth < maxImageWidth) {
+ maxImageWidth = self.options.maxWidth;
+ }
+ if (self.options.maxHeight && self.options.maxHeight < maxImageWidth) {
+ maxImageHeight = self.options.maxHeight;
+ }
+
+ // Is the current image's width or height is greater than the maxImageWidth or maxImageHeight
+ // option than we need to size down while maintaining the aspect ratio.
+ if ((preloader.width > maxImageWidth) || (preloader.height > maxImageHeight)) {
+ if ((preloader.width / maxImageWidth) > (preloader.height / maxImageHeight)) {
+ imageWidth = maxImageWidth;
+ imageHeight = parseInt(preloader.height / (preloader.width / imageWidth), 10);
+ $image.width(imageWidth);
+ $image.height(imageHeight);
+ } else {
+ imageHeight = maxImageHeight;
+ imageWidth = parseInt(preloader.width / (preloader.height / imageHeight), 10);
+ $image.width(imageWidth);
+ $image.height(imageHeight);
+ }
+ }
+ }
+ self.sizeContainer($image.width(), $image.height());
+ };
+
+ preloader.src = this.album[imageNumber].link;
+ this.currentImageIndex = imageNumber;
+ };
+
+ // Stretch overlay to fit the viewport
+ Lightbox.prototype.sizeOverlay = function() {
+ this.$overlay
+ .width($(document).width())
+ .height($(document).height());
+ };
+
+ // Animate the size of the lightbox to fit the image we are showing
+ Lightbox.prototype.sizeContainer = function(imageWidth, imageHeight) {
+ var self = this;
+
+ var oldWidth = this.$outerContainer.outerWidth();
+ var oldHeight = this.$outerContainer.outerHeight();
+ var newWidth = imageWidth + this.containerPadding.left + this.containerPadding.right + this.imageBorderWidth.left + this.imageBorderWidth.right;
+ var newHeight = imageHeight + this.containerPadding.top + this.containerPadding.bottom + this.imageBorderWidth.top + this.imageBorderWidth.bottom;
+
+ function postResize() {
+ self.$lightbox.find('.lb-dataContainer').width(newWidth);
+ self.$lightbox.find('.lb-prevLink').height(newHeight);
+ self.$lightbox.find('.lb-nextLink').height(newHeight);
+ self.showImage();
+ }
+
+ if (oldWidth !== newWidth || oldHeight !== newHeight) {
+ this.$outerContainer.animate({
+ width: newWidth,
+ height: newHeight
+ }, this.options.resizeDuration, 'swing', function() {
+ postResize();
+ });
+ } else {
+ postResize();
+ }
+ };
+
+ // Display the image and its details and begin preload neighboring images.
+ Lightbox.prototype.showImage = function() {
+ this.$lightbox.find('.lb-loader').stop(true).hide();
+ this.$lightbox.find('.lb-image').fadeIn(this.options.imageFadeDuration);
+
+ this.updateNav();
+ this.updateDetails();
+ this.preloadNeighboringImages();
+ this.enableKeyboardNav();
+ };
+
+ // Display previous and next navigation if appropriate.
+ Lightbox.prototype.updateNav = function() {
+ // Check to see if the browser supports touch events. If so, we take the conservative approach
+ // and assume that mouse hover events are not supported and always show prev/next navigation
+ // arrows in image sets.
+ var alwaysShowNav = false;
+ try {
+ document.createEvent('TouchEvent');
+ alwaysShowNav = (this.options.alwaysShowNavOnTouchDevices) ? true : false;
+ } catch (e) {}
+
+ this.$lightbox.find('.lb-nav').show();
+
+ if (this.album.length > 1) {
+ if (this.options.wrapAround) {
+ if (alwaysShowNav) {
+ this.$lightbox.find('.lb-prev, .lb-next').css('opacity', '1');
+ }
+ this.$lightbox.find('.lb-prev, .lb-next').show();
+ } else {
+ if (this.currentImageIndex > 0) {
+ this.$lightbox.find('.lb-prev').show();
+ if (alwaysShowNav) {
+ this.$lightbox.find('.lb-prev').css('opacity', '1');
+ }
+ }
+ if (this.currentImageIndex < this.album.length - 1) {
+ this.$lightbox.find('.lb-next').show();
+ if (alwaysShowNav) {
+ this.$lightbox.find('.lb-next').css('opacity', '1');
+ }
+ }
+ }
+ }
+ };
+
+ // Display caption, image number, and closing button.
+ Lightbox.prototype.updateDetails = function() {
+ var self = this;
+
+ // Enable anchor clicks in the injected caption html.
+ // Thanks Nate Wright for the fix. @https://github.com/NateWr
+ if (typeof this.album[this.currentImageIndex].title !== 'undefined' &&
+ this.album[this.currentImageIndex].title !== '') {
+ var $caption = this.$lightbox.find('.lb-caption');
+ if (this.options.sanitizeTitle) {
+ $caption.text(this.album[this.currentImageIndex].title);
+ } else {
+ $caption.html(this.album[this.currentImageIndex].title);
+ }
+ $caption.fadeIn('fast')
+ .find('a').on('click', function(event) {
+ if ($(this).attr('target') !== undefined) {
+ window.open($(this).attr('href'), $(this).attr('target'));
+ } else {
+ location.href = $(this).attr('href');
+ }
+ });
+ }
+
+ if (this.album.length > 1 && this.options.showImageNumberLabel) {
+ var labelText = this.imageCountLabel(this.currentImageIndex + 1, this.album.length);
+ this.$lightbox.find('.lb-number').text(labelText).fadeIn('fast');
+ } else {
+ this.$lightbox.find('.lb-number').hide();
+ }
+
+ this.$outerContainer.removeClass('animating');
+
+ this.$lightbox.find('.lb-dataContainer').fadeIn(this.options.resizeDuration, function() {
+ return self.sizeOverlay();
+ });
+ };
+
+ // Preload previous and next images in set.
+ Lightbox.prototype.preloadNeighboringImages = function() {
+ if (this.album.length > this.currentImageIndex + 1) {
+ var preloadNext = new Image();
+ preloadNext.src = this.album[this.currentImageIndex + 1].link;
+ }
+ if (this.currentImageIndex > 0) {
+ var preloadPrev = new Image();
+ preloadPrev.src = this.album[this.currentImageIndex - 1].link;
+ }
+ };
+
+ Lightbox.prototype.enableKeyboardNav = function() {
+ $(document).on('keyup.keyboard', $.proxy(this.keyboardAction, this));
+ };
+
+ Lightbox.prototype.disableKeyboardNav = function() {
+ $(document).off('.keyboard');
+ };
+
+ Lightbox.prototype.keyboardAction = function(event) {
+ var KEYCODE_ESC = 27;
+ var KEYCODE_LEFTARROW = 37;
+ var KEYCODE_RIGHTARROW = 39;
+
+ var keycode = event.keyCode;
+ var key = String.fromCharCode(keycode).toLowerCase();
+ if (keycode === KEYCODE_ESC || key.match(/x|o|c/)) {
+ this.end();
+ } else if (key === 'p' || keycode === KEYCODE_LEFTARROW) {
+ if (this.currentImageIndex !== 0) {
+ this.changeImage(this.currentImageIndex - 1);
+ } else if (this.options.wrapAround && this.album.length > 1) {
+ this.changeImage(this.album.length - 1);
+ }
+ } else if (key === 'n' || keycode === KEYCODE_RIGHTARROW) {
+ if (this.currentImageIndex !== this.album.length - 1) {
+ this.changeImage(this.currentImageIndex + 1);
+ } else if (this.options.wrapAround && this.album.length > 1) {
+ this.changeImage(0);
+ }
+ }
+ };
+
+ // Closing time. :-(
+ Lightbox.prototype.end = function() {
+ this.disableKeyboardNav();
+ $(window).off('resize', this.sizeOverlay);
+ this.$lightbox.fadeOut(this.options.fadeDuration);
+ this.$overlay.fadeOut(this.options.fadeDuration);
+ $('select, object, embed').css({
+ visibility: 'visible'
+ });
+ if (this.options.disableScrolling) {
+ $('html').removeClass('lb-disable-scrolling');
+ }
+ };
+
+ return new Lightbox();
+}));
+
+
+/**
+ * Owl Carousel v2.3.1
+ * Copyright 2013-2018 David Deutsch
+ * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
+ */
+/**
+ * Owl carousel
+ * @version 2.3.1
+ * @author Bartosz Wojciechowski
+ * @author David Deutsch
+ * @license The MIT License (MIT)
+ * @todo Lazy Load Icon
+ * @todo prevent animationend bubling
+ * @todo itemsScaleUp
+ * @todo Test Zepto
+ * @todo stagePadding calculate wrong active classes
+ */
+;(function($, window, document, undefined) {
+
+ /**
+ * Creates a carousel.
+ * @class The Owl Carousel.
+ * @public
+ * @param {HTMLElement|jQuery} element - The element to create the carousel for.
+ * @param {Object} [options] - The options
+ */
+ function Owl(element, options) {
+
+ /**
+ * Current settings for the carousel.
+ * @public
+ */
+ this.settings = null;
+
+ /**
+ * Current options set by the caller including defaults.
+ * @public
+ */
+ this.options = $.extend({}, Owl.Defaults, options);
+
+ /**
+ * Plugin element.
+ * @public
+ */
+ this.$element = $(element);
+
+ /**
+ * Proxied event handlers.
+ * @protected
+ */
+ this._handlers = {};
+
+ /**
+ * References to the running plugins of this carousel.
+ * @protected
+ */
+ this._plugins = {};
+
+ /**
+ * Currently suppressed events to prevent them from being retriggered.
+ * @protected
+ */
+ this._supress = {};
+
+ /**
+ * Absolute current position.
+ * @protected
+ */
+ this._current = null;
+
+ /**
+ * Animation speed in milliseconds.
+ * @protected
+ */
+ this._speed = null;
+
+ /**
+ * Coordinates of all items in pixel.
+ * @todo The name of this member is missleading.
+ * @protected
+ */
+ this._coordinates = [];
+
+ /**
+ * Current breakpoint.
+ * @todo Real media queries would be nice.
+ * @protected
+ */
+ this._breakpoint = null;
+
+ /**
+ * Current width of the plugin element.
+ */
+ this._width = null;
+
+ /**
+ * All real items.
+ * @protected
+ */
+ this._items = [];
+
+ /**
+ * All cloned items.
+ * @protected
+ */
+ this._clones = [];
+
+ /**
+ * Merge values of all items.
+ * @todo Maybe this could be part of a plugin.
+ * @protected
+ */
+ this._mergers = [];
+
+ /**
+ * Widths of all items.
+ */
+ this._widths = [];
+
+ /**
+ * Invalidated parts within the update process.
+ * @protected
+ */
+ this._invalidated = {};
+
+ /**
+ * Ordered list of workers for the update process.
+ * @protected
+ */
+ this._pipe = [];
+
+ /**
+ * Current state information for the drag operation.
+ * @todo #261
+ * @protected
+ */
+ this._drag = {
+ time: null,
+ target: null,
+ pointer: null,
+ stage: {
+ start: null,
+ current: null
+ },
+ direction: null
+ };
+
+ /**
+ * Current state information and their tags.
+ * @type {Object}
+ * @protected
+ */
+ this._states = {
+ current: {},
+ tags: {
+ 'initializing': [ 'busy' ],
+ 'animating': [ 'busy' ],
+ 'dragging': [ 'interacting' ]
+ }
+ };
+
+ $.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) {
+ this._handlers[handler] = $.proxy(this[handler], this);
+ }, this));
+
+ $.each(Owl.Plugins, $.proxy(function(key, plugin) {
+ this._plugins[key.charAt(0).toLowerCase() + key.slice(1)]
+ = new plugin(this);
+ }, this));
+
+ $.each(Owl.Workers, $.proxy(function(priority, worker) {
+ this._pipe.push({
+ 'filter': worker.filter,
+ 'run': $.proxy(worker.run, this)
+ });
+ }, this));
+
+ this.setup();
+ this.initialize();
+ }
+
+ /**
+ * Default options for the carousel.
+ * @public
+ */
+ Owl.Defaults = {
+ items: 3,
+ loop: false,
+ center: false,
+ rewind: false,
+
+ mouseDrag: true,
+ touchDrag: true,
+ pullDrag: true,
+ freeDrag: false,
+
+ margin: 0,
+ stagePadding: 0,
+
+ merge: false,
+ mergeFit: true,
+ autoWidth: false,
+
+ startPosition: 0,
+ rtl: false,
+
+ smartSpeed: 250,
+ fluidSpeed: false,
+ dragEndSpeed: false,
+
+ responsive: {},
+ responsiveRefreshRate: 200,
+ responsiveBaseElement: window,
+
+ fallbackEasing: 'swing',
+
+ info: false,
+
+ nestedItemSelector: false,
+ itemElement: 'div',
+ stageElement: 'div',
+
+ refreshClass: 'owl-refresh',
+ loadedClass: 'owl-loaded',
+ loadingClass: 'owl-loading',
+ rtlClass: 'owl-rtl',
+ responsiveClass: 'owl-responsive',
+ dragClass: 'owl-drag',
+ itemClass: 'owl-item',
+ stageClass: 'owl-stage',
+ stageOuterClass: 'owl-stage-outer',
+ grabClass: 'owl-grab'
+ };
+
+ /**
+ * Enumeration for width.
+ * @public
+ * @readonly
+ * @enum {String}
+ */
+ Owl.Width = {
+ Default: 'default',
+ Inner: 'inner',
+ Outer: 'outer'
+ };
+
+ /**
+ * Enumeration for types.
+ * @public
+ * @readonly
+ * @enum {String}
+ */
+ Owl.Type = {
+ Event: 'event',
+ State: 'state'
+ };
+
+ /**
+ * Contains all registered plugins.
+ * @public
+ */
+ Owl.Plugins = {};
+
+ /**
+ * List of workers involved in the update process.
+ */
+ Owl.Workers = [ {
+ filter: [ 'width', 'settings' ],
+ run: function() {
+ this._width = this.$element.width();
+ }
+ }, {
+ filter: [ 'width', 'items', 'settings' ],
+ run: function(cache) {
+ cache.current = this._items && this._items[this.relative(this._current)];
+ }
+ }, {
+ filter: [ 'items', 'settings' ],
+ run: function() {
+ this.$stage.children('.cloned').remove();
+ }
+ }, {
+ filter: [ 'width', 'items', 'settings' ],
+ run: function(cache) {
+ var margin = this.settings.margin || '',
+ grid = !this.settings.autoWidth,
+ rtl = this.settings.rtl,
+ css = {
+ 'width': 'auto',
+ 'margin-left': rtl ? margin : '',
+ 'margin-right': rtl ? '' : margin
+ };
+
+ !grid && this.$stage.children().css(css);
+
+ cache.css = css;
+ }
+ }, {
+ filter: [ 'width', 'items', 'settings' ],
+ run: function(cache) {
+ var width = (this.width() / this.settings.items).toFixed(3) - this.settings.margin,
+ merge = null,
+ iterator = this._items.length,
+ grid = !this.settings.autoWidth,
+ widths = [];
+
+ cache.items = {
+ merge: false,
+ width: width
+ };
+
+ while (iterator--) {
+ merge = this._mergers[iterator];
+ merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge;
+
+ cache.items.merge = merge > 1 || cache.items.merge;
+
+ widths[iterator] = !grid ? this._items[iterator].width() : width * merge;
+ }
+
+ this._widths = widths;
+ }
+ }, {
+ filter: [ 'items', 'settings' ],
+ run: function() {
+ var clones = [],
+ items = this._items,
+ settings = this.settings,
+ // TODO: Should be computed from number of min width items in stage
+ view = Math.max(settings.items * 2, 4),
+ size = Math.ceil(items.length / 2) * 2,
+ repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0,
+ append = '',
+ prepend = '';
+
+ repeat /= 2;
+
+ while (repeat > 0) {
+ // Switch to only using appended clones
+ clones.push(this.normalize(clones.length / 2, true));
+ append = append + items[clones[clones.length - 1]][0].outerHTML;
+ clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true));
+ prepend = items[clones[clones.length - 1]][0].outerHTML + prepend;
+ repeat -= 1;
+ }
+
+ this._clones = clones;
+
+ $(append).addClass('cloned').appendTo(this.$stage);
+ $(prepend).addClass('cloned').prependTo(this.$stage);
+ }
+ }, {
+ filter: [ 'width', 'items', 'settings' ],
+ run: function() {
+ var rtl = this.settings.rtl ? 1 : -1,
+ size = this._clones.length + this._items.length,
+ iterator = -1,
+ previous = 0,
+ current = 0,
+ coordinates = [];
+
+ while (++iterator < size) {
+ previous = coordinates[iterator - 1] || 0;
+ current = this._widths[this.relative(iterator)] + this.settings.margin;
+ coordinates.push(previous + current * rtl);
+ }
+
+ this._coordinates = coordinates;
+ }
+ }, {
+ filter: [ 'width', 'items', 'settings' ],
+ run: function() {
+ var padding = this.settings.stagePadding,
+ coordinates = this._coordinates,
+ css = {
+ 'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2,
+ 'padding-left': padding || '',
+ 'padding-right': padding || ''
+ };
+
+ this.$stage.css(css);
+ }
+ }, {
+ filter: [ 'width', 'items', 'settings' ],
+ run: function(cache) {
+ var iterator = this._coordinates.length,
+ grid = !this.settings.autoWidth,
+ items = this.$stage.children();
+
+ if (grid && cache.items.merge) {
+ while (iterator--) {
+ cache.css.width = this._widths[this.relative(iterator)];
+ items.eq(iterator).css(cache.css);
+ }
+ } else if (grid) {
+ cache.css.width = cache.items.width;
+ items.css(cache.css);
+ }
+ }
+ }, {
+ filter: [ 'items' ],
+ run: function() {
+ this._coordinates.length < 1 && this.$stage.removeAttr('style');
+ }
+ }, {
+ filter: [ 'width', 'items', 'settings' ],
+ run: function(cache) {
+ cache.current = cache.current ? this.$stage.children().index(cache.current) : 0;
+ cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current));
+ this.reset(cache.current);
+ }
+ }, {
+ filter: [ 'position' ],
+ run: function() {
+ this.animate(this.coordinates(this._current));
+ }
+ }, {
+ filter: [ 'width', 'position', 'items', 'settings' ],
+ run: function() {
+ var rtl = this.settings.rtl ? 1 : -1,
+ padding = this.settings.stagePadding * 2,
+ begin = this.coordinates(this.current()) + padding,
+ end = begin + this.width() * rtl,
+ inner, outer, matches = [], i, n;
+
+ for (i = 0, n = this._coordinates.length; i < n; i++) {
+ inner = this._coordinates[i - 1] || 0;
+ outer = Math.abs(this._coordinates[i]) + padding * rtl;
+
+ if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end)))
+ || (this.op(outer, '<', begin) && this.op(outer, '>', end))) {
+ matches.push(i);
+ }
+ }
+
+ this.$stage.children('.active').removeClass('active');
+ this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active');
+
+ this.$stage.children('.center').removeClass('center');
+ if (this.settings.center) {
+ this.$stage.children().eq(this.current()).addClass('center');
+ }
+ }
+ } ];
+
+ /**
+ * Initializes the carousel.
+ * @protected
+ */
+ Owl.prototype.initialize = function() {
+ this.enter('initializing');
+ this.trigger('initialize');
+
+ this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl);
+
+ if (this.settings.autoWidth && !this.is('pre-loading')) {
+ var imgs, nestedSelector, width;
+ imgs = this.$element.find('img');
+ nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined;
+ width = this.$element.children(nestedSelector).width();
+
+ if (imgs.length && width <= 0) {
+ this.preloadAutoWidthImages(imgs);
+ }
+ }
+
+ this.$element.addClass(this.options.loadingClass);
+
+ // create stage
+ this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>')
+ .wrap('
');
+
+ // append stage
+ this.$element.append(this.$stage.parent());
+
+ // append content
+ this.replace(this.$element.children().not(this.$stage.parent()));
+
+ // check visibility
+ if (this.$element.is(':visible')) {
+ // update view
+ this.refresh();
+ } else {
+ // invalidate width
+ this.invalidate('width');
+ }
+
+ this.$element
+ .removeClass(this.options.loadingClass)
+ .addClass(this.options.loadedClass);
+
+ // register event handlers
+ this.registerEventHandlers();
+
+ this.leave('initializing');
+ this.trigger('initialized');
+ };
+
+ /**
+ * Setups the current settings.
+ * @todo Remove responsive classes. Why should adaptive designs be brought into IE8?
+ * @todo Support for media queries by using `matchMedia` would be nice.
+ * @public
+ */
+ Owl.prototype.setup = function() {
+ var viewport = this.viewport(),
+ overwrites = this.options.responsive,
+ match = -1,
+ settings = null;
+
+ if (!overwrites) {
+ settings = $.extend({}, this.options);
+ } else {
+ $.each(overwrites, function(breakpoint) {
+ if (breakpoint <= viewport && breakpoint > match) {
+ match = Number(breakpoint);
+ }
+ });
+
+ settings = $.extend({}, this.options, overwrites[match]);
+ if (typeof settings.stagePadding === 'function') {
+ settings.stagePadding = settings.stagePadding();
+ }
+ delete settings.responsive;
+
+ // responsive class
+ if (settings.responsiveClass) {
+ this.$element.attr('class',
+ this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match)
+ );
+ }
+ }
+
+ this.trigger('change', { property: { name: 'settings', value: settings } });
+ this._breakpoint = match;
+ this.settings = settings;
+ this.invalidate('settings');
+ this.trigger('changed', { property: { name: 'settings', value: this.settings } });
+ };
+
+ /**
+ * Updates option logic if necessery.
+ * @protected
+ */
+ Owl.prototype.optionsLogic = function() {
+ if (this.settings.autoWidth) {
+ this.settings.stagePadding = false;
+ this.settings.merge = false;
+ }
+ };
+
+ /**
+ * Prepares an item before add.
+ * @todo Rename event parameter `content` to `item`.
+ * @protected
+ * @returns {jQuery|HTMLElement} - The item container.
+ */
+ Owl.prototype.prepare = function(item) {
+ var event = this.trigger('prepare', { content: item });
+
+ if (!event.data) {
+ event.data = $('<' + this.settings.itemElement + '/>')
+ .addClass(this.options.itemClass).append(item)
+ }
+
+ this.trigger('prepared', { content: event.data });
+
+ return event.data;
+ };
+
+ /**
+ * Updates the view.
+ * @public
+ */
+ Owl.prototype.update = function() {
+ var i = 0,
+ n = this._pipe.length,
+ filter = $.proxy(function(p) { return this[p] }, this._invalidated),
+ cache = {};
+
+ while (i < n) {
+ if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) {
+ this._pipe[i].run(cache);
+ }
+ i++;
+ }
+
+ this._invalidated = {};
+
+ !this.is('valid') && this.enter('valid');
+ };
+
+ /**
+ * Gets the width of the view.
+ * @public
+ * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return.
+ * @returns {Number} - The width of the view in pixel.
+ */
+ Owl.prototype.width = function(dimension) {
+ dimension = dimension || Owl.Width.Default;
+ switch (dimension) {
+ case Owl.Width.Inner:
+ case Owl.Width.Outer:
+ return this._width;
+ default:
+ return this._width - this.settings.stagePadding * 2 + this.settings.margin;
+ }
+ };
+
+ /**
+ * Refreshes the carousel primarily for adaptive purposes.
+ * @public
+ */
+ Owl.prototype.refresh = function() {
+ this.enter('refreshing');
+ this.trigger('refresh');
+
+ this.setup();
+
+ this.optionsLogic();
+
+ this.$element.addClass(this.options.refreshClass);
+
+ this.update();
+
+ this.$element.removeClass(this.options.refreshClass);
+
+ this.leave('refreshing');
+ this.trigger('refreshed');
+ };
+
+ /**
+ * Checks window `resize` event.
+ * @protected
+ */
+ Owl.prototype.onThrottledResize = function() {
+ window.clearTimeout(this.resizeTimer);
+ this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate);
+ };
+
+ /**
+ * Checks window `resize` event.
+ * @protected
+ */
+ Owl.prototype.onResize = function() {
+ if (!this._items.length) {
+ return false;
+ }
+
+ if (this._width === this.$element.width()) {
+ return false;
+ }
+
+ if (!this.$element.is(':visible')) {
+ return false;
+ }
+
+ this.enter('resizing');
+
+ if (this.trigger('resize').isDefaultPrevented()) {
+ this.leave('resizing');
+ return false;
+ }
+
+ this.invalidate('width');
+
+ this.refresh();
+
+ this.leave('resizing');
+ this.trigger('resized');
+ };
+
+ /**
+ * Registers event handlers.
+ * @todo Check `msPointerEnabled`
+ * @todo #261
+ * @protected
+ */
+ Owl.prototype.registerEventHandlers = function() {
+ if ($.support.transition) {
+ this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this));
+ }
+
+ if (this.settings.responsive !== false) {
+ this.on(window, 'resize', this._handlers.onThrottledResize);
+ }
+
+ if (this.settings.mouseDrag) {
+ this.$element.addClass(this.options.dragClass);
+ this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this));
+ this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false });
+ }
+
+ if (this.settings.touchDrag){
+ this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this));
+ this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this));
+ }
+ };
+
+ /**
+ * Handles `touchstart` and `mousedown` events.
+ * @todo Horizontal swipe threshold as option
+ * @todo #261
+ * @protected
+ * @param {Event} event - The event arguments.
+ */
+ Owl.prototype.onDragStart = function(event) {
+ var stage = null;
+
+ if (event.which === 3) {
+ return;
+ }
+
+ if ($.support.transform) {
+ stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(',');
+ stage = {
+ x: stage[stage.length === 16 ? 12 : 4],
+ y: stage[stage.length === 16 ? 13 : 5]
+ };
+ } else {
+ stage = this.$stage.position();
+ stage = {
+ x: this.settings.rtl ?
+ stage.left + this.$stage.width() - this.width() + this.settings.margin :
+ stage.left,
+ y: stage.top
+ };
+ }
+
+ if (this.is('animating')) {
+ $.support.transform ? this.animate(stage.x) : this.$stage.stop()
+ this.invalidate('position');
+ }
+
+ this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown');
+
+ this.speed(0);
+
+ this._drag.time = new Date().getTime();
+ this._drag.target = $(event.target);
+ this._drag.stage.start = stage;
+ this._drag.stage.current = stage;
+ this._drag.pointer = this.pointer(event);
+
+ $(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this));
+
+ $(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) {
+ var delta = this.difference(this._drag.pointer, this.pointer(event));
+
+ $(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this));
+
+ if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) {
+ return;
+ }
+
+ event.preventDefault();
+
+ this.enter('dragging');
+ this.trigger('drag');
+ }, this));
+ };
+
+ /**
+ * Handles the `touchmove` and `mousemove` events.
+ * @todo #261
+ * @protected
+ * @param {Event} event - The event arguments.
+ */
+ Owl.prototype.onDragMove = function(event) {
+ var minimum = null,
+ maximum = null,
+ pull = null,
+ delta = this.difference(this._drag.pointer, this.pointer(event)),
+ stage = this.difference(this._drag.stage.start, delta);
+
+ if (!this.is('dragging')) {
+ return;
+ }
+
+ event.preventDefault();
+
+ if (this.settings.loop) {
+ minimum = this.coordinates(this.minimum());
+ maximum = this.coordinates(this.maximum() + 1) - minimum;
+ stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum;
+ } else {
+ minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum());
+ maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum());
+ pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0;
+ stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull);
+ }
+
+ this._drag.stage.current = stage;
+
+ this.animate(stage.x);
+ };
+
+ /**
+ * Handles the `touchend` and `mouseup` events.
+ * @todo #261
+ * @todo Threshold for click event
+ * @protected
+ * @param {Event} event - The event arguments.
+ */
+ Owl.prototype.onDragEnd = function(event) {
+ var delta = this.difference(this._drag.pointer, this.pointer(event)),
+ stage = this._drag.stage.current,
+ direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right';
+
+ $(document).off('.owl.core');
+
+ this.$element.removeClass(this.options.grabClass);
+
+ if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) {
+ this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed);
+ this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction));
+ this.invalidate('position');
+ this.update();
+
+ this._drag.direction = direction;
+
+ if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) {
+ this._drag.target.one('click.owl.core', function() { return false; });
+ }
+ }
+
+ if (!this.is('dragging')) {
+ return;
+ }
+
+ this.leave('dragging');
+ this.trigger('dragged');
+ };
+
+ /**
+ * Gets absolute position of the closest item for a coordinate.
+ * @todo Setting `freeDrag` makes `closest` not reusable. See #165.
+ * @protected
+ * @param {Number} coordinate - The coordinate in pixel.
+ * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`.
+ * @return {Number} - The absolute position of the closest item.
+ */
+ Owl.prototype.closest = function(coordinate, direction) {
+ var position = -1,
+ pull = 30,
+ width = this.width(),
+ coordinates = this.coordinates();
+
+ if (!this.settings.freeDrag) {
+ // check closest item
+ $.each(coordinates, $.proxy(function(index, value) {
+ // on a left pull, check on current index
+ if (direction === 'left' && coordinate > value - pull && coordinate < value + pull) {
+ position = index;
+ // on a right pull, check on previous index
+ // to do so, subtract width from value and set position = index + 1
+ } else if (direction === 'right' && coordinate > value - width - pull && coordinate < value - width + pull) {
+ position = index + 1;
+ } else if (this.op(coordinate, '<', value)
+ && this.op(coordinate, '>', coordinates[index + 1] || value - width)) {
+ position = direction === 'left' ? index + 1 : index;
+ }
+ return position === -1;
+ }, this));
+ }
+
+ if (!this.settings.loop) {
+ // non loop boundries
+ if (this.op(coordinate, '>', coordinates[this.minimum()])) {
+ position = coordinate = this.minimum();
+ } else if (this.op(coordinate, '<', coordinates[this.maximum()])) {
+ position = coordinate = this.maximum();
+ }
+ }
+
+ return position;
+ };
+
+ /**
+ * Animates the stage.
+ * @todo #270
+ * @public
+ * @param {Number} coordinate - The coordinate in pixels.
+ */
+ Owl.prototype.animate = function(coordinate) {
+ var animate = this.speed() > 0;
+
+ this.is('animating') && this.onTransitionEnd();
+
+ if (animate) {
+ this.enter('animating');
+ this.trigger('translate');
+ }
+
+ if ($.support.transform3d && $.support.transition) {
+ this.$stage.css({
+ transform: 'translate3d(' + coordinate + 'px,0px,0px)',
+ transition: (this.speed() / 1000) + 's'
+ });
+ } else if (animate) {
+ this.$stage.animate({
+ left: coordinate + 'px'
+ }, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this));
+ } else {
+ this.$stage.css({
+ left: coordinate + 'px'
+ });
+ }
+ };
+
+ /**
+ * Checks whether the carousel is in a specific state or not.
+ * @param {String} state - The state to check.
+ * @returns {Boolean} - The flag which indicates if the carousel is busy.
+ */
+ Owl.prototype.is = function(state) {
+ return this._states.current[state] && this._states.current[state] > 0;
+ };
+
+ /**
+ * Sets the absolute position of the current item.
+ * @public
+ * @param {Number} [position] - The new absolute position or nothing to leave it unchanged.
+ * @returns {Number} - The absolute position of the current item.
+ */
+ Owl.prototype.current = function(position) {
+ if (position === undefined) {
+ return this._current;
+ }
+
+ if (this._items.length === 0) {
+ return undefined;
+ }
+
+ position = this.normalize(position);
+
+ if (this._current !== position) {
+ var event = this.trigger('change', { property: { name: 'position', value: position } });
+
+ if (event.data !== undefined) {
+ position = this.normalize(event.data);
+ }
+
+ this._current = position;
+
+ this.invalidate('position');
+
+ this.trigger('changed', { property: { name: 'position', value: this._current } });
+ }
+
+ return this._current;
+ };
+
+ /**
+ * Invalidates the given part of the update routine.
+ * @param {String} [part] - The part to invalidate.
+ * @returns {Array.} - The invalidated parts.
+ */
+ Owl.prototype.invalidate = function(part) {
+ if ($.type(part) === 'string') {
+ this._invalidated[part] = true;
+ this.is('valid') && this.leave('valid');
+ }
+ return $.map(this._invalidated, function(v, i) { return i });
+ };
+
+ /**
+ * Resets the absolute position of the current item.
+ * @public
+ * @param {Number} position - The absolute position of the new item.
+ */
+ Owl.prototype.reset = function(position) {
+ position = this.normalize(position);
+
+ if (position === undefined) {
+ return;
+ }
+
+ this._speed = 0;
+ this._current = position;
+
+ this.suppress([ 'translate', 'translated' ]);
+
+ this.animate(this.coordinates(position));
+
+ this.release([ 'translate', 'translated' ]);
+ };
+
+ /**
+ * Normalizes an absolute or a relative position of an item.
+ * @public
+ * @param {Number} position - The absolute or relative position to normalize.
+ * @param {Boolean} [relative=false] - Whether the given position is relative or not.
+ * @returns {Number} - The normalized position.
+ */
+ Owl.prototype.normalize = function(position, relative) {
+ var n = this._items.length,
+ m = relative ? 0 : this._clones.length;
+
+ if (!this.isNumeric(position) || n < 1) {
+ position = undefined;
+ } else if (position < 0 || position >= n + m) {
+ position = ((position - m / 2) % n + n) % n + m / 2;
+ }
+
+ return position;
+ };
+
+ /**
+ * Converts an absolute position of an item into a relative one.
+ * @public
+ * @param {Number} position - The absolute position to convert.
+ * @returns {Number} - The converted position.
+ */
+ Owl.prototype.relative = function(position) {
+ position -= this._clones.length / 2;
+ return this.normalize(position, true);
+ };
+
+ /**
+ * Gets the maximum position for the current item.
+ * @public
+ * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
+ * @returns {Number}
+ */
+ Owl.prototype.maximum = function(relative) {
+ var settings = this.settings,
+ maximum = this._coordinates.length,
+ iterator,
+ reciprocalItemsWidth,
+ elementWidth;
+
+ if (settings.loop) {
+ maximum = this._clones.length / 2 + this._items.length - 1;
+ } else if (settings.autoWidth || settings.merge) {
+ iterator = this._items.length;
+ if (iterator) {
+ reciprocalItemsWidth = this._items[--iterator].width();
+ elementWidth = this.$element.width();
+ while (iterator--) {
+ reciprocalItemsWidth += this._items[iterator].width() + this.settings.margin;
+ if (reciprocalItemsWidth > elementWidth) {
+ break;
+ }
+ }
+ }
+ maximum = iterator + 1;
+ } else if (settings.center) {
+ maximum = this._items.length - 1;
+ } else {
+ maximum = this._items.length - settings.items;
+ }
+
+ if (relative) {
+ maximum -= this._clones.length / 2;
+ }
+
+ return Math.max(maximum, 0);
+ };
+
+ /**
+ * Gets the minimum position for the current item.
+ * @public
+ * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
+ * @returns {Number}
+ */
+ Owl.prototype.minimum = function(relative) {
+ return relative ? 0 : this._clones.length / 2;
+ };
+
+ /**
+ * Gets an item at the specified relative position.
+ * @public
+ * @param {Number} [position] - The relative position of the item.
+ * @return {jQuery|Array.} - The item at the given position or all items if no position was given.
+ */
+ Owl.prototype.items = function(position) {
+ if (position === undefined) {
+ return this._items.slice();
+ }
+
+ position = this.normalize(position, true);
+ return this._items[position];
+ };
+
+ /**
+ * Gets an item at the specified relative position.
+ * @public
+ * @param {Number} [position] - The relative position of the item.
+ * @return {jQuery|Array.} - The item at the given position or all items if no position was given.
+ */
+ Owl.prototype.mergers = function(position) {
+ if (position === undefined) {
+ return this._mergers.slice();
+ }
+
+ position = this.normalize(position, true);
+ return this._mergers[position];
+ };
+
+ /**
+ * Gets the absolute positions of clones for an item.
+ * @public
+ * @param {Number} [position] - The relative position of the item.
+ * @returns {Array.} - The absolute positions of clones for the item or all if no position was given.
+ */
+ Owl.prototype.clones = function(position) {
+ var odd = this._clones.length / 2,
+ even = odd + this._items.length,
+ map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 };
+
+ if (position === undefined) {
+ return $.map(this._clones, function(v, i) { return map(i) });
+ }
+
+ return $.map(this._clones, function(v, i) { return v === position ? map(i) : null });
+ };
+
+ /**
+ * Sets the current animation speed.
+ * @public
+ * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged.
+ * @returns {Number} - The current animation speed in milliseconds.
+ */
+ Owl.prototype.speed = function(speed) {
+ if (speed !== undefined) {
+ this._speed = speed;
+ }
+
+ return this._speed;
+ };
+
+ /**
+ * Gets the coordinate of an item.
+ * @todo The name of this method is missleanding.
+ * @public
+ * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`.
+ * @returns {Number|Array.} - The coordinate of the item in pixel or all coordinates.
+ */
+ Owl.prototype.coordinates = function(position) {
+ var multiplier = 1,
+ newPosition = position - 1,
+ coordinate;
+
+ if (position === undefined) {
+ return $.map(this._coordinates, $.proxy(function(coordinate, index) {
+ return this.coordinates(index);
+ }, this));
+ }
+
+ if (this.settings.center) {
+ if (this.settings.rtl) {
+ multiplier = -1;
+ newPosition = position + 1;
+ }
+
+ coordinate = this._coordinates[position];
+ coordinate += (this.width() - coordinate + (this._coordinates[newPosition] || 0)) / 2 * multiplier;
+ } else {
+ coordinate = this._coordinates[newPosition] || 0;
+ }
+
+ coordinate = Math.ceil(coordinate);
+
+ return coordinate;
+ };
+
+ /**
+ * Calculates the speed for a translation.
+ * @protected
+ * @param {Number} from - The absolute position of the start item.
+ * @param {Number} to - The absolute position of the target item.
+ * @param {Number} [factor=undefined] - The time factor in milliseconds.
+ * @returns {Number} - The time in milliseconds for the translation.
+ */
+ Owl.prototype.duration = function(from, to, factor) {
+ if (factor === 0) {
+ return 0;
+ }
+
+ return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed));
+ };
+
+ /**
+ * Slides to the specified item.
+ * @public
+ * @param {Number} position - The position of the item.
+ * @param {Number} [speed] - The time in milliseconds for the transition.
+ */
+ Owl.prototype.to = function(position, speed) {
+ var current = this.current(),
+ revert = null,
+ distance = position - this.relative(current),
+ direction = (distance > 0) - (distance < 0),
+ items = this._items.length,
+ minimum = this.minimum(),
+ maximum = this.maximum();
+
+ if (this.settings.loop) {
+ if (!this.settings.rewind && Math.abs(distance) > items / 2) {
+ distance += direction * -1 * items;
+ }
+
+ position = current + distance;
+ revert = ((position - minimum) % items + items) % items + minimum;
+
+ if (revert !== position && revert - distance <= maximum && revert - distance > 0) {
+ current = revert - distance;
+ position = revert;
+ this.reset(current);
+ }
+ } else if (this.settings.rewind) {
+ maximum += 1;
+ position = (position % maximum + maximum) % maximum;
+ } else {
+ position = Math.max(minimum, Math.min(maximum, position));
+ }
+
+ this.speed(this.duration(current, position, speed));
+ this.current(position);
+
+ if (this.$element.is(':visible')) {
+ this.update();
+ }
+ };
+
+ /**
+ * Slides to the next item.
+ * @public
+ * @param {Number} [speed] - The time in milliseconds for the transition.
+ */
+ Owl.prototype.next = function(speed) {
+ speed = speed || false;
+ this.to(this.relative(this.current()) + 1, speed);
+ };
+
+ /**
+ * Slides to the previous item.
+ * @public
+ * @param {Number} [speed] - The time in milliseconds for the transition.
+ */
+ Owl.prototype.prev = function(speed) {
+ speed = speed || false;
+ this.to(this.relative(this.current()) - 1, speed);
+ };
+
+ /**
+ * Handles the end of an animation.
+ * @protected
+ * @param {Event} event - The event arguments.
+ */
+ Owl.prototype.onTransitionEnd = function(event) {
+
+ // if css2 animation then event object is undefined
+ if (event !== undefined) {
+ event.stopPropagation();
+
+ // Catch only owl-stage transitionEnd event
+ if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) {
+ return false;
+ }
+ }
+
+ this.leave('animating');
+ this.trigger('translated');
+ };
+
+ /**
+ * Gets viewport width.
+ * @protected
+ * @return {Number} - The width in pixel.
+ */
+ Owl.prototype.viewport = function() {
+ var width;
+ if (this.options.responsiveBaseElement !== window) {
+ width = $(this.options.responsiveBaseElement).width();
+ } else if (window.innerWidth) {
+ width = window.innerWidth;
+ } else if (document.documentElement && document.documentElement.clientWidth) {
+ width = document.documentElement.clientWidth;
+ } else {
+ console.warn('Can not detect viewport width.');
+ }
+ return width;
+ };
+
+ /**
+ * Replaces the current content.
+ * @public
+ * @param {HTMLElement|jQuery|String} content - The new content.
+ */
+ Owl.prototype.replace = function(content) {
+ this.$stage.empty();
+ this._items = [];
+
+ if (content) {
+ content = (content instanceof jQuery) ? content : $(content);
+ }
+
+ if (this.settings.nestedItemSelector) {
+ content = content.find('.' + this.settings.nestedItemSelector);
+ }
+
+ content.filter(function() {
+ return this.nodeType === 1;
+ }).each($.proxy(function(index, item) {
+ item = this.prepare(item);
+ this.$stage.append(item);
+ this._items.push(item);
+ this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
+ }, this));
+
+ this.reset(this.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0);
+
+ this.invalidate('items');
+ };
+
+ /**
+ * Adds an item.
+ * @todo Use `item` instead of `content` for the event arguments.
+ * @public
+ * @param {HTMLElement|jQuery|String} content - The item content to add.
+ * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end.
+ */
+ Owl.prototype.add = function(content, position) {
+ var current = this.relative(this._current);
+
+ position = position === undefined ? this._items.length : this.normalize(position, true);
+ content = content instanceof jQuery ? content : $(content);
+
+ this.trigger('add', { content: content, position: position });
+
+ content = this.prepare(content);
+
+ if (this._items.length === 0 || position === this._items.length) {
+ this._items.length === 0 && this.$stage.append(content);
+ this._items.length !== 0 && this._items[position - 1].after(content);
+ this._items.push(content);
+ this._mergers.push(content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
+ } else {
+ this._items[position].before(content);
+ this._items.splice(position, 0, content);
+ this._mergers.splice(position, 0, content.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
+ }
+
+ this._items[current] && this.reset(this._items[current].index());
+
+ this.invalidate('items');
+
+ this.trigger('added', { content: content, position: position });
+ };
+
+ /**
+ * Removes an item by its position.
+ * @todo Use `item` instead of `content` for the event arguments.
+ * @public
+ * @param {Number} position - The relative position of the item to remove.
+ */
+ Owl.prototype.remove = function(position) {
+ position = this.normalize(position, true);
+
+ if (position === undefined) {
+ return;
+ }
+
+ this.trigger('remove', { content: this._items[position], position: position });
+
+ this._items[position].remove();
+ this._items.splice(position, 1);
+ this._mergers.splice(position, 1);
+
+ this.invalidate('items');
+
+ this.trigger('removed', { content: null, position: position });
+ };
+
+ /**
+ * Preloads images with auto width.
+ * @todo Replace by a more generic approach
+ * @protected
+ */
+ Owl.prototype.preloadAutoWidthImages = function(images) {
+ images.each($.proxy(function(i, element) {
+ this.enter('pre-loading');
+ element = $(element);
+ $(new Image()).one('load', $.proxy(function(e) {
+ element.attr('src', e.target.src);
+ element.css('opacity', 1);
+ this.leave('pre-loading');
+ !this.is('pre-loading') && !this.is('initializing') && this.refresh();
+ }, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina'));
+ }, this));
+ };
+
+ /**
+ * Destroys the carousel.
+ * @public
+ */
+ Owl.prototype.destroy = function() {
+
+ this.$element.off('.owl.core');
+ this.$stage.off('.owl.core');
+ $(document).off('.owl.core');
+
+ if (this.settings.responsive !== false) {
+ window.clearTimeout(this.resizeTimer);
+ this.off(window, 'resize', this._handlers.onThrottledResize);
+ }
+
+ for (var i in this._plugins) {
+ this._plugins[i].destroy();
+ }
+
+ this.$stage.children('.cloned').remove();
+
+ this.$stage.unwrap();
+ this.$stage.children().contents().unwrap();
+ this.$stage.children().unwrap();
+ this.$stage.remove();
+ this.$element
+ .removeClass(this.options.refreshClass)
+ .removeClass(this.options.loadingClass)
+ .removeClass(this.options.loadedClass)
+ .removeClass(this.options.rtlClass)
+ .removeClass(this.options.dragClass)
+ .removeClass(this.options.grabClass)
+ .attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), ''))
+ .removeData('owl.carousel');
+ };
+
+ /**
+ * Operators to calculate right-to-left and left-to-right.
+ * @protected
+ * @param {Number} [a] - The left side operand.
+ * @param {String} [o] - The operator.
+ * @param {Number} [b] - The right side operand.
+ */
+ Owl.prototype.op = function(a, o, b) {
+ var rtl = this.settings.rtl;
+ switch (o) {
+ case '<':
+ return rtl ? a > b : a < b;
+ case '>':
+ return rtl ? a < b : a > b;
+ case '>=':
+ return rtl ? a <= b : a >= b;
+ case '<=':
+ return rtl ? a >= b : a <= b;
+ default:
+ break;
+ }
+ };
+
+ /**
+ * Attaches to an internal event.
+ * @protected
+ * @param {HTMLElement} element - The event source.
+ * @param {String} event - The event name.
+ * @param {Function} listener - The event handler to attach.
+ * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not.
+ */
+ Owl.prototype.on = function(element, event, listener, capture) {
+ if (element.addEventListener) {
+ element.addEventListener(event, listener, capture);
+ } else if (element.attachEvent) {
+ element.attachEvent('on' + event, listener);
+ }
+ };
+
+ /**
+ * Detaches from an internal event.
+ * @protected
+ * @param {HTMLElement} element - The event source.
+ * @param {String} event - The event name.
+ * @param {Function} listener - The attached event handler to detach.
+ * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not.
+ */
+ Owl.prototype.off = function(element, event, listener, capture) {
+ if (element.removeEventListener) {
+ element.removeEventListener(event, listener, capture);
+ } else if (element.detachEvent) {
+ element.detachEvent('on' + event, listener);
+ }
+ };
+
+ /**
+ * Triggers a public event.
+ * @todo Remove `status`, `relatedTarget` should be used instead.
+ * @protected
+ * @param {String} name - The event name.
+ * @param {*} [data=null] - The event data.
+ * @param {String} [namespace=carousel] - The event namespace.
+ * @param {String} [state] - The state which is associated with the event.
+ * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not.
+ * @returns {Event} - The event arguments.
+ */
+ Owl.prototype.trigger = function(name, data, namespace, state, enter) {
+ var status = {
+ item: { count: this._items.length, index: this.current() }
+ }, handler = $.camelCase(
+ $.grep([ 'on', name, namespace ], function(v) { return v })
+ .join('-').toLowerCase()
+ ), event = $.Event(
+ [ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(),
+ $.extend({ relatedTarget: this }, status, data)
+ );
+
+ if (!this._supress[name]) {
+ $.each(this._plugins, function(name, plugin) {
+ if (plugin.onTrigger) {
+ plugin.onTrigger(event);
+ }
+ });
+
+ this.register({ type: Owl.Type.Event, name: name });
+ this.$element.trigger(event);
+
+ if (this.settings && typeof this.settings[handler] === 'function') {
+ this.settings[handler].call(this, event);
+ }
+ }
+
+ return event;
+ };
+
+ /**
+ * Enters a state.
+ * @param name - The state name.
+ */
+ Owl.prototype.enter = function(name) {
+ $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
+ if (this._states.current[name] === undefined) {
+ this._states.current[name] = 0;
+ }
+
+ this._states.current[name]++;
+ }, this));
+ };
+
+ /**
+ * Leaves a state.
+ * @param name - The state name.
+ */
+ Owl.prototype.leave = function(name) {
+ $.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
+ this._states.current[name]--;
+ }, this));
+ };
+
+ /**
+ * Registers an event or state.
+ * @public
+ * @param {Object} object - The event or state to register.
+ */
+ Owl.prototype.register = function(object) {
+ if (object.type === Owl.Type.Event) {
+ if (!$.event.special[object.name]) {
+ $.event.special[object.name] = {};
+ }
+
+ if (!$.event.special[object.name].owl) {
+ var _default = $.event.special[object.name]._default;
+ $.event.special[object.name]._default = function(e) {
+ if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) {
+ return _default.apply(this, arguments);
+ }
+ return e.namespace && e.namespace.indexOf('owl') > -1;
+ };
+ $.event.special[object.name].owl = true;
+ }
+ } else if (object.type === Owl.Type.State) {
+ if (!this._states.tags[object.name]) {
+ this._states.tags[object.name] = object.tags;
+ } else {
+ this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags);
+ }
+
+ this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) {
+ return $.inArray(tag, this._states.tags[object.name]) === i;
+ }, this));
+ }
+ };
+
+ /**
+ * Suppresses events.
+ * @protected
+ * @param {Array.} events - The events to suppress.
+ */
+ Owl.prototype.suppress = function(events) {
+ $.each(events, $.proxy(function(index, event) {
+ this._supress[event] = true;
+ }, this));
+ };
+
+ /**
+ * Releases suppressed events.
+ * @protected
+ * @param {Array.} events - The events to release.
+ */
+ Owl.prototype.release = function(events) {
+ $.each(events, $.proxy(function(index, event) {
+ delete this._supress[event];
+ }, this));
+ };
+
+ /**
+ * Gets unified pointer coordinates from event.
+ * @todo #261
+ * @protected
+ * @param {Event} - The `mousedown` or `touchstart` event.
+ * @returns {Object} - Contains `x` and `y` coordinates of current pointer position.
+ */
+ Owl.prototype.pointer = function(event) {
+ var result = { x: null, y: null };
+
+ event = event.originalEvent || event || window.event;
+
+ event = event.touches && event.touches.length ?
+ event.touches[0] : event.changedTouches && event.changedTouches.length ?
+ event.changedTouches[0] : event;
+
+ if (event.pageX) {
+ result.x = event.pageX;
+ result.y = event.pageY;
+ } else {
+ result.x = event.clientX;
+ result.y = event.clientY;
+ }
+
+ return result;
+ };
+
+ /**
+ * Determines if the input is a Number or something that can be coerced to a Number
+ * @protected
+ * @param {Number|String|Object|Array|Boolean|RegExp|Function|Symbol} - The input to be tested
+ * @returns {Boolean} - An indication if the input is a Number or can be coerced to a Number
+ */
+ Owl.prototype.isNumeric = function(number) {
+ return !isNaN(parseFloat(number));
+ };
+
+ /**
+ * Gets the difference of two vectors.
+ * @todo #261
+ * @protected
+ * @param {Object} - The first vector.
+ * @param {Object} - The second vector.
+ * @returns {Object} - The difference.
+ */
+ Owl.prototype.difference = function(first, second) {
+ return {
+ x: first.x - second.x,
+ y: first.y - second.y
+ };
+ };
+
+ /**
+ * The jQuery Plugin for the Owl Carousel
+ * @todo Navigation plugin `next` and `prev`
+ * @public
+ */
+ $.fn.owlCarousel = function(option) {
+ var args = Array.prototype.slice.call(arguments, 1);
+
+ return this.each(function() {
+ var $this = $(this),
+ data = $this.data('owl.carousel');
+
+ if (!data) {
+ data = new Owl(this, typeof option == 'object' && option);
+ $this.data('owl.carousel', data);
+
+ $.each([
+ 'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove'
+ ], function(i, event) {
+ data.register({ type: Owl.Type.Event, name: event });
+ data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) {
+ if (e.namespace && e.relatedTarget !== this) {
+ this.suppress([ event ]);
+ data[event].apply(this, [].slice.call(arguments, 1));
+ this.release([ event ]);
+ }
+ }, data));
+ });
+ }
+
+ if (typeof option == 'string' && option.charAt(0) !== '_') {
+ data[option].apply(data, args);
+ }
+ });
+ };
+
+ /**
+ * The constructor for the jQuery Plugin
+ * @public
+ */
+ $.fn.owlCarousel.Constructor = Owl;
+
+})(window.Zepto || window.jQuery, window, document);
+
+/**
+ * AutoRefresh Plugin
+ * @version 2.3.1
+ * @author Artus Kolanowski
+ * @author David Deutsch
+ * @license The MIT License (MIT)
+ */
+;(function($, window, document, undefined) {
+
+ /**
+ * Creates the auto refresh plugin.
+ * @class The Auto Refresh Plugin
+ * @param {Owl} carousel - The Owl Carousel
+ */
+ var AutoRefresh = function(carousel) {
+ /**
+ * Reference to the core.
+ * @protected
+ * @type {Owl}
+ */
+ this._core = carousel;
+
+ /**
+ * Refresh interval.
+ * @protected
+ * @type {number}
+ */
+ this._interval = null;
+
+ /**
+ * Whether the element is currently visible or not.
+ * @protected
+ * @type {Boolean}
+ */
+ this._visible = null;
+
+ /**
+ * All event handlers.
+ * @protected
+ * @type {Object}
+ */
+ this._handlers = {
+ 'initialized.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && this._core.settings.autoRefresh) {
+ this.watch();
+ }
+ }, this)
+ };
+
+ // set default options
+ this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options);
+
+ // register event handlers
+ this._core.$element.on(this._handlers);
+ };
+
+ /**
+ * Default options.
+ * @public
+ */
+ AutoRefresh.Defaults = {
+ autoRefresh: true,
+ autoRefreshInterval: 500
+ };
+
+ /**
+ * Watches the element.
+ */
+ AutoRefresh.prototype.watch = function() {
+ if (this._interval) {
+ return;
+ }
+
+ this._visible = this._core.$element.is(':visible');
+ this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval);
+ };
+
+ /**
+ * Refreshes the element.
+ */
+ AutoRefresh.prototype.refresh = function() {
+ if (this._core.$element.is(':visible') === this._visible) {
+ return;
+ }
+
+ this._visible = !this._visible;
+
+ this._core.$element.toggleClass('owl-hidden', !this._visible);
+
+ this._visible && (this._core.invalidate('width') && this._core.refresh());
+ };
+
+ /**
+ * Destroys the plugin.
+ */
+ AutoRefresh.prototype.destroy = function() {
+ var handler, property;
+
+ window.clearInterval(this._interval);
+
+ for (handler in this._handlers) {
+ this._core.$element.off(handler, this._handlers[handler]);
+ }
+ for (property in Object.getOwnPropertyNames(this)) {
+ typeof this[property] != 'function' && (this[property] = null);
+ }
+ };
+
+ $.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh;
+
+})(window.Zepto || window.jQuery, window, document);
+
+/**
+ * Lazy Plugin
+ * @version 2.3.1
+ * @author Bartosz Wojciechowski
+ * @author David Deutsch
+ * @license The MIT License (MIT)
+ */
+;(function($, window, document, undefined) {
+
+ /**
+ * Creates the lazy plugin.
+ * @class The Lazy Plugin
+ * @param {Owl} carousel - The Owl Carousel
+ */
+ var Lazy = function(carousel) {
+
+ /**
+ * Reference to the core.
+ * @protected
+ * @type {Owl}
+ */
+ this._core = carousel;
+
+ /**
+ * Already loaded items.
+ * @protected
+ * @type {Array.}
+ */
+ this._loaded = [];
+
+ /**
+ * Event handlers.
+ * @protected
+ * @type {Object}
+ */
+ this._handlers = {
+ 'initialized.owl.carousel change.owl.carousel resized.owl.carousel': $.proxy(function(e) {
+ if (!e.namespace) {
+ return;
+ }
+
+ if (!this._core.settings || !this._core.settings.lazyLoad) {
+ return;
+ }
+
+ if ((e.property && e.property.name == 'position') || e.type == 'initialized') {
+ var settings = this._core.settings,
+ n = (settings.center && Math.ceil(settings.items / 2) || settings.items),
+ i = ((settings.center && n * -1) || 0),
+ position = (e.property && e.property.value !== undefined ? e.property.value : this._core.current()) + i,
+ clones = this._core.clones().length,
+ load = $.proxy(function(i, v) { this.load(v) }, this);
+
+ while (i++ < n) {
+ this.load(clones / 2 + this._core.relative(position));
+ clones && $.each(this._core.clones(this._core.relative(position)), load);
+ position++;
+ }
+ }
+ }, this)
+ };
+
+ // set the default options
+ this._core.options = $.extend({}, Lazy.Defaults, this._core.options);
+
+ // register event handler
+ this._core.$element.on(this._handlers);
+ };
+
+ /**
+ * Default options.
+ * @public
+ */
+ Lazy.Defaults = {
+ lazyLoad: false
+ };
+
+ /**
+ * Loads all resources of an item at the specified position.
+ * @param {Number} position - The absolute position of the item.
+ * @protected
+ */
+ Lazy.prototype.load = function(position) {
+ var $item = this._core.$stage.children().eq(position),
+ $elements = $item && $item.find('.owl-lazy');
+
+ if (!$elements || $.inArray($item.get(0), this._loaded) > -1) {
+ return;
+ }
+
+ $elements.each($.proxy(function(index, element) {
+ var $element = $(element), image,
+ url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src');
+
+ this._core.trigger('load', { element: $element, url: url }, 'lazy');
+
+ if ($element.is('img')) {
+ $element.one('load.owl.lazy', $.proxy(function() {
+ $element.css('opacity', 1);
+ this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
+ }, this)).attr('src', url);
+ } else {
+ image = new Image();
+ image.onload = $.proxy(function() {
+ $element.css({
+ 'background-image': 'url("' + url + '")',
+ 'opacity': '1'
+ });
+ this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
+ }, this);
+ image.src = url;
+ }
+ }, this));
+
+ this._loaded.push($item.get(0));
+ };
+
+ /**
+ * Destroys the plugin.
+ * @public
+ */
+ Lazy.prototype.destroy = function() {
+ var handler, property;
+
+ for (handler in this.handlers) {
+ this._core.$element.off(handler, this.handlers[handler]);
+ }
+ for (property in Object.getOwnPropertyNames(this)) {
+ typeof this[property] != 'function' && (this[property] = null);
+ }
+ };
+
+ $.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy;
+
+})(window.Zepto || window.jQuery, window, document);
+
+/**
+ * AutoHeight Plugin
+ * @version 2.3.1
+ * @author Bartosz Wojciechowski
+ * @author David Deutsch
+ * @license The MIT License (MIT)
+ */
+;(function($, window, document, undefined) {
+
+ /**
+ * Creates the auto height plugin.
+ * @class The Auto Height Plugin
+ * @param {Owl} carousel - The Owl Carousel
+ */
+ var AutoHeight = function(carousel) {
+ /**
+ * Reference to the core.
+ * @protected
+ * @type {Owl}
+ */
+ this._core = carousel;
+
+ /**
+ * All event handlers.
+ * @protected
+ * @type {Object}
+ */
+ this._handlers = {
+ 'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && this._core.settings.autoHeight) {
+ this.update();
+ }
+ }, this),
+ 'changed.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && this._core.settings.autoHeight && e.property.name == 'position'){
+ this.update();
+ }
+ }, this),
+ 'loaded.owl.lazy': $.proxy(function(e) {
+ if (e.namespace && this._core.settings.autoHeight
+ && e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) {
+ this.update();
+ }
+ }, this)
+ };
+
+ // set default options
+ this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options);
+
+ // register event handlers
+ this._core.$element.on(this._handlers);
+ };
+
+ /**
+ * Default options.
+ * @public
+ */
+ AutoHeight.Defaults = {
+ autoHeight: false,
+ autoHeightClass: 'owl-height'
+ };
+
+ /**
+ * Updates the view.
+ */
+ AutoHeight.prototype.update = function() {
+ var start = this._core._current,
+ end = start + this._core.settings.items,
+ visible = this._core.$stage.children().toArray().slice(start, end),
+ heights = [],
+ maxheight = 0;
+
+ $.each(visible, function(index, item) {
+ heights.push($(item).height());
+ });
+
+ maxheight = Math.max.apply(null, heights);
+
+ this._core.$stage.parent()
+ .height(maxheight)
+ .addClass(this._core.settings.autoHeightClass);
+ };
+
+ AutoHeight.prototype.destroy = function() {
+ var handler, property;
+
+ for (handler in this._handlers) {
+ this._core.$element.off(handler, this._handlers[handler]);
+ }
+ for (property in Object.getOwnPropertyNames(this)) {
+ typeof this[property] != 'function' && (this[property] = null);
+ }
+ };
+
+ $.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight;
+
+})(window.Zepto || window.jQuery, window, document);
+
+/**
+ * Video Plugin
+ * @version 2.3.1
+ * @author Bartosz Wojciechowski
+ * @author David Deutsch
+ * @license The MIT License (MIT)
+ */
+;(function($, window, document, undefined) {
+
+ /**
+ * Creates the video plugin.
+ * @class The Video Plugin
+ * @param {Owl} carousel - The Owl Carousel
+ */
+ var Video = function(carousel) {
+ /**
+ * Reference to the core.
+ * @protected
+ * @type {Owl}
+ */
+ this._core = carousel;
+
+ /**
+ * Cache all video URLs.
+ * @protected
+ * @type {Object}
+ */
+ this._videos = {};
+
+ /**
+ * Current playing item.
+ * @protected
+ * @type {jQuery}
+ */
+ this._playing = null;
+
+ /**
+ * All event handlers.
+ * @todo The cloned content removale is too late
+ * @protected
+ * @type {Object}
+ */
+ this._handlers = {
+ 'initialized.owl.carousel': $.proxy(function(e) {
+ if (e.namespace) {
+ this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] });
+ }
+ }, this),
+ 'resize.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && this._core.settings.video && this.isInFullScreen()) {
+ e.preventDefault();
+ }
+ }, this),
+ 'refreshed.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && this._core.is('resizing')) {
+ this._core.$stage.find('.cloned .owl-video-frame').remove();
+ }
+ }, this),
+ 'changed.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && e.property.name === 'position' && this._playing) {
+ this.stop();
+ }
+ }, this),
+ 'prepared.owl.carousel': $.proxy(function(e) {
+ if (!e.namespace) {
+ return;
+ }
+
+ var $element = $(e.content).find('.owl-video');
+
+ if ($element.length) {
+ $element.css('display', 'none');
+ this.fetch($element, $(e.content));
+ }
+ }, this)
+ };
+
+ // set default options
+ this._core.options = $.extend({}, Video.Defaults, this._core.options);
+
+ // register event handlers
+ this._core.$element.on(this._handlers);
+
+ this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) {
+ this.play(e);
+ }, this));
+ };
+
+ /**
+ * Default options.
+ * @public
+ */
+ Video.Defaults = {
+ video: false,
+ videoHeight: false,
+ videoWidth: false
+ };
+
+ /**
+ * Gets the video ID and the type (YouTube/Vimeo/vzaar only).
+ * @protected
+ * @param {jQuery} target - The target containing the video data.
+ * @param {jQuery} item - The item containing the video.
+ */
+ Video.prototype.fetch = function(target, item) {
+ var type = (function() {
+ if (target.attr('data-vimeo-id')) {
+ return 'vimeo';
+ } else if (target.attr('data-vzaar-id')) {
+ return 'vzaar'
+ } else {
+ return 'youtube';
+ }
+ })(),
+ id = target.attr('data-vimeo-id') || target.attr('data-youtube-id') || target.attr('data-vzaar-id'),
+ width = target.attr('data-width') || this._core.settings.videoWidth,
+ height = target.attr('data-height') || this._core.settings.videoHeight,
+ url = target.attr('href');
+
+ if (url) {
+
+ /*
+ Parses the id's out of the following urls (and probably more):
+ https://www.youtube.com/watch?v=:id
+ https://youtu.be/:id
+ https://vimeo.com/:id
+ https://vimeo.com/channels/:channel/:id
+ https://vimeo.com/groups/:group/videos/:id
+ https://app.vzaar.com/videos/:id
+
+ Visual example: https://regexper.com/#(http%3A%7Chttps%3A%7C)%5C%2F%5C%2F(player.%7Cwww.%7Capp.)%3F(vimeo%5C.com%7Cyoutu(be%5C.com%7C%5C.be%7Cbe%5C.googleapis%5C.com)%7Cvzaar%5C.com)%5C%2F(video%5C%2F%7Cvideos%5C%2F%7Cembed%5C%2F%7Cchannels%5C%2F.%2B%5C%2F%7Cgroups%5C%2F.%2B%5C%2F%7Cwatch%5C%3Fv%3D%7Cv%5C%2F)%3F(%5BA-Za-z0-9._%25-%5D*)(%5C%26%5CS%2B)%3F
+ */
+
+ id = url.match(/(http:|https:|)\/\/(player.|www.|app.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com)|vzaar\.com)\/(video\/|videos\/|embed\/|channels\/.+\/|groups\/.+\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);
+
+ if (id[3].indexOf('youtu') > -1) {
+ type = 'youtube';
+ } else if (id[3].indexOf('vimeo') > -1) {
+ type = 'vimeo';
+ } else if (id[3].indexOf('vzaar') > -1) {
+ type = 'vzaar';
+ } else {
+ throw new Error('Video URL not supported.');
+ }
+ id = id[6];
+ } else {
+ throw new Error('Missing video URL.');
+ }
+
+ this._videos[url] = {
+ type: type,
+ id: id,
+ width: width,
+ height: height
+ };
+
+ item.attr('data-video', url);
+
+ this.thumbnail(target, this._videos[url]);
+ };
+
+ /**
+ * Creates video thumbnail.
+ * @protected
+ * @param {jQuery} target - The target containing the video data.
+ * @param {Object} info - The video info object.
+ * @see `fetch`
+ */
+ Video.prototype.thumbnail = function(target, video) {
+ var tnLink,
+ icon,
+ path,
+ dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '',
+ customTn = target.find('img'),
+ srcType = 'src',
+ lazyClass = '',
+ settings = this._core.settings,
+ create = function(path) {
+ icon = '
';
+
+ if (settings.lazyLoad) {
+ tnLink = '
';
+ } else {
+ tnLink = '
';
+ }
+ target.after(tnLink);
+ target.after(icon);
+ };
+
+ // wrap video content into owl-video-wrapper div
+ target.wrap('
');
+
+ if (this._core.settings.lazyLoad) {
+ srcType = 'data-src';
+ lazyClass = 'owl-lazy';
+ }
+
+ // custom thumbnail
+ if (customTn.length) {
+ create(customTn.attr(srcType));
+ customTn.remove();
+ return false;
+ }
+
+ if (video.type === 'youtube') {
+ path = "//img.youtube.com/vi/" + video.id + "/hqdefault.jpg";
+ create(path);
+ } else if (video.type === 'vimeo') {
+ $.ajax({
+ type: 'GET',
+ url: '//vimeo.com/api/v2/video/' + video.id + '.json',
+ jsonp: 'callback',
+ dataType: 'jsonp',
+ success: function(data) {
+ path = data[0].thumbnail_large;
+ create(path);
+ }
+ });
+ } else if (video.type === 'vzaar') {
+ $.ajax({
+ type: 'GET',
+ url: '//vzaar.com/api/videos/' + video.id + '.json',
+ jsonp: 'callback',
+ dataType: 'jsonp',
+ success: function(data) {
+ path = data.framegrab_url;
+ create(path);
+ }
+ });
+ }
+ };
+
+ /**
+ * Stops the current video.
+ * @public
+ */
+ Video.prototype.stop = function() {
+ this._core.trigger('stop', null, 'video');
+ this._playing.find('.owl-video-frame').remove();
+ this._playing.removeClass('owl-video-playing');
+ this._playing = null;
+ this._core.leave('playing');
+ this._core.trigger('stopped', null, 'video');
+ };
+
+ /**
+ * Starts the current video.
+ * @public
+ * @param {Event} event - The event arguments.
+ */
+ Video.prototype.play = function(event) {
+ var target = $(event.target),
+ item = target.closest('.' + this._core.settings.itemClass),
+ video = this._videos[item.attr('data-video')],
+ width = video.width || '100%',
+ height = video.height || this._core.$stage.height(),
+ html;
+
+ if (this._playing) {
+ return;
+ }
+
+ this._core.enter('playing');
+ this._core.trigger('play', null, 'video');
+
+ item = this._core.items(this._core.relative(item.index()));
+
+ this._core.reset(item.index());
+
+ if (video.type === 'youtube') {
+ html = '';
+ } else if (video.type === 'vimeo') {
+ html = '';
+ } else if (video.type === 'vzaar') {
+ html = '';
+ }
+
+ $('' + html + '
').insertAfter(item.find('.owl-video'));
+
+ this._playing = item.addClass('owl-video-playing');
+ };
+
+ /**
+ * Checks whether an video is currently in full screen mode or not.
+ * @todo Bad style because looks like a readonly method but changes members.
+ * @protected
+ * @returns {Boolean}
+ */
+ Video.prototype.isInFullScreen = function() {
+ var element = document.fullscreenElement || document.mozFullScreenElement ||
+ document.webkitFullscreenElement;
+
+ return element && $(element).parent().hasClass('owl-video-frame');
+ };
+
+ /**
+ * Destroys the plugin.
+ */
+ Video.prototype.destroy = function() {
+ var handler, property;
+
+ this._core.$element.off('click.owl.video');
+
+ for (handler in this._handlers) {
+ this._core.$element.off(handler, this._handlers[handler]);
+ }
+ for (property in Object.getOwnPropertyNames(this)) {
+ typeof this[property] != 'function' && (this[property] = null);
+ }
+ };
+
+ $.fn.owlCarousel.Constructor.Plugins.Video = Video;
+
+})(window.Zepto || window.jQuery, window, document);
+
+/**
+ * Animate Plugin
+ * @version 2.3.1
+ * @author Bartosz Wojciechowski
+ * @author David Deutsch
+ * @license The MIT License (MIT)
+ */
+;(function($, window, document, undefined) {
+
+ /**
+ * Creates the animate plugin.
+ * @class The Navigation Plugin
+ * @param {Owl} scope - The Owl Carousel
+ */
+ var Animate = function(scope) {
+ this.core = scope;
+ this.core.options = $.extend({}, Animate.Defaults, this.core.options);
+ this.swapping = true;
+ this.previous = undefined;
+ this.next = undefined;
+
+ this.handlers = {
+ 'change.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && e.property.name == 'position') {
+ this.previous = this.core.current();
+ this.next = e.property.value;
+ }
+ }, this),
+ 'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) {
+ if (e.namespace) {
+ this.swapping = e.type == 'translated';
+ }
+ }, this),
+ 'translate.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) {
+ this.swap();
+ }
+ }, this)
+ };
+
+ this.core.$element.on(this.handlers);
+ };
+
+ /**
+ * Default options.
+ * @public
+ */
+ Animate.Defaults = {
+ animateOut: false,
+ animateIn: false
+ };
+
+ /**
+ * Toggles the animation classes whenever an translations starts.
+ * @protected
+ * @returns {Boolean|undefined}
+ */
+ Animate.prototype.swap = function() {
+
+ if (this.core.settings.items !== 1) {
+ return;
+ }
+
+ if (!$.support.animation || !$.support.transition) {
+ return;
+ }
+
+ this.core.speed(0);
+
+ var left,
+ clear = $.proxy(this.clear, this),
+ previous = this.core.$stage.children().eq(this.previous),
+ next = this.core.$stage.children().eq(this.next),
+ incoming = this.core.settings.animateIn,
+ outgoing = this.core.settings.animateOut;
+
+ if (this.core.current() === this.previous) {
+ return;
+ }
+
+ if (outgoing) {
+ left = this.core.coordinates(this.previous) - this.core.coordinates(this.next);
+ previous.one($.support.animation.end, clear)
+ .css( { 'left': left + 'px' } )
+ .addClass('animated owl-animated-out')
+ .addClass(outgoing);
+ }
+
+ if (incoming) {
+ next.one($.support.animation.end, clear)
+ .addClass('animated owl-animated-in')
+ .addClass(incoming);
+ }
+ };
+
+ Animate.prototype.clear = function(e) {
+ $(e.target).css( { 'left': '' } )
+ .removeClass('animated owl-animated-out owl-animated-in')
+ .removeClass(this.core.settings.animateIn)
+ .removeClass(this.core.settings.animateOut);
+ this.core.onTransitionEnd();
+ };
+
+ /**
+ * Destroys the plugin.
+ * @public
+ */
+ Animate.prototype.destroy = function() {
+ var handler, property;
+
+ for (handler in this.handlers) {
+ this.core.$element.off(handler, this.handlers[handler]);
+ }
+ for (property in Object.getOwnPropertyNames(this)) {
+ typeof this[property] != 'function' && (this[property] = null);
+ }
+ };
+
+ $.fn.owlCarousel.Constructor.Plugins.Animate = Animate;
+
+})(window.Zepto || window.jQuery, window, document);
+
+/**
+ * Autoplay Plugin
+ * @version 2.3.1
+ * @author Bartosz Wojciechowski
+ * @author Artus Kolanowski
+ * @author David Deutsch
+ * @author Tom De Caluwé
+ * @license The MIT License (MIT)
+ */
+;(function($, window, document, undefined) {
+
+ /**
+ * Creates the autoplay plugin.
+ * @class The Autoplay Plugin
+ * @param {Owl} scope - The Owl Carousel
+ */
+ var Autoplay = function(carousel) {
+ /**
+ * Reference to the core.
+ * @protected
+ * @type {Owl}
+ */
+ this._core = carousel;
+
+ /**
+ * The autoplay timeout id.
+ * @type {Number}
+ */
+ this._call = null;
+
+ /**
+ * Depending on the state of the plugin, this variable contains either
+ * the start time of the timer or the current timer value if it's
+ * paused. Since we start in a paused state we initialize the timer
+ * value.
+ * @type {Number}
+ */
+ this._time = 0;
+
+ /**
+ * Stores the timeout currently used.
+ * @type {Number}
+ */
+ this._timeout = 0;
+
+ /**
+ * Indicates whenever the autoplay is paused.
+ * @type {Boolean}
+ */
+ this._paused = true;
+
+ /**
+ * All event handlers.
+ * @protected
+ * @type {Object}
+ */
+ this._handlers = {
+ 'changed.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && e.property.name === 'settings') {
+ if (this._core.settings.autoplay) {
+ this.play();
+ } else {
+ this.stop();
+ }
+ } else if (e.namespace && e.property.name === 'position' && this._paused) {
+ // Reset the timer. This code is triggered when the position
+ // of the carousel was changed through user interaction.
+ this._time = 0;
+ }
+ }, this),
+ 'initialized.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && this._core.settings.autoplay) {
+ this.play();
+ }
+ }, this),
+ 'play.owl.autoplay': $.proxy(function(e, t, s) {
+ if (e.namespace) {
+ this.play(t, s);
+ }
+ }, this),
+ 'stop.owl.autoplay': $.proxy(function(e) {
+ if (e.namespace) {
+ this.stop();
+ }
+ }, this),
+ 'mouseover.owl.autoplay': $.proxy(function() {
+ if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
+ this.pause();
+ }
+ }, this),
+ 'mouseleave.owl.autoplay': $.proxy(function() {
+ if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
+ this.play();
+ }
+ }, this),
+ 'touchstart.owl.core': $.proxy(function() {
+ if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
+ this.pause();
+ }
+ }, this),
+ 'touchend.owl.core': $.proxy(function() {
+ if (this._core.settings.autoplayHoverPause) {
+ this.play();
+ }
+ }, this)
+ };
+
+ // register event handlers
+ this._core.$element.on(this._handlers);
+
+ // set default options
+ this._core.options = $.extend({}, Autoplay.Defaults, this._core.options);
+ };
+
+ /**
+ * Default options.
+ * @public
+ */
+ Autoplay.Defaults = {
+ autoplay: false,
+ autoplayTimeout: 5000,
+ autoplayHoverPause: false,
+ autoplaySpeed: false
+ };
+
+ /**
+ * Transition to the next slide and set a timeout for the next transition.
+ * @private
+ * @param {Number} [speed] - The animation speed for the animations.
+ */
+ Autoplay.prototype._next = function(speed) {
+ this._call = window.setTimeout(
+ $.proxy(this._next, this, speed),
+ this._timeout * (Math.round(this.read() / this._timeout) + 1) - this.read()
+ );
+
+ if (this._core.is('busy') || this._core.is('interacting') || document.hidden) {
+ return;
+ }
+ this._core.next(speed || this._core.settings.autoplaySpeed);
+ }
+
+ /**
+ * Reads the current timer value when the timer is playing.
+ * @public
+ */
+ Autoplay.prototype.read = function() {
+ return new Date().getTime() - this._time;
+ };
+
+ /**
+ * Starts the autoplay.
+ * @public
+ * @param {Number} [timeout] - The interval before the next animation starts.
+ * @param {Number} [speed] - The animation speed for the animations.
+ */
+ Autoplay.prototype.play = function(timeout, speed) {
+ var elapsed;
+
+ if (!this._core.is('rotating')) {
+ this._core.enter('rotating');
+ }
+
+ timeout = timeout || this._core.settings.autoplayTimeout;
+
+ // Calculate the elapsed time since the last transition. If the carousel
+ // wasn't playing this calculation will yield zero.
+ elapsed = Math.min(this._time % (this._timeout || timeout), timeout);
+
+ if (this._paused) {
+ // Start the clock.
+ this._time = this.read();
+ this._paused = false;
+ } else {
+ // Clear the active timeout to allow replacement.
+ window.clearTimeout(this._call);
+ }
+
+ // Adjust the origin of the timer to match the new timeout value.
+ this._time += this.read() % timeout - elapsed;
+
+ this._timeout = timeout;
+ this._call = window.setTimeout($.proxy(this._next, this, speed), timeout - elapsed);
+ };
+
+ /**
+ * Stops the autoplay.
+ * @public
+ */
+ Autoplay.prototype.stop = function() {
+ if (this._core.is('rotating')) {
+ // Reset the clock.
+ this._time = 0;
+ this._paused = true;
+
+ window.clearTimeout(this._call);
+ this._core.leave('rotating');
+ }
+ };
+
+ /**
+ * Pauses the autoplay.
+ * @public
+ */
+ Autoplay.prototype.pause = function() {
+ if (this._core.is('rotating') && !this._paused) {
+ // Pause the clock.
+ this._time = this.read();
+ this._paused = true;
+
+ window.clearTimeout(this._call);
+ }
+ };
+
+ /**
+ * Destroys the plugin.
+ */
+ Autoplay.prototype.destroy = function() {
+ var handler, property;
+
+ this.stop();
+
+ for (handler in this._handlers) {
+ this._core.$element.off(handler, this._handlers[handler]);
+ }
+ for (property in Object.getOwnPropertyNames(this)) {
+ typeof this[property] != 'function' && (this[property] = null);
+ }
+ };
+
+ $.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay;
+
+})(window.Zepto || window.jQuery, window, document);
+
+/**
+ * Navigation Plugin
+ * @version 2.3.1
+ * @author Artus Kolanowski
+ * @author David Deutsch
+ * @license The MIT License (MIT)
+ */
+;(function($, window, document, undefined) {
+ 'use strict';
+
+ /**
+ * Creates the navigation plugin.
+ * @class The Navigation Plugin
+ * @param {Owl} carousel - The Owl Carousel.
+ */
+ var Navigation = function(carousel) {
+ /**
+ * Reference to the core.
+ * @protected
+ * @type {Owl}
+ */
+ this._core = carousel;
+
+ /**
+ * Indicates whether the plugin is initialized or not.
+ * @protected
+ * @type {Boolean}
+ */
+ this._initialized = false;
+
+ /**
+ * The current paging indexes.
+ * @protected
+ * @type {Array}
+ */
+ this._pages = [];
+
+ /**
+ * All DOM elements of the user interface.
+ * @protected
+ * @type {Object}
+ */
+ this._controls = {};
+
+ /**
+ * Markup for an indicator.
+ * @protected
+ * @type {Array.}
+ */
+ this._templates = [];
+
+ /**
+ * The carousel element.
+ * @type {jQuery}
+ */
+ this.$element = this._core.$element;
+
+ /**
+ * Overridden methods of the carousel.
+ * @protected
+ * @type {Object}
+ */
+ this._overrides = {
+ next: this._core.next,
+ prev: this._core.prev,
+ to: this._core.to
+ };
+
+ /**
+ * All event handlers.
+ * @protected
+ * @type {Object}
+ */
+ this._handlers = {
+ 'prepared.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && this._core.settings.dotsData) {
+ this._templates.push('' +
+ $(e.content).find('[data-dot]').addBack('[data-dot]').attr('data-dot') + '
');
+ }
+ }, this),
+ 'added.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && this._core.settings.dotsData) {
+ this._templates.splice(e.position, 0, this._templates.pop());
+ }
+ }, this),
+ 'remove.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && this._core.settings.dotsData) {
+ this._templates.splice(e.position, 1);
+ }
+ }, this),
+ 'changed.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && e.property.name == 'position') {
+ this.draw();
+ }
+ }, this),
+ 'initialized.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && !this._initialized) {
+ this._core.trigger('initialize', null, 'navigation');
+ this.initialize();
+ this.update();
+ this.draw();
+ this._initialized = true;
+ this._core.trigger('initialized', null, 'navigation');
+ }
+ }, this),
+ 'refreshed.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && this._initialized) {
+ this._core.trigger('refresh', null, 'navigation');
+ this.update();
+ this.draw();
+ this._core.trigger('refreshed', null, 'navigation');
+ }
+ }, this)
+ };
+
+ // set default options
+ this._core.options = $.extend({}, Navigation.Defaults, this._core.options);
+
+ // register event handlers
+ this.$element.on(this._handlers);
+ };
+
+ /**
+ * Default options.
+ * @public
+ * @todo Rename `slideBy` to `navBy`
+ */
+ Navigation.Defaults = {
+ nav: false,
+ navText: [
+ '‹ ',
+ '› '
+ ],
+ navSpeed: false,
+ navElement: 'button role="presentation"',
+ navContainer: false,
+ navContainerClass: 'owl-nav',
+ navClass: [
+ 'owl-prev',
+ 'owl-next'
+ ],
+ slideBy: 1,
+ dotClass: 'owl-dot',
+ dotsClass: 'owl-dots',
+ dots: true,
+ dotsEach: false,
+ dotsData: false,
+ dotsSpeed: false,
+ dotsContainer: false
+ };
+
+ /**
+ * Initializes the layout of the plugin and extends the carousel.
+ * @protected
+ */
+ Navigation.prototype.initialize = function() {
+ var override,
+ settings = this._core.settings;
+
+ // create DOM structure for relative navigation
+ this._controls.$relative = (settings.navContainer ? $(settings.navContainer)
+ : $('').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled');
+
+ this._controls.$previous = $('<' + settings.navElement + '>')
+ .addClass(settings.navClass[0])
+ .html(settings.navText[0])
+ .prependTo(this._controls.$relative)
+ .on('click', $.proxy(function(e) {
+ this.prev(settings.navSpeed);
+ }, this));
+ this._controls.$next = $('<' + settings.navElement + '>')
+ .addClass(settings.navClass[1])
+ .html(settings.navText[1])
+ .appendTo(this._controls.$relative)
+ .on('click', $.proxy(function(e) {
+ this.next(settings.navSpeed);
+ }, this));
+
+ // create DOM structure for absolute navigation
+ if (!settings.dotsData) {
+ this._templates = [ $('
')
+ .addClass(settings.dotClass)
+ .append($(''))
+ .prop('outerHTML') ];
+ }
+
+ this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer)
+ : $('').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled');
+
+ this._controls.$absolute.on('click', 'button', $.proxy(function(e) {
+ var index = $(e.target).parent().is(this._controls.$absolute)
+ ? $(e.target).index() : $(e.target).parent().index();
+
+ e.preventDefault();
+
+ this.to(index, settings.dotsSpeed);
+ }, this));
+
+ /*$el.on('focusin', function() {
+ $(document).off(".carousel");
+
+ $(document).on('keydown.carousel', function(e) {
+ if(e.keyCode == 37) {
+ $el.trigger('prev.owl')
+ }
+ if(e.keyCode == 39) {
+ $el.trigger('next.owl')
+ }
+ });
+ });*/
+
+ // override public methods of the carousel
+ for (override in this._overrides) {
+ this._core[override] = $.proxy(this[override], this);
+ }
+ };
+
+ /**
+ * Destroys the plugin.
+ * @protected
+ */
+ Navigation.prototype.destroy = function() {
+ var handler, control, property, override, settings;
+ settings = this._core.settings;
+
+ for (handler in this._handlers) {
+ this.$element.off(handler, this._handlers[handler]);
+ }
+ for (control in this._controls) {
+ if (control === '$relative' && settings.navContainer) {
+ this._controls[control].html('');
+ } else {
+ this._controls[control].remove();
+ }
+ }
+ for (override in this.overides) {
+ this._core[override] = this._overrides[override];
+ }
+ for (property in Object.getOwnPropertyNames(this)) {
+ typeof this[property] != 'function' && (this[property] = null);
+ }
+ };
+
+ /**
+ * Updates the internal state.
+ * @protected
+ */
+ Navigation.prototype.update = function() {
+ var i, j, k,
+ lower = this._core.clones().length / 2,
+ upper = lower + this._core.items().length,
+ maximum = this._core.maximum(true),
+ settings = this._core.settings,
+ size = settings.center || settings.autoWidth || settings.dotsData
+ ? 1 : settings.dotsEach || settings.items;
+
+ if (settings.slideBy !== 'page') {
+ settings.slideBy = Math.min(settings.slideBy, settings.items);
+ }
+
+ if (settings.dots || settings.slideBy == 'page') {
+ this._pages = [];
+
+ for (i = lower, j = 0, k = 0; i < upper; i++) {
+ if (j >= size || j === 0) {
+ this._pages.push({
+ start: Math.min(maximum, i - lower),
+ end: i - lower + size - 1
+ });
+ if (Math.min(maximum, i - lower) === maximum) {
+ break;
+ }
+ j = 0, ++k;
+ }
+ j += this._core.mergers(this._core.relative(i));
+ }
+ }
+ };
+
+ /**
+ * Draws the user interface.
+ * @todo The option `dotsData` wont work.
+ * @protected
+ */
+ Navigation.prototype.draw = function() {
+ var difference,
+ settings = this._core.settings,
+ disabled = this._core.items().length <= settings.items,
+ index = this._core.relative(this._core.current()),
+ loop = settings.loop || settings.rewind;
+
+ this._controls.$relative.toggleClass('disabled', !settings.nav || disabled);
+
+ if (settings.nav) {
+ this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true));
+ this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true));
+ }
+
+ this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled);
+
+ if (settings.dots) {
+ difference = this._pages.length - this._controls.$absolute.children().length;
+
+ if (settings.dotsData && difference !== 0) {
+ this._controls.$absolute.html(this._templates.join(''));
+ } else if (difference > 0) {
+ this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0]));
+ } else if (difference < 0) {
+ this._controls.$absolute.children().slice(difference).remove();
+ }
+
+ this._controls.$absolute.find('.active').removeClass('active');
+ this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active');
+ }
+ };
+
+ /**
+ * Extends event data.
+ * @protected
+ * @param {Event} event - The event object which gets thrown.
+ */
+ Navigation.prototype.onTrigger = function(event) {
+ var settings = this._core.settings;
+
+ event.page = {
+ index: $.inArray(this.current(), this._pages),
+ count: this._pages.length,
+ size: settings && (settings.center || settings.autoWidth || settings.dotsData
+ ? 1 : settings.dotsEach || settings.items)
+ };
+ };
+
+ /**
+ * Gets the current page position of the carousel.
+ * @protected
+ * @returns {Number}
+ */
+ Navigation.prototype.current = function() {
+ var current = this._core.relative(this._core.current());
+ return $.grep(this._pages, $.proxy(function(page, index) {
+ return page.start <= current && page.end >= current;
+ }, this)).pop();
+ };
+
+ /**
+ * Gets the current succesor/predecessor position.
+ * @protected
+ * @returns {Number}
+ */
+ Navigation.prototype.getPosition = function(successor) {
+ var position, length,
+ settings = this._core.settings;
+
+ if (settings.slideBy == 'page') {
+ position = $.inArray(this.current(), this._pages);
+ length = this._pages.length;
+ successor ? ++position : --position;
+ position = this._pages[((position % length) + length) % length].start;
+ } else {
+ position = this._core.relative(this._core.current());
+ length = this._core.items().length;
+ successor ? position += settings.slideBy : position -= settings.slideBy;
+ }
+
+ return position;
+ };
+
+ /**
+ * Slides to the next item or page.
+ * @public
+ * @param {Number} [speed=false] - The time in milliseconds for the transition.
+ */
+ Navigation.prototype.next = function(speed) {
+ $.proxy(this._overrides.to, this._core)(this.getPosition(true), speed);
+ };
+
+ /**
+ * Slides to the previous item or page.
+ * @public
+ * @param {Number} [speed=false] - The time in milliseconds for the transition.
+ */
+ Navigation.prototype.prev = function(speed) {
+ $.proxy(this._overrides.to, this._core)(this.getPosition(false), speed);
+ };
+
+ /**
+ * Slides to the specified item or page.
+ * @public
+ * @param {Number} position - The position of the item or page.
+ * @param {Number} [speed] - The time in milliseconds for the transition.
+ * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not.
+ */
+ Navigation.prototype.to = function(position, speed, standard) {
+ var length;
+
+ if (!standard && this._pages.length) {
+ length = this._pages.length;
+ $.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed);
+ } else {
+ $.proxy(this._overrides.to, this._core)(position, speed);
+ }
+ };
+
+ $.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation;
+
+})(window.Zepto || window.jQuery, window, document);
+
+/**
+ * Hash Plugin
+ * @version 2.3.1
+ * @author Artus Kolanowski
+ * @author David Deutsch
+ * @license The MIT License (MIT)
+ */
+;(function($, window, document, undefined) {
+ 'use strict';
+
+ /**
+ * Creates the hash plugin.
+ * @class The Hash Plugin
+ * @param {Owl} carousel - The Owl Carousel
+ */
+ var Hash = function(carousel) {
+ /**
+ * Reference to the core.
+ * @protected
+ * @type {Owl}
+ */
+ this._core = carousel;
+
+ /**
+ * Hash index for the items.
+ * @protected
+ * @type {Object}
+ */
+ this._hashes = {};
+
+ /**
+ * The carousel element.
+ * @type {jQuery}
+ */
+ this.$element = this._core.$element;
+
+ /**
+ * All event handlers.
+ * @protected
+ * @type {Object}
+ */
+ this._handlers = {
+ 'initialized.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && this._core.settings.startPosition === 'URLHash') {
+ $(window).trigger('hashchange.owl.navigation');
+ }
+ }, this),
+ 'prepared.owl.carousel': $.proxy(function(e) {
+ if (e.namespace) {
+ var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash');
+
+ if (!hash) {
+ return;
+ }
+
+ this._hashes[hash] = e.content;
+ }
+ }, this),
+ 'changed.owl.carousel': $.proxy(function(e) {
+ if (e.namespace && e.property.name === 'position') {
+ var current = this._core.items(this._core.relative(this._core.current())),
+ hash = $.map(this._hashes, function(item, hash) {
+ return item === current ? hash : null;
+ }).join();
+
+ if (!hash || window.location.hash.slice(1) === hash) {
+ return;
+ }
+
+ window.location.hash = hash;
+ }
+ }, this)
+ };
+
+ // set default options
+ this._core.options = $.extend({}, Hash.Defaults, this._core.options);
+
+ // register the event handlers
+ this.$element.on(this._handlers);
+
+ // register event listener for hash navigation
+ $(window).on('hashchange.owl.navigation', $.proxy(function(e) {
+ var hash = window.location.hash.substring(1),
+ items = this._core.$stage.children(),
+ position = this._hashes[hash] && items.index(this._hashes[hash]);
+
+ if (position === undefined || position === this._core.current()) {
+ return;
+ }
+
+ this._core.to(this._core.relative(position), false, true);
+ }, this));
+ };
+
+ /**
+ * Default options.
+ * @public
+ */
+ Hash.Defaults = {
+ URLhashListener: false
+ };
+
+ /**
+ * Destroys the plugin.
+ * @public
+ */
+ Hash.prototype.destroy = function() {
+ var handler, property;
+
+ $(window).off('hashchange.owl.navigation');
+
+ for (handler in this._handlers) {
+ this._core.$element.off(handler, this._handlers[handler]);
+ }
+ for (property in Object.getOwnPropertyNames(this)) {
+ typeof this[property] != 'function' && (this[property] = null);
+ }
+ };
+
+ $.fn.owlCarousel.Constructor.Plugins.Hash = Hash;
+
+})(window.Zepto || window.jQuery, window, document);
+
+/**
+ * Support Plugin
+ *
+ * @version 2.3.1
+ * @author Vivid Planet Software GmbH
+ * @author Artus Kolanowski
+ * @author David Deutsch
+ * @license The MIT License (MIT)
+ */
+;(function($, window, document, undefined) {
+
+ var style = $('
').get(0).style,
+ prefixes = 'Webkit Moz O ms'.split(' '),
+ events = {
+ transition: {
+ end: {
+ WebkitTransition: 'webkitTransitionEnd',
+ MozTransition: 'transitionend',
+ OTransition: 'oTransitionEnd',
+ transition: 'transitionend'
+ }
+ },
+ animation: {
+ end: {
+ WebkitAnimation: 'webkitAnimationEnd',
+ MozAnimation: 'animationend',
+ OAnimation: 'oAnimationEnd',
+ animation: 'animationend'
+ }
+ }
+ },
+ tests = {
+ csstransforms: function() {
+ return !!test('transform');
+ },
+ csstransforms3d: function() {
+ return !!test('perspective');
+ },
+ csstransitions: function() {
+ return !!test('transition');
+ },
+ cssanimations: function() {
+ return !!test('animation');
+ }
+ };
+
+ function test(property, prefixed) {
+ var result = false,
+ upper = property.charAt(0).toUpperCase() + property.slice(1);
+
+ $.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) {
+ if (style[property] !== undefined) {
+ result = prefixed ? property : true;
+ return false;
+ }
+ });
+
+ return result;
+ }
+
+ function prefixed(property) {
+ return test(property, true);
+ }
+
+ if (tests.csstransitions()) {
+ /* jshint -W053 */
+ $.support.transition = new String(prefixed('transition'))
+ $.support.transition.end = events.transition.end[ $.support.transition ];
+ }
+
+ if (tests.cssanimations()) {
+ /* jshint -W053 */
+ $.support.animation = new String(prefixed('animation'))
+ $.support.animation.end = events.animation.end[ $.support.animation ];
+ }
+
+ if (tests.csstransforms()) {
+ /* jshint -W053 */
+ $.support.transform = new String(prefixed('transform'));
+ $.support.transform3d = tests.csstransforms3d();
+ }
+
+})(window.Zepto || window.jQuery, window, document);
\ No newline at end of file
diff --git a/index/js/vendor/bootstrap.js b/index/js/vendor/bootstrap.js
new file mode 100644
index 0000000..b6ac8d9
--- /dev/null
+++ b/index/js/vendor/bootstrap.js
@@ -0,0 +1,2320 @@
+/*!
+ * Bootstrap v3.3.1 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+
+if (typeof jQuery === 'undefined') {
+ throw new Error('Bootstrap\'s JavaScript requires jQuery')
+}
+
++function ($) {
+ var version = $.fn.jquery.split(' ')[0].split('.')
+ if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1)) {
+ throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher')
+ }
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: transition.js v3.3.1
+ * 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);
+
+/* ========================================================================
+ * Bootstrap: alert.js v3.3.1
+ * 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.3.1'
+
+ Alert.TRANSITION_DURATION = 150
+
+ 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.closest('.alert')
+ }
+
+ $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(Alert.TRANSITION_DURATION) :
+ 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.3.1
+ * 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.3.1'
+
+ 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]())
+
+ // push to event loop to allow forms to submit
+ setTimeout($.proxy(function () {
+ $el[val](data[state] == null ? this.options[state] : data[state])
+
+ 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')
+ } else {
+ this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
+ }
+
+ 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()
+ })
+ .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
+ $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: carousel.js v3.3.1
+ * 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)
+ this.$indicators = this.$element.find('.carousel-indicators')
+ this.options = options
+ this.paused =
+ this.sliding =
+ this.interval =
+ this.$active =
+ this.$items = null
+
+ this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
+
+ this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
+ .on('mouseenter.bs.carousel', $.proxy(this.pause, this))
+ .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
+ }
+
+ Carousel.VERSION = '3.3.1'
+
+ Carousel.TRANSITION_DURATION = 600
+
+ Carousel.DEFAULTS = {
+ interval: 5000,
+ pause: 'hover',
+ wrap: true,
+ keyboard: true
+ }
+
+ Carousel.prototype.keydown = function (e) {
+ if (/input|textarea/i.test(e.target.tagName)) return
+ 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.getItemForDirection = function (direction, active) {
+ var delta = direction == 'prev' ? -1 : 1
+ var activeIndex = this.getItemIndex(active)
+ var itemIndex = (activeIndex + delta) % this.$items.length
+ return this.$items.eq(itemIndex)
+ }
+
+ 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.eq(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 || this.getItemForDirection(type, $active)
+ 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(Carousel.TRANSITION_DURATION)
+ } 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
+ // =================
+
+ var clickHandler = 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()
+ }
+
+ $(document)
+ .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
+ .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
+
+ $(window).on('load', function () {
+ $('[data-ride="carousel"]').each(function () {
+ var $carousel = $(this)
+ Plugin.call($carousel, $carousel.data())
+ })
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: collapse.js v3.3.1
+ * 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.$trigger = $(this.options.trigger).filter('[href="#' + element.id + '"], [data-target="#' + element.id + '"]')
+ this.transitioning = null
+
+ if (this.options.parent) {
+ this.$parent = this.getParent()
+ } else {
+ this.addAriaAndCollapsedClass(this.$element, this.$trigger)
+ }
+
+ if (this.options.toggle) this.toggle()
+ }
+
+ Collapse.VERSION = '3.3.1'
+
+ Collapse.TRANSITION_DURATION = 350
+
+ Collapse.DEFAULTS = {
+ toggle: true,
+ trigger: '[data-toggle="collapse"]'
+ }
+
+ 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 activesData
+ var actives = this.$parent && this.$parent.find('> .panel').children('.in, .collapsing')
+
+ if (actives && actives.length) {
+ activesData = actives.data('bs.collapse')
+ if (activesData && activesData.transitioning) return
+ }
+
+ var startEvent = $.Event('show.bs.collapse')
+ this.$element.trigger(startEvent)
+ if (startEvent.isDefaultPrevented()) return
+
+ if (actives && actives.length) {
+ Plugin.call(actives, 'hide')
+ activesData || actives.data('bs.collapse', null)
+ }
+
+ var dimension = this.dimension()
+
+ this.$element
+ .removeClass('collapse')
+ .addClass('collapsing')[dimension](0)
+ .attr('aria-expanded', true)
+
+ this.$trigger
+ .removeClass('collapsed')
+ .attr('aria-expanded', true)
+
+ 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(Collapse.TRANSITION_DURATION)[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 in')
+ .attr('aria-expanded', false)
+
+ this.$trigger
+ .addClass('collapsed')
+ .attr('aria-expanded', false)
+
+ this.transitioning = 1
+
+ var complete = function () {
+ this.transitioning = 0
+ this.$element
+ .removeClass('collapsing')
+ .addClass('collapse')
+ .trigger('hidden.bs.collapse')
+ }
+
+ if (!$.support.transition) return complete.call(this)
+
+ this.$element
+ [dimension](0)
+ .one('bsTransitionEnd', $.proxy(complete, this))
+ .emulateTransitionEnd(Collapse.TRANSITION_DURATION)
+ }
+
+ Collapse.prototype.toggle = function () {
+ this[this.$element.hasClass('in') ? 'hide' : 'show']()
+ }
+
+ Collapse.prototype.getParent = function () {
+ return $(this.options.parent)
+ .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
+ .each($.proxy(function (i, element) {
+ var $element = $(element)
+ this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
+ }, this))
+ .end()
+ }
+
+ Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
+ var isOpen = $element.hasClass('in')
+
+ $element.attr('aria-expanded', isOpen)
+ $trigger
+ .toggleClass('collapsed', !isOpen)
+ .attr('aria-expanded', isOpen)
+ }
+
+ function getTargetFromTrigger($trigger) {
+ var href
+ var target = $trigger.attr('data-target')
+ || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
+
+ return $(target)
+ }
+
+
+ // 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') options.toggle = false
+ 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 $this = $(this)
+
+ if (!$this.attr('data-target')) e.preventDefault()
+
+ var $target = getTargetFromTrigger($this)
+ var data = $target.data('bs.collapse')
+ var option = data ? 'toggle' : $.extend({}, $this.data(), { trigger: this })
+
+ Plugin.call($target, option)
+ })
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: dropdown.js v3.3.1
+ * 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.3.1'
+
+ 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
+ $('
').insertAfter($(this)).on('click', clearMenus)
+ }
+
+ var relatedTarget = { relatedTarget: this }
+ $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
+
+ if (e.isDefaultPrevented()) return
+
+ $this
+ .trigger('focus')
+ .attr('aria-expanded', 'true')
+
+ $parent
+ .toggleClass('open')
+ .trigger('shown.bs.dropdown', relatedTarget)
+ }
+
+ return false
+ }
+
+ Dropdown.prototype.keydown = function (e) {
+ if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) 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 && e.which != 27) || (isActive && e.which == 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(e.target)
+
+ if (e.which == 38 && index > 0) index-- // up
+ if (e.which == 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 $this = $(this)
+ 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
+
+ $this.attr('aria-expanded', 'false')
+ $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, Dropdown.prototype.keydown)
+ .on('keydown.bs.dropdown.data-api', '[role="menu"]', Dropdown.prototype.keydown)
+ .on('keydown.bs.dropdown.data-api', '[role="listbox"]', Dropdown.prototype.keydown)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: modal.js v3.3.1
+ * 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.3.1'
+
+ Modal.TRANSITION_DURATION = 300
+ Modal.BACKDROP_TRANSITION_DURATION = 150
+
+ 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.setScrollbar()
+ this.$body.addClass('modal-open')
+
+ this.escape()
+ this.resize()
+
+ 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 (that.options.backdrop) that.adjustBackdrop()
+ that.adjustDialog()
+
+ 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(Modal.TRANSITION_DURATION) :
+ 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.escape()
+ this.resize()
+
+ $(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(Modal.TRANSITION_DURATION) :
+ 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('keydown.dismiss.bs.modal', $.proxy(function (e) {
+ e.which == 27 && this.hide()
+ }, this))
+ } else if (!this.isShown) {
+ this.$element.off('keydown.dismiss.bs.modal')
+ }
+ }
+
+ Modal.prototype.resize = function () {
+ if (this.isShown) {
+ $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
+ } else {
+ $(window).off('resize.bs.modal')
+ }
+ }
+
+ Modal.prototype.hideModal = function () {
+ var that = this
+ this.$element.hide()
+ this.backdrop(function () {
+ that.$body.removeClass('modal-open')
+ that.resetAdjustments()
+ that.resetScrollbar()
+ 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 = $('
')
+ .prependTo(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(Modal.BACKDROP_TRANSITION_DURATION) :
+ 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(Modal.BACKDROP_TRANSITION_DURATION) :
+ callbackRemove()
+
+ } else if (callback) {
+ callback()
+ }
+ }
+
+ // these following methods are used to handle overflowing modals
+
+ Modal.prototype.handleUpdate = function () {
+ if (this.options.backdrop) this.adjustBackdrop()
+ this.adjustDialog()
+ }
+
+ Modal.prototype.adjustBackdrop = function () {
+ this.$backdrop
+ .css('height', 0)
+ .css('height', this.$element[0].scrollHeight)
+ }
+
+ Modal.prototype.adjustDialog = function () {
+ var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
+
+ this.$element.css({
+ paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
+ paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
+ })
+ }
+
+ Modal.prototype.resetAdjustments = function () {
+ this.$element.css({
+ paddingLeft: '',
+ paddingRight: ''
+ })
+ }
+
+ Modal.prototype.checkScrollbar = function () {
+ this.bodyIsOverflowing = document.body.scrollHeight > document.documentElement.clientHeight
+ this.scrollbarWidth = this.measureScrollbar()
+ }
+
+ Modal.prototype.setScrollbar = function () {
+ var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
+ if (this.bodyIsOverflowing) 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.3.1
+ * 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.3.1'
+
+ Tooltip.TRANSITION_DURATION = 150
+
+ Tooltip.DEFAULTS = {
+ animation: true,
+ placement: 'top',
+ selector: false,
+ template: '',
+ 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.$tip && self.$tip.is(':visible')) {
+ self.hoverState = 'in'
+ return
+ }
+
+ 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(this.$element[0].ownerDocument.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 $container = this.options.container ? $(this.options.container) : this.$element.parent()
+ var containerDim = this.getPosition($container)
+
+ placement = placement == 'bottom' && pos.bottom + actualHeight > containerDim.bottom ? 'top' :
+ placement == 'top' && pos.top - actualHeight < containerDim.top ? 'bottom' :
+ placement == 'right' && pos.right + actualWidth > containerDim.width ? 'left' :
+ placement == 'left' && pos.left - actualWidth < containerDim.left ? 'right' :
+ placement
+
+ $tip
+ .removeClass(orgPlacement)
+ .addClass(placement)
+ }
+
+ var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
+
+ this.applyPlacement(calculatedOffset, placement)
+
+ var complete = function () {
+ var prevHoverState = that.hoverState
+ that.$element.trigger('shown.bs.' + that.type)
+ that.hoverState = null
+
+ if (prevHoverState == 'out') that.leave(that)
+ }
+
+ $.support.transition && this.$tip.hasClass('fade') ?
+ $tip
+ .one('bsTransitionEnd', complete)
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+ 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 isVertical = /top|bottom/.test(placement)
+ var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
+ var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'
+
+ $tip.offset(offset)
+ this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)
+ }
+
+ Tooltip.prototype.replaceArrow = function (delta, dimension, isHorizontal) {
+ this.arrow()
+ .css(isHorizontal ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')
+ .css(isHorizontal ? 'top' : 'left', '')
+ }
+
+ 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 (callback) {
+ var that = this
+ var $tip = this.tip()
+ var e = $.Event('hide.bs.' + this.type)
+
+ function complete() {
+ if (that.hoverState != 'in') $tip.detach()
+ that.$element
+ .removeAttr('aria-describedby')
+ .trigger('hidden.bs.' + that.type)
+ callback && callback()
+ }
+
+ this.$element.trigger(e)
+
+ if (e.isDefaultPrevented()) return
+
+ $tip.removeClass('in')
+
+ $.support.transition && this.$tip.hasClass('fade') ?
+ $tip
+ .one('bsTransitionEnd', complete)
+ .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :
+ 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'
+
+ var elRect = el.getBoundingClientRect()
+ if (elRect.width == null) {
+ // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
+ elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
+ }
+ var elOffset = isBody ? { top: 0, left: 0 } : $element.offset()
+ var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
+ var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null
+
+ return $.extend({}, elRect, scroll, outerDims, elOffset)
+ }
+
+ 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.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 () {
+ var that = this
+ clearTimeout(this.timeout)
+ this.hide(function () {
+ that.$element.off('.' + that.type).removeData('bs.' + that.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
+ var selector = options && options.selector
+
+ if (!data && option == 'destroy') return
+ if (selector) {
+ if (!data) $this.data('bs.tooltip', (data = {}))
+ if (!data[selector]) data[selector] = new Tooltip(this, options)
+ } else {
+ 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.3.1
+ * 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.3.1'
+
+ Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
+ placement: 'right',
+ trigger: 'click',
+ content: '',
+ template: ''
+ })
+
+
+ // 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').children().detach().end()[ // 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
+ var selector = options && options.selector
+
+ if (!data && option == 'destroy') return
+ if (selector) {
+ if (!data) $this.data('bs.popover', (data = {}))
+ if (!data[selector]) data[selector] = new Popover(this, options)
+ } else {
+ 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: scrollspy.js v3.3.1
+ * 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.3.1'
+
+ 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]) {
+ this.activeTarget = null
+ return this.clear()
+ }
+
+ 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.clear()
+
+ 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.prototype.clear = function () {
+ $(this.selector)
+ .parentsUntil(this.options.target, '.active')
+ .removeClass('active')
+ }
+
+
+ // 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: tab.js v3.3.1
+ * 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.3.1'
+
+ Tab.TRANSITION_DURATION = 150
+
+ 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')
+ var hideEvent = $.Event('hide.bs.tab', {
+ relatedTarget: $this[0]
+ })
+ var showEvent = $.Event('show.bs.tab', {
+ relatedTarget: $previous[0]
+ })
+
+ $previous.trigger(hideEvent)
+ $this.trigger(showEvent)
+
+ if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return
+
+ var $target = $(selector)
+
+ this.activate($this.closest('li'), $ul)
+ this.activate($target, $target.parent(), function () {
+ $previous.trigger({
+ type: 'hidden.bs.tab',
+ relatedTarget: $this[0]
+ })
+ $this.trigger({
+ type: 'shown.bs.tab',
+ relatedTarget: $previous[0]
+ })
+ })
+ }
+
+ Tab.prototype.activate = function (element, container, callback) {
+ var $active = container.find('> .active')
+ var transition = callback
+ && $.support.transition
+ && (($active.length && $active.hasClass('fade')) || !!container.find('> .fade').length)
+
+ function next() {
+ $active
+ .removeClass('active')
+ .find('> .dropdown-menu > .active')
+ .removeClass('active')
+ .end()
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', false)
+
+ element
+ .addClass('active')
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', true)
+
+ 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')
+ .end()
+ .find('[data-toggle="tab"]')
+ .attr('aria-expanded', true)
+ }
+
+ callback && callback()
+ }
+
+ $active.length && transition ?
+ $active
+ .one('bsTransitionEnd', next)
+ .emulateTransitionEnd(Tab.TRANSITION_DURATION) :
+ 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
+ // ============
+
+ var clickHandler = function (e) {
+ e.preventDefault()
+ Plugin.call($(this), 'show')
+ }
+
+ $(document)
+ .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler)
+ .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler)
+
+}(jQuery);
+
+/* ========================================================================
+ * Bootstrap: affix.js v3.3.1
+ * 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.3.1'
+
+ Affix.RESET = 'affix affix-top affix-bottom'
+
+ Affix.DEFAULTS = {
+ offset: 0,
+ target: window
+ }
+
+ Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
+ var scrollTop = this.$target.scrollTop()
+ var position = this.$element.offset()
+ var targetHeight = this.$target.height()
+
+ if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
+
+ if (this.affixed == 'bottom') {
+ if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
+ return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
+ }
+
+ var initializing = this.affixed == null
+ var colliderTop = initializing ? scrollTop : position.top
+ var colliderHeight = initializing ? targetHeight : height
+
+ if (offsetTop != null && colliderTop <= offsetTop) return 'top'
+ if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
+
+ return false
+ }
+
+ 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 height = this.$element.height()
+ var offset = this.options.offset
+ var offsetTop = offset.top
+ var offsetBottom = offset.bottom
+ var scrollHeight = $('body').height()
+
+ 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.getState(scrollHeight, height, offsetTop, offsetBottom)
+
+ if (this.affixed != affix) {
+ 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(affixType.replace('affix', 'affixed') + '.bs.affix')
+ }
+
+ if (affix == 'bottom') {
+ this.$element.offset({
+ top: scrollHeight - 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 != null) data.offset.bottom = data.offsetBottom
+ if (data.offsetTop != null) data.offset.top = data.offsetTop
+
+ Plugin.call($spy, data)
+ })
+ })
+
+}(jQuery);
diff --git a/index/js/vendor/bootstrap.min.js b/index/js/vendor/bootstrap.min.js
new file mode 100644
index 0000000..d839865
--- /dev/null
+++ b/index/js/vendor/bootstrap.min.js
@@ -0,0 +1,7 @@
+/*!
+ * Bootstrap v3.3.1 (http://getbootstrap.com)
+ * Copyright 2011-2014 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.1",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.1",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")&&(c.prop("checked")&&this.$element.hasClass("active")?a=!1:b.find(".active").removeClass("active")),a&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));a&&this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=this.sliding=this.interval=this.$active=this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.1",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c="prev"==a?-1:1,d=this.getItemIndex(b),e=(d+c)%this.$items.length;return this.$items.eq(e)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i="next"==b?"first":"last",j=this;if(!f.length){if(!this.options.wrap)return;f=this.$element.find(".item")[i]()}if(f.hasClass("active"))return this.sliding=!1;var k=f[0],l=a.Event("slide.bs.carousel",{relatedTarget:k,direction:h});if(this.$element.trigger(l),!l.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var m=a(this.$indicators.children()[this.getItemIndex(f)]);m&&m.addClass("active")}var n=a.Event("slid.bs.carousel",{relatedTarget:k,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),j.sliding=!1,setTimeout(function(){j.$element.trigger(n)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(n)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&"show"==b&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a(this.options.trigger).filter('[href="#'+b.id+'"], [data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.1",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0,trigger:'[data-toggle="collapse"]'},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.find("> .panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":a.extend({},e.data(),{trigger:this});c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){b&&3===b.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=c(d),f={relatedTarget:this};e.hasClass("open")&&(e.trigger(b=a.Event("hide.bs.dropdown",f)),b.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f)))}))}function c(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.1",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=c(e),g=f.hasClass("open");if(b(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a('
').insertAfter(a(this)).on("click",b);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(b){if(/(38|40|27|32)/.test(b.which)&&!/input|textarea/i.test(b.target.tagName)){var d=a(this);if(b.preventDefault(),b.stopPropagation(),!d.is(".disabled, :disabled")){var e=c(d),g=e.hasClass("open");if(!g&&27!=b.which||g&&27==b.which)return 27==b.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.divider):visible a",i=e.find('[role="menu"]'+h+', [role="listbox"]'+h);if(i.length){var j=i.index(b.target);38==b.which&&j>0&&j--,40==b.which&&j ').prependTo(this.$element).on("click.dismiss.bs.modal",a.proxy(function(a){a.target===a.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),f&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!b)return;f?this.$backdrop.one("bsTransitionEnd",b).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):b()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var g=function(){d.removeBackdrop(),b&&b()};a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",g).emulateTransitionEnd(c.BACKDROP_TRANSITION_DURATION):g()}else b&&b()},c.prototype.handleUpdate=function(){this.options.backdrop&&this.adjustBackdrop(),this.adjustDialog()},c.prototype.adjustBackdrop=function(){this.$backdrop.css("height",0).css("height",this.$element[0].scrollHeight)},c.prototype.adjustDialog=function(){var a=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){this.bodyIsOverflowing=document.body.scrollHeight>document.documentElement.clientHeight,this.scrollbarWidth=this.measureScrollbar()},c.prototype.setScrollbar=function(){var a=parseInt(this.$body.css("padding-right")||0,10);this.bodyIsOverflowing&&this.$body.css("padding-right",a+this.scrollbarWidth)},c.prototype.resetScrollbar=function(){this.$body.css("padding-right","")},c.prototype.measureScrollbar=function(){var a=document.createElement("div");a.className="modal-scrollbar-measure",this.$body.append(a);var b=a.offsetWidth-a.clientWidth;return this.$body[0].removeChild(a),b};var d=a.fn.modal;a.fn.modal=b,a.fn.modal.Constructor=c,a.fn.modal.noConflict=function(){return a.fn.modal=d,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(c){var d=a(this),e=d.attr("href"),f=a(d.attr("data-target")||e&&e.replace(/.*(?=#[^\s]+$)/,"")),g=f.data("bs.modal")?"toggle":a.extend({remote:!/#/.test(e)&&e},f.data(),d.data());d.is("a")&&c.preventDefault(),f.one("show.bs.modal",function(a){a.isDefaultPrevented()||f.one("hidden.bs.modal",function(){d.is(":visible")&&d.trigger("focus")})}),b.call(f,g,this)})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f="object"==typeof b&&b,g=f&&f.selector;(e||"destroy"!=b)&&(g?(e||d.data("bs.tooltip",e={}),e[g]||(e[g]=new c(this,f))):e||d.data("bs.tooltip",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};c.VERSION="3.3.1",c.TRANSITION_DURATION=150,c.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(this.options.viewport.selector||this.options.viewport);for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c&&c.$tip&&c.$tip.is(":visible")?void(c.hoverState="in"):(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.options.container?a(this.options.container):this.$element.parent(),p=this.getPosition(o);h="bottom"==h&&k.bottom+m>p.bottom?"top":"top"==h&&k.top-mp.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.width&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type)})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b,g=f&&f.selector;(e||"destroy"!=b)&&(g?(e||d.data("bs.popover",e={}),e[g]||(e[g]=new c(this,f))):e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.1",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},c.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){var e=a.proxy(this.process,this);this.$body=a("body"),this.$scrollElement=a(a(c).is("body")?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",e),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.1",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b="offset",c=0;a.isWindow(this.$scrollElement[0])||(b="position",c=this.$scrollElement.scrollTop()),this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight();var d=this;this.$body.find(this.selector).map(function(){var d=a(this),e=d.data("target")||d.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[b]().top+c,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){d.offsets.push(this[0]),d.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(!e[a+1]||b<=e[a+1])&&this.activate(f[a])},b.prototype.activate=function(b){this.activeTarget=b,this.clear();var c=this.selector+'[data-target="'+b+'"],'+this.selector+'[href="'+b+'"]',d=a(c).parents("li").addClass("active");d.parent(".dropdown-menu").length&&(d=d.closest("li.dropdown").addClass("active")),d.trigger("activate.bs.scrollspy")},b.prototype.clear=function(){a(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var d=a.fn.scrollspy;a.fn.scrollspy=c,a.fn.scrollspy.Constructor=b,a.fn.scrollspy.noConflict=function(){return a.fn.scrollspy=d,this},a(window).on("load.bs.scrollspy.data-api",function(){a('[data-spy="scroll"]').each(function(){var b=a(this);c.call(b,b.data())})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new c(this)),"string"==typeof b&&e[b]()})}var c=function(b){this.element=a(b)};c.VERSION="3.3.1",c.TRANSITION_DURATION=150,c.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");if(d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,"")),!b.parent("li").hasClass("active")){var e=c.find(".active:last a"),f=a.Event("hide.bs.tab",{relatedTarget:b[0]}),g=a.Event("show.bs.tab",{relatedTarget:e[0]});if(e.trigger(f),b.trigger(g),!g.isDefaultPrevented()&&!f.isDefaultPrevented()){var h=a(d);this.activate(b.closest("li"),c),this.activate(h,h.parent(),function(){e.trigger({type:"hidden.bs.tab",relatedTarget:b[0]}),b.trigger({type:"shown.bs.tab",relatedTarget:e[0]})
+})}}},c.prototype.activate=function(b,d,e){function f(){g.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.1",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=i?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=a("body").height();"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery);
\ No newline at end of file
diff --git a/index/js/vendor/jquery-1.11.2.min.js b/index/js/vendor/jquery-1.11.2.min.js
new file mode 100644
index 0000000..d8d11ba
--- /dev/null
+++ b/index/js/vendor/jquery-1.11.2.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.11.2 | (c) 2005, 2014 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="1.11.2",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,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=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.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},m.extend=m.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||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},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=r(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(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[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=r(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&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=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=hb(),z=hb(),A=hb(),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-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),db=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)},eb=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fb){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 gb(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(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+rb(o[l]);w=ab.test(a)&&pb(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 hb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ib(a){return a[u]=!0,a}function jb(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function kb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function lb(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 mb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function nb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function ob(a){return ib(function(b){return b=+b,ib(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 pb(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=gb.support={},f=gb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=gb.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",eb,!1):e.attachEvent&&e.attachEvent("onunload",eb)),p=!f(g),c.attributes=jb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=jb(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=jb(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(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);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))&&(jb(function(a){o.appendChild(a).innerHTML=" ",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(".#.+[+~]")}),jb(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))&&jb(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 lb(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?lb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},gb.matches=function(a,b){return gb(a,null,null,b)},gb.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 gb(b,n,null,[a]).length>0},gb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},gb.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},gb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},gb.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=gb.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=gb.selectors={cacheLength:50,createPseudo:ib,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(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===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]||gb.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]&&gb.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(cb,db).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=gb.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()]||gb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ib(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:ib(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ib(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:ib(function(a){return function(b){return gb(a,b).length>0}}),contains:ib(function(a){return a=a.replace(cb,db),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ib(function(a){return W.test(a||"")||gb.error("unsupported lang: "+a),a=a.replace(cb,db).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:ob(function(){return[0]}),last:ob(function(a,b){return[b-1]}),eq:ob(function(a,b,c){return[0>c?c+b:c]}),even:ob(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:ob(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:ob(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:ob(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sb(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 tb(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 ub(a,b,c){for(var d=0,e=b.length;e>d;d++)gb(a,b[d],c);return c}function vb(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 wb(a,b,c,d,e,f){return d&&!d[u]&&(d=wb(d)),e&&!e[u]&&(e=wb(e,f)),ib(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ub(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:vb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=vb(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=vb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sb(function(a){return a===b},h,!0),l=sb(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=[sb(tb(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 wb(i>1&&tb(m),i>1&&rb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xb(a.slice(i,e)),f>e&&xb(a=a.slice(e)),f>e&&rb(a))}m.push(c)}return tb(m)}function yb(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=vb(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&gb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ib(f):f}return h=gb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,yb(e,d)),f.selector=a}return f},i=gb.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(cb,db),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(cb,db),ab.test(j[0].type)&&pb(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&rb(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&pb(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=jb(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),jb(function(a){return a.innerHTML=" ","#"===a.firstChild.getAttribute("href")})||kb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&jb(function(a){return a.innerHTML=" ",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||kb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),jb(function(a){return null==a.getAttribute("disabled")})||kb(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}),gb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(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&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.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?m.extend(a,d):d}},e={};return d.pipe=d.then,m.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&&m.isFunction(a.promise)?e:0,g=1===f?a:m.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]&&m.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;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;
+return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.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.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.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 m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;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},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" a ",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML=" ",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!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(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h ]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/\s*$/g,rb={option:[1,""," "],legend:[1,""," "],area:[1,""," "],param:[1,""," "],thead:[1,""],tr:[2,""],col:[2,""],td:[3,""],_default:k.htmlSerialize?[0,"",""]:[1,"X","
"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1><$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?""!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(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=wb(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=wb(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?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1><$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(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,m.cleanData(ub(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,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.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+""}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" a ",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.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",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight),b.removeChild(i)),b.innerHTML="",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.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 Mb=/alpha\([^)]*\)/i,Nb=/opacity\s*=\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp("^("+S+")(.*)$","i"),Qb=new RegExp("^([+-])=("+S+")","i"),Rb={position:"absolute",visibility:"hidden",display:"block"},Sb={letterSpacing:"0",fontWeight:"400"},Tb=["Webkit","O","Moz","ms"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fb(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.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}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xb(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+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Yb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(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":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.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)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),"normal"===f&&b in Sb&&(f=Sb[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Mb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+" "+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Jb,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e)
+}m.Tween=Zb,Zb.prototype={constructor:Zb,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||(m.cssNumber[c]?"":"px")},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):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):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.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,m.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 fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.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 kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),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:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.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(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.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)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(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=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.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)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.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})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc("show"),slideUp:gc("hide"),slideToggle:gc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();ca ",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lc=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lc,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.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&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.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 m.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=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.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||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.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){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var uc=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.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(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(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(uc," ").indexOf(b)>=0)return!0;return!1}}),m.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){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.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 vc=m.now(),wc=/\?/,xc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\/\//,Gc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hc={},Ic={},Jc="*/".concat("*");try{zc=location.href}catch(Kc){zc=y.createElement("a"),zc.href="",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.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 Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(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}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:"GET",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jc,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":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f: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 i&&i.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||zc)+"").replace(Ac,"").replace(Fc,yc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yc[3]||("http:"===yc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=m.event&&k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,"$1_="+vc++):e+(wc.test(e)?"&":"?")+"_="+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(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]?", "+Jc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=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,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\[\]$/,Sc=/\r?\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vc(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join("&").replace(Qc,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,"\r\n")}}):{name:b.name,value:c.replace(Sc,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&"withCredentials"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;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)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_c.pop()||m.expando+"_"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ad.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,"$1"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.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,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.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?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});
diff --git a/index/js/vendor/modernizr-2.8.3-respond-1.4.2.min.js b/index/js/vendor/modernizr-2.8.3-respond-1.4.2.min.js
new file mode 100644
index 0000000..69fb72a
--- /dev/null
+++ b/index/js/vendor/modernizr-2.8.3-respond-1.4.2.min.js
@@ -0,0 +1,11 @@
+/* Modernizr 2.8.3 (Custom Build) | MIT & BSD
+ * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-mq-cssclasses-addtest-prefixed-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load
+ */
+;window.Modernizr=function(a,b,c){function D(a){j.cssText=a}function E(a,b){return D(n.join(a+";")+(b||""))}function F(a,b){return typeof a===b}function G(a,b){return!!~(""+a).indexOf(b)}function H(a,b){for(var d in a){var e=a[d];if(!G(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function I(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:F(f,"function")?f.bind(d||b):f}return!1}function J(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return F(b,"string")||F(b,"undefined")?H(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),I(e,b,c))}function K(){e.input=function(c){for(var d=0,e=c.length;d
',a,""].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},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b)&&c(b).matches||!1;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=F(e[d],"function"),F(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),B={}.hasOwnProperty,C;!F(B,"undefined")&&!F(B.call,"undefined")?C=function(a,b){return B.call(a,b)}:C=function(a,b){return b in a&&F(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=w.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(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return J("flexWrap")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!F(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!J("indexedDB",a)},s.hashchange=function(){return A("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return D("background-color:rgba(150,255,150,.5)"),G(j.backgroundColor,"rgba")},s.hsla=function(){return D("background-color:hsla(120,40%,100%,.5)"),G(j.backgroundColor,"rgba")||G(j.backgroundColor,"hsla")},s.multiplebgs=function(){return D("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return J("backgroundSize")},s.borderimage=function(){return J("borderImage")},s.borderradius=function(){return J("borderRadius")},s.boxshadow=function(){return J("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return E("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return J("animationName")},s.csscolumns=function(){return J("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return D((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),G(j.backgroundImage,"gradient")},s.cssreflections=function(){return J("boxReflect")},s.csstransforms=function(){return!!J("transform")},s.csstransforms3d=function(){var a=!!J("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return J("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML=" ",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var L in s)C(s,L)&&(x=L.toLowerCase(),e[x]=s[L](),v.push((e[x]?"":"no-")+x));return e.input||K(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)C(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},D(""),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",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="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._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.hasEvent=A,e.testProp=function(a){return H([a])},e.testAllProps=J,e.testStyles=y,e.prefixed=function(a,b,c){return b?J(a,b,c):J(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+v.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 #mq-test-1 { width: 42px; }',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){"use strict";function b(){v(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},g=function(a){return a.replace(c.regex.minmaxwh,"").match(c.regex.other)};if(c.ajax=f,c.queue=d,c.unsupportedmq=g,c.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,comments:/\/\*[^*]*\*+([^/][^*]*\*+)*\//gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\(\s*min\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,maxw:/\(\s*max\-width\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/,minmaxwh:/\(\s*m(in|ax)\-(height|width)\s*:\s*(\s*[0-9\.]+)(px|em)\s*\)/gi,other:/\([^\)]*\)/g},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia("only all")&&a.matchMedia("only all").matches,!c.mediaQueriesSupported){var h,i,j,k=a.document,l=k.documentElement,m=[],n=[],o=[],p={},q=30,r=k.getElementsByTagName("head")[0]||l,s=k.getElementsByTagName("base")[0],t=r.getElementsByTagName("link"),u=function(){var a,b=k.createElement("div"),c=k.body,d=l.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",c||(c=f=k.createElement("body"),c.style.background="none"),l.style.fontSize="100%",c.style.fontSize="100%",c.appendChild(b),f&&l.insertBefore(c,l.firstChild),a=b.offsetWidth,f?l.removeChild(c):c.removeChild(b),l.style.fontSize=d,e&&(c.style.fontSize=e),a=j=parseFloat(a)},v=function(b){var c="clientWidth",d=l[c],e="CSS1Compat"===k.compatMode&&d||k.body[c]||d,f={},g=t[t.length-1],p=(new Date).getTime();if(b&&h&&q>p-h)return a.clearTimeout(i),i=a.setTimeout(v,q),void 0;h=p;for(var s in m)if(m.hasOwnProperty(s)){var w=m[s],x=w.minw,y=w.maxw,z=null===x,A=null===y,B="em";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?j||u():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?j||u():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(n[w.rules]))}for(var C in o)o.hasOwnProperty(C)&&o[C]&&o[C].parentNode===r&&r.removeChild(o[C]);o.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=k.createElement("style"),F=f[D].join("\n");E.type="text/css",E.media=D,r.insertBefore(E,g.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(k.createTextNode(F)),o.push(E)}},w=function(a,b,d){var e=a.replace(c.regex.comments,"").replace(c.regex.keyframes,"").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf("/"));var h=function(a){return a.replace(c.regex.urls,"$1"+b+"$2$3")},i=!f&&d;b.length&&(b+="/"),i&&(f=1);for(var j=0;f>j;j++){var k,l,o,p;i?(k=d,n.push(h(a))):(k=e[j].match(c.regex.findStyles)&&RegExp.$1,n.push(RegExp.$2&&h(RegExp.$2))),o=k.split(","),p=o.length;for(var q=0;p>q;q++)l=o[q],g(l)||m.push({media:l.split("(")[0].match(c.regex.only)&&RegExp.$2||"all",rules:n.length-1,hasquery:l.indexOf("(")>-1,minw:l.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:l.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}v()},x=function(){if(d.length){var b=d.shift();f(b.href,function(c){w(c,b.href,b.media),p[b.href]=!0,a.setTimeout(function(){x()},0)})}},y=function(){for(var b=0;bquery($sql) === TRUE) {$return_array = array(status=>1);
+
+
+header('Content-type: text/json');
+echo json_encode($return_array);
+die();} else {echo json_encode(array(status=>"Error: " . $sql . " " . $conn->error));}
+
+?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+connect_error)
+{
+ die("连接失败: " . $conn->connect_error);
+}
+
+return ($conn);
+}
+
+
+//fnct of get table row number::(data_cnnct var,table name) ::(row number)
+function sql_rowNum($conn,$tableSql)
+{
+$row_count = $conn->query("SELECT COUNT(*) FROM $tableSql");
+list($row_num) = $row_count->fetch_row();
+return ($row_num);
+}
+
+//fnct of getting row data from database::(data_cnnct var, table name,column name, column value)::(row info)
+function sql_data($conn,$table,$clmnName,$value)
+{
+$sql = "SELECT * FROM $table where $clmnName=$value";
+
+$result = $conn->query($sql);
+///禁止非法访问
+if ($result->num_rows > 0) {}else{echo "";}
+
+$row = $result->fetch_assoc();
+
+return ($row);
+
+}
+
+function array_orderby()
+{
+ $args = func_get_args();
+ $data = array_shift($args);
+ foreach ($args as $n => $field) {
+ if (is_string($field)) {
+ $tmp = array();
+ foreach ($data as $key => $row)
+ $tmp[$key] = $row[$field];
+ $args[$n] = $tmp;
+ }
+ }
+ $args[] = &$data;
+ call_user_func_array('array_multisort', $args);
+ return array_pop($args);
+}
+
+?>
\ No newline at end of file
diff --git a/log/aus/ssr.log b/log/aus/ssr.log
new file mode 100644
index 0000000..b481ae1
--- /dev/null
+++ b/log/aus/ssr.log
@@ -0,0 +1,48 @@
+Mon Oct 8 07:00:14 2018; ******** TCP/UDP service monitor started ********
+
+*** TCP/UDP traffic log, generated Mon Oct 8 07:01:14 2018
+
+TCP/22: 266 packets, 31176 bytes total, 4.15 kbps; 108 packets, 10940 bytes incoming, 1.46 kbps; 158 packets, 20236 bytes outgoing, 2.70 kbps
+
+UDP/53: 10 packets, 1050 bytes total, 0.14 kbps; 5 packets, 351 bytes incoming, 0.05 kbps; 5 packets, 699 bytes outgoing, 0.10 kbps
+
+TCP/8890: 4745 packets, 4007765 bytes total, 782.00 kbps; 1894 packets, 114879 bytes incoming, 22.41 kbps; 2851 packets, 3892886 bytes outgoing, 759.58 kbps
+
+TCP/53: 20 packets, 1404 bytes total, 0.27 kbps; 12 packets, 723 bytes incoming, 0.14 kbps; 8 packets, 681 bytes outgoing, 0.13 kbps
+
+TCP/443: 2480 packets, 3423948 bytes total, 668.08 kbps; 2138 packets, 117491 bytes incoming, 22.92 kbps; 342 packets, 3306457 bytes outgoing, 645.16 kbps
+
+
+Running time: 60 seconds
+
+
+*** TCP/UDP traffic log, generated Mon Oct 8 07:02:14 2018
+
+TCP/22: 575 packets, 67874 bytes total, 4.52 kbps; 234 packets, 22501 bytes incoming, 1.50 kbps; 341 packets, 45373 bytes outgoing, 3.02 kbps
+
+UDP/53: 18 packets, 1846 bytes total, 0.12 kbps; 9 packets, 639 bytes incoming, 0.04 kbps; 9 packets, 1207 bytes outgoing, 0.08 kbps
+
+TCP/8890: 8196 packets, 7165642 bytes total, 567.57 kbps; 3177 packets, 175531 bytes incoming, 13.90 kbps; 5019 packets, 6990111 bytes outgoing, 553.67 kbps
+
+TCP/53: 20 packets, 1404 bytes total, 0.10 kbps; 12 packets, 723 bytes incoming, 0.06 kbps; 8 packets, 681 bytes outgoing, 0.05 kbps
+
+TCP/443: 4260 packets, 5504353 bytes total, 435.98 kbps; 3785 packets, 190995 bytes incoming, 15.13 kbps; 475 packets, 5313358 bytes outgoing, 420.86 kbps
+
+
+Running time: 120 seconds
+*** TCP/UDP traffic log, generated Mon Oct 8 07:03:14 2018
+
+TCP/22: 947 packets, 114347 bytes total, 5.08 kbps; 388 packets, 36705 bytes incoming, 1.62 kbps; 559 packets, 77642 bytes outgoing, 3.45 kbps
+
+UDP/53: 26 packets, 2642 bytes total, 0.11 kbps; 13 packets, 927 bytes incoming, 0.04 kbps; 13 packets, 1715 bytes outgoing, 0.07 kbps
+
+TCP/8890: 8202 packets, 7165882 bytes total, 356.06 kbps; 3179 packets, 175611 bytes incoming, 8.72 kbps; 5023 packets, 6990271 bytes outgoing, 347.34 kbps
+
+TCP/53: 20 packets, 1404 bytes total, 0.06 kbps; 12 packets, 723 bytes incoming, 0.03 kbps; 8 packets, 681 bytes outgoing, 0.03 kbps
+
+TCP/443: 4268 packets, 5504673 bytes total, 273.52 kbps; 3789 packets, 191155 bytes incoming, 9.50 kbps; 479 packets, 5313518 bytes outgoing, 264.02 kbps
+
+
+Running time: 180 seconds
+
+
diff --git a/log/ssr.log b/log/ssr.log
new file mode 100644
index 0000000..b481ae1
--- /dev/null
+++ b/log/ssr.log
@@ -0,0 +1,48 @@
+Mon Oct 8 07:00:14 2018; ******** TCP/UDP service monitor started ********
+
+*** TCP/UDP traffic log, generated Mon Oct 8 07:01:14 2018
+
+TCP/22: 266 packets, 31176 bytes total, 4.15 kbps; 108 packets, 10940 bytes incoming, 1.46 kbps; 158 packets, 20236 bytes outgoing, 2.70 kbps
+
+UDP/53: 10 packets, 1050 bytes total, 0.14 kbps; 5 packets, 351 bytes incoming, 0.05 kbps; 5 packets, 699 bytes outgoing, 0.10 kbps
+
+TCP/8890: 4745 packets, 4007765 bytes total, 782.00 kbps; 1894 packets, 114879 bytes incoming, 22.41 kbps; 2851 packets, 3892886 bytes outgoing, 759.58 kbps
+
+TCP/53: 20 packets, 1404 bytes total, 0.27 kbps; 12 packets, 723 bytes incoming, 0.14 kbps; 8 packets, 681 bytes outgoing, 0.13 kbps
+
+TCP/443: 2480 packets, 3423948 bytes total, 668.08 kbps; 2138 packets, 117491 bytes incoming, 22.92 kbps; 342 packets, 3306457 bytes outgoing, 645.16 kbps
+
+
+Running time: 60 seconds
+
+
+*** TCP/UDP traffic log, generated Mon Oct 8 07:02:14 2018
+
+TCP/22: 575 packets, 67874 bytes total, 4.52 kbps; 234 packets, 22501 bytes incoming, 1.50 kbps; 341 packets, 45373 bytes outgoing, 3.02 kbps
+
+UDP/53: 18 packets, 1846 bytes total, 0.12 kbps; 9 packets, 639 bytes incoming, 0.04 kbps; 9 packets, 1207 bytes outgoing, 0.08 kbps
+
+TCP/8890: 8196 packets, 7165642 bytes total, 567.57 kbps; 3177 packets, 175531 bytes incoming, 13.90 kbps; 5019 packets, 6990111 bytes outgoing, 553.67 kbps
+
+TCP/53: 20 packets, 1404 bytes total, 0.10 kbps; 12 packets, 723 bytes incoming, 0.06 kbps; 8 packets, 681 bytes outgoing, 0.05 kbps
+
+TCP/443: 4260 packets, 5504353 bytes total, 435.98 kbps; 3785 packets, 190995 bytes incoming, 15.13 kbps; 475 packets, 5313358 bytes outgoing, 420.86 kbps
+
+
+Running time: 120 seconds
+*** TCP/UDP traffic log, generated Mon Oct 8 07:03:14 2018
+
+TCP/22: 947 packets, 114347 bytes total, 5.08 kbps; 388 packets, 36705 bytes incoming, 1.62 kbps; 559 packets, 77642 bytes outgoing, 3.45 kbps
+
+UDP/53: 26 packets, 2642 bytes total, 0.11 kbps; 13 packets, 927 bytes incoming, 0.04 kbps; 13 packets, 1715 bytes outgoing, 0.07 kbps
+
+TCP/8890: 8202 packets, 7165882 bytes total, 356.06 kbps; 3179 packets, 175611 bytes incoming, 8.72 kbps; 5023 packets, 6990271 bytes outgoing, 347.34 kbps
+
+TCP/53: 20 packets, 1404 bytes total, 0.06 kbps; 12 packets, 723 bytes incoming, 0.03 kbps; 8 packets, 681 bytes outgoing, 0.03 kbps
+
+TCP/443: 4268 packets, 5504673 bytes total, 273.52 kbps; 3789 packets, 191155 bytes incoming, 9.50 kbps; 479 packets, 5313518 bytes outgoing, 264.02 kbps
+
+
+Running time: 180 seconds
+
+
diff --git a/log/usa/ssr.log b/log/usa/ssr.log
new file mode 100644
index 0000000..39929c0
--- /dev/null
+++ b/log/usa/ssr.log
@@ -0,0 +1,48 @@
+Mon Oct 8 07:00:14 2018; ******** TCP/UDP service monitor started ********
+
+*** TCP/UDP traffic log, generated Mon Oct 8 07:01:14 2018
+
+TCP/22: 266 packets, 31176 bytes total, 4.15 kbps; 108 packets, 10940 bytes incoming, 1.46 kbps; 158 packets, 20236 bytes outgoing, 2.70 kbps
+
+UDP/53: 10 packets, 1050 bytes total, 0.14 kbps; 5 packets, 351 bytes incoming, 0.05 kbps; 5 packets, 699 bytes outgoing, 0.10 kbps
+
+TCP/8890: 4745 packets, 4007765 bytes total, 782.00 kbps; 1894 packets, 114879 bytes incoming, 22.41 kbps; 2851 packets, 3892886 bytes outgoing, 759.58 kbps
+
+TCP/53: 20 packets, 1404 bytes total, 0.27 kbps; 12 packets, 723 bytes incoming, 0.14 kbps; 8 packets, 681 bytes outgoing, 0.13 kbps
+
+TCP/443: 2480 packets, 3423948 bytes total, 668.08 kbps; 2138 packets, 117491 bytes incoming, 22.92 kbps; 342 packets, 3306457 bytes outgoing, 645.16 kbps
+
+
+Running time: 60 seconds
+
+
+*** TCP/UDP traffic log, generated Mon Oct 8 07:02:14 2018
+
+TCP/22: 575 packets, 67874 bytes total, 4.52 kbps; 234 packets, 22501 bytes incoming, 1.50 kbps; 341 packets, 45373 bytes outgoing, 3.02 kbps
+
+UDP/53: 18 packets, 1846 bytes total, 0.12 kbps; 9 packets, 639 bytes incoming, 0.04 kbps; 9 packets, 1207 bytes outgoing, 0.08 kbps
+
+TCP/8890: 8196 packets, 7165642 bytes total, 567.57 kbps; 3177 packets, 175531 bytes incoming, 13.90 kbps; 5019 packets, 6990111 bytes outgoing, 553.67 kbps
+
+TCP/53: 20 packets, 1404 bytes total, 0.10 kbps; 12 packets, 723 bytes incoming, 0.06 kbps; 8 packets, 681 bytes outgoing, 0.05 kbps
+
+TCP/443: 4260 packets, 5504353 bytes total, 435.98 kbps; 3785 packets, 190995 bytes incoming, 15.13 kbps; 475 packets, 5313358 bytes outgoing, 420.86 kbps
+
+
+Running time: 120 seconds
+*** TCP/UDP traffic log, generated Mon Oct 8 07:03:14 2018
+
+TCP/22: 947 packets, 114347 bytes total, 5.08 kbps; 388 packets, 36705 bytes incoming, 1.62 kbps; 559 packets, 77642 bytes outgoing, 3.45 kbps
+
+UDP/53: 26 packets, 2642 bytes total, 0.11 kbps; 13 packets, 927 bytes incoming, 0.04 kbps; 13 packets, 1715 bytes outgoing, 0.07 kbps
+
+TCP/8889: 8202 packets, 7165882 bytes total, 356.06 kbps; 3179 packets, 175611 bytes incoming, 8.72 kbps; 5023 packets, 6990271 bytes outgoing, 347.34 kbps
+
+TCP/53: 20 packets, 1404 bytes total, 0.06 kbps; 12 packets, 723 bytes incoming, 0.03 kbps; 8 packets, 681 bytes outgoing, 0.03 kbps
+
+TCP/443: 4268 packets, 5504673 bytes total, 273.52 kbps; 3789 packets, 191155 bytes incoming, 9.50 kbps; 479 packets, 5313518 bytes outgoing, 264.02 kbps
+
+
+Running time: 180 seconds
+
+
diff --git a/mail.php b/mail.php
new file mode 100644
index 0000000..40cfb7c
--- /dev/null
+++ b/mail.php
@@ -0,0 +1,28 @@
+
+
+
+
+
+Yimian Mailer
+
+
+
+
+
+
diff --git a/msg.php b/msg.php
new file mode 100644
index 0000000..dd62991
--- /dev/null
+++ b/msg.php
@@ -0,0 +1,124 @@
+sendWithParam("86", $phoneNumbers[0], $templateId,
+ $params, $smsSign, "", ""); // 签名参数未提供或者为空时,会使用默认签名发送短信
+ $rsp = json_decode($result);
+ echo $result;
+} catch(\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+$conn=database_cnnct();
+
+$ip= getip();
+
+$time=time();
+
+$shu='||';
+$cnnct=$msg1.$shu.$msg2.$shu.$msg3.$shu.$result;
+
+$tel=$_POST['tel'];
+
+$sql="INSERT sms set ip='$ip',time=$time,tel='$phoneNumbers[0]',tpl='$tpl',val='$msg3',cnnct='$cnnct' ";
+
+ if ($conn->query($sql) === TRUE) {$return_array = array(status=>1);}
+
+
+
+//fnct of get usr ip::()::(ip)
+function getip()
+{
+ if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
+ {
+ $ip = getenv("HTTP_CLIENT_IP");
+ }
+ else
+ if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
+ {
+ $ip = getenv("HTTP_X_FORWARDED_FOR");
+ }
+ else
+ if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
+ {
+ $ip = getenv("REMOTE_ADDR");
+ }
+ else
+ if (isset ($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
+ {
+ $ip = $_SERVER['REMOTE_ADDR'];
+ }
+ else
+ {
+ $ip = "unknown";
+ }
+return ($ip);
+}
+
+
+//fnct of connecting database::()::(database conn)
+function database_cnnct ()
+{
+$servername = "114.116.65.152";
+$username = "yimian";
+$password = "Lymian0904@112";
+$dbname = "yimian";
+
+// 创建连接
+$conn = new mysqli($servername, $username, $password, $dbname);
+// Check connection
+
+
+if ($conn->connect_error)
+{
+ die("连接失败: " . $conn->connect_error);
+}
+
+return ($conn);
+}
+
+?>
+
diff --git a/pay/alipay.php b/pay/alipay.php
new file mode 100644
index 0000000..426fc80
--- /dev/null
+++ b/pay/alipay.php
@@ -0,0 +1,8 @@
+
+window.location.href='https://qr.alipay.com/fkx026308kzz3uy2t8krefb';
+";
+
+?>
\ No newline at end of file
diff --git a/phonecheck.php b/phonecheck.php
new file mode 100644
index 0000000..6dc8f80
--- /dev/null
+++ b/phonecheck.php
@@ -0,0 +1,118 @@
+(time()-300)&&$time1));}
+else{echo json_encode(array(status=>0));}
+
+
+?>
+
+connect_error)
+{
+ die("连接失败: " . $conn->connect_error);
+}
+
+return ($conn);
+}
+
+
+//fnct of get table row number::(data_cnnct var,table name) ::(row number)
+function sql_rowNum($conn,$tableSql)
+{
+$row_count = $conn->query("SELECT COUNT(*) FROM $tableSql");
+list($row_num) = $row_count->fetch_row();
+return ($row_num);
+}
+
+//fnct of getting row data from database::(data_cnnct var, table name,column name, column value)::(row info)
+function sql_data($conn,$table,$clmnName,$value)
+{
+$sql = "SELECT * FROM $table where $clmnName=$value";
+
+$result = $conn->query($sql);
+///禁止非法访问
+if ($result->num_rows > 0) {}else{echo "";}
+
+$row = $result->fetch_assoc();
+
+return ($row);
+
+}
+
+function array_orderby()
+{
+ $args = func_get_args();
+ $data = array_shift($args);
+ foreach ($args as $n => $field) {
+ if (is_string($field)) {
+ $tmp = array();
+ foreach ($data as $key => $row)
+ $tmp[$key] = $row[$field];
+ $args[$n] = $tmp;
+ }
+ }
+ $args[] = &$data;
+ call_user_func_array('array_multisort', $args);
+ return array_pop($args);
+}
+
+?>
\ No newline at end of file
diff --git a/qcloudsms/.gitignore b/qcloudsms/.gitignore
new file mode 100644
index 0000000..c045bc8
--- /dev/null
+++ b/qcloudsms/.gitignore
@@ -0,0 +1,5 @@
+/bin
+.env
+/cache
+composer.lock
+/vendor
diff --git a/qcloudsms/LICENSE b/qcloudsms/LICENSE
new file mode 100644
index 0000000..83c0c6b
--- /dev/null
+++ b/qcloudsms/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 qcloudsms
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/qcloudsms/README.md b/qcloudsms/README.md
new file mode 100644
index 0000000..7376981
--- /dev/null
+++ b/qcloudsms/README.md
@@ -0,0 +1,338 @@
+腾讯云短信 PHP SDK
+===
+
+## 腾讯短信服务
+
+目前`腾讯云短信`为客户提供`国内短信`、`国内语音`和`海外短信`三大服务,腾讯云短信SDK支持以下操作:
+
+### 国内短信
+
+国内短信支持操作:
+
+- 单发短信
+- 指定模板单发短信
+- 群发短信
+- 指定模板群发短信
+- 拉取短信回执和短信回复状态
+
+> `Note` 短信拉取功能需要联系腾讯云短信技术支持(QQ:3012203387)开通权限,量大客户可以使用此功能批量拉取,其他客户不建议使用。
+
+### 海外短信
+
+海外短信支持操作:
+
+- 单发短信
+- 指定模板单发短信
+- 群发短信
+- 指定模板群发短信
+- 拉取短信回执和短信回复状态
+
+> `Note` 海外短信和国内短信使用同一接口,只需替换相应的国家码与手机号码,每次请求群发接口手机号码需全部为国内或者海外手机号码。
+
+### 语音通知
+
+语音通知支持操作:
+
+- 发送语音验证码
+- 发送语音通知
+- 上传语音文件
+- 按语音文件fid发送语音通知
+- 指定模板发送语音通知类
+
+## 开发
+
+### 准备
+
+在开始开发云短信应用之前,需要准备如下信息:
+
+- [x] 获取SDK AppID和AppKey
+
+云短信应用SDK `AppID`和`AppKey`可在[短信控制台](https://console.cloud.tencent.com/sms)的应用信息里获取,如您尚未添加应用,请到[短信控制台](https://console.cloud.tencent.com/sms)中添加应用。
+
+- [x] 申请签名
+
+一个完整的短信由短信`签名`和短信正文内容两部分组成,短信`签名`须申请和审核,`签名`可在[短信控制台](https://console.cloud.tencent.com/sms)的相应服务模块`内容配置`中进行申请。
+
+- [x] 申请模板
+
+同样短信或语音正文内容`模板`须申请和审核,`模板`可在[短信控制台](https://console.cloud.tencent.com/sms)的相应服务模块`内容配置`中进行申请。
+
+## 安装
+
+### Composer
+
+qcloudsms_php采用composer进行安装,要使用qcloudsms功能,只需要在composer.json中添加如下依赖:
+
+```json
+{
+ "require": {
+ "qcloudsms/qcloudsms_php": "0.1.*"
+ }
+}
+```
+
+> `Note` Composer的使用可以参考demo目录下面的示例。
+
+### 手动
+
+1. 手动下载或clone最新版本qcloudsms_php代码
+2. 把qcloudsms_php放入项目目录
+3. `require` qcloudsms_php src目录下面的index.php,即可使用,如把qcloudsms放在当前目录下,只需要:
+
+```php
+require __DIR__ . "/qcloudsms_php/src/index.php";
+```
+
+## 用法
+
+若您对接口存在疑问,可以查阅 [API文档](https://cloud.tencent.com/document/product/382/13297) 、[SDK文档](https://qcloudsms.github.io/qcloudsms_php/) 和 [错误码](https://cloud.tencent.com/document/product/382/3771)。
+
+- **准备必要参数**
+
+```php
+// 短信应用SDK AppID
+$appid = 1400009099; // 1400开头
+
+// 短信应用SDK AppKey
+$appkey = "9ff91d87c2cd7cd0ea762f141975d1df37481d48700d70ac37470aefc60f9bad";
+
+// 需要发送短信的手机号码
+$phoneNumbers = ["21212313123", "12345678902", "12345678903"];
+
+// 短信模板ID,需要在短信应用中申请
+$templateId = 7839; // NOTE: 这里的模板ID`7839`只是一个示例,真实的模板ID需要在短信控制台中申请
+
+$smsSign = "腾讯云"; // NOTE: 这里的签名只是示例,请使用真实的已申请的签名,签名参数使用的是`签名内容`,而不是`签名ID`
+```
+
+- **单发短信**
+
+```php
+use Qcloud\Sms\SmsSingleSender;
+
+try {
+ $ssender = new SmsSingleSender($appid, $appkey);
+ $result = $ssender->send(0, "86", $phoneNumbers[0],
+ "【腾讯云】您的验证码是: 5678", "", "");
+ $rsp = json_decode($result);
+ echo $result;
+} catch(\Exception $e) {
+ echo var_dump($e);
+}
+```
+
+> `Note` 如需发送海外短信,同样可以使用此接口,只需将国家码 `86` 改写成对应国家码号。
+> `Note` 无论单发/群发短信还是指定模板ID单发/群发短信都需要从控制台中申请模板并且模板已经审核通过,才可能下发成功,否则返回失败。
+
+- **指定模板ID单发短信**
+
+```php
+use Qcloud\Sms\SmsSingleSender;
+
+try {
+ $ssender = new SmsSingleSender($appid, $appkey);
+ $params = ["5678"];
+ $result = $ssender->sendWithParam("86", $phoneNumbers[0], $templateId,
+ $params, $smsSign, "", ""); // 签名参数未提供或者为空时,会使用默认签名发送短信
+ $rsp = json_decode($result);
+ echo $result;
+} catch(\Exception $e) {
+ echo var_dump($e);
+}
+```
+
+> `Note` 无论单发/群发短信还是指定模板ID单发/群发短信都需要从控制台中申请模板并且模板已经审核通过,才可能下发成功,否则返回失败。
+
+- **群发**
+
+```php
+use Qcloud\Sms\SmsMultiSender;
+
+try {
+ $msender = new SmsMultiSender($appid, $appkey);
+ $result = $msender->send(0, "86", $phoneNumbers,
+ "【腾讯云】您的验证码是: 5678", "", "");
+ $rsp = json_decode($result);
+ echo $result;
+} catch(\Exception $e) {
+ echo var_dump($e);
+}
+```
+
+> `Note` 无论单发/群发短信还是指定模板ID单发/群发短信都需要从控制台中申请模板并且模板已经审核通过,才可能下发成功,否则返回失败。
+
+- **指定模板ID群发**
+
+```php
+use Qcloud\Sms\SmsMultiSender;
+
+try {
+ $msender = new SmsMultiSender($appid, $appkey);
+ $params = ["5678"];
+ $result = $msender->sendWithParam("86", $phoneNumbers,
+ $templateId, $params, $smsSign, "", ""); // 签名参数未提供或者为空时,会使用默认签名发送短信
+ $rsp = json_decode($result);
+ echo $result;
+} catch(\Exception $e) {
+ echo var_dump($e);
+}
+```
+
+> `Note` 群发一次请求最多支持200个号码,如有对号码数量有特殊需求请联系腾讯云短信技术支持(QQ:3012203387)。
+> `Note` 无论单发/群发短信还是指定模板ID单发/群发短信都需要从控制台中申请模板并且模板已经审核通过,才可能下发成功,否则返回失败。
+
+- **发送语音验证码**
+
+```php
+use Qcloud\Sms\SmsVoiceVerifyCodeSender;
+
+try {
+ $vvcsender = new SmsVoiceVerifyCodeSender($appid, $appkey);
+ $result = $vvcsender->send("86", $phoneNumbers[0], "5678", 2, "");
+ $rsp = json_decode($result);
+ echo $result;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+```
+
+> `Note` 语音验证码发送只需提供验证码数字,例如当msg=“5678”时,您收到的语音通知为“您的语音验证码是5678”,如需自定义内容,可以使用语音通知。
+
+- **发送语音通知**
+
+```php
+use Qcloud\Sms\SmsVoicePromptSender;
+
+try {
+ $vpsender = new SmsVoicePromptSender($appid, $appkey);
+ $result = $vpsender->send("86", $phoneNumbers[0], 2, "5678", "");
+ $rsp = json_decode($result);
+ echo $result;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+```
+
+- **拉取短信回执以及回复**
+
+```php
+use Qcloud\Sms\SmsStatusPuller;
+
+try {
+ $sspuller = new SmsStatusPuller($appid, $appkey);
+
+ // 拉取短信回执
+ $callbackResult = $spuller->pullCallback(10);
+ $callbackRsp = json_decode($callbackResult);
+ echo $callbackResult;
+
+ // 拉取回复
+ $replyResult = $spuller->pullReply(10);
+ $replyRsp = json_decode($replyResult);
+ echo $replyResult;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+```
+
+> `Note` 短信拉取功能需要联系腾讯云短信技术支持(QQ:3012203387),量大客户可以使用此功能批量拉取,其他客户不建议使用。
+
+- **拉取单个手机短信状态**
+
+```php
+use Qcloud\Sms\SmsMobileStatusPuller;
+
+try {
+ $beginTime = 1511125600; // 开始时间(unix timestamp)
+ $endTime = 1511841600; // 结束时间(unix timestamp)
+ $maxNum = 10; // 单次拉取最大量
+ $mspuller = new SmsMobileStatusPuller($appid, $appkey);
+
+ // 拉取短信回执
+ $callbackResult = $mspuller->pullCallback("86", $phoneNumbers[0],
+ $beginTime, $endTime, $maxNum);
+ $callbackRsp = json_decode($callbackResult);
+ echo $callbackResult;
+
+ // 拉取回复
+ $replyResult = $mspuller->pullReply("86", $phoneNumbers[0],
+ $beginTime, $endTime, $maxNum);
+ $replyRsp = json_decode($replyResult);
+ echo $replyResult;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+```
+
+> `Note` 短信拉取功能需要联系腾讯云短信技术支持(QQ:3012203387),量大客户可以使用此功能批量拉取,其他客户不建议使用。
+
+- **发送海外短信**
+
+海外短信与国内短信发送类似, 发送海外短信只需替换相应国家码。
+
+
+
+- **上传语音文件**
+
+```php
+use Qcloud\Sms\VoiceFileUploader;
+
+try {
+ // Note: 语音文件大小上传限制400K字节
+ $filepath = "path/to/example.mp3";
+ $fileContent = file_get_contents($filepath);
+ if ($fileContent == false) {
+ throw new \Exception("can not read file " . $filepath);
+ }
+
+ $contentType = VoiceFileUploader::MP3;
+ $uploader = new VoiceFileUploader($appid, $appkey);
+ $result = $uploader->upload($fileContent, $contentType);
+ // 上传成功后,$rsp里会带有语音文件的fid
+ $rsp = json_decode($result);
+ echo $result;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+```
+
+> `Note` '语音文件上传'功能需要联系腾讯云短信技术支持(QQ:3012203387)才能开通
+
+
+- **按语音文件fid发送语音通知**
+
+```php
+use Qcloud\Sms\FileVoiceSender;
+
+try {
+ // Note:这里$fid来自`上传语音文件`接口返回的响应,要按语音
+ // 文件fid发送语音通知,需要先上传语音文件获取$fid
+ $fid = "73844bb649ca38f37e596ec2781ce6a56a2a3a1b.mp3";
+ $fvsender = new FileVoiceSender($appid, $appkey);
+ $result = $fvsender->send("86", $phoneNumbers[0], $fid);
+ $rsp = json_decode($result);
+ echo $result;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+```
+
+> `Note` 按'语音文件fid发送语音通知'功能需要联系腾讯云短信技术支持(QQ:3012203387)才能开通
+
+
+- **指定模板发送语音通知**
+
+```php
+use Qcloud\Sms\TtsVoiceSender;
+
+try {
+ $templateId = 1013;
+ $params = ["54321"];
+ $tvsender = new TtsVoiceSender($appid, $appkey);
+ $result = $tvsender->send("86", $phoneNumbers[0], $templateId, $params);
+ $rsp = json_decode($result);
+ echo $result;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+```
diff --git a/qcloudsms/composer.json b/qcloudsms/composer.json
new file mode 100644
index 0000000..6a8a5d3
--- /dev/null
+++ b/qcloudsms/composer.json
@@ -0,0 +1,15 @@
+{
+ "name": "qcloudsms/qcloudsms_php",
+ "type": "library",
+ "description": "qcloud sms php sdk",
+ "keywords": ["qcloud", "sms", "php", "sdk"],
+ "license": "MIT",
+ "autoload": {
+ "psr-4": {
+ "Qcloud\\Sms\\": "src/"
+ }
+ },
+ "require-dev": {
+ "sami/sami": "dev-master"
+ }
+}
diff --git a/qcloudsms/demo/README.md b/qcloudsms/demo/README.md
new file mode 100644
index 0000000..d93ddc8
--- /dev/null
+++ b/qcloudsms/demo/README.md
@@ -0,0 +1,12 @@
+腾讯云短信 PHP SDK DEMO
+=====
+
+
+## 使用composer
+
+使用composer的项目请参考 `composer` 目录
+
+
+## 不使用composer
+
+没有使用composer的项目请参考 `simple` 目录
diff --git a/qcloudsms/demo/composer/README.md b/qcloudsms/demo/composer/README.md
new file mode 100644
index 0000000..e3581b3
--- /dev/null
+++ b/qcloudsms/demo/composer/README.md
@@ -0,0 +1,22 @@
+腾讯云短信 PHP SDK Demo
+===
+
+## 使用
+
+1. 安装依赖
+
+```sh
+php /path/to/composer install
+```
+
+2. 配置必要参数,如SDK appid/appkey
+
+```sh
+emacs app.php
+```
+
+3. 运行
+
+```sh
+php ./app.php
+```
diff --git a/qcloudsms/demo/composer/app.php b/qcloudsms/demo/composer/app.php
new file mode 100644
index 0000000..8949c13
--- /dev/null
+++ b/qcloudsms/demo/composer/app.php
@@ -0,0 +1,202 @@
+send(0, "86", $phoneNumbers[0],
+ "【腾讯云】您的验证码是: 5678", "", "");
+ $rsp = json_decode($result);
+ echo $result;
+} catch(\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 指定模板ID单发短信
+try {
+ $ssender = new SmsSingleSender($appid, $appkey);
+ $params = ["5678"];
+ $result = $ssender->sendWithParam("86", $phoneNumbers[0], $templateId,
+ $params, $smsSign, "", ""); // 签名参数未提供或者为空时,会使用默认签名发送短信
+ $rsp = json_decode($result);
+ echo $result;
+} catch(\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 群发
+try {
+ $msender = new SmsMultiSender($appid, $appkey);
+ $result = $msender->send(0, "86", $phoneNumbers,
+ "【腾讯云】您的验证码是: 5678", "", "");
+ $rsp = json_decode($result);
+ echo $result;
+} catch(\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 指定模板ID群发
+try {
+ $msender = new SmsMultiSender($appid, $appkey);
+ $params = ["5678"];
+ $result = $msender->sendWithParam("86", $phoneNumbers,
+ $templateId, $params, $smsSign, "", ""); // 签名参数未提供或者为空时,会使用默认签名发送短信
+ $rsp = json_decode($result);
+ echo $result;
+} catch(\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 发送语音验证码
+try {
+ $vvcsender = new SmsVoiceVerifyCodeSender($appid, $appkey);
+ $result = $vvcsender->send("86", $phoneNumbers[0], "5678", 2, "");
+ $rsp = json_decode($result);
+ echo $result;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 发送语音通知
+try {
+ $vpsender = new SmsVoicePromptSender($appid, $appkey);
+ $result = $vpsender->send("86", $phoneNumbers[0], 2, "5678", "");
+ $rsp = json_decode($result);
+ echo $result;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 拉取短信回执以及回复
+try {
+ $sspuller = new SmsStatusPuller($appid, $appkey);
+
+ // 拉取短信回执
+ $callbackResult = $sspuller->pullCallback(10);
+ $callbackRsp = json_decode($callbackResult);
+ echo $callbackResult;
+
+ // 拉取回复
+ $replyResult = $spuller->pullReply(10);
+ $replyRsp = json_decode($replyResult);
+ echo $replyResult;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 拉取单个手机短信状态
+try {
+ $beginTime = 1516670595; // 开始时间(unix timestamp)
+ $endTime = 1516680595; // 结束时间(unix timestamp)
+ $maxNum = 10; // 单次拉取最大量
+ $mspuller = new SmsMobileStatusPuller($appid, $appkey);
+
+ // 拉取短信回执
+ $callbackResult = $mspuller->pullCallback("86", $phoneNumbers[0],
+ $beginTime, $endTime, $maxNum);
+ $callbackRsp = json_decode($callbackResult);
+ echo $callbackResult;
+ echo "\n";
+
+ // 拉取回复
+ $replyResult = $mspuller->pullReply("86", $phoneNumbers[0],
+ $beginTime, $endTime, $maxNum);
+ $replyRsp = json_decode($replyResult);
+ echo $replyResult;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 上传语音文件
+try {
+ $filepath = "path/to/example.mp3";
+ $fileContent = file_get_contents($filepath);
+ if ($fileContent == false) {
+ throw new \Exception("can not read file " . $filepath);
+ }
+
+ $contentType = VoiceFileUploader::MP3;
+ $uploader = new VoiceFileUploader($appid, $appkey);
+ $result = $uploader->upload($fileContent, $contentType);
+ $rsp = json_decode($result);
+ echo $result;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 按语音文件fid发送语音通知
+try {
+ $fid = "73844bb649ca38f37e596ec2781ce6a56a2a3a1b.mp3";
+
+ $fvsender = new FileVoiceSender($appid, $appkey);
+ $result = $fvsender->send("86", $phoneNumbers[0], $fid);
+
+ $rsp = json_decode($result);
+ echo $result;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 指定模板发送语音通知类
+try {
+ $templateId = 1013;
+ $params = ["54321"];
+
+ $tvsender = new TtsVoiceSender($appid, $appkey);
+ $result = $tvsender->send("86", $phoneNumbers[0], $templateId, $params);
+
+ $rsp = json_decode($result);
+ echo $result;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
diff --git a/qcloudsms/demo/composer/composer.json b/qcloudsms/demo/composer/composer.json
new file mode 100644
index 0000000..2e94496
--- /dev/null
+++ b/qcloudsms/demo/composer/composer.json
@@ -0,0 +1,16 @@
+{
+ "name": "qcloudsms_demo",
+ "description": "qcloudms demo",
+ "type": "project",
+ "license": "mit",
+ "authors": [
+ {
+ "name": "qcloudsms",
+ "email": "qcloudsms@yeah.net"
+ }
+ ],
+ "minimum-stability": "dev",
+ "require": {
+ "qcloudsms/qcloudsms_php": "*"
+ }
+}
diff --git a/qcloudsms/demo/simple/app.php b/qcloudsms/demo/simple/app.php
new file mode 100644
index 0000000..8f48e9e
--- /dev/null
+++ b/qcloudsms/demo/simple/app.php
@@ -0,0 +1,204 @@
+send(0, "86", $phoneNumbers[0],
+ "Yimian SSR", "", "");
+ $rsp = json_decode($result);
+ echo $result;
+} catch(\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+*/
+
+// 指定模板ID单发短信
+try {
+ $ssender = new SmsSingleSender($appid, $appkey);
+ $params = ["Yimian SSR","验证码","1515"];
+ $result = $ssender->sendWithParam("86", $phoneNumbers[0], $templateId,
+ $params, $smsSign, "", ""); // 签名参数未提供或者为空时,会使用默认签名发送短信
+ $rsp = json_decode($result);
+ echo $result;
+} catch(\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+/*
+// 群发
+try {
+ $msender = new SmsMultiSender($appid, $appkey);
+ $result = $msender->send(0, "86", $phoneNumbers,
+ "【腾讯云】您的验证码是: 5678", "", "");
+ $rsp = json_decode($result);
+ echo $result;
+} catch(\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 指定模板ID群发
+try {
+ $msender = new SmsMultiSender($appid, $appkey);
+ $params = ["5678"];
+ $result = $msender->sendWithParam("86", $phoneNumbers,
+ $templateId, $params, $smsSign, "", ""); // 签名参数未提供或者为空时,会使用默认签名发送短信
+ $rsp = json_decode($result);
+ echo $result;
+} catch(\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 发送语音验证码
+try {
+ $vvcsender = new SmsVoiceVerifyCodeSender($appid, $appkey);
+ $result = $vvcsender->send("86", $phoneNumbers[0], "5678", 2, "");
+ $rsp = json_decode($result);
+ echo $result;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 发送语音通知
+try {
+ $vpsender = new SmsVoicePromptSender($appid, $appkey);
+ $result = $vpsender->send("86", $phoneNumbers[0], 2, "5678", "");
+ $rsp = json_decode($result);
+ echo $result;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 拉取短信回执以及回复
+try {
+ $sspuller = new SmsStatusPuller($appid, $appkey);
+
+ // 拉取短信回执
+ $callbackResult = $sspuller->pullCallback(10);
+ $callbackRsp = json_decode($callbackResult);
+ echo $callbackResult;
+
+ // 拉取回复
+ $replyResult = $spuller->pullReply(10);
+ $replyRsp = json_decode($replyResult);
+ echo $replyResult;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 拉取单个手机短信状态
+try {
+ $beginTime = 1516670595; // 开始时间(unix timestamp)
+ $endTime = 1516680595; // 结束时间(unix timestamp)
+ $maxNum = 10; // 单次拉取最大量
+ $mspuller = new SmsMobileStatusPuller($appid, $appkey);
+
+ // 拉取短信回执
+ $callbackResult = $mspuller->pullCallback("86", $phoneNumbers[0],
+ $beginTime, $endTime, $maxNum);
+ $callbackRsp = json_decode($callbackResult);
+ echo $callbackResult;
+ echo "\n";
+
+ // 拉取回复
+ $replyResult = $mspuller->pullReply("86", $phoneNumbers[0],
+ $beginTime, $endTime, $maxNum);
+ $replyRsp = json_decode($replyResult);
+ echo $replyResult;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 上传语音文件
+try {
+ $filepath = "path/to/example.mp3";
+ $fileContent = file_get_contents($filepath);
+ if ($fileContent == false) {
+ throw new \Exception("can not read file " . $filepath);
+ }
+
+ $contentType = VoiceFileUploader::MP3;
+ $uploader = new VoiceFileUploader($appid, $appkey);
+ $result = $uploader->upload($fileContent, $contentType);
+ $rsp = json_decode($result);
+ echo $result;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 按语音文件fid发送语音通知
+try {
+ $fid = "73844bb649ca38f37e596ec2781ce6a56a2a3a1b.mp3";
+
+ $fvsender = new FileVoiceSender($appid, $appkey);
+ $result = $fvsender->send("86", $phoneNumbers[0], $fid);
+
+ $rsp = json_decode($result);
+ echo $result;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+
+// 指定模板发送语音通知类
+try {
+ $templateId = 1013;
+ $params = ["54321"];
+
+ $tvsender = new TtsVoiceSender($appid, $appkey);
+ $result = $tvsender->send("86", $phoneNumbers[0], $templateId, $params);
+
+ $rsp = json_decode($result);
+ echo $result;
+} catch (\Exception $e) {
+ echo var_dump($e);
+}
+echo "\n";
+
+*/
\ No newline at end of file
diff --git a/qcloudsms/docs/PROJECT_VERSION b/qcloudsms/docs/PROJECT_VERSION
new file mode 100644
index 0000000..8b25206
--- /dev/null
+++ b/qcloudsms/docs/PROJECT_VERSION
@@ -0,0 +1 @@
+master
\ No newline at end of file
diff --git a/qcloudsms/docs/Qcloud.html b/qcloudsms/docs/Qcloud.html
new file mode 100644
index 0000000..c55990e
--- /dev/null
+++ b/qcloudsms/docs/Qcloud.html
@@ -0,0 +1,94 @@
+
+
+
+
+
+ Qcloud | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Namespaces
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/Qcloud/Sms.html b/qcloudsms/docs/Qcloud/Sms.html
new file mode 100644
index 0000000..f0a2035
--- /dev/null
+++ b/qcloudsms/docs/Qcloud/Sms.html
@@ -0,0 +1,185 @@
+
+
+
+
+
+ Qcloud\Sms | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Classes
+
+
+
+
+
+ 按语音文件fid发送语音通知类
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/Qcloud/Sms/FileVoiceSender.html b/qcloudsms/docs/Qcloud/Sms/FileVoiceSender.html
new file mode 100644
index 0000000..8cb394e
--- /dev/null
+++ b/qcloudsms/docs/Qcloud/Sms/FileVoiceSender.html
@@ -0,0 +1,231 @@
+
+
+
+
+
+ Qcloud\Sms\FileVoiceSender | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
class
+ FileVoiceSender
+
+
+
+
+
+
+
+
+
+
+
Methods
+
+
+
+
+
+ string
+
+
+
send (string $nationCode, string $phoneNumber, string $fid, string $playtimes = 2, string $ext = "")
+
+
按语音文件fid发送语音通知
+
+
+
+
+
+
Details
+
+
+
+
+ at line 25
+
+ __construct (string $appid, string $appkey)
+
+
+
+
+
+
+
+ at line 44
+ string
+ send (string $nationCode, string $phoneNumber, string $fid, string $playtimes = 2, string $ext = "")
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/Qcloud/Sms/SmsMobileStatusPuller.html b/qcloudsms/docs/Qcloud/Sms/SmsMobileStatusPuller.html
new file mode 100644
index 0000000..60eaeba
--- /dev/null
+++ b/qcloudsms/docs/Qcloud/Sms/SmsMobileStatusPuller.html
@@ -0,0 +1,301 @@
+
+
+
+
+
+ Qcloud\Sms\SmsMobileStatusPuller | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ class
+ Qcloud \ Sms \ SmsMobileStatusPuller
+
+
+
+
+
+
+
class
+ SmsMobileStatusPuller
+
+
+
+
+
+
+
+
+
+
+
Methods
+
+
+
+
+
+ string
+
+
+
pullCallback (string $nationCode, string $mobile, int $beginTime, int $endTime, int $max)
+
+
拉取回执结果
+
+
+
+
+ string
+
+
+
pullReply (string $nationCode, string $mobile, int $beginTime, int $endTime, int $max)
+
+
拉取回复信息
+
+
+
+
+
+
Details
+
+
+
+
+ at line 24
+
+ __construct (string $appid, string $appkey)
+
+
+
+
+
+
+
+ at line 72
+ string
+ pullCallback (string $nationCode, string $mobile, int $beginTime, int $endTime, int $max)
+
+
+
+
+
+
+
+ at line 87
+ string
+ pullReply (string $nationCode, string $mobile, int $beginTime, int $endTime, int $max)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/Qcloud/Sms/SmsMultiSender.html b/qcloudsms/docs/Qcloud/Sms/SmsMultiSender.html
new file mode 100644
index 0000000..89420ca
--- /dev/null
+++ b/qcloudsms/docs/Qcloud/Sms/SmsMultiSender.html
@@ -0,0 +1,317 @@
+
+
+
+
+
+ Qcloud\Sms\SmsMultiSender | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
class
+ SmsMultiSender
+
+
+
+
+
+
+
+
+
+
+
Methods
+
+
+
+
+
+ string
+
+
+
send (int $type, string $nationCode, array $phoneNumbers, string $msg, string $extend = "", string $ext = "")
+
+
普通群发
+
+
+
+
+ string
+
+
+
sendWithParam (string $nationCode, array $phoneNumbers, int $templId, array $params, string $sign = "", string $extend = "", string $ext = "")
+
+
指定模板群发
+
+
+
+
+
+
Details
+
+
+
+
+ at line 24
+
+ __construct (string $appid, string $appkey)
+
+
+
+
+
+
+
+ at line 47
+ string
+ send (int $type, string $nationCode, array $phoneNumbers, string $msg, string $extend = "", string $ext = "")
+
+
+
+
+
+
+
+
普通群发
普通群发需明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,
+否则系统将使用默认签名。
+
+
+
+
+
+
+ at line 79
+ string
+ sendWithParam (string $nationCode, array $phoneNumbers, int $templId, array $params, string $sign = "", string $extend = "", string $ext = "")
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/Qcloud/Sms/SmsSenderUtil.html b/qcloudsms/docs/Qcloud/Sms/SmsSenderUtil.html
new file mode 100644
index 0000000..ba1d81a
--- /dev/null
+++ b/qcloudsms/docs/Qcloud/Sms/SmsSenderUtil.html
@@ -0,0 +1,675 @@
+
+
+
+
+
+ Qcloud\Sms\SmsSenderUtil | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
class
+ SmsSenderUtil
+
+
+
+
+
+
+
+
+
+
+
Methods
+
+
+
+
+
+ string
+
+
+
calculateSig (string $appkey, string $random, string $curTime, array $phoneNumbers)
+
+
生成签名
+
+
+
+
+
+
+ string
+
+
+
calculateSigForTempl (string $appkey, string $random, string $curTime, array $phoneNumber)
+
+
生成签名
+
+
+
+
+
+ string
+
+
+
calculateAuth (string $appkey, string $random, string $curTime, array $fileSha1Sum)
+
+
生成上传文件授权
+
+
+
+
+ string
+
+
+
sha1sum (string $content)
+
+
生成sha1sum
+
+
+
+
+
+ string
+
+
+
fetch (string $req)
+
+
发送请求
+
+
+
+
+
+
Details
+
+
+
+
+ at line 17
+ int
+ getRandom ()
+
+
+
+
+
+
+
+ at line 31
+ string
+ calculateSig (string $appkey, string $random, string $curTime, array $phoneNumbers)
+
+
+
+
+
+
+
+ at line 51
+ string
+ calculateSigForTemplAndPhoneNumbers (string $appkey, string $random, string $curTime, array $phoneNumbers)
+
+
+
+
+
+
+
+ at line 63
+
+ phoneNumbersToArray ($nationCode, $phoneNumbers)
+
+
+
+
+
+
+
+ at line 86
+ string
+ calculateSigForTempl (string $appkey, string $random, string $curTime, array $phoneNumber)
+
+
+
+
+
+
+
+ at line 102
+ string
+ calculateSigForPuller (string $appkey, string $random, string $curTime)
+
+
+
+
+
+
+
+ at line 117
+ string
+ calculateAuth (string $appkey, string $random, string $curTime, array $fileSha1Sum)
+
+
+
+
+
+
+
+ at line 129
+ string
+ sha1sum (string $content)
+
+
+
+
+
+
+
+ at line 141
+ string
+ sendCurlPost (string $url, array $dataObj)
+
+
+
+
+
+
+
+ at line 178
+ string
+ fetch (string $req)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/Qcloud/Sms/SmsSingleSender.html b/qcloudsms/docs/Qcloud/Sms/SmsSingleSender.html
new file mode 100644
index 0000000..9f0ffcd
--- /dev/null
+++ b/qcloudsms/docs/Qcloud/Sms/SmsSingleSender.html
@@ -0,0 +1,316 @@
+
+
+
+
+
+ Qcloud\Sms\SmsSingleSender | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
class
+ SmsSingleSender
+
+
+
+
+
+
+
+
+
+
+
Methods
+
+
+
+
+
+ string
+
+
+
send (int $type, string $nationCode, string $phoneNumber, string $msg, string $extend = "", string $ext = "")
+
+
普通单发
+
+
+
+
+ string
+
+
+
sendWithParam (string $nationCode, string $phoneNumber, int $templId = 0, array $params, string $sign = "", string $extend = "", string $ext = "")
+
+
指定模板单发
+
+
+
+
+
+
Details
+
+
+
+
+ at line 24
+
+ __construct (string $appid, string $appkey)
+
+
+
+
+
+
+
+ at line 45
+ string
+ send (int $type, string $nationCode, string $phoneNumber, string $msg, string $extend = "", string $ext = "")
+
+
+
+
+
+
+
+
普通单发
普通单发需明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,否则系统将使用默认签名。
+
+
+
+
+
+
+ at line 82
+ string
+ sendWithParam (string $nationCode, string $phoneNumber, int $templId = 0, array $params, string $sign = "", string $extend = "", string $ext = "")
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/Qcloud/Sms/SmsStatusPuller.html b/qcloudsms/docs/Qcloud/Sms/SmsStatusPuller.html
new file mode 100644
index 0000000..ff7f138
--- /dev/null
+++ b/qcloudsms/docs/Qcloud/Sms/SmsStatusPuller.html
@@ -0,0 +1,261 @@
+
+
+
+
+
+ Qcloud\Sms\SmsStatusPuller | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
class
+ SmsStatusPuller
+
+
+
+
+
+
+
+
+
+
+
Methods
+
+
+
+
+
Details
+
+
+
+
+ at line 24
+
+ __construct (string $appid, string $appkey)
+
+
+
+
+
+
+
+ at line 60
+ string
+ pullCallback (int $max)
+
+
+
+
+
+
+
+ at line 71
+ string
+ pullReply (int $max)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/Qcloud/Sms/SmsVoicePromptSender.html b/qcloudsms/docs/Qcloud/Sms/SmsVoicePromptSender.html
new file mode 100644
index 0000000..6bed37c
--- /dev/null
+++ b/qcloudsms/docs/Qcloud/Sms/SmsVoicePromptSender.html
@@ -0,0 +1,236 @@
+
+
+
+
+
+ Qcloud\Sms\SmsVoicePromptSender | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ class
+ Qcloud \ Sms \ SmsVoicePromptSender
+
+
+
+
+
+
+
class
+ SmsVoicePromptSender
+
+
+
+
+
+
+
+
+
+
+
Methods
+
+
+
+
+
+ string
+
+
+
send (string $nationCode, string $phoneNumber, string $prompttype, string $msg, string $playtimes = 2, string $ext = "")
+
+
发送语音通知
+
+
+
+
+
+
Details
+
+
+
+
+ at line 24
+
+ __construct (string $appid, string $appkey)
+
+
+
+
+
+
+
+ at line 44
+ string
+ send (string $nationCode, string $phoneNumber, string $prompttype, string $msg, string $playtimes = 2, string $ext = "")
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/Qcloud/Sms/SmsVoiceVerifyCodeSender.html b/qcloudsms/docs/Qcloud/Sms/SmsVoiceVerifyCodeSender.html
new file mode 100644
index 0000000..4cd61f8
--- /dev/null
+++ b/qcloudsms/docs/Qcloud/Sms/SmsVoiceVerifyCodeSender.html
@@ -0,0 +1,231 @@
+
+
+
+
+
+ Qcloud\Sms\SmsVoiceVerifyCodeSender | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ class
+ Qcloud \ Sms \ SmsVoiceVerifyCodeSender
+
+
+
+
+
+
+
class
+ SmsVoiceVerifyCodeSender
+
+
+
+
+
+
+
+
+
+
+
Methods
+
+
+
+
+
+ string
+
+
+
send (string $nationCode, string $phoneNumber, string $msg, int $playtimes = 2, string $ext = "")
+
+
发送语音验证码
+
+
+
+
+
+
Details
+
+
+
+
+ at line 24
+
+ __construct (string $appid, string $appkey)
+
+
+
+
+
+
+
+ at line 42
+ string
+ send (string $nationCode, string $phoneNumber, string $msg, int $playtimes = 2, string $ext = "")
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/Qcloud/Sms/TtsVoiceSender.html b/qcloudsms/docs/Qcloud/Sms/TtsVoiceSender.html
new file mode 100644
index 0000000..51f29a0
--- /dev/null
+++ b/qcloudsms/docs/Qcloud/Sms/TtsVoiceSender.html
@@ -0,0 +1,236 @@
+
+
+
+
+
+ Qcloud\Sms\TtsVoiceSender | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
class
+ TtsVoiceSender
+
+
+
+
+
+
+
+
+
+
+
Methods
+
+
+
+
+
+ string
+
+
+
send (string $nationCode, string $phoneNumber, int $templId, array $params, string $playtimes = 2, string $ext = "")
+
+
指定模板发送语音短信
+
+
+
+
+
+
Details
+
+
+
+
+ at line 25
+
+ __construct (string $appid, string $appkey)
+
+
+
+
+
+
+
+ at line 45
+ string
+ send (string $nationCode, string $phoneNumber, int $templId, array $params, string $playtimes = 2, string $ext = "")
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/Qcloud/Sms/VoiceFileUploader.html b/qcloudsms/docs/Qcloud/Sms/VoiceFileUploader.html
new file mode 100644
index 0000000..a4bc888
--- /dev/null
+++ b/qcloudsms/docs/Qcloud/Sms/VoiceFileUploader.html
@@ -0,0 +1,235 @@
+
+
+
+
+
+ Qcloud\Sms\VoiceFileUploader | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
class
+ VoiceFileUploader
+
+
+
+
+
+
+
+
+
Constants
+
+
+
+ WAV
+
+
+
+
+
+
+ MP3
+
+
+
+
+
+
+
+
+
+
Methods
+
+
+
+
+
+ string
+
+
+
upload (string $fileContent, string $contentType)
+
+
上传语音文件
+
+
+
+
+
+
Details
+
+
+
+
+ at line 28
+
+ __construct (string $appid, string $appkey)
+
+
+
+
+
+
+
+ at line 44
+ string
+ upload (string $fileContent, string $contentType)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/SAMI_VERSION b/qcloudsms/docs/SAMI_VERSION
new file mode 100644
index 0000000..fc28f8e
--- /dev/null
+++ b/qcloudsms/docs/SAMI_VERSION
@@ -0,0 +1 @@
+4.0.14-DEV
\ No newline at end of file
diff --git a/qcloudsms/docs/classes.html b/qcloudsms/docs/classes.html
new file mode 100644
index 0000000..fc150b0
--- /dev/null
+++ b/qcloudsms/docs/classes.html
@@ -0,0 +1,173 @@
+
+
+
+
+
+ All Classes | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 按语音文件fid发送语音通知类
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/css/bootstrap-theme.min.css b/qcloudsms/docs/css/bootstrap-theme.min.css
new file mode 100644
index 0000000..7d213d9
--- /dev/null
+++ b/qcloudsms/docs/css/bootstrap-theme.min.css
@@ -0,0 +1,10 @@
+/*!
+ * Bootstrap v3.3.1 (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=cb5a84c449e8302c563e)
+ * Config saved to config.json and https://gist.github.com/cb5a84c449e8302c563e
+ */.btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-default .badge,.btn-primary .badge,.btn-success .badge,.btn-info .badge,.btn-warning .badge,.btn-danger .badge{text-shadow:none}.btn:active,.btn.active{background-image:none}.btn-default{background-image:-webkit-linear-gradient(top, #fff 0, #e0e0e0 100%);background-image:-o-linear-gradient(top, #fff 0, #e0e0e0 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), to(#e0e0e0));background-image:linear-gradient(to bottom, #fff 0, #e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#dbdbdb;text-shadow:0 1px 0 #fff;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top, #428bca 0, #2d6ca2 100%);background-image:-o-linear-gradient(top, #428bca 0, #2d6ca2 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #428bca), to(#2d6ca2));background-image:linear-gradient(to bottom, #428bca 0, #2d6ca2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#2b669a}.btn-primary:hover,.btn-primary:focus{background-color:#2d6ca2;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#2d6ca2;border-color:#2b669a}.btn-primary:disabled,.btn-primary[disabled]{background-color:#2d6ca2;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top, #5cb85c 0, #419641 100%);background-image:-o-linear-gradient(top, #5cb85c 0, #419641 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #5cb85c), to(#419641));background-image:linear-gradient(to bottom, #5cb85c 0, #419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top, #5bc0de 0, #2aabd2 100%);background-image:-o-linear-gradient(top, #5bc0de 0, #2aabd2 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #5bc0de), to(#2aabd2));background-image:linear-gradient(to bottom, #5bc0de 0, #2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top, #f0ad4e 0, #eb9316 100%);background-image:-o-linear-gradient(top, #f0ad4e 0, #eb9316 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #f0ad4e), to(#eb9316));background-image:linear-gradient(to bottom, #f0ad4e 0, #eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-warning:disabled,.btn-warning[disabled]{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top, #d9534f 0, #c12e2a 100%);background-image:-o-linear-gradient(top, #d9534f 0, #c12e2a 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #d9534f), to(#c12e2a));background-image:linear-gradient(to bottom, #d9534f 0, #c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.btn-danger:disabled,.btn-danger[disabled]{background-color:#c12e2a;background-image:none}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-image:-webkit-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);background-image:-o-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #f5f5f5), to(#e8e8e8));background-image:linear-gradient(to bottom, #f5f5f5 0, #e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-color:#e8e8e8}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-image:-webkit-linear-gradient(top, #428bca 0, #357ebd 100%);background-image:-o-linear-gradient(top, #428bca 0, #357ebd 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #428bca), to(#357ebd));background-image:linear-gradient(to bottom, #428bca 0, #357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);background-color:#357ebd}.navbar-default{background-image:-webkit-linear-gradient(top, #fff 0, #f8f8f8 100%);background-image:-o-linear-gradient(top, #fff 0, #f8f8f8 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #fff), to(#f8f8f8));background-image:linear-gradient(to bottom, #fff 0, #f8f8f8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075)}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top, #dbdbdb 0, #e2e2e2 100%);background-image:-o-linear-gradient(top, #dbdbdb 0, #e2e2e2 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #dbdbdb), to(#e2e2e2));background-image:linear-gradient(to bottom, #dbdbdb 0, #e2e2e2 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,0.075);box-shadow:inset 0 3px 9px rgba(0,0,0,0.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,0.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top, #3c3c3c 0, #222 100%);background-image:-o-linear-gradient(top, #3c3c3c 0, #222 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #3c3c3c), to(#222));background-image:linear-gradient(to bottom, #3c3c3c 0, #222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false)}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top, #080808 0, #0f0f0f 100%);background-image:-o-linear-gradient(top, #080808 0, #0f0f0f 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #080808), to(#0f0f0f));background-image:linear-gradient(to bottom, #080808 0, #0f0f0f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,0.25);box-shadow:inset 0 3px 9px rgba(0,0,0,0.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-image:-webkit-linear-gradient(top, #428bca 0, #357ebd 100%);background-image:-o-linear-gradient(top, #428bca 0, #357ebd 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #428bca), to(#357ebd));background-image:linear-gradient(to bottom, #428bca 0, #357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0)}}.alert{text-shadow:0 1px 0 rgba(255,255,255,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05)}.alert-success{background-image:-webkit-linear-gradient(top, #dff0d8 0, #c8e5bc 100%);background-image:-o-linear-gradient(top, #dff0d8 0, #c8e5bc 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #dff0d8), to(#c8e5bc));background-image:linear-gradient(to bottom, #dff0d8 0, #c8e5bc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top, #d9edf7 0, #b9def0 100%);background-image:-o-linear-gradient(top, #d9edf7 0, #b9def0 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #d9edf7), to(#b9def0));background-image:linear-gradient(to bottom, #d9edf7 0, #b9def0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top, #fcf8e3 0, #f8efc0 100%);background-image:-o-linear-gradient(top, #fcf8e3 0, #f8efc0 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #fcf8e3), to(#f8efc0));background-image:linear-gradient(to bottom, #fcf8e3 0, #f8efc0 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top, #f2dede 0, #e7c3c3 100%);background-image:-o-linear-gradient(top, #f2dede 0, #e7c3c3 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #f2dede), to(#e7c3c3));background-image:linear-gradient(to bottom, #f2dede 0, #e7c3c3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top, #ebebeb 0, #f5f5f5 100%);background-image:-o-linear-gradient(top, #ebebeb 0, #f5f5f5 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #ebebeb), to(#f5f5f5));background-image:linear-gradient(to bottom, #ebebeb 0, #f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0)}.progress-bar{background-image:-webkit-linear-gradient(top, #428bca 0, #3071a9 100%);background-image:-o-linear-gradient(top, #428bca 0, #3071a9 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #428bca), to(#3071a9));background-image:linear-gradient(to bottom, #428bca 0, #3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0)}.progress-bar-success{background-image:-webkit-linear-gradient(top, #5cb85c 0, #449d44 100%);background-image:-o-linear-gradient(top, #5cb85c 0, #449d44 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #5cb85c), to(#449d44));background-image:linear-gradient(to bottom, #5cb85c 0, #449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0)}.progress-bar-info{background-image:-webkit-linear-gradient(top, #5bc0de 0, #31b0d5 100%);background-image:-o-linear-gradient(top, #5bc0de 0, #31b0d5 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #5bc0de), to(#31b0d5));background-image:linear-gradient(to bottom, #5bc0de 0, #31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0)}.progress-bar-warning{background-image:-webkit-linear-gradient(top, #f0ad4e 0, #ec971f 100%);background-image:-o-linear-gradient(top, #f0ad4e 0, #ec971f 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #f0ad4e), to(#ec971f));background-image:linear-gradient(to bottom, #f0ad4e 0, #ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0)}.progress-bar-danger{background-image:-webkit-linear-gradient(top, #d9534f 0, #c9302c 100%);background-image:-o-linear-gradient(top, #d9534f 0, #c9302c 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #d9534f), to(#c9302c));background-image:linear-gradient(to bottom, #d9534f 0, #c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0)}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top, #428bca 0, #3278b3 100%);background-image:-o-linear-gradient(top, #428bca 0, #3278b3 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #428bca), to(#3278b3));background-image:linear-gradient(to bottom, #428bca 0, #3278b3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);border-color:#3278b3}.list-group-item.active .badge,.list-group-item.active:hover .badge,.list-group-item.active:focus .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);background-image:-o-linear-gradient(top, #f5f5f5 0, #e8e8e8 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #f5f5f5), to(#e8e8e8));background-image:linear-gradient(to bottom, #f5f5f5 0, #e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0)}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top, #428bca 0, #357ebd 100%);background-image:-o-linear-gradient(top, #428bca 0, #357ebd 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #428bca), to(#357ebd));background-image:linear-gradient(to bottom, #428bca 0, #357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0)}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top, #dff0d8 0, #d0e9c6 100%);background-image:-o-linear-gradient(top, #dff0d8 0, #d0e9c6 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #dff0d8), to(#d0e9c6));background-image:linear-gradient(to bottom, #dff0d8 0, #d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0)}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top, #d9edf7 0, #c4e3f3 100%);background-image:-o-linear-gradient(top, #d9edf7 0, #c4e3f3 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #d9edf7), to(#c4e3f3));background-image:linear-gradient(to bottom, #d9edf7 0, #c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0)}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top, #fcf8e3 0, #faf2cc 100%);background-image:-o-linear-gradient(top, #fcf8e3 0, #faf2cc 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #fcf8e3), to(#faf2cc));background-image:linear-gradient(to bottom, #fcf8e3 0, #faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0)}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top, #f2dede 0, #ebcccc 100%);background-image:-o-linear-gradient(top, #f2dede 0, #ebcccc 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #f2dede), to(#ebcccc));background-image:linear-gradient(to bottom, #f2dede 0, #ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0)}.well{background-image:-webkit-linear-gradient(top, #e8e8e8 0, #f5f5f5 100%);background-image:-o-linear-gradient(top, #e8e8e8 0, #f5f5f5 100%);background-image:-webkit-gradient(linear, left top, left bottom, color-stop(0, #e8e8e8), to(#f5f5f5));background-image:linear-gradient(to bottom, #e8e8e8 0, #f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1)}
\ No newline at end of file
diff --git a/qcloudsms/docs/css/bootstrap.min.css b/qcloudsms/docs/css/bootstrap.min.css
new file mode 100644
index 0000000..a517ad7
--- /dev/null
+++ b/qcloudsms/docs/css/bootstrap.min.css
@@ -0,0 +1,10 @@
+/*!
+ * Bootstrap v3.3.1 (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=cb5a84c449e8302c563e)
+ * Config saved to config.json and https://gist.github.com/cb5a84c449e8302c563e
+ *//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff !important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}mark,.mark{background-color:#fcf8e3;padding:.2em}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#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}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}kbd kbd{padding:0;font-size:100%;font-weight:bold;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{overflow-x:auto;min-height:0.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6)}.form-control::-moz-placeholder{color:#777;opacity:1}.form-control:-ms-input-placeholder{color:#777}.form-control::-webkit-input-placeholder{color:#777}.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="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"],input[type="time"],input[type="datetime-local"],input[type="month"]{line-height:34px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm{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}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"].disabled,input[type="checkbox"].disabled,fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm,.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm,select.form-group-sm .form-control{height:30px;line-height:30px}textarea.input-sm,textarea.form-group-sm .form-control,select[multiple].input-sm,select[multiple].form-group-sm .form-control{height:auto}.input-lg,.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg,select.form-group-lg .form-control{height:46px;line-height:46px}textarea.input-lg,textarea.form-group-lg .form-control,select[multiple].input-lg,select[multiple].form-group-lg .form-control{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:7px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default.focus,.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary.focus,.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#3071a9;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success.focus,.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info.focus,.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning.focus,.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger.focus,.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#428bca;font-weight:normal;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height, visibility;-o-transition-property:height, visibility;transition-property:height, visibility;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function: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{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;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,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);-webkit-background-clip:padding-box;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#428bca}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.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>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.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-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.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{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-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:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width: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}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.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="radio"],[data-toggle="buttons"]>.btn-group>.btn input[type="radio"],[data-toggle="buttons"]>.btn input[type="checkbox"],[data-toggle="buttons"]>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.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 16px;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}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].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:12px;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}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control: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 12px;font-size:14px;font-weight:normal;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:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{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:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{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:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{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+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{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:hover,.nav-tabs>li.active>a:focus{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}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.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:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.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:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.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}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block !important;visibility:visible !important;height:auto !important;padding-bottom:0;overflow:visible !important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius: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 15px;font-size:18px;line-height:20px;height:50px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.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;background-image:none;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}@media (min-width:768px){.navbar-toggle{display:none}}.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;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);margin-top:8px;margin-bottom:8px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.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-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-top-right-radius:4px;border-top-left-radius:4px;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}}@media (min-width:768px){.navbar-left{float:left !important}.navbar-right{float:right !important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{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:hover,.navbar-default .navbar-nav>.open>a:focus{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:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{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:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#777}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#777}.navbar-inverse .navbar-nav>li>a{color:#777}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{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:hover,.navbar-inverse .navbar-nav>.open>a:focus{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:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{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:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#ccc}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857143;text-decoration:none;color:#428bca;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;background-color:#fff;border-color:#ddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;background-color:#fff;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{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]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;color:#fff;line-height:1;vertical-align:baseline;white-space:nowrap;text-align:center;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-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{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-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-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.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,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;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}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;color:#555;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{background-color:#eee;color:#777;cursor:not-allowed}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .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:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{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:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{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:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{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:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.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,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.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-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.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,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:3px;border-top-left-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-left:15px;padding-right:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.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 td:first-child,.panel>.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 td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th: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 th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.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 td:last-child,.panel>.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 td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th: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 th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-left-radius:3px;border-bottom-right-radius:3px}.panel>.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 td:first-child,.panel>.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 td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.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 td:last-child,.panel>.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 td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.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,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom: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{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{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;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{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,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);-o-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform 0.3s ease-out;-o-transition:-o-transform 0.3s ease-out;transition:transform 0.3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(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,0.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);-webkit-background-clip:padding-box;background-clip:padding-box;outline:0}.modal-backdrop{position:absolute;top:0;right:0;left:0;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.42857143px}.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}.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,0.5);box-shadow:0 5px 15px rgba(0,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-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:normal;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{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.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{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-weight:normal;line-height:1.42857143;text-align:left;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,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;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}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,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.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,0.25)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;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,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,0.25)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;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>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.next,.carousel-inner>.item.active.right{-webkit-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);left:0}}.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;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-control.left{background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-webkit-gradient(linear, left top, right top, color-stop(0, rgba(0,0,0,0.5)), to(rgba(0,0,0,0.0001)));background-image:linear-gradient(to right, rgba(0,0,0,0.5) 0, rgba(0,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,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-webkit-gradient(linear, left top, right top, color-stop(0, rgba(0,0,0,0.0001)), to(rgba(0,0,0,0.5)));background-image:linear-gradient(to right, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{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:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;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;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{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}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important;visibility:hidden !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (max-width:767px){.visible-xs-block{display:block !important}}@media (max-width:767px){.visible-xs-inline{display:inline !important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (min-width:1200px){.visible-lg-block{display:block !important}}@media (min-width:1200px){.visible-lg-inline{display:inline !important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}.visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}.visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}}
\ No newline at end of file
diff --git a/qcloudsms/docs/css/sami.css b/qcloudsms/docs/css/sami.css
new file mode 100644
index 0000000..4c089c3
--- /dev/null
+++ b/qcloudsms/docs/css/sami.css
@@ -0,0 +1,459 @@
+html, body, #content {
+ height: 100%;
+}
+
+/* Site menu */
+
+#site-nav.navbar-default {
+ margin: 0;
+ border-radius: 0;
+ border-bottom: 1px solid #ccc;
+ background-color: #EDF3FE;
+ background-image: none;
+}
+
+#site-nav.navbar-default .navbar-brand,
+#site-nav.navbar-default .navbar-nav > li > a {
+ color: #000;
+}
+
+#site-nav.navbar-default .navbar-nav > li > a:hover {
+ text-decoration: underline;
+}
+
+#navbar-elements {
+ float: right;
+}
+
+@media (max-width: 768px) {
+ #navbar-elements {
+ float: none !important;
+ }
+}
+
+/* Namespace breadcrumbs */
+
+.namespace-breadcrumbs .breadcrumb {
+ margin: 0 0 12px;
+ border-radius: 0 0 4px 4px;
+ padding-left: 35px;
+}
+
+.namespace-breadcrumbs .breadcrumb > li + li:before {
+ content: "";
+}
+.namespace-breadcrumbs .breadcrumb > .backslash {
+ color: #ccc;
+}
+
+/* Site columns */
+
+#right-column {
+ margin-left: 20%;
+}
+
+#page-content {
+ padding: 0 30px;
+}
+
+#left-column {
+ width: 20%;
+ position: fixed;
+ height: 100%;
+ border-right: 1px solid #ccc;
+ line-height: 18px;
+ font-size: 13px;
+ display: flex;
+ flex-flow: column;
+}
+
+@media (max-width: 991px) {
+ #left-column {
+ display: none;
+ }
+ #right-column {
+ width: 100%;
+ margin-left: 0;
+ }
+}
+
+/* API Tree */
+
+#api-tree {
+ background: linear-gradient(
+ to bottom,
+ #FFF,
+ #FFF 50%,
+ #EDF3FE 50%,
+ #EDF3FE
+ );
+ background-size: 100% 56px;
+ overflow: auto;
+ height: 100%;
+ background-attachment: local;
+}
+
+#api-tree ul {
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+
+#api-tree ul li {
+ padding: 0;
+ margin: 0;
+}
+
+/* Prevents the menu from jittering on lad */
+#api-tree .glyphicon-play {
+ width: 26px;
+}
+
+#api-tree ul li .hd {
+ padding: 5px;
+}
+
+#api-tree li .hd:nth-child(even) {
+ background-color: #EDF3FE;
+}
+
+#api-tree ul li.opened > .hd span {
+ -webkit-transform: rotate(90deg);
+ -moz-transform: rotate(90deg);
+ -o-transform: rotate(90deg);
+ -ms-transform: rotate(90deg);
+ transform: rotate(90deg);
+}
+
+#api-tree .bd {
+ display: none;
+}
+
+#api-tree li.opened > .bd {
+ display: block;
+}
+
+#api-tree li .hd:hover {
+ background-color: #eee;
+}
+
+#api-tree li.active > .hd {
+ background-color: #3875D7;
+}
+
+#api-tree li.active > .hd a {
+ color: #eee;
+ font-weight: bold;
+}
+
+#api-tree a {
+ color: #222;
+}
+
+#api-tree div.leaf a {
+ margin-left: 20px;
+}
+
+#api-tree .hd span {
+ padding: 2px 8px;
+ font-size: 10px;
+ line-height: 85%;
+}
+
+/* Control panel, search form, version drop-down */
+
+#control-panel {
+ background: #e8e8e8;
+ border-bottom: 1px solid #666;
+ padding: 4px;
+}
+
+#control-panel form {
+ margin: 4px 4px 5px 4px;
+}
+
+#search-form {
+ position: relative;
+}
+
+#search-form input {
+ width: 100%;
+ padding-left: 28px;
+}
+
+#search-form span.glyphicon-search {
+ position: absolute;
+ left: 9px;
+ top: 9px;
+ font-size: 14px;
+ z-index: 2;
+}
+
+/* Typeahead */
+
+.twitter-typeahead {
+ width: 100%;
+ z-index: 1;
+}
+
+.tt-dropdown-menu {
+ overflow: auto;
+ max-height: 260px;
+ margin-top: 9px;
+ background-color: #fff;
+ border: 1px solid #ccc;
+ border-radius: 8px;
+ box-shadow: 0 5px 10px rgba(0,0,0,.2);
+ padding: 8px;
+}
+
+.tt-dropdown-menu p {
+ margin: 0;
+ padding: 0;
+}
+
+.tt-suggestion {
+ padding: 8px;
+ border-bottom: 1px solid #ccc;
+ font-size: 1.1em;
+}
+
+.tt-cursor {
+ background-color: #3875D7;
+ color: #fff;
+}
+
+/** General typography **/
+
+.navbar {
+ border-bottom: 0;
+}
+
+.page-header {
+ margin: 0 0 20px;
+}
+
+abbr[title], abbr[data-original-title], abbr {
+ border-bottom: none;
+ cursor: pointer;
+}
+
+a abbr {
+ cursor: pointer;
+}
+
+.method-description table, .description table {
+ border: solid 1px #ccc;
+ padding: 1em;
+ margin: 1em;
+}
+
+.method-description td, .method-description th,
+.description td, .description th {
+ padding: 0.75em 1.25em;
+}
+
+.method-description tbody tr:nth-child(even),
+.description tbody tr:nth-child(even) {
+ background: #edf3fe;
+}
+
+.method-description tbody tr:nth-child(odd),
+.description tbody tr:nth-child(odd) {
+ background: #fff;
+}
+
+.method-description thead tr,
+.description thead tr {
+ background: #edf3fe;
+}
+
+/** General Sami styling **/
+
+.underlined > .row {
+ padding: 8px 0;
+ border-bottom: 1px solid #ddd;
+}
+
+#footer {
+ text-align: right;
+ margin: 30px;
+ font-size: 11px;
+}
+
+.description {
+ margin: 10px 0;
+ padding: 10px;
+ background-color: #efefef;
+}
+
+.description p {
+ padding: 0;
+ margin: 8px 0;
+}
+
+.method-description {
+ margin: 0 0 24px 0;
+}
+
+.details {
+ padding-left: 30px;
+}
+
+#method-details .method-item {
+ margin-bottom: 30px;
+}
+
+.method-item h3,
+.method-item h3 code {
+ background-color: #eee;
+}
+
+.method-item h3 {
+ padding: 4px;
+ margin-bottom: 20px;
+ font-size: 20px;
+}
+
+.location {
+ font-size: 11px;
+ float: right;
+ font-style: italic;
+}
+
+.namespace-list a {
+ padding: 3px 8px;
+ margin: 0 5px 5px 0;
+ border: 1px solid #ddd;
+ background-color: #f9f9f9;
+ display: inline-block;
+ border-radius: 4px;
+}
+
+.no-description {
+ color: #ccc;
+ font-size: 90%;
+}
+
+/* Namespaces page */
+
+.namespaces {
+ clear: both;
+}
+
+.namespaces .namespace-container {
+ float: left;
+ margin: 0 14px 14px 0;
+ min-width: 30%;
+}
+
+.namespaces h2 {
+ margin: 0 0 20px 0;
+}
+
+@media (max-width: 991px) {
+ .namespaces .namespace-container {
+ margin-right: 0;
+ width: 100%;
+ }
+}
+
+/** Code and pre tags **/
+
+tt, code, pre {
+ font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
+}
+
+code {
+ padding: 0;
+ padding-top: 0.2em;
+ padding-bottom: 0.2em;
+ margin: 0;
+ font-size: 85%;
+ background-color: rgba(0,0,0,0.04);
+ border-radius: 3px;
+ color: #333;
+}
+
+pre {
+ padding: 16px;
+ overflow: auto;
+ font-size: 85%;
+ line-height: 1.45;
+ background-color: #f7f7f7;
+ border-radius: 3px;
+}
+
+h2 {
+ background-color: #EDF3FE;
+ padding: 4px 4px 4px 8px;
+ font-size: 25px;
+ margin: 20px 0;
+}
+
+/** Doc index **/
+
+dt {
+ font-weight: normal;
+}
+
+dd {
+ margin-left: 30px;
+ line-height: 1.5em;
+}
+
+#doc-index h2 {
+ font-weight: bold;
+ margin: 30px 0;
+}
+
+#doc-index .pagination {
+ margin: 0;
+}
+
+/* Search page */
+
+.search-results {
+ list-style-type: none;
+ padding: 0;
+ margin: 0;
+}
+
+.search-results li {
+ list-style-type: none;
+ margin: 0;
+ padding: 14px 0;
+ border-bottom: 1px solid #ccc;
+}
+
+.search-results h2 {
+ background: none;
+ margin: 0;
+ padding: 0;
+ font-size: 18px;
+}
+
+.search-results h2 a {
+ float: left;
+ display: block;
+ margin: 0 0 4px 0;
+}
+
+.search-results .search-type {
+ float: right;
+ margin: 0 0 4px 0;
+}
+
+.search-results .search-from {
+ margin: 0 0 12px 0;
+ font-size: 12px;
+ color: #999;
+}
+
+.search-results .search-from a {
+ font-style: italic;
+}
+
+.search-results .search-description {
+ margin: 8px 0 0 30px;
+}
diff --git a/qcloudsms/docs/doc-index.html b/qcloudsms/docs/doc-index.html
new file mode 100644
index 0000000..91b96e7
--- /dev/null
+++ b/qcloudsms/docs/doc-index.html
@@ -0,0 +1,161 @@
+
+
+
+
+
+ Index | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/fonts/glyphicons-halflings-regular.eot b/qcloudsms/docs/fonts/glyphicons-halflings-regular.eot
new file mode 100644
index 0000000..4a4ca86
Binary files /dev/null and b/qcloudsms/docs/fonts/glyphicons-halflings-regular.eot differ
diff --git a/qcloudsms/docs/fonts/glyphicons-halflings-regular.svg b/qcloudsms/docs/fonts/glyphicons-halflings-regular.svg
new file mode 100644
index 0000000..25691af
--- /dev/null
+++ b/qcloudsms/docs/fonts/glyphicons-halflings-regular.svg
@@ -0,0 +1,229 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/qcloudsms/docs/fonts/glyphicons-halflings-regular.ttf b/qcloudsms/docs/fonts/glyphicons-halflings-regular.ttf
new file mode 100644
index 0000000..67fa00b
Binary files /dev/null and b/qcloudsms/docs/fonts/glyphicons-halflings-regular.ttf differ
diff --git a/qcloudsms/docs/fonts/glyphicons-halflings-regular.woff b/qcloudsms/docs/fonts/glyphicons-halflings-regular.woff
new file mode 100644
index 0000000..8c54182
Binary files /dev/null and b/qcloudsms/docs/fonts/glyphicons-halflings-regular.woff differ
diff --git a/qcloudsms/docs/images/image1.png b/qcloudsms/docs/images/image1.png
new file mode 100644
index 0000000..8c513c3
Binary files /dev/null and b/qcloudsms/docs/images/image1.png differ
diff --git a/qcloudsms/docs/images/image2.png b/qcloudsms/docs/images/image2.png
new file mode 100644
index 0000000..98dee4f
Binary files /dev/null and b/qcloudsms/docs/images/image2.png differ
diff --git a/qcloudsms/docs/images/image3.png b/qcloudsms/docs/images/image3.png
new file mode 100644
index 0000000..381e8e7
Binary files /dev/null and b/qcloudsms/docs/images/image3.png differ
diff --git a/qcloudsms/docs/images/image4.png b/qcloudsms/docs/images/image4.png
new file mode 100644
index 0000000..9c65ceb
Binary files /dev/null and b/qcloudsms/docs/images/image4.png differ
diff --git a/qcloudsms/docs/images/image5.png b/qcloudsms/docs/images/image5.png
new file mode 100644
index 0000000..cfecd5f
Binary files /dev/null and b/qcloudsms/docs/images/image5.png differ
diff --git a/qcloudsms/docs/images/image6.png b/qcloudsms/docs/images/image6.png
new file mode 100644
index 0000000..c211054
Binary files /dev/null and b/qcloudsms/docs/images/image6.png differ
diff --git a/qcloudsms/docs/images/image7.png b/qcloudsms/docs/images/image7.png
new file mode 100644
index 0000000..83bcd16
Binary files /dev/null and b/qcloudsms/docs/images/image7.png differ
diff --git a/qcloudsms/docs/images/image8.png b/qcloudsms/docs/images/image8.png
new file mode 100644
index 0000000..79c37d2
Binary files /dev/null and b/qcloudsms/docs/images/image8.png differ
diff --git a/qcloudsms/docs/images/image9.png b/qcloudsms/docs/images/image9.png
new file mode 100644
index 0000000..76f6bd8
Binary files /dev/null and b/qcloudsms/docs/images/image9.png differ
diff --git a/qcloudsms/docs/index.html b/qcloudsms/docs/index.html
new file mode 100644
index 0000000..4875e70
--- /dev/null
+++ b/qcloudsms/docs/index.html
@@ -0,0 +1,90 @@
+
+
+
+
+
+ Namespaces | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/interfaces.html b/qcloudsms/docs/interfaces.html
new file mode 100644
index 0000000..479cd52
--- /dev/null
+++ b/qcloudsms/docs/interfaces.html
@@ -0,0 +1,83 @@
+
+
+
+
+
+ Interfaces | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/js/bootstrap.min.js b/qcloudsms/docs/js/bootstrap.min.js
new file mode 100644
index 0000000..051dd94
--- /dev/null
+++ b/qcloudsms/docs/js/bootstrap.min.js
@@ -0,0 +1,12 @@
+/*!
+ * Bootstrap v3.3.1 (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=cb5a84c449e8302c563e)
+ * Config saved to config.json and https://gist.github.com/cb5a84c449e8302c563e
+ */
+if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(t){var e=t.fn.jquery.split(" ")[0].split(".");if(e[0]<2&&e[1]<9||1==e[0]&&9==e[1]&&e[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var i=t(this),s=i.data("bs.alert");s||i.data("bs.alert",s=new o(this)),"string"==typeof e&&s[e].call(i)})}var i='[data-dismiss="alert"]',o=function(e){t(e).on("click",i,this.close)};o.VERSION="3.3.1",o.TRANSITION_DURATION=150,o.prototype.close=function(e){function i(){a.detach().trigger("closed.bs.alert").remove()}var s=t(this),n=s.attr("data-target");n||(n=s.attr("href"),n=n&&n.replace(/.*(?=#[^\s]*$)/,""));var a=t(n);e&&e.preventDefault(),a.length||(a=s.closest(".alert")),a.trigger(e=t.Event("close.bs.alert")),e.isDefaultPrevented()||(a.removeClass("in"),t.support.transition&&a.hasClass("fade")?a.one("bsTransitionEnd",i).emulateTransitionEnd(o.TRANSITION_DURATION):i())};var s=t.fn.alert;t.fn.alert=e,t.fn.alert.Constructor=o,t.fn.alert.noConflict=function(){return t.fn.alert=s,this},t(document).on("click.bs.alert.data-api",i,o.prototype.close)}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),s=o.data("bs.button"),n="object"==typeof e&&e;s||o.data("bs.button",s=new i(this,n)),"toggle"==e?s.toggle():e&&s.setState(e)})}var i=function(e,o){this.$element=t(e),this.options=t.extend({},i.DEFAULTS,o),this.isLoading=!1};i.VERSION="3.3.1",i.DEFAULTS={loadingText:"loading..."},i.prototype.setState=function(e){var i="disabled",o=this.$element,s=o.is("input")?"val":"html",n=o.data();e+="Text",null==n.resetText&&o.data("resetText",o[s]()),setTimeout(t.proxy(function(){o[s](null==n[e]?this.options[e]:n[e]),"loadingText"==e?(this.isLoading=!0,o.addClass(i).attr(i,i)):this.isLoading&&(this.isLoading=!1,o.removeClass(i).removeAttr(i))},this),0)},i.prototype.toggle=function(){var t=!0,e=this.$element.closest('[data-toggle="buttons"]');if(e.length){var i=this.$element.find("input");"radio"==i.prop("type")&&(i.prop("checked")&&this.$element.hasClass("active")?t=!1:e.find(".active").removeClass("active")),t&&i.prop("checked",!this.$element.hasClass("active")).trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active"));t&&this.$element.toggleClass("active")};var o=t.fn.button;t.fn.button=e,t.fn.button.Constructor=i,t.fn.button.noConflict=function(){return t.fn.button=o,this},t(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(i){var o=t(i.target);o.hasClass("btn")||(o=o.closest(".btn")),e.call(o,"toggle"),i.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(e){t(e.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(e.type))})}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),s=o.data("bs.carousel"),n=t.extend({},i.DEFAULTS,o.data(),"object"==typeof e&&e),a="string"==typeof e?e:n.slide;s||o.data("bs.carousel",s=new i(this,n)),"number"==typeof e?s.to(e):a?s[a]():n.interval&&s.pause().cycle()})}var i=function(e,i){this.$element=t(e),this.$indicators=this.$element.find(".carousel-indicators"),this.options=i,this.paused=this.sliding=this.interval=this.$active=this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",t.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",t.proxy(this.pause,this)).on("mouseleave.bs.carousel",t.proxy(this.cycle,this))};i.VERSION="3.3.1",i.TRANSITION_DURATION=600,i.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},i.prototype.keydown=function(t){if(!/input|textarea/i.test(t.target.tagName)){switch(t.which){case 37:this.prev();break;case 39:this.next();break;default:return}t.preventDefault()}},i.prototype.cycle=function(e){return e||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(t.proxy(this.next,this),this.options.interval)),this},i.prototype.getItemIndex=function(t){return this.$items=t.parent().children(".item"),this.$items.index(t||this.$active)},i.prototype.getItemForDirection=function(t,e){var i="prev"==t?-1:1,o=this.getItemIndex(e),s=(o+i)%this.$items.length;return this.$items.eq(s)},i.prototype.to=function(t){var e=this,i=this.getItemIndex(this.$active=this.$element.find(".item.active"));return t>this.$items.length-1||0>t?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){e.to(t)}):i==t?this.pause().cycle():this.slide(t>i?"next":"prev",this.$items.eq(t))},i.prototype.pause=function(e){return e||(this.paused=!0),this.$element.find(".next, .prev").length&&t.support.transition&&(this.$element.trigger(t.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},i.prototype.next=function(){return this.sliding?void 0:this.slide("next")},i.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},i.prototype.slide=function(e,o){var s=this.$element.find(".item.active"),n=o||this.getItemForDirection(e,s),a=this.interval,r="next"==e?"left":"right",l="next"==e?"first":"last",h=this;if(!n.length){if(!this.options.wrap)return;n=this.$element.find(".item")[l]()}if(n.hasClass("active"))return this.sliding=!1;var d=n[0],p=t.Event("slide.bs.carousel",{relatedTarget:d,direction:r});if(this.$element.trigger(p),!p.isDefaultPrevented()){if(this.sliding=!0,a&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var c=t(this.$indicators.children()[this.getItemIndex(n)]);c&&c.addClass("active")}var f=t.Event("slid.bs.carousel",{relatedTarget:d,direction:r});return t.support.transition&&this.$element.hasClass("slide")?(n.addClass(e),n[0].offsetWidth,s.addClass(r),n.addClass(r),s.one("bsTransitionEnd",function(){n.removeClass([e,r].join(" ")).addClass("active"),s.removeClass(["active",r].join(" ")),h.sliding=!1,setTimeout(function(){h.$element.trigger(f)},0)}).emulateTransitionEnd(i.TRANSITION_DURATION)):(s.removeClass("active"),n.addClass("active"),this.sliding=!1,this.$element.trigger(f)),a&&this.cycle(),this}};var o=t.fn.carousel;t.fn.carousel=e,t.fn.carousel.Constructor=i,t.fn.carousel.noConflict=function(){return t.fn.carousel=o,this};var s=function(i){var o,s=t(this),n=t(s.attr("data-target")||(o=s.attr("href"))&&o.replace(/.*(?=#[^\s]+$)/,""));if(n.hasClass("carousel")){var a=t.extend({},n.data(),s.data()),r=s.attr("data-slide-to");r&&(a.interval=!1),e.call(n,a),r&&n.data("bs.carousel").to(r),i.preventDefault()}};t(document).on("click.bs.carousel.data-api","[data-slide]",s).on("click.bs.carousel.data-api","[data-slide-to]",s),t(window).on("load",function(){t('[data-ride="carousel"]').each(function(){var i=t(this);e.call(i,i.data())})})}(jQuery),+function(t){"use strict";function e(e){e&&3===e.which||(t(s).remove(),t(n).each(function(){var o=t(this),s=i(o),n={relatedTarget:this};s.hasClass("open")&&(s.trigger(e=t.Event("hide.bs.dropdown",n)),e.isDefaultPrevented()||(o.attr("aria-expanded","false"),s.removeClass("open").trigger("hidden.bs.dropdown",n)))}))}function i(e){var i=e.attr("data-target");i||(i=e.attr("href"),i=i&&/#[A-Za-z]/.test(i)&&i.replace(/.*(?=#[^\s]*$)/,""));var o=i&&t(i);return o&&o.length?o:e.parent()}function o(e){return this.each(function(){var i=t(this),o=i.data("bs.dropdown");o||i.data("bs.dropdown",o=new a(this)),"string"==typeof e&&o[e].call(i)})}var s=".dropdown-backdrop",n='[data-toggle="dropdown"]',a=function(e){t(e).on("click.bs.dropdown",this.toggle)};a.VERSION="3.3.1",a.prototype.toggle=function(o){var s=t(this);if(!s.is(".disabled, :disabled")){var n=i(s),a=n.hasClass("open");if(e(),!a){"ontouchstart"in document.documentElement&&!n.closest(".navbar-nav").length&&t('
').insertAfter(t(this)).on("click",e);var r={relatedTarget:this};if(n.trigger(o=t.Event("show.bs.dropdown",r)),o.isDefaultPrevented())return;s.trigger("focus").attr("aria-expanded","true"),n.toggleClass("open").trigger("shown.bs.dropdown",r)}return!1}},a.prototype.keydown=function(e){if(/(38|40|27|32)/.test(e.which)&&!/input|textarea/i.test(e.target.tagName)){var o=t(this);if(e.preventDefault(),e.stopPropagation(),!o.is(".disabled, :disabled")){var s=i(o),a=s.hasClass("open");if(!a&&27!=e.which||a&&27==e.which)return 27==e.which&&s.find(n).trigger("focus"),o.trigger("click");var r=" li:not(.divider):visible a",l=s.find('[role="menu"]'+r+', [role="listbox"]'+r);if(l.length){var h=l.index(e.target);38==e.which&&h>0&&h--,40==e.which&&h ').prependTo(this.$element).on("click.dismiss.bs.modal",t.proxy(function(t){t.target===t.currentTarget&&("static"==this.options.backdrop?this.$element[0].focus.call(this.$element[0]):this.hide.call(this))},this)),n&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in"),!e)return;n?this.$backdrop.one("bsTransitionEnd",e).emulateTransitionEnd(i.BACKDROP_TRANSITION_DURATION):e()}else if(!this.isShown&&this.$backdrop){this.$backdrop.removeClass("in");var a=function(){o.removeBackdrop(),e&&e()};t.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one("bsTransitionEnd",a).emulateTransitionEnd(i.BACKDROP_TRANSITION_DURATION):a()}else e&&e()},i.prototype.handleUpdate=function(){this.options.backdrop&&this.adjustBackdrop(),this.adjustDialog()},i.prototype.adjustBackdrop=function(){this.$backdrop.css("height",0).css("height",this.$element[0].scrollHeight)},i.prototype.adjustDialog=function(){var t=this.$element[0].scrollHeight>document.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&t?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!t?this.scrollbarWidth:""})},i.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},i.prototype.checkScrollbar=function(){this.bodyIsOverflowing=document.body.scrollHeight>document.documentElement.clientHeight,this.scrollbarWidth=this.measureScrollbar()},i.prototype.setScrollbar=function(){var t=parseInt(this.$body.css("padding-right")||0,10);this.bodyIsOverflowing&&this.$body.css("padding-right",t+this.scrollbarWidth)},i.prototype.resetScrollbar=function(){this.$body.css("padding-right","")},i.prototype.measureScrollbar=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",this.$body.append(t);var e=t.offsetWidth-t.clientWidth;return this.$body[0].removeChild(t),e};var o=t.fn.modal;t.fn.modal=e,t.fn.modal.Constructor=i,t.fn.modal.noConflict=function(){return t.fn.modal=o,this},t(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(i){var o=t(this),s=o.attr("href"),n=t(o.attr("data-target")||s&&s.replace(/.*(?=#[^\s]+$)/,"")),a=n.data("bs.modal")?"toggle":t.extend({remote:!/#/.test(s)&&s},n.data(),o.data());o.is("a")&&i.preventDefault(),n.one("show.bs.modal",function(t){t.isDefaultPrevented()||n.one("hidden.bs.modal",function(){o.is(":visible")&&o.trigger("focus")})}),e.call(n,a,this)})}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),s=o.data("bs.tooltip"),n="object"==typeof e&&e,a=n&&n.selector;(s||"destroy"!=e)&&(a?(s||o.data("bs.tooltip",s={}),s[a]||(s[a]=new i(this,n))):s||o.data("bs.tooltip",s=new i(this,n)),"string"==typeof e&&s[e]())})}var i=function(t,e){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",t,e)};i.VERSION="3.3.1",i.TRANSITION_DURATION=150,i.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},i.prototype.init=function(e,i,o){this.enabled=!0,this.type=e,this.$element=t(i),this.options=this.getOptions(o),this.$viewport=this.options.viewport&&t(this.options.viewport.selector||this.options.viewport);for(var s=this.options.trigger.split(" "),n=s.length;n--;){var a=s[n];if("click"==a)this.$element.on("click."+this.type,this.options.selector,t.proxy(this.toggle,this));else if("manual"!=a){var r="hover"==a?"mouseenter":"focusin",l="hover"==a?"mouseleave":"focusout";this.$element.on(r+"."+this.type,this.options.selector,t.proxy(this.enter,this)),this.$element.on(l+"."+this.type,this.options.selector,t.proxy(this.leave,this))}}this.options.selector?this._options=t.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},i.prototype.getDefaults=function(){return i.DEFAULTS},i.prototype.getOptions=function(e){return e=t.extend({},this.getDefaults(),this.$element.data(),e),e.delay&&"number"==typeof e.delay&&(e.delay={show:e.delay,hide:e.delay}),e},i.prototype.getDelegateOptions=function(){var e={},i=this.getDefaults();return this._options&&t.each(this._options,function(t,o){i[t]!=o&&(e[t]=o)}),e},i.prototype.enter=function(e){var i=e instanceof this.constructor?e:t(e.currentTarget).data("bs."+this.type);return i&&i.$tip&&i.$tip.is(":visible")?void(i.hoverState="in"):(i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i)),clearTimeout(i.timeout),i.hoverState="in",i.options.delay&&i.options.delay.show?void(i.timeout=setTimeout(function(){"in"==i.hoverState&&i.show()},i.options.delay.show)):i.show())},i.prototype.leave=function(e){var i=e instanceof this.constructor?e:t(e.currentTarget).data("bs."+this.type);return i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i)),clearTimeout(i.timeout),i.hoverState="out",i.options.delay&&i.options.delay.hide?void(i.timeout=setTimeout(function(){"out"==i.hoverState&&i.hide()},i.options.delay.hide)):i.hide()},i.prototype.show=function(){var e=t.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(e);var o=t.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(e.isDefaultPrevented()||!o)return;var s=this,n=this.tip(),a=this.getUID(this.type);this.setContent(),n.attr("id",a),this.$element.attr("aria-describedby",a),this.options.animation&&n.addClass("fade");var r="function"==typeof this.options.placement?this.options.placement.call(this,n[0],this.$element[0]):this.options.placement,l=/\s?auto?\s?/i,h=l.test(r);h&&(r=r.replace(l,"")||"top"),n.detach().css({top:0,left:0,display:"block"}).addClass(r).data("bs."+this.type,this),this.options.container?n.appendTo(this.options.container):n.insertAfter(this.$element);var d=this.getPosition(),p=n[0].offsetWidth,c=n[0].offsetHeight;if(h){var f=r,u=this.options.container?t(this.options.container):this.$element.parent(),g=this.getPosition(u);r="bottom"==r&&d.bottom+c>g.bottom?"top":"top"==r&&d.top-cg.width?"left":"left"==r&&d.left-pa.top+a.height&&(s.top=a.top+a.height-l)}else{var h=e.left-n,d=e.left+n+i;ha.width&&(s.left=a.left+a.width-d)}return s},i.prototype.getTitle=function(){var t,e=this.$element,i=this.options;return t=e.attr("data-original-title")||("function"==typeof i.title?i.title.call(e[0]):i.title)},i.prototype.getUID=function(t){do t+=~~(1e6*Math.random());while(document.getElementById(t));return t},i.prototype.tip=function(){return this.$tip=this.$tip||t(this.options.template)},i.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},i.prototype.enable=function(){this.enabled=!0},i.prototype.disable=function(){this.enabled=!1},i.prototype.toggleEnabled=function(){this.enabled=!this.enabled},i.prototype.toggle=function(e){var i=this;e&&(i=t(e.currentTarget).data("bs."+this.type),i||(i=new this.constructor(e.currentTarget,this.getDelegateOptions()),t(e.currentTarget).data("bs."+this.type,i))),i.tip().hasClass("in")?i.leave(i):i.enter(i)},i.prototype.destroy=function(){var t=this;clearTimeout(this.timeout),this.hide(function(){t.$element.off("."+t.type).removeData("bs."+t.type)})};var o=t.fn.tooltip;t.fn.tooltip=e,t.fn.tooltip.Constructor=i,t.fn.tooltip.noConflict=function(){return t.fn.tooltip=o,this}}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),s=o.data("bs.popover"),n="object"==typeof e&&e,a=n&&n.selector;(s||"destroy"!=e)&&(a?(s||o.data("bs.popover",s={}),s[a]||(s[a]=new i(this,n))):s||o.data("bs.popover",s=new i(this,n)),"string"==typeof e&&s[e]())})}var i=function(t,e){this.init("popover",t,e)};if(!t.fn.tooltip)throw new Error("Popover requires tooltip.js");i.VERSION="3.3.1",i.DEFAULTS=t.extend({},t.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),i.prototype=t.extend({},t.fn.tooltip.Constructor.prototype),i.prototype.constructor=i,i.prototype.getDefaults=function(){return i.DEFAULTS},i.prototype.setContent=function(){var t=this.tip(),e=this.getTitle(),i=this.getContent();t.find(".popover-title")[this.options.html?"html":"text"](e),t.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof i?"html":"append":"text"](i),t.removeClass("fade top bottom left right in"),t.find(".popover-title").html()||t.find(".popover-title").hide()},i.prototype.hasContent=function(){return this.getTitle()||this.getContent()},i.prototype.getContent=function(){var t=this.$element,e=this.options;return t.attr("data-content")||("function"==typeof e.content?e.content.call(t[0]):e.content)},i.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},i.prototype.tip=function(){return this.$tip||(this.$tip=t(this.options.template)),this.$tip};var o=t.fn.popover;t.fn.popover=e,t.fn.popover.Constructor=i,t.fn.popover.noConflict=function(){return t.fn.popover=o,this}}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),s=o.data("bs.tab");s||o.data("bs.tab",s=new i(this)),"string"==typeof e&&s[e]()})}var i=function(e){this.element=t(e)};i.VERSION="3.3.1",i.TRANSITION_DURATION=150,i.prototype.show=function(){var e=this.element,i=e.closest("ul:not(.dropdown-menu)"),o=e.data("target");if(o||(o=e.attr("href"),o=o&&o.replace(/.*(?=#[^\s]*$)/,"")),!e.parent("li").hasClass("active")){var s=i.find(".active:last a"),n=t.Event("hide.bs.tab",{relatedTarget:e[0]}),a=t.Event("show.bs.tab",{relatedTarget:s[0]});if(s.trigger(n),e.trigger(a),!a.isDefaultPrevented()&&!n.isDefaultPrevented()){var r=t(o);this.activate(e.closest("li"),i),this.activate(r,r.parent(),function(){s.trigger({type:"hidden.bs.tab",relatedTarget:e[0]}),e.trigger({type:"shown.bs.tab",relatedTarget:s[0]})})}}},i.prototype.activate=function(e,o,s){function n(){a.removeClass("active").find("> .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),e.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),r?(e[0].offsetWidth,e.addClass("in")):e.removeClass("fade"),e.parent(".dropdown-menu")&&e.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),s&&s()}var a=o.find("> .active"),r=s&&t.support.transition&&(a.length&&a.hasClass("fade")||!!o.find("> .fade").length);a.length&&r?a.one("bsTransitionEnd",n).emulateTransitionEnd(i.TRANSITION_DURATION):n(),a.removeClass("in")};var o=t.fn.tab;t.fn.tab=e,t.fn.tab.Constructor=i,t.fn.tab.noConflict=function(){return t.fn.tab=o,this};var s=function(i){i.preventDefault(),e.call(t(this),"show")};t(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',s).on("click.bs.tab.data-api",'[data-toggle="pill"]',s)}(jQuery),+function(t){"use strict";function e(e){return this.each(function(){var o=t(this),s=o.data("bs.affix"),n="object"==typeof e&&e;s||o.data("bs.affix",s=new i(this,n)),"string"==typeof e&&s[e]()})}var i=function(e,o){this.options=t.extend({},i.DEFAULTS,o),this.$target=t(this.options.target).on("scroll.bs.affix.data-api",t.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",t.proxy(this.checkPositionWithEventLoop,this)),this.$element=t(e),this.affixed=this.unpin=this.pinnedOffset=null,this.checkPosition()};i.VERSION="3.3.1",i.RESET="affix affix-top affix-bottom",i.DEFAULTS={offset:0,target:window},i.prototype.getState=function(t,e,i,o){var s=this.$target.scrollTop(),n=this.$element.offset(),a=this.$target.height();if(null!=i&&"top"==this.affixed)return i>s?"top":!1;if("bottom"==this.affixed)return null!=i?s+this.unpin<=n.top?!1:"bottom":t-o>=s+a?!1:"bottom";var r=null==this.affixed,l=r?s:n.top,h=r?a:e;return null!=i&&i>=l?"top":null!=o&&l+h>=t-o?"bottom":!1},i.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(i.RESET).addClass("affix");var t=this.$target.scrollTop(),e=this.$element.offset();return this.pinnedOffset=e.top-t},i.prototype.checkPositionWithEventLoop=function(){setTimeout(t.proxy(this.checkPosition,this),1)},i.prototype.checkPosition=function(){if(this.$element.is(":visible")){var e=this.$element.height(),o=this.options.offset,s=o.top,n=o.bottom,a=t("body").height();"object"!=typeof o&&(n=s=o),"function"==typeof s&&(s=o.top(this.$element)),"function"==typeof n&&(n=o.bottom(this.$element));var r=this.getState(a,e,s,n);if(this.affixed!=r){null!=this.unpin&&this.$element.css("top","");var l="affix"+(r?"-"+r:""),h=t.Event(l+".bs.affix");if(this.$element.trigger(h),h.isDefaultPrevented())return;this.affixed=r,this.unpin="bottom"==r?this.getPinnedOffset():null,this.$element.removeClass(i.RESET).addClass(l).trigger(l.replace("affix","affixed")+".bs.affix")}"bottom"==r&&this.$element.offset({top:a-e-n})}};var o=t.fn.affix;t.fn.affix=e,t.fn.affix.Constructor=i,t.fn.affix.noConflict=function(){return t.fn.affix=o,this},t(window).on("load",function(){t('[data-spy="affix"]').each(function(){var i=t(this),o=i.data();o.offset=o.offset||{},null!=o.offsetBottom&&(o.offset.bottom=o.offsetBottom),null!=o.offsetTop&&(o.offset.top=o.offsetTop),e.call(i,o)})})}(jQuery),+function(t){"use strict";function e(e){var i,o=e.attr("data-target")||(i=e.attr("href"))&&i.replace(/.*(?=#[^\s]+$)/,"");return t(o)}function i(e){return this.each(function(){var i=t(this),s=i.data("bs.collapse"),n=t.extend({},o.DEFAULTS,i.data(),"object"==typeof e&&e);!s&&n.toggle&&"show"==e&&(n.toggle=!1),s||i.data("bs.collapse",s=new o(this,n)),"string"==typeof e&&s[e]()})}var o=function(e,i){this.$element=t(e),this.options=t.extend({},o.DEFAULTS,i),this.$trigger=t(this.options.trigger).filter('[href="#'+e.id+'"], [data-target="#'+e.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};o.VERSION="3.3.1",o.TRANSITION_DURATION=350,o.DEFAULTS={toggle:!0,trigger:'[data-toggle="collapse"]'},o.prototype.dimension=function(){var t=this.$element.hasClass("width");return t?"width":"height"},o.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var e,s=this.$parent&&this.$parent.find("> .panel").children(".in, .collapsing");if(!(s&&s.length&&(e=s.data("bs.collapse"),e&&e.transitioning))){var n=t.Event("show.bs.collapse");if(this.$element.trigger(n),!n.isDefaultPrevented()){s&&s.length&&(i.call(s,"hide"),e||s.data("bs.collapse",null));var a=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[a](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var r=function(){this.$element.removeClass("collapsing").addClass("collapse in")[a](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!t.support.transition)return r.call(this);var l=t.camelCase(["scroll",a].join("-"));this.$element.one("bsTransitionEnd",t.proxy(r,this)).emulateTransitionEnd(o.TRANSITION_DURATION)[a](this.$element[0][l])}}}},o.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var e=t.Event("hide.bs.collapse");if(this.$element.trigger(e),!e.isDefaultPrevented()){var i=this.dimension();this.$element[i](this.$element[i]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var s=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return t.support.transition?void this.$element[i](0).one("bsTransitionEnd",t.proxy(s,this)).emulateTransitionEnd(o.TRANSITION_DURATION):s.call(this)}}},o.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},o.prototype.getParent=function(){return t(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(t.proxy(function(i,o){var s=t(o);this.addAriaAndCollapsedClass(e(s),s)},this)).end()},o.prototype.addAriaAndCollapsedClass=function(t,e){var i=t.hasClass("in");t.attr("aria-expanded",i),e.toggleClass("collapsed",!i).attr("aria-expanded",i)};var s=t.fn.collapse;t.fn.collapse=i,t.fn.collapse.Constructor=o,t.fn.collapse.noConflict=function(){return t.fn.collapse=s,this
+},t(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(o){var s=t(this);s.attr("data-target")||o.preventDefault();var n=e(s),a=n.data("bs.collapse"),r=a?"toggle":t.extend({},s.data(),{trigger:this});i.call(n,r)})}(jQuery),+function(t){"use strict";function e(i,o){var s=t.proxy(this.process,this);this.$body=t("body"),this.$scrollElement=t(t(i).is("body")?window:i),this.options=t.extend({},e.DEFAULTS,o),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",s),this.refresh(),this.process()}function i(i){return this.each(function(){var o=t(this),s=o.data("bs.scrollspy"),n="object"==typeof i&&i;s||o.data("bs.scrollspy",s=new e(this,n)),"string"==typeof i&&s[i]()})}e.VERSION="3.3.1",e.DEFAULTS={offset:10},e.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},e.prototype.refresh=function(){var e="offset",i=0;t.isWindow(this.$scrollElement[0])||(e="position",i=this.$scrollElement.scrollTop()),this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight();var o=this;this.$body.find(this.selector).map(function(){var o=t(this),s=o.data("target")||o.attr("href"),n=/^#./.test(s)&&t(s);return n&&n.length&&n.is(":visible")&&[[n[e]().top+i,s]]||null}).sort(function(t,e){return t[0]-e[0]}).each(function(){o.offsets.push(this[0]),o.targets.push(this[1])})},e.prototype.process=function(){var t,e=this.$scrollElement.scrollTop()+this.options.offset,i=this.getScrollHeight(),o=this.options.offset+i-this.$scrollElement.height(),s=this.offsets,n=this.targets,a=this.activeTarget;if(this.scrollHeight!=i&&this.refresh(),e>=o)return a!=(t=n[n.length-1])&&this.activate(t);if(a&&e=s[t]&&(!s[t+1]||e<=s[t+1])&&this.activate(n[t])},e.prototype.activate=function(e){this.activeTarget=e,this.clear();var i=this.selector+'[data-target="'+e+'"],'+this.selector+'[href="'+e+'"]',o=t(i).parents("li").addClass("active");o.parent(".dropdown-menu").length&&(o=o.closest("li.dropdown").addClass("active")),o.trigger("activate.bs.scrollspy")},e.prototype.clear=function(){t(this.selector).parentsUntil(this.options.target,".active").removeClass("active")};var o=t.fn.scrollspy;t.fn.scrollspy=i,t.fn.scrollspy.Constructor=e,t.fn.scrollspy.noConflict=function(){return t.fn.scrollspy=o,this},t(window).on("load.bs.scrollspy.data-api",function(){t('[data-spy="scroll"]').each(function(){var e=t(this);i.call(e,e.data())})})}(jQuery),+function(t){"use strict";function e(){var t=document.createElement("bootstrap"),e={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var i in e)if(void 0!==t.style[i])return{end:e[i]};return!1}t.fn.emulateTransitionEnd=function(e){var i=!1,o=this;t(this).one("bsTransitionEnd",function(){i=!0});var s=function(){i||t(o).trigger(t.support.transition.end)};return setTimeout(s,e),this},t(function(){t.support.transition=e(),t.support.transition&&(t.event.special.bsTransitionEnd={bindType:t.support.transition.end,delegateType:t.support.transition.end,handle:function(e){return t(e.target).is(this)?e.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery);
\ No newline at end of file
diff --git a/qcloudsms/docs/js/jquery-1.11.1.min.js b/qcloudsms/docs/js/jquery-1.11.1.min.js
new file mode 100644
index 0000000..ab28a24
--- /dev/null
+++ b/qcloudsms/docs/js/jquery-1.11.1.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.11.1 | (c) 2005, 2014 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="1.11.1",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,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=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.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},m.extend=m.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||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},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=r(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(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[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=r(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&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b=a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+-new Date,v=a.document,w=0,x=0,y=gb(),z=gb(),A=gb(),B=function(a,b){return a===b&&(l=!0),0},C="undefined",D=1<<31,E={}.hasOwnProperty,F=[],G=F.pop,H=F.push,I=F.push,J=F.slice,K=F.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},L="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",N="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=N.replace("w","w#"),P="\\["+M+"*("+N+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+O+"))|)"+M+"*\\]",Q=":("+N+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+P+")*)|.*)\\)|)",R=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),S=new RegExp("^"+M+"*,"+M+"*"),T=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),V=new RegExp(Q),W=new RegExp("^"+O+"$"),X={ID:new RegExp("^#("+N+")"),CLASS:new RegExp("^\\.("+N+")"),TAG:new RegExp("^("+N.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+Q),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+L+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),db=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)};try{I.apply(F=J.call(v.childNodes),v.childNodes),F[v.childNodes.length].nodeType}catch(eb){I={apply:F.length?function(a,b){H.apply(a,J.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fb(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||[],!a||"string"!=typeof a)return d;if(1!==(k=b.nodeType)&&9!==k)return[];if(p&&!e){if(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 I.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return I.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=9===k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+qb(o[l]);w=ab.test(a)&&ob(b.parentNode)||b,x=o.join(",")}if(x)try{return I.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function gb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function hb(a){return a[u]=!0,a}function ib(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function jb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function kb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||D)-(~a.sourceIndex||D);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function lb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function nb(a){return hb(function(b){return b=+b,hb(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 ob(a){return a&&typeof a.getElementsByTagName!==C&&a}c=fb.support={},f=fb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fb.setDocument=function(a){var b,e=a?a.ownerDocument||a:v,g=e.defaultView;return e!==n&&9===e.nodeType&&e.documentElement?(n=e,o=e.documentElement,p=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){m()},!1):g.attachEvent&&g.attachEvent("onunload",function(){m()})),c.attributes=ib(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ib(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(e.getElementsByClassName)&&ib(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=ib(function(a){return o.appendChild(a).id=u,!e.getElementsByName||!e.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==C&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c=typeof a.getAttributeNode!==C&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==C?b.getElementsByTagName(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 typeof b.getElementsByClassName!==C&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(e.querySelectorAll))&&(ib(function(a){a.innerHTML=" ",a.querySelectorAll("[msallowclip^='']").length&&q.push("[*^$]="+M+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+M+"*(?:value|"+L+")"),a.querySelectorAll(":checked").length||q.push(":checked")}),ib(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+M+"*[*^$|!~]?="),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))&&ib(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",Q)}),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===e||a.ownerDocument===v&&t(v,a)?-1:b===e||b.ownerDocument===v&&t(v,b)?1:k?K.call(k,a)-K.call(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],i=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:k?K.call(k,a)-K.call(k,b):0;if(f===g)return kb(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?kb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},e):n},fb.matches=function(a,b){return fb(a,null,null,b)},fb.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 fb(b,n,null,[a]).length>0},fb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&E.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},fb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fb.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=fb.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=fb.selectors={cacheLength:50,createPseudo:hb,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(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===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]||fb.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]&&fb.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(cb,db).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("(^|"+M+")"+a+"("+M+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==C&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fb.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+" ").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()]||fb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?hb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=K.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:hb(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?hb(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),!c.pop()}}),has:hb(function(a){return function(b){return fb(a,b).length>0}}),contains:hb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:hb(function(a){return W.test(a||"")||fb.error("unsupported lang: "+a),a=a.replace(cb,db).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:nb(function(){return[0]}),last:nb(function(a,b){return[b-1]}),eq:nb(function(a,b,c){return[0>c?c+b:c]}),even:nb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:nb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:nb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:nb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function rb(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 sb(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 tb(a,b,c){for(var d=0,e=b.length;e>d;d++)fb(a,b[d],c);return c}function ub(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 vb(a,b,c,d,e,f){return d&&!d[u]&&(d=vb(d)),e&&!e[u]&&(e=vb(e,f)),hb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||tb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ub(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ub(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?K.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ub(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):I.apply(g,r)})}function wb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=rb(function(a){return a===b},h,!0),l=rb(function(a){return K.call(b,a)>-1},h,!0),m=[function(a,c,d){return!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>i;i++)if(c=d.relative[a[i].type])m=[rb(sb(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 vb(i>1&&sb(m),i>1&&qb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&wb(a.slice(i,e)),f>e&&wb(a=a.slice(e)),f>e&&qb(a))}m.push(c)}return sb(m)}function xb(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]=G.call(i));s=ub(s)}I.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&fb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?hb(f):f}return h=fb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xb(e,d)),f.selector=a}return f},i=fb.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(cb,db),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(cb,db),ab.test(j[0].type)&&ob(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qb(j),!a)return I.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&ob(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ib(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ib(function(a){return a.innerHTML=" ","#"===a.firstChild.getAttribute("href")})||jb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ib(function(a){return a.innerHTML=" ",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||jb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ib(function(a){return null==a.getAttribute("disabled")})||jb(L,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fb}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(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&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.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?m.extend(a,d):d}},e={};return d.pipe=d.then,m.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&&m.isFunction(a.promise)?e:0,g=1===f?a:m.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]&&m.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;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;
+if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.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.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.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 m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;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},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" a ",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML=" ",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function ab(){return!0}function bb(){return!1}function cb(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!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(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h ]","i"),hb=/^\s+/,ib=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,jb=/<([\w:]+)/,kb=/\s*$/g,rb={option:[1,""," "],legend:[1,""," "],area:[1,""," "],param:[1,""," "],thead:[1,""],tr:[2,""],col:[2,""],td:[3,""],_default:k.htmlSerialize?[0,"",""]:[1,"X","
"]},sb=db(y),tb=sb.appendChild(y.createElement("div"));rb.optgroup=rb.option,rb.tbody=rb.tfoot=rb.colgroup=rb.caption=rb.thead,rb.th=rb.td;function ub(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ub(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function vb(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wb(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xb(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function yb(a){var b=pb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function zb(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Ab(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Bb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xb(b).text=a.text,yb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!gb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(tb.innerHTML=a.outerHTML,tb.removeChild(f=tb.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ub(f),h=ub(a),g=0;null!=(e=h[g]);++g)d[g]&&Bb(e,d[g]);if(b)if(c)for(h=h||ub(a),d=d||ub(f),g=0;null!=(e=h[g]);g++)Ab(e,d[g]);else Ab(a,f);return d=ub(f,"script"),d.length>0&&zb(d,!i&&ub(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=db(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(lb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(jb.exec(f)||["",""])[1].toLowerCase(),l=rb[i]||rb._default,h.innerHTML=l[1]+f.replace(ib,"<$1>$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&hb.test(f)&&p.push(b.createTextNode(hb.exec(f)[0])),!k.tbody){f="table"!==i||kb.test(f)?""!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(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=wb(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=wb(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?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(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,m.cleanData(ub(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,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.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+""}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" a ",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.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",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight)),b.innerHTML="",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.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 Mb=/alpha\([^)]*\)/i,Nb=/opacity\s*=\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp("^("+S+")(.*)$","i"),Qb=new RegExp("^([+-])=("+S+")","i"),Rb={position:"absolute",visibility:"hidden",display:"block"},Sb={letterSpacing:"0",fontWeight:"400"},Tb=["Webkit","O","Moz","ms"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fb(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.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}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xb(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+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Yb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(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":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.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)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),"normal"===f&&b in Sb&&(f=Sb[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Mb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+" "+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Jb,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e)}m.Tween=Zb,Zb.prototype={constructor:Zb,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||(m.cssNumber[c]?"":"px")
+},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):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):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.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,m.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 fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.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 kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),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:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.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(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.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)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(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=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.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)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.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})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc("show"),slideUp:gc("hide"),slideToggle:gc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();ca ",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lc=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lc,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.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&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.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 m.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=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.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||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.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){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var uc=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.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(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(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(uc," ").indexOf(b)>=0)return!0;return!1}}),m.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){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.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 vc=m.now(),wc=/\?/,xc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\/\//,Gc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hc={},Ic={},Jc="*/".concat("*");try{zc=location.href}catch(Kc){zc=y.createElement("a"),zc.href="",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.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 Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(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}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:"GET",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jc,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":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f: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 i&&i.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||zc)+"").replace(Ac,"").replace(Fc,yc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yc[3]||("http:"===yc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,"$1_="+vc++):e+(wc.test(e)?"&":"?")+"_="+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(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]?", "+Jc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=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,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\[\]$/,Sc=/\r?\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vc(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join("&").replace(Qc,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,"\r\n")}}):{name:b.name,value:c.replace(Sc,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.ActiveXObject&&m(a).on("unload",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&"withCredentials"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;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)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_c.pop()||m.expando+"_"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ad.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,"$1"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.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,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.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?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});
diff --git a/qcloudsms/docs/js/typeahead.min.js b/qcloudsms/docs/js/typeahead.min.js
new file mode 100644
index 0000000..47c2f02
--- /dev/null
+++ b/qcloudsms/docs/js/typeahead.min.js
@@ -0,0 +1,6 @@
+/*!
+ * typeahead.js 0.10.5
+ * https://github.com/twitter/typeahead.js
+ * Copyright 2013-2014 Twitter, Inc. and other contributors; Licensed MIT
+ */
+!function(t){var e=function(){"use strict";return{isMsie:function(){return/(msie|trident)/i.test(navigator.userAgent)?navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2]:!1},isBlankString:function(t){return!t||/^\s*$/.test(t)},escapeRegExChars:function(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isString:function(t){return"string"==typeof t},isNumber:function(t){return"number"==typeof t},isArray:t.isArray,isFunction:t.isFunction,isObject:t.isPlainObject,isUndefined:function(t){return"undefined"==typeof t},toStr:function(t){return e.isUndefined(t)||null===t?"":t+""},bind:t.proxy,each:function(e,n){function i(t,e){return n(e,t)}t.each(e,i)},map:t.map,filter:t.grep,every:function(e,n){var i=!0;return e?(t.each(e,function(t,r){return(i=n.call(null,r,t,e))?void 0:!1}),!!i):i},some:function(e,n){var i=!1;return e?(t.each(e,function(t,r){return(i=n.call(null,r,t,e))?!1:void 0}),!!i):i},mixin:t.extend,getUniqueId:function(){var t=0;return function(){return t++}}(),templatify:function(e){function n(){return String(e)}return t.isFunction(e)?e:n},defer:function(t){setTimeout(t,0)},debounce:function(t,e,n){var i,r;return function(){var s,o,u=this,a=arguments;return s=function(){i=null,n||(r=t.apply(u,a))},o=n&&!i,clearTimeout(i),i=setTimeout(s,e),o&&(r=t.apply(u,a)),r}},throttle:function(t,e){var n,i,r,s,o,u;return o=0,u=function(){o=new Date,r=null,s=t.apply(n,i)},function(){var a=new Date,c=e-(a-o);return n=this,i=arguments,0>=c?(clearTimeout(r),r=null,o=a,s=t.apply(n,i)):r||(r=setTimeout(u,c)),s}},noop:function(){}}}(),n="0.10.5",i=function(){"use strict";function t(t){return t=e.toStr(t),t?t.split(/\s+/):[]}function n(t){return t=e.toStr(t),t?t.split(/\W+/):[]}function i(t){return function(){var n=[].slice.call(arguments,0);return function(i){var r=[];return e.each(n,function(n){r=r.concat(t(e.toStr(i[n])))}),r}}}return{nonword:n,whitespace:t,obj:{nonword:i(n),whitespace:i(t)}}}(),r=function(){"use strict";function n(n){this.maxSize=e.isNumber(n)?n:100,this.reset(),this.maxSize<=0&&(this.set=this.get=t.noop)}function i(){this.head=this.tail=null}function r(t,e){this.key=t,this.val=e,this.prev=this.next=null}return e.mixin(n.prototype,{set:function(t,e){var n,i=this.list.tail;this.size>=this.maxSize&&(this.list.remove(i),delete this.hash[i.key]),(n=this.hash[t])?(n.val=e,this.list.moveToFront(n)):(n=new r(t,e),this.list.add(n),this.hash[t]=n,this.size++)},get:function(t){var e=this.hash[t];return e?(this.list.moveToFront(e),e.val):void 0},reset:function(){this.size=0,this.hash={},this.list=new i}}),e.mixin(i.prototype,{add:function(t){this.head&&(t.next=this.head,this.head.prev=t),this.head=t,this.tail=this.tail||t},remove:function(t){t.prev?t.prev.next=t.next:this.head=t.next,t.next?t.next.prev=t.prev:this.tail=t.prev},moveToFront:function(t){this.remove(t),this.add(t)}}),n}(),s=function(){"use strict";function t(t){this.prefix=["__",t,"__"].join(""),this.ttlKey="__ttl__",this.keyMatcher=new RegExp("^"+e.escapeRegExChars(this.prefix))}function n(){return(new Date).getTime()}function i(t){return JSON.stringify(e.isUndefined(t)?null:t)}function r(t){return JSON.parse(t)}var s,o;try{s=window.localStorage,s.setItem("~~~","!"),s.removeItem("~~~")}catch(u){s=null}return o=s&&window.JSON?{_prefix:function(t){return this.prefix+t},_ttlKey:function(t){return this._prefix(t)+this.ttlKey},get:function(t){return this.isExpired(t)&&this.remove(t),r(s.getItem(this._prefix(t)))},set:function(t,r,o){return e.isNumber(o)?s.setItem(this._ttlKey(t),i(n()+o)):s.removeItem(this._ttlKey(t)),s.setItem(this._prefix(t),i(r))},remove:function(t){return s.removeItem(this._ttlKey(t)),s.removeItem(this._prefix(t)),this},clear:function(){var t,e,n=[],i=s.length;for(t=0;i>t;t++)(e=s.key(t)).match(this.keyMatcher)&&n.push(e.replace(this.keyMatcher,""));for(t=n.length;t--;)this.remove(n[t]);return this},isExpired:function(t){var i=r(s.getItem(this._ttlKey(t)));return e.isNumber(i)&&n()>i?!0:!1}}:{get:e.noop,set:e.noop,remove:e.noop,clear:e.noop,isExpired:e.noop},e.mixin(t.prototype,o),t}(),o=function(){"use strict";function n(e){e=e||{},this.cancelled=!1,this.lastUrl=null,this._send=e.transport?i(e.transport):t.ajax,this._get=e.rateLimiter?e.rateLimiter(this._get):this._get,this._cache=e.cache===!1?new r(0):a}function i(n){return function(i,r){function s(t){e.defer(function(){u.resolve(t)})}function o(t){e.defer(function(){u.reject(t)})}var u=t.Deferred();return n(i,r,s,o),u}}var s=0,o={},u=6,a=new r(10);return n.setMaxPendingRequests=function(t){u=t},n.resetCache=function(){a.reset()},e.mixin(n.prototype,{_get:function(t,e,n){function i(e){n&&n(null,e),h._cache.set(t,e)}function r(){n&&n(!0)}function a(){s--,delete o[t],h.onDeckRequestArgs&&(h._get.apply(h,h.onDeckRequestArgs),h.onDeckRequestArgs=null)}var c,h=this;this.cancelled||t!==this.lastUrl||((c=o[t])?c.done(i).fail(r):u>s?(s++,o[t]=this._send(t,e).done(i).fail(r).always(a)):this.onDeckRequestArgs=[].slice.call(arguments,0))},get:function(t,n,i){var r;return e.isFunction(n)&&(i=n,n={}),this.cancelled=!1,this.lastUrl=t,(r=this._cache.get(t))?e.defer(function(){i&&i(null,r)}):this._get(t,n,i),!!r},cancel:function(){this.cancelled=!0}}),n}(),u=function(){"use strict";function n(e){e=e||{},e.datumTokenizer&&e.queryTokenizer||t.error("datumTokenizer and queryTokenizer are both required"),this.datumTokenizer=e.datumTokenizer,this.queryTokenizer=e.queryTokenizer,this.reset()}function i(t){return t=e.filter(t,function(t){return!!t}),t=e.map(t,function(t){return t.toLowerCase()})}function r(){return{ids:[],children:{}}}function s(t){for(var e={},n=[],i=0,r=t.length;r>i;i++)e[t[i]]||(e[t[i]]=!0,n.push(t[i]));return n}function o(t,e){function n(t,e){return t-e}var i=0,r=0,s=[];t=t.sort(n),e=e.sort(n);for(var o=t.length,u=e.length;o>i&&u>r;)t[i]
e[r]?r++:(s.push(t[i]),i++,r++);return s}return e.mixin(n.prototype,{bootstrap:function(t){this.datums=t.datums,this.trie=t.trie},add:function(t){var n=this;t=e.isArray(t)?t:[t],e.each(t,function(t){var s,o;s=n.datums.push(t)-1,o=i(n.datumTokenizer(t)),e.each(o,function(t){var e,i,o;for(e=n.trie,i=t.split("");o=i.shift();)e=e.children[o]||(e.children[o]=r()),e.ids.push(s)})})},get:function(t){var n,r,u=this;return n=i(this.queryTokenizer(t)),e.each(n,function(t){var e,n,i,s;if(r&&0===r.length)return!1;for(e=u.trie,n=t.split("");e&&(i=n.shift());)e=e.children[i];return e&&0===n.length?(s=e.ids.slice(0),void(r=r?o(r,s):s)):(r=[],!1)}),r?e.map(s(r),function(t){return u.datums[t]}):[]},reset:function(){this.datums=[],this.trie=r()},serialize:function(){return{datums:this.datums,trie:this.trie}}}),n}(),a=function(){"use strict";function i(t){return t.local||null}function r(i){var r,s;return s={url:null,thumbprint:"",ttl:864e5,filter:null,ajax:{}},(r=i.prefetch||null)&&(r=e.isString(r)?{url:r}:r,r=e.mixin(s,r),r.thumbprint=n+r.thumbprint,r.ajax.type=r.ajax.type||"GET",r.ajax.dataType=r.ajax.dataType||"json",!r.url&&t.error("prefetch requires url to be set")),r}function s(n){function i(t){return function(n){return e.debounce(n,t)}}function r(t){return function(n){return e.throttle(n,t)}}var s,o;return o={url:null,cache:!0,wildcard:"%QUERY",replace:null,rateLimitBy:"debounce",rateLimitWait:300,send:null,filter:null,ajax:{}},(s=n.remote||null)&&(s=e.isString(s)?{url:s}:s,s=e.mixin(o,s),s.rateLimiter=/^throttle$/i.test(s.rateLimitBy)?r(s.rateLimitWait):i(s.rateLimitWait),s.ajax.type=s.ajax.type||"GET",s.ajax.dataType=s.ajax.dataType||"json",delete s.rateLimitBy,delete s.rateLimitWait,!s.url&&t.error("remote requires url to be set")),s}return{local:i,prefetch:r,remote:s}}();!function(n){"use strict";function r(e){e&&(e.local||e.prefetch||e.remote)||t.error("one of local, prefetch, or remote is required"),this.limit=e.limit||5,this.sorter=c(e.sorter),this.dupDetector=e.dupDetector||h,this.local=a.local(e),this.prefetch=a.prefetch(e),this.remote=a.remote(e),this.cacheKey=this.prefetch?this.prefetch.cacheKey||this.prefetch.url:null,this.index=new u({datumTokenizer:e.datumTokenizer,queryTokenizer:e.queryTokenizer}),this.storage=this.cacheKey?new s(this.cacheKey):null}function c(t){function n(e){return e.sort(t)}function i(t){return t}return e.isFunction(t)?n:i}function h(){return!1}var l,d;return l=n.Bloodhound,d={data:"data",protocol:"protocol",thumbprint:"thumbprint"},n.Bloodhound=r,r.noConflict=function(){return n.Bloodhound=l,r},r.tokenizers=i,e.mixin(r.prototype,{_loadPrefetch:function(e){function n(t){s.clear(),s.add(e.filter?e.filter(t):t),s._saveToStorage(s.index.serialize(),e.thumbprint,e.ttl)}var i,r,s=this;return(i=this._readFromStorage(e.thumbprint))?(this.index.bootstrap(i),r=t.Deferred().resolve()):r=t.ajax(e.url,e.ajax).done(n),r},_getFromRemote:function(t,e){function n(t,n){e(t?[]:s.remote.filter?s.remote.filter(n):n)}var i,r,s=this;if(this.transport)return t=t||"",r=encodeURIComponent(t),i=this.remote.replace?this.remote.replace(this.remote.url,t):this.remote.url.replace(this.remote.wildcard,r),this.transport.get(i,this.remote.ajax,n)},_cancelLastRemoteRequest:function(){this.transport&&this.transport.cancel()},_saveToStorage:function(t,e,n){this.storage&&(this.storage.set(d.data,t,n),this.storage.set(d.protocol,location.protocol,n),this.storage.set(d.thumbprint,e,n))},_readFromStorage:function(t){var e,n={};return this.storage&&(n.data=this.storage.get(d.data),n.protocol=this.storage.get(d.protocol),n.thumbprint=this.storage.get(d.thumbprint)),e=n.thumbprint!==t||n.protocol!==location.protocol,n.data&&!e?n.data:null},_initialize:function(){function n(){r.add(e.isFunction(s)?s():s)}var i,r=this,s=this.local;return i=this.prefetch?this._loadPrefetch(this.prefetch):t.Deferred().resolve(),s&&i.done(n),this.transport=this.remote?new o(this.remote):null,this.initPromise=i.promise()},initialize:function(t){return!this.initPromise||t?this._initialize():this.initPromise},add:function(t){this.index.add(t)},get:function(t,n){function i(t){var i=s.slice(0);e.each(t,function(t){var n;return n=e.some(i,function(e){return r.dupDetector(t,e)}),!n&&i.push(t),i.length0||!this.transport)&&n&&n(s)},clear:function(){this.index.reset()},clearPrefetchCache:function(){this.storage&&this.storage.clear()},clearRemoteCache:function(){this.transport&&o.resetCache()},ttAdapter:function(){return e.bind(this.get,this)}}),r}(this);var c=function(){return{wrapper:'',dropdown:'',dataset:'
',suggestions:' ',suggestion:'
'}}(),h=function(){"use strict";var t={wrapper:{position:"relative",display:"inline-block"},hint:{position:"absolute",top:"0",left:"0",borderColor:"transparent",boxShadow:"none",opacity:"1"},input:{position:"relative",verticalAlign:"top",backgroundColor:"transparent"},inputWithNoHint:{position:"relative",verticalAlign:"top"},dropdown:{position:"absolute",top:"100%",left:"0",zIndex:"100",display:"none"},suggestions:{display:"block"},suggestion:{whiteSpace:"nowrap",cursor:"pointer"},suggestionChild:{whiteSpace:"normal"},ltr:{left:"0",right:"auto"},rtl:{left:"auto",right:" 0"}};return e.isMsie()&&e.mixin(t.input,{backgroundImage:"url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)"}),e.isMsie()&&e.isMsie()<=7&&e.mixin(t.input,{marginTop:"-1px"}),t}(),l=function(){"use strict";function n(e){e&&e.el||t.error("EventBus initialized without el"),this.$el=t(e.el)}var i="typeahead:";return e.mixin(n.prototype,{trigger:function(t){var e=[].slice.call(arguments,1);this.$el.trigger(i+t,e)}}),n}(),d=function(){"use strict";function t(t,e,n,i){var r;if(!n)return this;for(e=e.split(a),n=i?u(n,i):n,this._callbacks=this._callbacks||{};r=e.shift();)this._callbacks[r]=this._callbacks[r]||{sync:[],async:[]},this._callbacks[r][t].push(n);return this}function e(e,n,i){return t.call(this,"async",e,n,i)}function n(e,n,i){return t.call(this,"sync",e,n,i)}function i(t){var e;if(!this._callbacks)return this;for(t=t.split(a);e=t.shift();)delete this._callbacks[e];return this}function r(t){var e,n,i,r,o;if(!this._callbacks)return this;for(t=t.split(a),i=[].slice.call(arguments,1);(e=t.shift())&&(n=this._callbacks[e]);)r=s(n.sync,this,[e].concat(i)),o=s(n.async,this,[e].concat(i)),r()&&c(o);return this}function s(t,e,n){function i(){for(var i,r=0,s=t.length;!i&&s>r;r+=1)i=t[r].apply(e,n)===!1;return!i}return i}function o(){var t;return t=window.setImmediate?function(t){setImmediate(function(){t()})}:function(t){setTimeout(function(){t()},0)}}function u(t,e){return t.bind?t.bind(e):function(){t.apply(e,[].slice.call(arguments,0))}}var a=/\s+/,c=o();return{onSync:n,onAsync:e,off:i,trigger:r}}(),p=function(t){"use strict";function n(t,n,i){for(var r,s=[],o=0,u=t.length;u>o;o++)s.push(e.escapeRegExChars(t[o]));return r=i?"\\b("+s.join("|")+")\\b":"("+s.join("|")+")",n?new RegExp(r):new RegExp(r,"i")}var i={node:null,pattern:null,tagName:"strong",className:null,wordsOnly:!1,caseSensitive:!1};return function(r){function s(e){var n,i,s;return(n=u.exec(e.data))&&(s=t.createElement(r.tagName),r.className&&(s.className=r.className),i=e.splitText(n.index),i.splitText(n[0].length),s.appendChild(i.cloneNode(!0)),e.parentNode.replaceChild(s,i)),!!n}function o(t,e){for(var n,i=3,r=0;r').css({position:"absolute",visibility:"hidden",whiteSpace:"pre",fontFamily:e.css("font-family"),fontSize:e.css("font-size"),fontStyle:e.css("font-style"),fontVariant:e.css("font-variant"),fontWeight:e.css("font-weight"),wordSpacing:e.css("word-spacing"),letterSpacing:e.css("letter-spacing"),textIndent:e.css("text-indent"),textRendering:e.css("text-rendering"),textTransform:e.css("text-transform")}).insertAfter(e)}function r(t,e){return n.normalizeQuery(t)===n.normalizeQuery(e)}function s(t){return t.altKey||t.ctrlKey||t.metaKey||t.shiftKey}var o;return o={9:"tab",27:"esc",37:"left",39:"right",13:"enter",38:"up",40:"down"},n.normalizeQuery=function(t){return(t||"").replace(/^\s*/g,"").replace(/\s{2,}/g," ")},e.mixin(n.prototype,d,{_onBlur:function(){this.resetInputValue(),this.trigger("blurred")},_onFocus:function(){this.trigger("focused")},_onKeydown:function(t){var e=o[t.which||t.keyCode];this._managePreventDefault(e,t),e&&this._shouldTrigger(e,t)&&this.trigger(e+"Keyed",t)},_onInput:function(){this._checkInputValue()},_managePreventDefault:function(t,e){var n,i,r;switch(t){case"tab":i=this.getHint(),r=this.getInputValue(),n=i&&i!==r&&!s(e);break;case"up":case"down":n=!s(e);break;default:n=!1}n&&e.preventDefault()},_shouldTrigger:function(t,e){var n;switch(t){case"tab":n=!s(e);break;default:n=!0}return n},_checkInputValue:function(){var t,e,n;t=this.getInputValue(),e=r(t,this.query),n=e?this.query.length!==t.length:!1,this.query=t,e?n&&this.trigger("whitespaceChanged",this.query):this.trigger("queryChanged",this.query)},focus:function(){this.$input.focus()},blur:function(){this.$input.blur()},getQuery:function(){return this.query},setQuery:function(t){this.query=t},getInputValue:function(){return this.$input.val()},setInputValue:function(t,e){this.$input.val(t),e?this.clearHint():this._checkInputValue()},resetInputValue:function(){this.setInputValue(this.query,!0)},getHint:function(){return this.$hint.val()},setHint:function(t){this.$hint.val(t)},clearHint:function(){this.setHint("")},clearHintIfInvalid:function(){var t,e,n,i;t=this.getInputValue(),e=this.getHint(),n=t!==e&&0===e.indexOf(t),i=""!==t&&n&&!this.hasOverflow(),!i&&this.clearHint()},getLanguageDirection:function(){return(this.$input.css("direction")||"ltr").toLowerCase()},hasOverflow:function(){var t=this.$input.width()-2;return this.$overflowHelper.text(this.getInputValue()),this.$overflowHelper.width()>=t},isCursorAtEnd:function(){var t,n,i;return t=this.$input.val().length,n=this.$input[0].selectionStart,e.isNumber(n)?n===t:document.selection?(i=document.selection.createRange(),i.moveStart("character",-t),t===i.text.length):!0},destroy:function(){this.$hint.off(".tt"),this.$input.off(".tt"),this.$hint=this.$input=this.$overflowHelper=null}}),n}(),g=function(){"use strict";function n(n){n=n||{},n.templates=n.templates||{},n.source||t.error("missing source"),n.name&&!s(n.name)&&t.error("invalid dataset name: "+n.name),this.query=null,this.highlight=!!n.highlight,this.name=n.name||e.getUniqueId(),this.source=n.source,this.displayFn=i(n.display||n.displayKey),this.templates=r(n.templates,this.displayFn),this.$el=t(c.dataset.replace("%CLASS%",this.name))}function i(t){function n(e){return e[t]}return t=t||"value",e.isFunction(t)?t:n}function r(t,n){function i(t){return""+n(t)+"
"}return{empty:t.empty&&e.templatify(t.empty),header:t.header&&e.templatify(t.header),footer:t.footer&&e.templatify(t.footer),suggestion:t.suggestion||i}}function s(t){return/^[_a-zA-Z0-9-]+$/.test(t)}var o="ttDataset",u="ttValue",a="ttDatum";return n.extractDatasetName=function(e){return t(e).data(o)},n.extractValue=function(e){return t(e).data(u)},n.extractDatum=function(e){return t(e).data(a)},e.mixin(n.prototype,d,{_render:function(n,i){function r(){return g.templates.empty({query:n,isEmpty:!0})}function s(){function r(e){var n;return n=t(c.suggestion).append(g.templates.suggestion(e)).data(o,g.name).data(u,g.displayFn(e)).data(a,e),n.children().each(function(){t(this).css(h.suggestionChild)}),n}var s,l;return s=t(c.suggestions).css(h.suggestions),l=e.map(i,r),s.append.apply(s,l),g.highlight&&p({className:"tt-highlight",node:s[0],pattern:n}),s}function l(){return g.templates.header({query:n,isEmpty:!f})}function d(){return g.templates.footer({query:n,isEmpty:!f})}if(this.$el){var f,g=this;this.$el.empty(),f=i&&i.length,!f&&this.templates.empty?this.$el.html(r()).prepend(g.templates.header?l():null).append(g.templates.footer?d():null):f&&this.$el.html(s()).prepend(g.templates.header?l():null).append(g.templates.footer?d():null),this.trigger("rendered")}},getRoot:function(){return this.$el},update:function(t){function e(e){n.canceled||t!==n.query||n._render(t,e)}var n=this;this.query=t,this.canceled=!1,this.source(t,e)},cancel:function(){this.canceled=!0},clear:function(){this.cancel(),this.$el.empty(),this.trigger("rendered")},isEmpty:function(){return this.$el.is(":empty")},destroy:function(){this.$el=null}}),n}(),m=function(){"use strict";function n(n){var r,s,o,u=this;n=n||{},n.menu||t.error("menu is required"),this.isOpen=!1,this.isEmpty=!0,this.datasets=e.map(n.datasets,i),r=e.bind(this._onSuggestionClick,this),s=e.bind(this._onSuggestionMouseEnter,this),o=e.bind(this._onSuggestionMouseLeave,this),this.$menu=t(n.menu).on("click.tt",".tt-suggestion",r).on("mouseenter.tt",".tt-suggestion",s).on("mouseleave.tt",".tt-suggestion",o),e.each(this.datasets,function(t){u.$menu.append(t.getRoot()),t.onSync("rendered",u._onRendered,u)})}function i(t){return new g(t)}return e.mixin(n.prototype,d,{_onSuggestionClick:function(e){this.trigger("suggestionClicked",t(e.currentTarget))},_onSuggestionMouseEnter:function(e){this._removeCursor(),this._setCursor(t(e.currentTarget),!0)},_onSuggestionMouseLeave:function(){this._removeCursor()},_onRendered:function(){function t(t){return t.isEmpty()}this.isEmpty=e.every(this.datasets,t),this.isEmpty?this._hide():this.isOpen&&this._show(),this.trigger("datasetRendered")},_hide:function(){this.$menu.hide()},_show:function(){this.$menu.css("display","block")},_getSuggestions:function(){return this.$menu.find(".tt-suggestion")},_getCursor:function(){return this.$menu.find(".tt-cursor").first()},_setCursor:function(t,e){t.first().addClass("tt-cursor"),!e&&this.trigger("cursorMoved")},_removeCursor:function(){this._getCursor().removeClass("tt-cursor")},_moveCursor:function(t){var e,n,i,r;if(this.isOpen){if(n=this._getCursor(),e=this._getSuggestions(),this._removeCursor(),i=e.index(n)+t,i=(i+1)%(e.length+1)-1,-1===i)return void this.trigger("cursorRemoved");-1>i&&(i=e.length-1),this._setCursor(r=e.eq(i)),this._ensureVisible(r)}},_ensureVisible:function(t){var e,n,i,r;e=t.position().top,n=e+t.outerHeight(!0),i=this.$menu.scrollTop(),r=this.$menu.height()+parseInt(this.$menu.css("paddingTop"),10)+parseInt(this.$menu.css("paddingBottom"),10),0>e?this.$menu.scrollTop(i+e):n>r&&this.$menu.scrollTop(i+(n-r))},close:function(){this.isOpen&&(this.isOpen=!1,this._removeCursor(),this._hide(),this.trigger("closed"))},open:function(){this.isOpen||(this.isOpen=!0,!this.isEmpty&&this._show(),this.trigger("opened"))},setLanguageDirection:function(t){this.$menu.css("ltr"===t?h.ltr:h.rtl)},moveCursorUp:function(){this._moveCursor(-1)},moveCursorDown:function(){this._moveCursor(1)},getDatumForSuggestion:function(t){var e=null;return t.length&&(e={raw:g.extractDatum(t),value:g.extractValue(t),datasetName:g.extractDatasetName(t)}),e},getDatumForCursor:function(){return this.getDatumForSuggestion(this._getCursor().first())},getDatumForTopSuggestion:function(){return this.getDatumForSuggestion(this._getSuggestions().first())},update:function(t){function n(e){e.update(t)}e.each(this.datasets,n)},empty:function(){function t(t){t.clear()}e.each(this.datasets,t),this.isEmpty=!0},isVisible:function(){return this.isOpen&&!this.isEmpty},destroy:function(){function t(t){t.destroy()}this.$menu.off(".tt"),this.$menu=null,e.each(this.datasets,t)}}),n}(),y=function(){"use strict";function n(n){var r,s,o;n=n||{},n.input||t.error("missing input"),this.isActivated=!1,this.autoselect=!!n.autoselect,this.minLength=e.isNumber(n.minLength)?n.minLength:1,this.$node=i(n.input,n.withHint),r=this.$node.find(".tt-dropdown-menu"),s=this.$node.find(".tt-input"),o=this.$node.find(".tt-hint"),s.on("blur.tt",function(t){var n,i,o;n=document.activeElement,i=r.is(n),o=r.has(n).length>0,e.isMsie()&&(i||o)&&(t.preventDefault(),t.stopImmediatePropagation(),e.defer(function(){s.focus()}))}),r.on("mousedown.tt",function(t){t.preventDefault()}),this.eventBus=n.eventBus||new l({el:s}),this.dropdown=new m({menu:r,datasets:n.datasets}).onSync("suggestionClicked",this._onSuggestionClicked,this).onSync("cursorMoved",this._onCursorMoved,this).onSync("cursorRemoved",this._onCursorRemoved,this).onSync("opened",this._onOpened,this).onSync("closed",this._onClosed,this).onAsync("datasetRendered",this._onDatasetRendered,this),this.input=new f({input:s,hint:o}).onSync("focused",this._onFocused,this).onSync("blurred",this._onBlurred,this).onSync("enterKeyed",this._onEnterKeyed,this).onSync("tabKeyed",this._onTabKeyed,this).onSync("escKeyed",this._onEscKeyed,this).onSync("upKeyed",this._onUpKeyed,this).onSync("downKeyed",this._onDownKeyed,this).onSync("leftKeyed",this._onLeftKeyed,this).onSync("rightKeyed",this._onRightKeyed,this).onSync("queryChanged",this._onQueryChanged,this).onSync("whitespaceChanged",this._onWhitespaceChanged,this),this._setLanguageDirection()}function i(e,n){var i,s,u,a;i=t(e),s=t(c.wrapper).css(h.wrapper),u=t(c.dropdown).css(h.dropdown),a=i.clone().css(h.hint).css(r(i)),a.val("").removeData().addClass("tt-hint").removeAttr("id name placeholder required").prop("readonly",!0).attr({autocomplete:"off",spellcheck:"false",tabindex:-1}),i.data(o,{dir:i.attr("dir"),autocomplete:i.attr("autocomplete"),spellcheck:i.attr("spellcheck"),style:i.attr("style")}),i.addClass("tt-input").attr({autocomplete:"off",spellcheck:!1}).css(n?h.input:h.inputWithNoHint);try{!i.attr("dir")&&i.attr("dir","auto")}catch(l){}return i.wrap(s).parent().prepend(n?a:null).append(u)}function r(t){return{backgroundAttachment:t.css("background-attachment"),backgroundClip:t.css("background-clip"),backgroundColor:t.css("background-color"),backgroundImage:t.css("background-image"),backgroundOrigin:t.css("background-origin"),backgroundPosition:t.css("background-position"),backgroundRepeat:t.css("background-repeat"),backgroundSize:t.css("background-size")}}function s(t){var n=t.find(".tt-input");e.each(n.data(o),function(t,i){e.isUndefined(t)?n.removeAttr(i):n.attr(i,t)}),n.detach().removeData(o).removeClass("tt-input").insertAfter(t),t.remove()}var o="ttAttrs";return e.mixin(n.prototype,{_onSuggestionClicked:function(t,e){var n;(n=this.dropdown.getDatumForSuggestion(e))&&this._select(n)},_onCursorMoved:function(){var t=this.dropdown.getDatumForCursor();this.input.setInputValue(t.value,!0),this.eventBus.trigger("cursorchanged",t.raw,t.datasetName)},_onCursorRemoved:function(){this.input.resetInputValue(),this._updateHint()},_onDatasetRendered:function(){this._updateHint()},_onOpened:function(){this._updateHint(),this.eventBus.trigger("opened")},_onClosed:function(){this.input.clearHint(),this.eventBus.trigger("closed")},_onFocused:function(){this.isActivated=!0,this.dropdown.open()},_onBlurred:function(){this.isActivated=!1,this.dropdown.empty(),this.dropdown.close()},_onEnterKeyed:function(t,e){var n,i;n=this.dropdown.getDatumForCursor(),i=this.dropdown.getDatumForTopSuggestion(),n?(this._select(n),e.preventDefault()):this.autoselect&&i&&(this._select(i),e.preventDefault())},_onTabKeyed:function(t,e){var n;(n=this.dropdown.getDatumForCursor())?(this._select(n),e.preventDefault()):this._autocomplete(!0)},_onEscKeyed:function(){this.dropdown.close(),this.input.resetInputValue()},_onUpKeyed:function(){var t=this.input.getQuery();this.dropdown.isEmpty&&t.length>=this.minLength?this.dropdown.update(t):this.dropdown.moveCursorUp(),this.dropdown.open()},_onDownKeyed:function(){var t=this.input.getQuery();this.dropdown.isEmpty&&t.length>=this.minLength?this.dropdown.update(t):this.dropdown.moveCursorDown(),this.dropdown.open()},_onLeftKeyed:function(){"rtl"===this.dir&&this._autocomplete()},_onRightKeyed:function(){"ltr"===this.dir&&this._autocomplete()},_onQueryChanged:function(t,e){this.input.clearHintIfInvalid(),e.length>=this.minLength?this.dropdown.update(e):this.dropdown.empty(),this.dropdown.open(),this._setLanguageDirection()},_onWhitespaceChanged:function(){this._updateHint(),this.dropdown.open()},_setLanguageDirection:function(){var t;this.dir!==(t=this.input.getLanguageDirection())&&(this.dir=t,this.$node.css("direction",t),this.dropdown.setLanguageDirection(t))},_updateHint:function(){var t,n,i,r,s,o;t=this.dropdown.getDatumForTopSuggestion(),t&&this.dropdown.isVisible()&&!this.input.hasOverflow()?(n=this.input.getInputValue(),i=f.normalizeQuery(n),r=e.escapeRegExChars(i),s=new RegExp("^(?:"+r+")(.+$)","i"),o=s.exec(t.value),o?this.input.setHint(n+o[1]):this.input.clearHint()):this.input.clearHint()},_autocomplete:function(t){var e,n,i,r;e=this.input.getHint(),n=this.input.getQuery(),i=t||this.input.isCursorAtEnd(),e&&n!==e&&i&&(r=this.dropdown.getDatumForTopSuggestion(),r&&this.input.setInputValue(r.value),this.eventBus.trigger("autocompleted",r.raw,r.datasetName))},_select:function(t){this.input.setQuery(t.value),this.input.setInputValue(t.value,!0),this._setLanguageDirection(),this.eventBus.trigger("selected",t.raw,t.datasetName),this.dropdown.close(),e.defer(e.bind(this.dropdown.empty,this.dropdown))},open:function(){this.dropdown.open()},close:function(){this.dropdown.close()},setVal:function(t){t=e.toStr(t),this.isActivated?this.input.setInputValue(t):(this.input.setQuery(t),this.input.setInputValue(t,!0)),this._setLanguageDirection()},getVal:function(){return this.input.getQuery()},destroy:function(){this.input.destroy(),this.dropdown.destroy(),s(this.$node),this.$node=null}}),n}();!function(){"use strict";var n,i,r;n=t.fn.typeahead,i="ttTypeahead",r={initialize:function(n,r){function s(){var s,o,u=t(this);e.each(r,function(t){t.highlight=!!n.highlight}),o=new y({input:u,eventBus:s=new l({el:u}),withHint:e.isUndefined(n.hint)?!0:!!n.hint,minLength:n.minLength,autoselect:n.autoselect,datasets:r}),u.data(i,o)}return r=e.isArray(r)?r:[].slice.call(arguments,1),n=n||{},this.each(s)},open:function(){function e(){var e,n=t(this);(e=n.data(i))&&e.open()}return this.each(e)},close:function(){function e(){var e,n=t(this);(e=n.data(i))&&e.close()}return this.each(e)},val:function(e){function n(){var n,r=t(this);(n=r.data(i))&&n.setVal(e)}function r(t){var e,n;return(e=t.data(i))&&(n=e.getVal()),n}return arguments.length?this.each(n):r(this.first())},destroy:function(){function e(){var e,n=t(this);(e=n.data(i))&&(e.destroy(),n.removeData(i))}return this.each(e)}},t.fn.typeahead=function(e){var n;return r[e]&&"initialize"!==e?(n=this.filter(function(){return!!t(this).data(i)}),r[e].apply(n,[].slice.call(arguments,1))):r.initialize.apply(this,arguments)},t.fn.typeahead.noConflict=function(){return t.fn.typeahead=n,this}}()}(window.jQuery);
diff --git a/qcloudsms/docs/namespaces.html b/qcloudsms/docs/namespaces.html
new file mode 100644
index 0000000..85d3a88
--- /dev/null
+++ b/qcloudsms/docs/namespaces.html
@@ -0,0 +1,90 @@
+
+
+
+
+
+ Namespaces | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/opensearch.xml b/qcloudsms/docs/opensearch.xml
new file mode 100644
index 0000000..e69de29
diff --git a/qcloudsms/docs/renderer.index b/qcloudsms/docs/renderer.index
new file mode 100644
index 0000000..037adcc
--- /dev/null
+++ b/qcloudsms/docs/renderer.index
@@ -0,0 +1 @@
+C:19:"Sami\Renderer\Index":931:{a:3:{i:0;a:10:{s:26:"Qcloud\Sms\FileVoiceSender";s:40:"95a81dc5f7ec5f7554576b5996b86083cdb19760";s:32:"Qcloud\Sms\SmsMobileStatusPuller";s:40:"728a70f32eddaa9ce779996e17f2f972119b180d";s:25:"Qcloud\Sms\SmsMultiSender";s:40:"8d39c5c50a70a4b3a409a72edbcb0a5ebecc67cf";s:24:"Qcloud\Sms\SmsSenderUtil";s:40:"caf29c3ee6375b8aaeb59f0a1bb1d8aca124ef47";s:26:"Qcloud\Sms\SmsSingleSender";s:40:"f814e68da128f2363023997f93bc081ec2fd166a";s:26:"Qcloud\Sms\SmsStatusPuller";s:40:"956c7c7432dbe6038e1713bfbc003c361c7a6bf0";s:31:"Qcloud\Sms\SmsVoicePromptSender";s:40:"9f3c118ec943dfcf418c8adc77cbb503f3d0d5b9";s:35:"Qcloud\Sms\SmsVoiceVerifyCodeSender";s:40:"842a013386d41859b7b0e26fb6532541d9c18c51";s:25:"Qcloud\Sms\TtsVoiceSender";s:40:"c05faacea56b5618681373dcab6498f3c12a7e81";s:28:"Qcloud\Sms\VoiceFileUploader";s:40:"fa72915839744397494e6c8e973aaa0374219473";}i:1;a:1:{i:0;s:6:"master";}i:2;a:2:{i:0;s:6:"Qcloud";i:1;s:10:"Qcloud\Sms";}}}
\ No newline at end of file
diff --git a/qcloudsms/docs/sami.js b/qcloudsms/docs/sami.js
new file mode 100644
index 0000000..a866f6d
--- /dev/null
+++ b/qcloudsms/docs/sami.js
@@ -0,0 +1,248 @@
+
+window.projectVersion = 'master';
+
+(function(root) {
+
+ var bhIndex = null;
+ var rootPath = '';
+ var treeHtml = ' ';
+
+ var searchTypeClasses = {
+ 'Namespace': 'label-default',
+ 'Class': 'label-info',
+ 'Interface': 'label-primary',
+ 'Trait': 'label-success',
+ 'Method': 'label-danger',
+ '_': 'label-warning'
+ };
+
+ var searchIndex = [
+
+ {"type": "Namespace", "link": "Qcloud.html", "name": "Qcloud", "doc": "Namespace Qcloud"},{"type": "Namespace", "link": "Qcloud/Sms.html", "name": "Qcloud\\Sms", "doc": "Namespace Qcloud\\Sms"},
+
+ {"type": "Class", "fromName": "Qcloud\\Sms", "fromLink": "Qcloud/Sms.html", "link": "Qcloud/Sms/FileVoiceSender.html", "name": "Qcloud\\Sms\\FileVoiceSender", "doc": ""\u6309\u8bed\u97f3\u6587\u4ef6fid\u53d1\u9001\u8bed\u97f3\u901a\u77e5\u7c7b""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\FileVoiceSender", "fromLink": "Qcloud/Sms/FileVoiceSender.html", "link": "Qcloud/Sms/FileVoiceSender.html#method___construct", "name": "Qcloud\\Sms\\FileVoiceSender::__construct", "doc": ""\u6784\u9020\u51fd\u6570""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\FileVoiceSender", "fromLink": "Qcloud/Sms/FileVoiceSender.html", "link": "Qcloud/Sms/FileVoiceSender.html#method_send", "name": "Qcloud\\Sms\\FileVoiceSender::send", "doc": ""\u6309\u8bed\u97f3\u6587\u4ef6fid\u53d1\u9001\u8bed\u97f3\u901a\u77e5""},
+
+ {"type": "Class", "fromName": "Qcloud\\Sms", "fromLink": "Qcloud/Sms.html", "link": "Qcloud/Sms/SmsMobileStatusPuller.html", "name": "Qcloud\\Sms\\SmsMobileStatusPuller", "doc": ""\u62c9\u53d6\u5355\u4e2a\u624b\u673a\u77ed\u4fe1\u72b6\u6001\u7c7b""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsMobileStatusPuller", "fromLink": "Qcloud/Sms/SmsMobileStatusPuller.html", "link": "Qcloud/Sms/SmsMobileStatusPuller.html#method___construct", "name": "Qcloud\\Sms\\SmsMobileStatusPuller::__construct", "doc": ""\u6784\u9020\u51fd\u6570""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsMobileStatusPuller", "fromLink": "Qcloud/Sms/SmsMobileStatusPuller.html", "link": "Qcloud/Sms/SmsMobileStatusPuller.html#method_pullCallback", "name": "Qcloud\\Sms\\SmsMobileStatusPuller::pullCallback", "doc": ""\u62c9\u53d6\u56de\u6267\u7ed3\u679c""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsMobileStatusPuller", "fromLink": "Qcloud/Sms/SmsMobileStatusPuller.html", "link": "Qcloud/Sms/SmsMobileStatusPuller.html#method_pullReply", "name": "Qcloud\\Sms\\SmsMobileStatusPuller::pullReply", "doc": ""\u62c9\u53d6\u56de\u590d\u4fe1\u606f""},
+
+ {"type": "Class", "fromName": "Qcloud\\Sms", "fromLink": "Qcloud/Sms.html", "link": "Qcloud/Sms/SmsMultiSender.html", "name": "Qcloud\\Sms\\SmsMultiSender", "doc": ""\u7fa4\u53d1\u77ed\u4fe1\u7c7b""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsMultiSender", "fromLink": "Qcloud/Sms/SmsMultiSender.html", "link": "Qcloud/Sms/SmsMultiSender.html#method___construct", "name": "Qcloud\\Sms\\SmsMultiSender::__construct", "doc": ""\u6784\u9020\u51fd\u6570""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsMultiSender", "fromLink": "Qcloud/Sms/SmsMultiSender.html", "link": "Qcloud/Sms/SmsMultiSender.html#method_send", "name": "Qcloud\\Sms\\SmsMultiSender::send", "doc": ""\u666e\u901a\u7fa4\u53d1""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsMultiSender", "fromLink": "Qcloud/Sms/SmsMultiSender.html", "link": "Qcloud/Sms/SmsMultiSender.html#method_sendWithParam", "name": "Qcloud\\Sms\\SmsMultiSender::sendWithParam", "doc": ""\u6307\u5b9a\u6a21\u677f\u7fa4\u53d1""},
+
+ {"type": "Class", "fromName": "Qcloud\\Sms", "fromLink": "Qcloud/Sms.html", "link": "Qcloud/Sms/SmsSenderUtil.html", "name": "Qcloud\\Sms\\SmsSenderUtil", "doc": ""\u53d1\u9001Util\u7c7b""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsSenderUtil", "fromLink": "Qcloud/Sms/SmsSenderUtil.html", "link": "Qcloud/Sms/SmsSenderUtil.html#method_getRandom", "name": "Qcloud\\Sms\\SmsSenderUtil::getRandom", "doc": ""\u751f\u6210\u968f\u673a\u6570""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsSenderUtil", "fromLink": "Qcloud/Sms/SmsSenderUtil.html", "link": "Qcloud/Sms/SmsSenderUtil.html#method_calculateSig", "name": "Qcloud\\Sms\\SmsSenderUtil::calculateSig", "doc": ""\u751f\u6210\u7b7e\u540d""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsSenderUtil", "fromLink": "Qcloud/Sms/SmsSenderUtil.html", "link": "Qcloud/Sms/SmsSenderUtil.html#method_calculateSigForTemplAndPhoneNumbers", "name": "Qcloud\\Sms\\SmsSenderUtil::calculateSigForTemplAndPhoneNumbers", "doc": ""\u751f\u6210\u7b7e\u540d""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsSenderUtil", "fromLink": "Qcloud/Sms/SmsSenderUtil.html", "link": "Qcloud/Sms/SmsSenderUtil.html#method_phoneNumbersToArray", "name": "Qcloud\\Sms\\SmsSenderUtil::phoneNumbersToArray", "doc": """"},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsSenderUtil", "fromLink": "Qcloud/Sms/SmsSenderUtil.html", "link": "Qcloud/Sms/SmsSenderUtil.html#method_calculateSigForTempl", "name": "Qcloud\\Sms\\SmsSenderUtil::calculateSigForTempl", "doc": ""\u751f\u6210\u7b7e\u540d""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsSenderUtil", "fromLink": "Qcloud/Sms/SmsSenderUtil.html", "link": "Qcloud/Sms/SmsSenderUtil.html#method_calculateSigForPuller", "name": "Qcloud\\Sms\\SmsSenderUtil::calculateSigForPuller", "doc": ""\u751f\u6210\u7b7e\u540d""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsSenderUtil", "fromLink": "Qcloud/Sms/SmsSenderUtil.html", "link": "Qcloud/Sms/SmsSenderUtil.html#method_calculateAuth", "name": "Qcloud\\Sms\\SmsSenderUtil::calculateAuth", "doc": ""\u751f\u6210\u4e0a\u4f20\u6587\u4ef6\u6388\u6743""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsSenderUtil", "fromLink": "Qcloud/Sms/SmsSenderUtil.html", "link": "Qcloud/Sms/SmsSenderUtil.html#method_sha1sum", "name": "Qcloud\\Sms\\SmsSenderUtil::sha1sum", "doc": ""\u751f\u6210sha1sum""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsSenderUtil", "fromLink": "Qcloud/Sms/SmsSenderUtil.html", "link": "Qcloud/Sms/SmsSenderUtil.html#method_sendCurlPost", "name": "Qcloud\\Sms\\SmsSenderUtil::sendCurlPost", "doc": ""\u53d1\u9001\u8bf7\u6c42""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsSenderUtil", "fromLink": "Qcloud/Sms/SmsSenderUtil.html", "link": "Qcloud/Sms/SmsSenderUtil.html#method_fetch", "name": "Qcloud\\Sms\\SmsSenderUtil::fetch", "doc": ""\u53d1\u9001\u8bf7\u6c42""},
+
+ {"type": "Class", "fromName": "Qcloud\\Sms", "fromLink": "Qcloud/Sms.html", "link": "Qcloud/Sms/SmsSingleSender.html", "name": "Qcloud\\Sms\\SmsSingleSender", "doc": ""\u5355\u53d1\u77ed\u4fe1\u7c7b""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsSingleSender", "fromLink": "Qcloud/Sms/SmsSingleSender.html", "link": "Qcloud/Sms/SmsSingleSender.html#method___construct", "name": "Qcloud\\Sms\\SmsSingleSender::__construct", "doc": ""\u6784\u9020\u51fd\u6570""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsSingleSender", "fromLink": "Qcloud/Sms/SmsSingleSender.html", "link": "Qcloud/Sms/SmsSingleSender.html#method_send", "name": "Qcloud\\Sms\\SmsSingleSender::send", "doc": ""\u666e\u901a\u5355\u53d1""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsSingleSender", "fromLink": "Qcloud/Sms/SmsSingleSender.html", "link": "Qcloud/Sms/SmsSingleSender.html#method_sendWithParam", "name": "Qcloud\\Sms\\SmsSingleSender::sendWithParam", "doc": ""\u6307\u5b9a\u6a21\u677f\u5355\u53d1""},
+
+ {"type": "Class", "fromName": "Qcloud\\Sms", "fromLink": "Qcloud/Sms.html", "link": "Qcloud/Sms/SmsStatusPuller.html", "name": "Qcloud\\Sms\\SmsStatusPuller", "doc": ""\u62c9\u53d6\u77ed\u4fe1\u72b6\u6001\u7c7b""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsStatusPuller", "fromLink": "Qcloud/Sms/SmsStatusPuller.html", "link": "Qcloud/Sms/SmsStatusPuller.html#method___construct", "name": "Qcloud\\Sms\\SmsStatusPuller::__construct", "doc": ""\u6784\u9020\u51fd\u6570""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsStatusPuller", "fromLink": "Qcloud/Sms/SmsStatusPuller.html", "link": "Qcloud/Sms/SmsStatusPuller.html#method_pullCallback", "name": "Qcloud\\Sms\\SmsStatusPuller::pullCallback", "doc": ""\u62c9\u53d6\u56de\u6267\u7ed3\u679c""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsStatusPuller", "fromLink": "Qcloud/Sms/SmsStatusPuller.html", "link": "Qcloud/Sms/SmsStatusPuller.html#method_pullReply", "name": "Qcloud\\Sms\\SmsStatusPuller::pullReply", "doc": ""\u62c9\u53d6\u56de\u590d\u4fe1\u606f""},
+
+ {"type": "Class", "fromName": "Qcloud\\Sms", "fromLink": "Qcloud/Sms.html", "link": "Qcloud/Sms/SmsVoicePromptSender.html", "name": "Qcloud\\Sms\\SmsVoicePromptSender", "doc": ""\u53d1\u9001\u8bed\u97f3\u901a\u77e5\u7c7b""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsVoicePromptSender", "fromLink": "Qcloud/Sms/SmsVoicePromptSender.html", "link": "Qcloud/Sms/SmsVoicePromptSender.html#method___construct", "name": "Qcloud\\Sms\\SmsVoicePromptSender::__construct", "doc": ""\u6784\u9020\u51fd\u6570""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsVoicePromptSender", "fromLink": "Qcloud/Sms/SmsVoicePromptSender.html", "link": "Qcloud/Sms/SmsVoicePromptSender.html#method_send", "name": "Qcloud\\Sms\\SmsVoicePromptSender::send", "doc": ""\u53d1\u9001\u8bed\u97f3\u901a\u77e5""},
+
+ {"type": "Class", "fromName": "Qcloud\\Sms", "fromLink": "Qcloud/Sms.html", "link": "Qcloud/Sms/SmsVoiceVerifyCodeSender.html", "name": "Qcloud\\Sms\\SmsVoiceVerifyCodeSender", "doc": ""\u53d1\u9001\u8bed\u97f3\u9a8c\u8bc1\u7801\u7c7b""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsVoiceVerifyCodeSender", "fromLink": "Qcloud/Sms/SmsVoiceVerifyCodeSender.html", "link": "Qcloud/Sms/SmsVoiceVerifyCodeSender.html#method___construct", "name": "Qcloud\\Sms\\SmsVoiceVerifyCodeSender::__construct", "doc": ""\u6784\u9020\u51fd\u6570""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\SmsVoiceVerifyCodeSender", "fromLink": "Qcloud/Sms/SmsVoiceVerifyCodeSender.html", "link": "Qcloud/Sms/SmsVoiceVerifyCodeSender.html#method_send", "name": "Qcloud\\Sms\\SmsVoiceVerifyCodeSender::send", "doc": ""\u53d1\u9001\u8bed\u97f3\u9a8c\u8bc1\u7801""},
+
+ {"type": "Class", "fromName": "Qcloud\\Sms", "fromLink": "Qcloud/Sms.html", "link": "Qcloud/Sms/TtsVoiceSender.html", "name": "Qcloud\\Sms\\TtsVoiceSender", "doc": ""\u6307\u5b9a\u6a21\u677f\u53d1\u9001\u8bed\u97f3\u901a\u77e5\u7c7b""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\TtsVoiceSender", "fromLink": "Qcloud/Sms/TtsVoiceSender.html", "link": "Qcloud/Sms/TtsVoiceSender.html#method___construct", "name": "Qcloud\\Sms\\TtsVoiceSender::__construct", "doc": ""\u6784\u9020\u51fd\u6570""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\TtsVoiceSender", "fromLink": "Qcloud/Sms/TtsVoiceSender.html", "link": "Qcloud/Sms/TtsVoiceSender.html#method_send", "name": "Qcloud\\Sms\\TtsVoiceSender::send", "doc": ""\u6307\u5b9a\u6a21\u677f\u53d1\u9001\u8bed\u97f3\u77ed\u4fe1""},
+
+ {"type": "Class", "fromName": "Qcloud\\Sms", "fromLink": "Qcloud/Sms.html", "link": "Qcloud/Sms/VoiceFileUploader.html", "name": "Qcloud\\Sms\\VoiceFileUploader", "doc": ""\u4e0a\u4f20\u8bed\u97f3\u6587\u4ef6\u7c7b""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\VoiceFileUploader", "fromLink": "Qcloud/Sms/VoiceFileUploader.html", "link": "Qcloud/Sms/VoiceFileUploader.html#method___construct", "name": "Qcloud\\Sms\\VoiceFileUploader::__construct", "doc": ""\u6784\u9020\u51fd\u6570""},
+ {"type": "Method", "fromName": "Qcloud\\Sms\\VoiceFileUploader", "fromLink": "Qcloud/Sms/VoiceFileUploader.html", "link": "Qcloud/Sms/VoiceFileUploader.html#method_upload", "name": "Qcloud\\Sms\\VoiceFileUploader::upload", "doc": ""\u4e0a\u4f20\u8bed\u97f3\u6587\u4ef6""},
+
+
+ // Fix trailing commas in the index
+ {}
+ ];
+
+ /** Tokenizes strings by namespaces and functions */
+ function tokenizer(term) {
+ if (!term) {
+ return [];
+ }
+
+ var tokens = [term];
+ var meth = term.indexOf('::');
+
+ // Split tokens into methods if "::" is found.
+ if (meth > -1) {
+ tokens.push(term.substr(meth + 2));
+ term = term.substr(0, meth - 2);
+ }
+
+ // Split by namespace or fake namespace.
+ if (term.indexOf('\\') > -1) {
+ tokens = tokens.concat(term.split('\\'));
+ } else if (term.indexOf('_') > 0) {
+ tokens = tokens.concat(term.split('_'));
+ }
+
+ // Merge in splitting the string by case and return
+ tokens = tokens.concat(term.match(/(([A-Z]?[^A-Z]*)|([a-z]?[^a-z]*))/g).slice(0,-1));
+
+ return tokens;
+ };
+
+ root.Sami = {
+ /**
+ * Cleans the provided term. If no term is provided, then one is
+ * grabbed from the query string "search" parameter.
+ */
+ cleanSearchTerm: function(term) {
+ // Grab from the query string
+ if (typeof term === 'undefined') {
+ var name = 'search';
+ var regex = new RegExp("[\\?&]" + name + "=([^]*)");
+ var results = regex.exec(location.search);
+ if (results === null) {
+ return null;
+ }
+ term = decodeURIComponent(results[1].replace(/\+/g, " "));
+ }
+
+ return term.replace(/<(?:.|\n)*?>/gm, '');
+ },
+
+ /** Searches through the index for a given term */
+ search: function(term) {
+ // Create a new search index if needed
+ if (!bhIndex) {
+ bhIndex = new Bloodhound({
+ limit: 500,
+ local: searchIndex,
+ datumTokenizer: function (d) {
+ return tokenizer(d.name);
+ },
+ queryTokenizer: Bloodhound.tokenizers.whitespace
+ });
+ bhIndex.initialize();
+ }
+
+ results = [];
+ bhIndex.get(term, function(matches) {
+ results = matches;
+ });
+
+ if (!rootPath) {
+ return results;
+ }
+
+ // Fix the element links based on the current page depth.
+ return $.map(results, function(ele) {
+ if (ele.link.indexOf('..') > -1) {
+ return ele;
+ }
+ ele.link = rootPath + ele.link;
+ if (ele.fromLink) {
+ ele.fromLink = rootPath + ele.fromLink;
+ }
+ return ele;
+ });
+ },
+
+ /** Get a search class for a specific type */
+ getSearchClass: function(type) {
+ return searchTypeClasses[type] || searchTypeClasses['_'];
+ },
+
+ /** Add the left-nav tree to the site */
+ injectApiTree: function(ele) {
+ ele.html(treeHtml);
+ }
+ };
+
+ $(function() {
+ // Modify the HTML to work correctly based on the current depth
+ rootPath = $('body').attr('data-root-path');
+ treeHtml = treeHtml.replace(/href="/g, 'href="' + rootPath);
+ Sami.injectApiTree($('#api-tree'));
+ });
+
+ return root.Sami;
+})(window);
+
+$(function() {
+
+ // Enable the version switcher
+ $('#version-switcher').change(function() {
+ window.location = $(this).val()
+ });
+
+
+ // Toggle left-nav divs on click
+ $('#api-tree .hd span').click(function() {
+ $(this).parent().parent().toggleClass('opened');
+ });
+
+ // Expand the parent namespaces of the current page.
+ var expected = $('body').attr('data-name');
+
+ if (expected) {
+ // Open the currently selected node and its parents.
+ var container = $('#api-tree');
+ var node = $('#api-tree li[data-name="' + expected + '"]');
+ // Node might not be found when simulating namespaces
+ if (node.length > 0) {
+ node.addClass('active').addClass('opened');
+ node.parents('li').addClass('opened');
+ var scrollPos = node.offset().top - container.offset().top + container.scrollTop();
+ // Position the item nearer to the top of the screen.
+ scrollPos -= 200;
+ container.scrollTop(scrollPos);
+ }
+ }
+
+
+
+ var form = $('#search-form .typeahead');
+ form.typeahead({
+ hint: true,
+ highlight: true,
+ minLength: 1
+ }, {
+ name: 'search',
+ displayKey: 'name',
+ source: function (q, cb) {
+ cb(Sami.search(q));
+ }
+ });
+
+ // The selection is direct-linked when the user selects a suggestion.
+ form.on('typeahead:selected', function(e, suggestion) {
+ window.location = suggestion.link;
+ });
+
+ // The form is submitted when the user hits enter.
+ form.keypress(function (e) {
+ if (e.which == 13) {
+ $('#search-form').submit();
+ return true;
+ }
+ });
+
+
+});
+
+
diff --git a/qcloudsms/docs/search.html b/qcloudsms/docs/search.html
new file mode 100644
index 0000000..69656ca
--- /dev/null
+++ b/qcloudsms/docs/search.html
@@ -0,0 +1,154 @@
+
+
+
+
+
+ Search | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
This page allows you to search through the API documentation for
+ specific terms. Enter your search words into the box below and click
+ "submit". The search will be performed on namespaces, classes, interfaces,
+ traits, functions, and methods.
+
+
+
+
Search Results
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/docs/traits.html b/qcloudsms/docs/traits.html
new file mode 100644
index 0000000..f7635bd
--- /dev/null
+++ b/qcloudsms/docs/traits.html
@@ -0,0 +1,82 @@
+
+
+
+
+
+ Traits | API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/qcloudsms/gendoc.sh b/qcloudsms/gendoc.sh
new file mode 100644
index 0000000..c895c7c
--- /dev/null
+++ b/qcloudsms/gendoc.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+composer install
+php ./vendor/sami/sami/sami.php update ./sami_config.php -v
diff --git a/qcloudsms/sami_config.php b/qcloudsms/sami_config.php
new file mode 100644
index 0000000..8ee308c
--- /dev/null
+++ b/qcloudsms/sami_config.php
@@ -0,0 +1,17 @@
+files()
+ ->name("*.php")
+ ->exclude("Resources")
+ ->exclude("Tests")
+ ->in(__DIR__."/src/");
+
+return new Sami($iterator, array(
+ "build_dir" => __DIR__."/docs",
+ "cache_dir" => __DIR__."/cache",
+));
diff --git a/qcloudsms/src/FileVoiceSender.php b/qcloudsms/src/FileVoiceSender.php
new file mode 100644
index 0000000..42b6d87
--- /dev/null
+++ b/qcloudsms/src/FileVoiceSender.php
@@ -0,0 +1,69 @@
+url = "https://cloud.tim.qq.com/v5/tlsvoicesvr/sendfvoice";
+ $this->appid = $appid;
+ $this->appkey = $appkey;
+ $this->util = new SmsSenderUtil();
+ }
+
+ /**
+ *
+ * 按语音文件fid发送语音通知
+ *
+ * @param string $nationCode 国家码,如 86 为中国
+ * @param string $phoneNumber 不带国家码的手机号
+ * @param string $fid 语音文件fid
+ * @param string $playtimes 播放次数,可选,最多3次,默认2次
+ * @param string $ext 用户的session内容,服务端原样返回,可选字段,不需要可填空串
+ * @return string 应答json字符串,详细内容参见腾讯云协议文档
+ */
+ public function send($nationCode, $phoneNumber, $fid, $playtimes = 2, $ext = "")
+ {
+ $random = $this->util->getRandom();
+ $curTime = time();
+ $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+ // 按照协议组织 post 包体
+ $data = new \stdClass();
+ $tel = new \stdClass();
+ $tel->nationcode = "".$nationCode;
+ $tel->mobile = "".$phoneNumber;
+ $data->tel = $tel;
+ $data->fid = $fid;
+ $data->playtimes = $playtimes;
+
+ // app凭证
+ $data->sig = $this->util->calculateSig($this->appkey, $random,
+ $curTime, array($phoneNumber));
+
+ // unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
+ $data->time = $curTime;
+ $data->ext = $ext;
+
+ return $this->util->sendCurlPost($wholeUrl, $data);
+ }
+}
diff --git a/qcloudsms/src/SmsMobileStatusPuller.php b/qcloudsms/src/SmsMobileStatusPuller.php
new file mode 100644
index 0000000..a9863d6
--- /dev/null
+++ b/qcloudsms/src/SmsMobileStatusPuller.php
@@ -0,0 +1,91 @@
+url = "https://yun.tim.qq.com/v5/tlssmssvr/pullstatus4mobile";
+ $this->appid = $appid;
+ $this->appkey = $appkey;
+ $this->util = new SmsSenderUtil();
+ }
+
+ /**
+ * 拉取回执结果
+ *
+ * @param int $type 拉取类型,0表示回执结果,1表示回复信息
+ * @param string $nationCode 国家码,如 86 为中国
+ * @param string $mobile 不带国家码的手机号
+ * @param int $beginTime 开始时间(unix timestamp)
+ * @param int $endTime 结束时间(unix timestamp)
+ * @param int $max 拉取最大条数,最多100
+ * @return string 应答json字符串,详细内容参见腾讯云协议文档
+ */
+ private function pull($type, $nationCode, $mobile, $beginTime, $endTime, $max)
+ {
+ $random = $this->util->getRandom();
+ $curTime = time();
+ $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+ $data = new \stdClass();
+ $data->sig = $this->util->calculateSigForPuller($this->appkey, $random, $curTime);
+ $data->time = $curTime;
+ $data->type = $type;
+ $data->max = $max;
+ $data->begin_time = $beginTime;
+ $data->end_time = $endTime;
+ $data->nationcode = $nationCode;
+ $data->mobile = $mobile;
+
+ return $this->util->sendCurlPost($wholeUrl, $data);
+ }
+
+ /**
+ * 拉取回执结果
+ *
+ * @param string $nationCode 国家码,如 86 为中国
+ * @param string $mobile 不带国家码的手机号
+ * @param int $beginTime 开始时间(unix timestamp)
+ * @param int $endTime 结束时间(unix timestamp)
+ * @param int $max 拉取最大条数,最多100
+ * @return string 应答json字符串,详细内容参见腾讯云协议文档
+ */
+ public function pullCallback($nationCode, $mobile, $beginTime, $endTime, $max)
+ {
+ return $this->pull(0, $nationCode, $mobile, $beginTime, $endTime, $max);
+ }
+
+ /**
+ * 拉取回复信息
+ *
+ * @param string $nationCode 国家码,如 86 为中国
+ * @param string $mobile 不带国家码的手机号
+ * @param int $beginTime 开始时间(unix timestamp)
+ * @param int $endTime 结束时间(unix timestamp)
+ * @param int $max 拉取最大条数,最多100
+ * @return string 应答json字符串,详细内容参见腾讯云协议文档
+ */
+ public function pullReply($nationCode, $mobile, $beginTime, $endTime, $max)
+ {
+ return $this->pull(1, $nationCode, $mobile, $beginTime, $endTime, $max);
+ }
+}
\ No newline at end of file
diff --git a/qcloudsms/src/SmsMultiSender.php b/qcloudsms/src/SmsMultiSender.php
new file mode 100644
index 0000000..605cd27
--- /dev/null
+++ b/qcloudsms/src/SmsMultiSender.php
@@ -0,0 +1,99 @@
+url = "https://yun.tim.qq.com/v5/tlssmssvr/sendmultisms2";
+ $this->appid = $appid;
+ $this->appkey = $appkey;
+ $this->util = new SmsSenderUtil();
+ }
+
+ /**
+ * 普通群发
+ *
+ * 普通群发需明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,
+ * 否则系统将使用默认签名。
+ *
+ *
+ * @param int $type 短信类型,0 为普通短信,1 营销短信
+ * @param string $nationCode 国家码,如 86 为中国
+ * @param array $phoneNumbers 不带国家码的手机号列表
+ * @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
+ * @param string $extend 扩展码,可填空串
+ * @param string $ext 服务端原样返回的参数,可填空串
+ * @return string 应答json字符串,详细内容参见腾讯云协议文档
+ */
+ public function send($type, $nationCode, $phoneNumbers, $msg, $extend = "", $ext = "")
+ {
+ $random = $this->util->getRandom();
+ $curTime = time();
+ $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+ $data = new \stdClass();
+ $data->tel = $this->util->phoneNumbersToArray($nationCode, $phoneNumbers);
+ $data->type = $type;
+ $data->msg = $msg;
+ $data->sig = $this->util->calculateSig($this->appkey, $random,
+ $curTime, $phoneNumbers);
+ $data->time = $curTime;
+ $data->extend = $extend;
+ $data->ext = $ext;
+
+ return $this->util->sendCurlPost($wholeUrl, $data);
+ }
+
+ /**
+ * 指定模板群发
+ *
+ *
+ * @param string $nationCode 国家码,如 86 为中国
+ * @param array $phoneNumbers 不带国家码的手机号列表
+ * @param int $templId 模板id
+ * @param array $params 模板参数列表,如模板 {1}...{2}...{3},那么需要带三个参数
+ * @param string $sign 签名,如果填空串,系统会使用默认签名
+ * @param string $extend 扩展码,可填空串
+ * @param string $ext 服务端原样返回的参数,可填空串
+ * @return string 应答json字符串,详细内容参见腾讯云协议文档
+ */
+ public function sendWithParam($nationCode, $phoneNumbers, $templId, $params,
+ $sign = "", $extend = "", $ext = "")
+ {
+ $random = $this->util->getRandom();
+ $curTime = time();
+ $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+ $data = new \stdClass();
+ $data->tel = $this->util->phoneNumbersToArray($nationCode, $phoneNumbers);
+ $data->sign = $sign;
+ $data->tpl_id = $templId;
+ $data->params = $params;
+ $data->sig = $this->util->calculateSigForTemplAndPhoneNumbers(
+ $this->appkey, $random, $curTime, $phoneNumbers);
+ $data->time = $curTime;
+ $data->extend = $extend;
+ $data->ext = $ext;
+
+ return $this->util->sendCurlPost($wholeUrl, $data);
+ }
+}
diff --git a/qcloudsms/src/SmsSenderUtil.php b/qcloudsms/src/SmsSenderUtil.php
new file mode 100644
index 0000000..1dcf35d
--- /dev/null
+++ b/qcloudsms/src/SmsSenderUtil.php
@@ -0,0 +1,208 @@
+nationcode = $nationCode;
+ $telElement->mobile = $phoneNumbers[$i];
+ array_push($tel, $telElement);
+ } while (++$i < count($phoneNumbers));
+
+ return $tel;
+ }
+
+ /**
+ * 生成签名
+ *
+ * @param string $appkey sdkappid对应的appkey
+ * @param string $random 随机正整数
+ * @param string $curTime 当前时间
+ * @param array $phoneNumber 手机号码
+ * @return string 签名结果
+ */
+ public function calculateSigForTempl($appkey, $random, $curTime, $phoneNumber)
+ {
+ $phoneNumbers = array($phoneNumber);
+
+ return $this->calculateSigForTemplAndPhoneNumbers($appkey, $random,
+ $curTime, $phoneNumbers);
+ }
+
+ /**
+ * 生成签名
+ *
+ * @param string $appkey sdkappid对应的appkey
+ * @param string $random 随机正整数
+ * @param string $curTime 当前时间
+ * @return string 签名结果
+ */
+ public function calculateSigForPuller($appkey, $random, $curTime)
+ {
+ return hash("sha256", "appkey=".$appkey."&random=".$random
+ ."&time=".$curTime);
+ }
+
+ /**
+ * 生成上传文件授权
+ *
+ * @param string $appkey sdkappid对应的appkey
+ * @param string $random 随机正整数
+ * @param string $curTime 当前时间
+ * @param array $fileSha1Sum 文件sha1sum
+ * @return string 授权结果
+ */
+ public function calculateAuth($appkey, $random, $curTime, $fileSha1Sum)
+ {
+ return hash("sha256", "appkey=".$appkey."&random=".$random
+ ."&time=".$curTime."&content-sha1=".$fileSha1Sum);
+ }
+
+ /**
+ * 生成sha1sum
+ *
+ * @param string $content 内容
+ * @return string 内容sha1散列值
+ */
+ public function sha1sum($content)
+ {
+ return hash("sha1", $content);
+ }
+
+ /**
+ * 发送请求
+ *
+ * @param string $url 请求地址
+ * @param array $dataObj 请求内容
+ * @return string 应答json字符串
+ */
+ public function sendCurlPost($url, $dataObj)
+ {
+ $curl = curl_init();
+ curl_setopt($curl, CURLOPT_URL, $url);
+ curl_setopt($curl, CURLOPT_HEADER, 0);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($dataObj));
+ curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
+
+ $ret = curl_exec($curl);
+ if (false == $ret) {
+ // curl_exec failed
+ $result = "{ \"result\":" . -2 . ",\"errmsg\":\"" . curl_error($curl) . "\"}";
+ } else {
+ $rsp = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+ if (200 != $rsp) {
+ $result = "{ \"result\":" . -1 . ",\"errmsg\":\"". $rsp
+ . " " . curl_error($curl) ."\"}";
+ } else {
+ $result = $ret;
+ }
+ }
+
+ curl_close($curl);
+
+ return $result;
+ }
+
+ /**
+ * 发送请求
+ *
+ * @param string $req 请求对象
+ * @return string 应答json字符串
+ */
+ public function fetch($req)
+ {
+ $curl = curl_init();
+
+ curl_setopt($curl, CURLOPT_URL, $req->url);
+ curl_setopt($curl, CURLOPT_HTTPHEADER, $req->headers);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $req->body);
+ curl_setopt($curl, CURLOPT_HEADER, 0);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 60);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
+
+ $result = curl_exec($curl);
+
+ if (false == $result) {
+ // curl_exec failed
+ $result = "{ \"result\":" . -2 . ",\"errmsg\":\"" . curl_error($curl) . "\"}";
+ } else {
+ $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+ if (200 != $code) {
+ $result = "{ \"result\":" . -1 . ",\"errmsg\":\"". $rsp
+ . " " . curl_error($curl) ."\"}";
+ }
+ }
+ curl_close($curl);
+
+ return $result;
+ }
+}
diff --git a/qcloudsms/src/SmsSingleSender.php b/qcloudsms/src/SmsSingleSender.php
new file mode 100644
index 0000000..4181fb2
--- /dev/null
+++ b/qcloudsms/src/SmsSingleSender.php
@@ -0,0 +1,107 @@
+url = "https://yun.tim.qq.com/v5/tlssmssvr/sendsms";
+ $this->appid = $appid;
+ $this->appkey = $appkey;
+ $this->util = new SmsSenderUtil();
+ }
+
+ /**
+ * 普通单发
+ *
+ * 普通单发需明确指定内容,如果有多个签名,请在内容中以【】的方式添加到信息内容中,否则系统将使用默认签名。
+ *
+ * @param int $type 短信类型,0 为普通短信,1 营销短信
+ * @param string $nationCode 国家码,如 86 为中国
+ * @param string $phoneNumber 不带国家码的手机号
+ * @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
+ * @param string $extend 扩展码,可填空串
+ * @param string $ext 服务端原样返回的参数,可填空串
+ * @return string 应答json字符串,详细内容参见腾讯云协议文档
+ */
+ public function send($type, $nationCode, $phoneNumber, $msg, $extend = "", $ext = "")
+ {
+ $random = $this->util->getRandom();
+ $curTime = time();
+ $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+ // 按照协议组织 post 包体
+ $data = new \stdClass();
+ $tel = new \stdClass();
+ $tel->nationcode = "".$nationCode;
+ $tel->mobile = "".$phoneNumber;
+
+ $data->tel = $tel;
+ $data->type = (int)$type;
+ $data->msg = $msg;
+ $data->sig = hash("sha256",
+ "appkey=".$this->appkey."&random=".$random."&time="
+ .$curTime."&mobile=".$phoneNumber, FALSE);
+ $data->time = $curTime;
+ $data->extend = $extend;
+ $data->ext = $ext;
+
+ return $this->util->sendCurlPost($wholeUrl, $data);
+ }
+
+ /**
+ * 指定模板单发
+ *
+ * @param string $nationCode 国家码,如 86 为中国
+ * @param string $phoneNumber 不带国家码的手机号
+ * @param int $templId 模板 id
+ * @param array $params 模板参数列表,如模板 {1}...{2}...{3},那么需要带三个参数
+ * @param string $sign 签名,如果填空串,系统会使用默认签名
+ * @param string $extend 扩展码,可填空串
+ * @param string $ext 服务端原样返回的参数,可填空串
+ * @return string 应答json字符串,详细内容参见腾讯云协议文档
+ */
+ public function sendWithParam($nationCode, $phoneNumber, $templId = 0, $params,
+ $sign = "", $extend = "", $ext = "")
+ {
+ $random = $this->util->getRandom();
+ $curTime = time();
+ $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+ // 按照协议组织 post 包体
+ $data = new \stdClass();
+ $tel = new \stdClass();
+ $tel->nationcode = "".$nationCode;
+ $tel->mobile = "".$phoneNumber;
+
+ $data->tel = $tel;
+ $data->sig = $this->util->calculateSigForTempl($this->appkey, $random,
+ $curTime, $phoneNumber);
+ $data->tpl_id = $templId;
+ $data->params = $params;
+ $data->sign = $sign;
+ $data->time = $curTime;
+ $data->extend = $extend;
+ $data->ext = $ext;
+
+ return $this->util->sendCurlPost($wholeUrl, $data);
+ }
+}
diff --git a/qcloudsms/src/SmsStatusPuller.php b/qcloudsms/src/SmsStatusPuller.php
new file mode 100644
index 0000000..3490403
--- /dev/null
+++ b/qcloudsms/src/SmsStatusPuller.php
@@ -0,0 +1,75 @@
+url = "https://yun.tim.qq.com/v5/tlssmssvr/pullstatus";
+ $this->appid = $appid;
+ $this->appkey = $appkey;
+ $this->util = new SmsSenderUtil();
+ }
+
+ /**
+ * 拉取回执结果
+ *
+ * @param int $type 拉取类型,0表示回执结果,1表示回复信息
+ * @param int $max 最大条数,最多100
+ * @return string 应答json字符串,详细内容参见腾讯云协议文档
+ */
+ private function pull($type, $max)
+ {
+ $random = $this->util->getRandom();
+ $curTime = time();
+ $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+ $data = new \stdClass();
+ $data->sig = $this->util->calculateSigForPuller($this->appkey, $random, $curTime);
+ $data->time = $curTime;
+ $data->type = $type;
+ $data->max = $max;
+
+ return $this->util->sendCurlPost($wholeUrl, $data);
+ }
+
+ /**
+ * 拉取回执结果
+ *
+ * @param int $max 拉取最大条数,最多100
+ * @return string 应答json字符串,详细内容参见腾讯云协议文档
+ */
+ public function pullCallback($max)
+ {
+ return $this->pull(0, $max);
+ }
+
+ /**
+ * 拉取回复信息
+ *
+ * @param int $max 拉取最大条数,最多100
+ * @return string 应答json字符串,详细内容参见腾讯云协议文档
+ */
+ public function pullReply($max)
+ {
+ return $this->pull(1, $max);
+ }
+}
\ No newline at end of file
diff --git a/qcloudsms/src/SmsVoicePromptSender.php b/qcloudsms/src/SmsVoicePromptSender.php
new file mode 100644
index 0000000..ad68a22
--- /dev/null
+++ b/qcloudsms/src/SmsVoicePromptSender.php
@@ -0,0 +1,72 @@
+url = "https://cloud.tim.qq.com/v5/tlsvoicesvr/sendvoiceprompt";
+ $this->appid = $appid;
+ $this->appkey = $appkey;
+ $this->util = new SmsSenderUtil();
+ }
+
+ /**
+ *
+ * 发送语音通知
+ *
+ * @param string $nationCode 国家码,如 86 为中国
+ * @param string $phoneNumber 不带国家码的手机号
+ * @param string $prompttype 语音类型,目前固定为2
+ * @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
+ * @param string $playtimes 播放次数,可选,最多3次,默认2次
+ * @param string $ext 用户的session内容,服务端原样返回,可选字段,不需要可填空串
+ * @return string 应答json字符串,详细内容参见腾讯云协议文档
+ */
+ public function send($nationCode, $phoneNumber, $prompttype, $msg, $playtimes = 2, $ext = "")
+ {
+ $random = $this->util->getRandom();
+ $curTime = time();
+ $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+ // 按照协议组织 post 包体
+ $data = new \stdClass();
+ $tel = new \stdClass();
+ $tel->nationcode = "".$nationCode;
+ $tel->mobile = "".$phoneNumber;
+
+ $data->tel = $tel;
+ // 通知内容,utf8编码,支持中文英文、数字及组合,需要和语音内容模版相匹配
+ $data->promptfile = $msg;
+ // 固定值 2
+ $data->prompttype = $prompttype;
+ $data->playtimes = $playtimes;
+ // app凭证
+ $data->sig = hash("sha256",
+ "appkey=".$this->appkey."&random=".$random."&time="
+ .$curTime."&mobile=".$phoneNumber, FALSE);
+ // unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
+ $data->time = $curTime;
+ $data->ext = $ext;
+
+ return $this->util->sendCurlPost($wholeUrl, $data);
+ }
+}
diff --git a/qcloudsms/src/SmsVoiceVerifyCodeSender.php b/qcloudsms/src/SmsVoiceVerifyCodeSender.php
new file mode 100644
index 0000000..ceb062b
--- /dev/null
+++ b/qcloudsms/src/SmsVoiceVerifyCodeSender.php
@@ -0,0 +1,67 @@
+url = "https://cloud.tim.qq.com/v5/tlsvoicesvr/sendvoice";
+ $this->appid = $appid;
+ $this->appkey = $appkey;
+ $this->util = new SmsSenderUtil();
+ }
+
+ /**
+ * 发送语音验证码
+ *
+ * @param string $nationCode 国家码,如 86 为中国
+ * @param string $phoneNumber 不带国家码的手机号
+ * @param string $msg 信息内容,必须与申请的模板格式一致,否则将返回错误
+ * @param int $playtimes 播放次数,可选,最多3次,默认2次
+ * @param string $ext 用户的session内容,服务端原样返回,可选字段,不需要可填空串
+ * @return string 应答json字符串,详细内容参见腾讯云协议文档
+ */
+ public function send($nationCode, $phoneNumber, $msg, $playtimes = 2, $ext = "")
+ {
+ $random = $this->util->getRandom();
+ $curTime = time();
+ $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+ // 按照协议组织 post 包体
+ $data = new \stdClass();
+ $tel = new \stdClass();
+ $tel->nationcode = "".$nationCode;
+ $tel->mobile = "".$phoneNumber;
+
+ $data->tel = $tel;
+ $data->msg = $msg;
+ $data->playtimes = $playtimes;
+ // app凭证
+ $data->sig = hash("sha256",
+ "appkey=".$this->appkey."&random=".$random."&time="
+ .$curTime."&mobile=".$phoneNumber, FALSE);
+ // unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
+ $data->time = $curTime;
+ $data->ext = $ext;
+
+ return $this->util->sendCurlPost($wholeUrl, $data);
+ }
+}
diff --git a/qcloudsms/src/TtsVoiceSender.php b/qcloudsms/src/TtsVoiceSender.php
new file mode 100644
index 0000000..559f1b5
--- /dev/null
+++ b/qcloudsms/src/TtsVoiceSender.php
@@ -0,0 +1,71 @@
+url = "https://cloud.tim.qq.com/v5/tlsvoicesvr/sendtvoice";
+ $this->appid = $appid;
+ $this->appkey = $appkey;
+ $this->util = new SmsSenderUtil();
+ }
+
+ /**
+ *
+ * 指定模板发送语音短信
+ *
+ * @param string $nationCode 国家码,如 86 为中国
+ * @param string $phoneNumber 不带国家码的手机号
+ * @param int $templId 模板 id
+ * @param array $params 模板参数列表,如模板 {1}...{2}...{3},需要带三个参数
+ * @param string $playtimes 播放次数,可选,最多3次,默认2次
+ * @param string $ext 用户的session内容,服务端原样返回,可选字段,不需要可填空串
+ * @return string 应答json字符串,详细内容参见腾讯云协议文档
+ */
+ public function send($nationCode, $phoneNumber, $templId, $params, $playtimes = 2, $ext = "")
+ {
+ $random = $this->util->getRandom();
+ $curTime = time();
+ $wholeUrl = $this->url . "?sdkappid=" . $this->appid . "&random=" . $random;
+
+ // 按照协议组织 post 包体
+ $data = new \stdClass();
+ $tel = new \stdClass();
+ $tel->nationcode = "".$nationCode;
+ $tel->mobile = "".$phoneNumber;
+ $data->tel = $tel;
+ $data->tpl_id = $templId;
+ $data->params = $params;
+ $data->playtimes = $playtimes;
+
+ // app凭证
+ $data->sig = $this->util->calculateSig($this->appkey, $random,
+ $curTime, array($phoneNumber));
+
+ // unix时间戳,请求发起时间,如果和系统时间相差超过10分钟则会返回失败
+ $data->time = $curTime;
+ $data->ext = $ext;
+
+ return $this->util->sendCurlPost($wholeUrl, $data);
+ }
+}
diff --git a/qcloudsms/src/VoiceFileUploader.php b/qcloudsms/src/VoiceFileUploader.php
new file mode 100644
index 0000000..cef6fee
--- /dev/null
+++ b/qcloudsms/src/VoiceFileUploader.php
@@ -0,0 +1,66 @@
+url = "https://cloud.tim.qq.com/v5/tlsvoicesvr/uploadvoicefile";
+ $this->appid = $appid;
+ $this->appkey = $appkey;
+ $this->util = new SmsSenderUtil();
+ }
+
+ /**
+ *
+ * 上传语音文件
+ *
+ * @param string $fileContent 语音文件内容
+ * @param string $contentType 语音文件类型,目前支持 VoiceFileUploader::WAV 和 VoiceFileUploader::MP3
+ * @return string 应答json字符串,详细内容参见腾讯云协议文档
+ */
+ public function upload($fileContent, $contentType)
+ {
+ assert($contentType == self::WAV || $contentType == self::MP3);
+
+ $random = $this->util->getRandom();
+ $curTime = time();
+ $fileSha1Sum = $this->util->sha1sum($fileContent);
+ $auth = $this->util->calculateAuth($this->appkey, $random,
+ $curTime, $fileSha1Sum);
+
+ $req = new \stdClass();
+ $req->url = $this->url . "?sdkappid=" . $this->appid
+ . "&random=" . $random . "&time=" . $curTime;
+ $req->body = $fileContent;
+ $req->headers = array(
+ "Content-Type: " . $contentType,
+ "x-content-sha1: " . $fileSha1Sum,
+ "Authorization: " . $auth
+ );
+
+ return $this->util->fetch($req);
+ }
+}
diff --git a/qcloudsms/src/index.php b/qcloudsms/src/index.php
new file mode 100644
index 0000000..d3f64df
--- /dev/null
+++ b/qcloudsms/src/index.php
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ssr/css/base.css b/ssr/css/base.css
new file mode 100644
index 0000000..452155d
--- /dev/null
+++ b/ssr/css/base.css
@@ -0,0 +1,299 @@
+/**
+ * åˆå§‹åŒ–æµè§ˆå™¨é»˜è®¤æ ·å¼
+ **/
+
+html,body,div,ol,ul,li,dl,dt,dd,h1,h2,h3,h4,h5,h6,input,button,textarea,p,span,table,th,td,form{margin:0;padding:0}
+body,input,button,select,textarea{font:12px/1.5 "Microsoft Yahei","Helvetica Neue";color:#34495e;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ -moz-font-feature-settings: "liga","kern";}
+table{border-collapse:collapse;border-spacing:0}
+img,a img{border:0}
+a{color:#369;outline:medium none;text-decoration:none;}
+a:hover{text-decoration:none}
+label{cursor:pointer}
+ul li,.ol li{list-style:none}
+em,cite,i{font-style:normal}
+p{word-wrap: break-word; word-break: break-all;} /*全部英文å—符下自动æ¢è¡Œ*/
+
+/* 去除Chromeç‰æµè§ˆå™¨æ–‡æœ¬æ¡†é»˜è®¤å‘光边框 */
+input:focus, textarea:focus {outline: none;}
+/* 去除IE10+æµè§ˆå™¨æ–‡æœ¬æ¡†åŽé¢çš„å°å‰å‰ */
+input::-ms-clear {display: none;}
+/* ç¦æ¢å¤šè¡Œæ–‡æœ¬æ¡†textarea拖拽 */
+textarea {resize: none;}
+
+/* ==å…¨å±€é€šç”¨æ ·å¼== */
+
+/* é¿å…å› åå…ƒç´ æµ®åŠ¨è€Œå¯¼è‡´çš„çˆ¶å…ƒç´ é«˜åº¦ç¼ºå¤±èƒ½é—®é¢˜ */
+.cl:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; } .cl { zoom: 1; }
+
+/* 浮动 */
+.z { float: left !important; }
+.y { float: right !important; }
+
+/* é¼ æ ‡æ ·å¼ï¼Œå¯ä»¥æ ¹æ®éœ€è¦æŒ‰åºæ·»åŠ */
+.cur1 { cursor: pointer; }
+
+/* 显示/éšè— */
+.show { display: block !important; }
+.hide { display: none !important; }
+
+/* ç›¸å¯¹å®šä½ */
+.pos { position: relative; }
+
+/* ç°è‰² */
+.grays {
+ filter: url("data:image/svg+xml;utf8, #grayscale"); /* Firefox 3.5+ */
+ -webkit-filter: grayscale(100%); /* chrome+ */
+ filter: grayscale(100%); /* 未æ¥æµè§ˆå™¨ */
+ filter: gray; /* ie6-8 */
+ filter:progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);/*ie6-9 */
+}
+
+/* 通用容器,定义页é¢å®½åº¦ 具有 n, m, w 三个级别 */
+.wpn { width: 1180px; margin: 0 auto; } /* 4 列 * 300 */
+.wpm { width: 1480px; margin: 0 auto; } /* 5 列 * 300 */
+.wpw { width: 1780px; margin: 0 auto; } /* 6 列 * 300 */
+
+.wpf { width: 100%; max-width: 1260px; margin: 0 auto; } /* 4 列 * 300 */ /*实际宽度1180+å·¦å³è¾¹è·å„40*/
+.wpf-row { width: 93.6507936%; margin: 0 3.1746031%;} /*1180/1260,40/1260*/
+.row { width: 100% }
+
+/* 主体内容 */
+.ct { display: block; min-height: 530px;}
+
+/* 主体内容 - 带边æ */
+/*.ctn .mn { width: 880px; float: left; }
+.ctn .sd { width: 280px; float: right; }*/
+.ctn .mn {margin:0 300px 0 0; padding-top: 20px;}
+.ctn .sd {position: absolute; right: 280px; top: 0; bottom: 0; }
+
+/* 文本属性:å—å·ã€é¢œè‰²ã€ç²—细ã€æ£æ–œ */
+/* å—å· */
+.f12 { font-size: 12px; }
+.f14 { font-size: 14px; }
+.f16 { font-size: 16px; }
+.f26 { font-size: 26px; }
+
+/* 颜色 */
+.b8c5ce { color: #b8c5ce; }
+.ff8326 { color: #ff8326; }
+
+/* 粗细 */
+.b { font-weight: bold; }
+
+/* æ£æ–œ */
+.i { font-style: italic; }
+
+/* 外边è·æ ·å¼ï¼Œä½œç”¨äºŽå…ƒç´ 的上下外边è·ï¼Œä¸Šä¸‹å„具有 n, m, w 三个级别 */
+.mtn { margin-top: 5px !important; }
+.mtm { margin-top: 10px !important; }
+.mtw { margin-top: 20px !important; }
+
+.mbn { margin-bottom: 5px !important; }
+.mbm { margin-bottom: 10px !important; }
+.mbw { margin-bottom: 20px !important; }
+
+.mrn { margin-right: 5px !important; }
+.mrm { margin-right: 10px !important; }
+.mrw { margin-right: 20px !important; }/*20/1180=1.6949152%*/
+
+.mln { margin-left: 5px !important; }
+.mlm { margin-left: 10px !important; }
+.mlw { margin-left: 20px !important; }
+
+.mtbn { margin: 5px 0 !important; }
+.mtbm { margin: 10px 0 !important; }
+.mtbw { margin: 20px 0 !important; }
+
+.mlrn { margin: 0 5px !important; }
+.mlrm { margin: 0 10px !important; }
+.mlrw { margin: 0 20px !important; }
+
+
+/* 内边è·æ ·å¼ï¼Œä½œç”¨äºŽå…ƒç´ 的上下内边è·ï¼Œä¸Šä¸‹å„具有 n, m, w 三个级别 */
+.ptn { padding-top: 5px !important; }
+.ptm { padding-top: 10px !important; }
+.ptw { padding-top: 20px !important; }
+
+.pbn { padding-bottom: 5px !important; }
+.pbm { padding-bottom: 10px !important; }
+.pbw { padding-bottom: 20px !important; }
+
+.ptbn { padding: 5px 0 !important; }
+.ptbm { padding: 10px 0 !important; }
+.ptbw { padding: 20px 0 !important; }
+
+.plrn { padding: 0 5px !important; }
+.plrm { padding: 0 10px !important; }
+.plrw { padding: 0 20px !important; }
+
+
+/* ==== 按钮 Buttons 2015-1-12==== */
+.lang-btn {
+ display: inline-block;
+ position: relative;
+ vertical-align: middle;
+ cursor: pointer;
+ white-space: nowrap;
+ background-color: #3499DA;
+ height: 40px;
+ line-height: 40px;
+ font-size: 16px;
+ color: #FFF;
+ border: none;
+ letter-spacing: 1px;
+ overflow: hidden;
+ text-align: center;
+ border-radius:2px;
+}
+/* æ— èƒŒæ™¯æŒ‰é’® */
+.lang-cancel{background:0;color:#2d3e50}
+/* å–消按钮 */
+.lang-btn-none{background:#e4e9ed;color:#2d3e50;}
+.lang-btn-none:hover{background:#e4e9ed;color:#2d3e50;}
+
+.lang-btn-c{display:inline-block;position:relative;vertical-align:middle;cursor:pointer;white-space:nowrap;background:#e4e9ed;height:40px;line-height:40px;
+ font-size:16px;color:#2d3e50;border:0;letter-spacing:1px;overflow:hidden;text-align:center;border-radius:2px}
+/* ä¿®æ”¹æŒ‰é’®çš„é»˜è®¤çŠ¶æ€ */
+.lang-btn:active{outline:0;box-shadow:none}
+.lang-btn:focus{border:0;outline:0;box-shadow:none}
+.lang-btn:hover{text-decoration:none}
+
+/* ç«ç‹å…¼å®¹ */
+.lang-btn::-moz-focus-inner {border: 0;padding: 0;}
+/* æˆåŠŸ */
+.lang-btn-success { background-color: #4a993e; }
+/* 错误 */
+.lang-btn-eroor { background-color: #b33630; }
+/* ä¸å¯æäº¤çŠ¶æ€ */
+.lang-btn-disabled { background-color: #ddd; color: #777; cursor: default; }
+/* 展示 */
+.lang-btn-show { background-color: #e4e9ed; color: #2d3e50; cursor: default; }
+/* å…³è” */
+.lang-btn-relating { background-color: #b8c5ce; color: #2d3e50; }
+
+
+/* æŒ‰é’®æ–‡å— */
+.lang-btn .lang-btn-content { padding: 0 30px; display: block; }
+/* 大的 */
+.lang-btn-big .lang-btn-content { padding: 0 45px; }
+/* 巨大的 */
+.lang-btn-huge { height: 50px; line-height: 50px; }
+.lang-btn-huge .lang-btn-content { padding: 0 45px; }
+/* 按钮的颜色 */
+.lang-btn-col-blue{background:#3499DA;color:#fff;}
+.lang-btn-col-blue:hover{background:#3da2e3;color:#fff;}
+/* 固定宽度的 */
+.lang-btn-fixed-small { width: 100px; }
+.lang-btn-fixed-small .lang-btn-content { padding: 0; }
+
+.lang-btn-fixed-big { width: 160px; }
+.lang-btn-fixed-big .lang-btn-content { padding: 0; }
+
+.lang-btn-fixed-Large { width: 100%; }
+.lang-btn-fixed-Large .lang-btn-content { padding: 0; }
+
+/* å°å—å·æŒ‰é’® 举报弹出框å†ç”¨ */
+.submit-button{width:80px;height:40px;background:#3499da;color:#fff;font-size:14px;cursor:pointer;line-height:40px;border:0;border-radius:2px}
+.submit-button:hover{background:#3da2e3;transition:all .4s ease-in-out 0s}
+.submit-button:active{background:#2e93d4}
+.mini-button-disabble{width:80px;height:40px;background:#b8c5ce;color:#fff;font-size:14px;cursor:pointer;line-height:40px;border:0;border-radius:2px}
+.mini-button-disabble:hover{background:#c8d4db;transition:all .4s ease-in-out 0s}
+.mini-button-disabble:active{background:#a9b9c3}
+
+/* 按钮 Buttons END */
+
+ /* ==== è¡¨å• Input 框 2015-2-28==== 以å‰çš„颜色b8c4ce*/
+.lang-input{padding:14px 15px;height:20px;border:#e4e9ed 1px solid;border-radius:2px;background:#fff;color:#5d6d7e;font-size:16px;line-height:20px;box-sizing: content-box;}
+
+.lang-input:focus {
+ border: 1px solid #3498db;
+ box-shadow: 0 0 4px rgba(41, 128, 185, 0.4);
+}
+/* 焦点/æˆåŠŸ */
+.lang-input-on, .lang-input-success {
+ border: #3498db 1px solid;
+ box-shadow: 0 0 4px rgba(41, 128, 185, 0.4);
+ color: #34495e;
+}
+/* 错误 */
+.lang-input-error {
+ border: #fcab2b 1px solid;
+ box-shadow: 0 0 4px rgba(252, 171, 43, 0.4);
+}
+
+/* form 表å•å›ºå®šå®½åº¦ */
+.w520 { width: 488px; } /* 实际宽度520-内边è·å·¦å³å„15px-边框2 */
+.w880 { width: 848px; } /* 实际宽度520-内边è·å·¦å³å„15px-边框2 */
+.w580 { width: 548px; } /* 实际宽度520-内边è·å·¦å³å„15px-边框2 */
+
+/* textarea使用 */
+.h164 { height: 130px; }
+.lh20 { line-height: 24px; }
+
+.lang-must{ position: absolute; right: 11px; color: #FD8335!important; line-height: 50px!important;}
+/* è¡¨å• Input 框 END */
+
+ /* ====注册输入框 2015-1-12==== */
+.login-icon { display: block; height: 40px; width: 100%; border-bottom: #e9ecee 1px solid; margin-top: 30px; }
+
+/* 输入框活动状æ€/æˆåŠŸ */
+.login-on, .login-success { border-bottom: #3498db 1px solid; }
+.login-on .log-input, .login-error .log-input, .login-success .log-input { color: #5d6d7e; }
+.login-on .iconfont, .login-success .iconfont{color: #3A99D8;}
+
+/* 错误 */
+.login-error { border-bottom: #fcab2b 1px solid; }
+.login-error .iconfont{ color: #fcab2b;}
+
+/* 登录输入框 */
+.log-input { border: none; height: 20px; font-size: 16px; padding: 10px 2.5%; line-height: 20px; color: #b8c4ce; background: #fff; width: 90%;}
+ /*30/400=7.5%,360/400=90%,10/400=2.5%*/
+.log-input-half { border: none; height: 20px; font-size: 16px; padding: 10px 5%; line-height: 20px; color: #b8c4ce; background: #fff; width: 80%;}
+ /*30/200=15%,160/200=80%,10/200=5%*/
+.log-input::-moz-placeholder { color: #b8c4ce;}
+.log-input::-ms-input-placeholder { color: #b8c4ce;}
+.log-input::-webkit-input-placeholder { color: #b8c4ce;}
+.log-input:placeholder { color: #b8c4ce;}
+
+textarea::-moz-placeholder { color: #b8c4ce;}
+textarea::-ms-input-placeholder { color: #b8c4ce;}
+textarea::-webkit-input-placeholder { color: #b8c4ce;}
+textarea:placeholder { color: #b8c4ce;}
+/* 注册输入框 end */
+
+/*message æ醒消æ¯*/
+#ajax-hook{ position:fixed; top:0; z-index:99999; width:100%;}
+.globalInfoTip {z-index: 20; height: 60px;width: 100%;position: relative;cursor: pointer;}
+.globalInfoTip p {text-align: center;font-size: 16px;height: 30px;line-height: 30px;padding: 15px 0;color: #FFF;position: relative;}
+.globalInfoTip .infoTipBack {position: absolute;top: 0;left: 0;right: 0;bottom: 0;background: #3498db;box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);opacity: 0.8;filter:alpha(opacity=80);-moz-opacity: 0.8;-khtml-opacity: 0.8;}
+.msg-bor{border-bottom-color:#e74c3c}
+
+
+/*å—ä½“å›¾æ ‡*/
+.iconfont, [class^="icon-"], [class*=" icon-"] {
+ font-family:"iconfont" !important;
+ font-size:16px;
+ color: #b8c4ce;
+ font-style:normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+ -webkit-font-smoothing: antialiased;
+ -webkit-text-stroke-width: 0.2px;
+ -moz-osx-font-smoothing: grayscale;
+}
+[id^="xunlei_com"],[id*="xunlei_com"]{
+ display:none !important;
+}
+
+/*网站整体ç°è‰²èƒŒæ™¯*/
+body,
+.body-gray { background-color: #eff3f5; }
+/*部分白色背景*/
+.bg-white { background-color: #fff;}
+/*认è¯*/
+.icon-certified2{color: #e74c3c;font-size: 14px;}
\ No newline at end of file
diff --git a/ssr/css/demo.css b/ssr/css/demo.css
new file mode 100644
index 0000000..1864e00
--- /dev/null
+++ b/ssr/css/demo.css
@@ -0,0 +1,29 @@
+body, html { font-size: 100%; padding: 0; margin: 0;}
+
+/* Reset */
+*,
+*:after,
+*:before {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+/* Clearfix hack by Nicolas Gallagher: http://nicolasgallagher.com/micro-clearfix-hack/ */
+.clearfix:before,
+.clearfix:after {
+ content: " ";
+ display: table;
+}
+
+.clearfix:after {
+ clear: both;
+}
+
+body{
+ background: #494A5F;
+ color: #D5D6E2;
+ font-weight: 500;
+ font-size: 1.05em;
+ font-family: "Microsoft YaHei","Segoe UI", "Lucida Grande", Helvetica, Arial,sans-serif;
+}
\ No newline at end of file
diff --git a/ssr/css/iconfont.css b/ssr/css/iconfont.css
new file mode 100644
index 0000000..95fe15e
--- /dev/null
+++ b/ssr/css/iconfont.css
@@ -0,0 +1,683 @@
+
+@font-face {font-family: "iconfont";
+ src: url('iconfont.eot?t=1506407224992'); /* IE9*/
+ src: url('iconfont.eot?t=1506407224992#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('data:application/x-font-woff;charset=utf-8;base64,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') format('woff'),
+ url('iconfont.ttf?t=1506407224992') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
+ url('iconfont.svg?t=1506407224992#iconfont') format('svg'); /* iOS 4.1- */
+}
+
+.iconfont {
+ font-family:"iconfont" !important;
+ font-size:16px;
+ font-style:normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-yuedu:before { content: "\e73f"; }
+
+.icon-xiazai:before { content: "\e73e"; }
+
+.icon-renminbi:before { content: "\e722"; }
+
+.icon-xuanzhuan:before { content: "\e72d"; }
+
+.icon-youjiantou:before { content: "\e708"; }
+
+.icon-dian:before { content: "\e71c"; }
+
+.icon-fail:before { content: "\e718"; }
+
+.icon-succ:before { content: "\e719"; }
+
+.icon-site2:before { content: "\e70a"; }
+
+.icon-bofang:before { content: "\e73c"; }
+
+.icon-activity:before { content: "\e600"; }
+
+.icon-add-dot:before { content: "\e602"; }
+
+.icon-add-round:before { content: "\e603"; }
+
+.icon-add-solid:before { content: "\e604"; }
+
+.icon-add:before { content: "\e605"; }
+
+.icon-android:before { content: "\e606"; }
+
+.icon-arrows-left:before { content: "\e607"; }
+
+.icon-arrows-right:before { content: "\e608"; }
+
+.icon-attachment:before { content: "\e609"; }
+
+.icon-attachment2:before { content: "\e60a"; }
+
+.icon-bag-line:before { content: "\e60b"; }
+
+.icon-ball:before { content: "\e60c"; }
+
+.icon-baoming:before { content: "\e60d"; }
+
+.icon-be:before { content: "\e60e"; }
+
+.icon-bell:before { content: "\e60f"; }
+
+.icon-briefcase:before { content: "\e610"; }
+
+.icon-briefcase2:before { content: "\e611"; }
+
+.icon-butterfly:before { content: "\e612"; }
+
+.icon-cake-line:before { content: "\e613"; }
+
+.icon-captcha:before { content: "\e614"; }
+
+.icon-card:before { content: "\e615"; }
+
+.icon-check:before { content: "\e616"; }
+
+.icon-checked:before { content: "\e617"; }
+
+.icon-close:before { content: "\e619"; }
+
+.icon-cloud:before { content: "\e61a"; }
+
+.icon-code:before { content: "\e61b"; }
+
+.icon-comment-round:before { content: "\e61c"; }
+
+.icon-copyright1:before { content: "\e61d"; }
+
+.icon-copyright2:before { content: "\e61e"; }
+
+.icon-copyright3:before { content: "\e61f"; }
+
+.icon-copyright4:before { content: "\e620"; }
+
+.icon-copyright5:before { content: "\e621"; }
+
+.icon-dang:before { content: "\e622"; }
+
+.icon-del-round:before { content: "\e623"; }
+
+.icon-del:before { content: "\e624"; }
+
+.icon-del1:before { content: "\e625"; }
+
+.icon-dibbble:before { content: "\e626"; }
+
+.icon-dot:before { content: "\e627"; }
+
+.icon-douban1:before { content: "\e628"; }
+
+.icon-down-mini:before { content: "\e629"; }
+
+.icon-down:before { content: "\e62a"; }
+
+.icon-download:before { content: "\e62b"; }
+
+.icon-download2:before { content: "\e62c"; }
+
+.icon-download3:before { content: "\e62d"; }
+
+.icon-edit-round:before { content: "\e62e"; }
+
+.icon-edit:before { content: "\e62f"; }
+
+.icon-edit2:before { content: "\e630"; }
+
+.icon-edu-line:before { content: "\e631"; }
+
+.icon-email-line:before { content: "\e632"; }
+
+.icon-email-line2:before { content: "\e633"; }
+
+.icon-envelope-line:before { content: "\e634"; }
+
+.icon-envelope-round:before { content: "\e635"; }
+
+.icon-envelope-square:before { content: "\e636"; }
+
+.icon-envelope-thin-r:before { content: "\e637"; }
+
+.icon-envelope:before { content: "\e638"; }
+
+.icon-error-thin:before { content: "\e639"; }
+
+.icon-error:before { content: "\e63a"; }
+
+.icon-exit:before { content: "\e63b"; }
+
+.icon-douban:before { content: "\e63c"; }
+
+.icon-exit2:before { content: "\e63d"; }
+
+.icon-experience:before { content: "\e63e"; }
+
+.icon-eye:before { content: "\e63f"; }
+
+.icon-face:before { content: "\e640"; }
+
+.icon-fail1:before { content: "\e641"; }
+
+.icon-flowerpot:before { content: "\e642"; }
+
+.icon-gift:before { content: "\e643"; }
+
+.icon-globe:before { content: "\e644"; }
+
+.icon-heart:before { content: "\e645"; }
+
+.icon-help:before { content: "\e646"; }
+
+.icon-hexagon1:before { content: "\e647"; }
+
+.icon-hexagon-down:before { content: "\e648"; }
+
+.icon-hexagon-up:before { content: "\e649"; }
+
+.icon-hexagon-zan:before { content: "\e64a"; }
+
+.icon-hexagon:before { content: "\e64b"; }
+
+.icon-hexagon11:before { content: "\e64c"; }
+
+.icon-home-line:before { content: "\e64d"; }
+
+.icon-home:before { content: "\e64e"; }
+
+.icon-hot:before { content: "\e64f"; }
+
+.icon-huaban:before { content: "\e650"; }
+
+.icon-txweibo-r:before { content: "\e651"; }
+
+.icon-iconfans-round:before { content: "\e652"; }
+
+.icon-iconfans:before { content: "\e653"; }
+
+.icon-in:before { content: "\e654"; }
+
+.icon-info:before { content: "\e655"; }
+
+.icon-ins:before { content: "\e656"; }
+
+.icon-inspiration:before { content: "\e657"; }
+
+.icon-iphone2:before { content: "\e658"; }
+
+.icon-item:before { content: "\e659"; }
+
+.icon-jiabin:before { content: "\e65a"; }
+
+.icon-join:before { content: "\e65b"; }
+
+.icon-job:before { content: "\e65c"; }
+
+.icon-leaf-round:before { content: "\e65d"; }
+
+.icon-leaf:before { content: "\e65e"; }
+
+.icon-left-thin:before { content: "\e65f"; }
+
+.icon-lef-tthin2:before { content: "\e660"; }
+
+.icon-left:before { content: "\e661"; }
+
+.icon-list:before { content: "\e662"; }
+
+.icon-liucheng:before { content: "\e663"; }
+
+.icon-lock-double:before { content: "\e664"; }
+
+.icon-lock-line:before { content: "\e665"; }
+
+.icon-lock:before { content: "\e666"; }
+
+.icon-lofter:before { content: "\e667"; }
+
+.icon-mac:before { content: "\e668"; }
+
+.icon-mags:before { content: "\e669"; }
+
+.icon-mi:before { content: "\e66a"; }
+
+.icon-microsoft:before { content: "\e66b"; }
+
+.icon-mitag:before { content: "\e66c"; }
+
+.icon-mitag2:before { content: "\e66d"; }
+
+.icon-muni:before { content: "\e66e"; }
+
+.icon-nav:before { content: "\e66f"; }
+
+.icon-next:before { content: "\e670"; }
+
+.icon-ok:before { content: "\e672"; }
+
+.icon-phone-line:before { content: "\e673"; }
+
+.icon-phone:before { content: "\e674"; }
+
+.icon-phone3:before { content: "\e675"; }
+
+.icon-pic-round:before { content: "\e676"; }
+
+.icon-pic:before { content: "\e677"; }
+
+.icon-point:before { content: "\e678"; }
+
+.icon-popularity:before { content: "\e679"; }
+
+.icon-praise1:before { content: "\e67a"; }
+
+.icon-praise2:before { content: "\e67b"; }
+
+.icon-praise3:before { content: "\e67c"; }
+
+.icon-praise4:before { content: "\e67d"; }
+
+.icon-praise5:before { content: "\e67e"; }
+
+.icon-prev:before { content: "\e67f"; }
+
+.icon-py:before { content: "\e680"; }
+
+.icon-qiniu:before { content: "\e681"; }
+
+.icon-qq-line:before { content: "\e682"; }
+
+.icon-qq-round:before { content: "\e683"; }
+
+.icon-qq:before { content: "\e684"; }
+
+.icon-qq2:before { content: "\e685"; }
+
+.icon-quxiao:before { content: "\e686"; }
+
+.icon-qzone:before { content: "\e687"; }
+
+.icon-qzone2:before { content: "\e688"; }
+
+.icon-read:before { content: "\e689"; }
+
+.icon-refresh:before { content: "\e68a"; }
+
+.icon-relating-round:before { content: "\e68c"; }
+
+.icon-relating:before { content: "\e68d"; }
+
+.icon-reply:before { content: "\e68e"; }
+
+.icon-report:before { content: "\e68f"; }
+
+.icon-res:before { content: "\e690"; }
+
+.icon-retract:before { content: "\e691"; }
+
+.icon-right-line:before { content: "\e692"; }
+
+.icon-right-thin:before { content: "\e693"; }
+
+.icon-right-thin2:before { content: "\e694"; }
+
+.icon-right:before { content: "\e695"; }
+
+.icon-right2:before { content: "\e696"; }
+
+.icon-ruzhu:before { content: "\e697"; }
+
+.icon-save:before { content: "\e698"; }
+
+.icon-search:before { content: "\e699"; }
+
+.icon-set:before { content: "\e69a"; }
+
+.icon-share:before { content: "\e69b"; }
+
+.icon-share2:before { content: "\e69c"; }
+
+.icon-sina1:before { content: "\e69d"; }
+
+.icon-sina:before { content: "\e69e"; }
+
+.icon-site:before { content: "\e69f"; }
+
+.icon-site21:before { content: "\e6a0"; }
+
+.icon-star-round:before { content: "\e6a1"; }
+
+.icon-star-solid:before { content: "\e6a2"; }
+
+.icon-star2:before { content: "\e6a3"; }
+
+.icon-student:before { content: "\e6a4"; }
+
+.icon-study:before { content: "\e6a5"; }
+
+.icon-succ1:before { content: "\e6a6"; }
+
+.icon-tag-mini:before { content: "\e6a7"; }
+
+.icon-tag:before { content: "\e6a8"; }
+
+.icon-talk:before { content: "\e6a9"; }
+
+.icon-tel-round:before { content: "\e6aa"; }
+
+.icon-tel:before { content: "\e6ab"; }
+
+.icon-tel2:before { content: "\e6ac"; }
+
+.icon-time:before { content: "\e6ad"; }
+
+.icon-time1:before { content: "\e6ae"; }
+
+.icon-tool:before { content: "\e6af"; }
+
+.icon-topic:before { content: "\e6b0"; }
+
+.icon-trophy:before { content: "\e6b1"; }
+
+.icon-twitter:before { content: "\e6b2"; }
+
+.icon-txweibo:before { content: "\e6b3"; }
+
+.icon-txweibo1:before { content: "\e6b4"; }
+
+.icon-type1:before { content: "\e6b5"; }
+
+.icon-type2:before { content: "\e6b6"; }
+
+.icon-ucloud:before { content: "\e6b7"; }
+
+.icon-ui:before { content: "\e6b8"; }
+
+.icon-ui3:before { content: "\e6b9"; }
+
+.icon-ui4:before { content: "\e6ba"; }
+
+.icon-uicn:before { content: "\e6bb"; }
+
+.icon-uimini:before { content: "\e6bc"; }
+
+.icon-up-experience:before { content: "\e6bd"; }
+
+.icon-up-pic:before { content: "\e6be"; }
+
+.icon-up-posts:before { content: "\e6bf"; }
+
+.icon-up:before { content: "\e6c0"; }
+
+.icon-upload:before { content: "\e6c1"; }
+
+.icon-uptop:before { content: "\e6c2"; }
+
+.icon-user:before { content: "\e6c4"; }
+
+.icon-warn:before { content: "\e6c5"; }
+
+.icon-warn2:before { content: "\e6c6"; }
+
+.icon-weixin:before { content: "\e6c7"; }
+
+.icon-weixin1:before { content: "\e6d4"; }
+
+.icon-xiangqing:before { content: "\e6d6"; }
+
+.icon-zanzhu:before { content: "\e6d7"; }
+
+.icon-zcn:before { content: "\e6d8"; }
+
+.icon-zhihu:before { content: "\e6d9"; }
+
+.icon-zhuibo:before { content: "\e6da"; }
+
+.icon-comment:before { content: "\e601"; }
+
+.icon-envelope-thin:before { content: "\e618"; }
+
+.icon-fans:before { content: "\e671"; }
+
+.icon-horn:before { content: "\e68b"; }
+
+.icon-bell2:before { content: "\e6ca"; }
+
+.icon-soup:before { content: "\e6cc"; }
+
+.icon-heart-round:before { content: "\e6cd"; }
+
+.icon-star1:before { content: "\e6ce"; }
+
+.icon-hexagon-tag:before { content: "\e6cb"; }
+
+.icon-star:before { content: "\e6c9"; }
+
+.icon-user-line:before { content: "\e6c3"; }
+
+.icon-add-bold:before { content: "\e6cf"; }
+
+.icon-close-bold:before { content: "\e6d0"; }
+
+.icon-ok-sign:before { content: "\e6d1"; }
+
+.icon-relating-bold:before { content: "\e6d2"; }
+
+.icon-leaf-line:before { content: "\e6d3"; }
+
+.icon-hexagon-line:before { content: "\e6c8"; }
+
+.icon-xingbie:before { content: "\e6d5"; }
+
+.icon-hexagon-tag2:before { content: "\e6db"; }
+
+.icon-loading:before { content: "\e6dc"; }
+
+.icon-kefu:before { content: "\e73d"; }
+
+.icon-noeye:before { content: "\e739"; }
+
+.icon-ok_00:before { content: "\e6dd"; }
+
+.icon-more_info:before { content: "\e6de"; }
+
+.icon-account_safe:before { content: "\e6df"; }
+
+.icon-bsc_info:before { content: "\e6e0"; }
+
+.icon-renzheng:before { content: "\e6e1"; }
+
+.icon-not_by:before { content: "\e6e2"; }
+
+.icon-warning_0:before { content: "\e6e3"; }
+
+.icon-updata:before { content: "\e6e5"; }
+
+.icon-ok_j:before { content: "\e6e4"; }
+
+.icon-sotip:before { content: "\e6e6"; }
+
+.icon-uptop_1:before { content: "\e6e7"; }
+
+.icon-article:before { content: "\e6e8"; }
+
+.icon-photo:before { content: "\e6e9"; }
+
+.icon-review:before { content: "\e6ea"; }
+
+.icon-huigubg:before { content: "\e6eb"; }
+
+.icon-sanjiaoxing:before { content: "\e706"; }
+
+.icon-gongbu:before { content: "\e6ed"; }
+
+.icon-zuopin:before { content: "\e6ee"; }
+
+.icon-dasai:before { content: "\e6ef"; }
+
+.icon-arrow:before { content: "\e6ec"; }
+
+.icon-zuo:before { content: "\e6f0"; }
+
+.icon-shiming:before { content: "\e6f1"; }
+
+.icon-tuijian:before { content: "\e6f2"; }
+
+.icon-guan:before { content: "\e6f3"; }
+
+.icon-xin:before { content: "\e6f4"; }
+
+.icon-huoju:before { content: "\e6f5"; }
+
+.icon-banquan:before { content: "\e6f6"; }
+
+.icon-xingxing:before { content: "\e6f7"; }
+
+.icon-z01:before { content: "\e6f8"; }
+
+.icon-certified2:before { content: "\e6f9"; }
+
+.icon-zungui01:before { content: "\e6fa"; }
+
+.icon-tiexin01:before { content: "\e6fb"; }
+
+.icon-bq1:before { content: "\e6fc"; }
+
+.icon-xia:before { content: "\e709"; }
+
+.icon-gongbu1:before { content: "\e6fd"; }
+
+.icon-qian:before { content: "\e707"; }
+
+.icon-icon7:before { content: "\e6fe"; }
+
+.icon-icon8:before { content: "\e6ff"; }
+
+.icon-feiji:before { content: "\e73a"; }
+
+.icon-eqq:before { content: "\e700"; }
+
+.icon-e0:before { content: "\e701"; }
+
+.icon-ecom:before { content: "\e702"; }
+
+.icon-ecn:before { content: "\e703"; }
+
+.icon-ea:before { content: "\e704"; }
+
+.icon-zuojiantou:before { content: "\e71a"; }
+
+.icon-fangkuang:before { content: "\e705"; }
+
+.icon-yuan:before { content: "\e71b"; }
+
+.icon-zhongguodianxin:before { content: "\e75e"; }
+
+.icon-list1:before { content: "\e70b"; }
+
+.icon-tubiao:before { content: "\e717"; }
+
+.icon-kongyuan:before { content: "\e71d"; }
+
+.icon-sanjiao:before { content: "\e71e"; }
+
+.icon-fang:before { content: "\e71f"; }
+
+.icon-ue:before { content: "\e720"; }
+
+.icon-zhinanzhen:before { content: "\e73b"; }
+
+.icon-fenghui:before { content: "\e721"; }
+
+.icon-hupo:before { content: "\e723"; }
+
+.icon-perpson:before { content: "\e724"; }
+
+.icon-meiyou:before { content: "\e725"; }
+
+.icon-safe:before { content: "\e727"; }
+
+.icon-liubian:before { content: "\e728"; }
+
+.icon-qizi:before { content: "\e726"; }
+
+.icon-dizhenju:before { content: "\e729"; }
+
+.icon-click:before { content: "\e72a"; }
+
+.icon-location-ball:before { content: "\e72b"; }
+
+.icon-utalk1:before { content: "\e72c"; }
+
+.icon-shu:before { content: "\e740"; }
+
+.icon-yun:before { content: "\e72e"; }
+
+.icon-xxx:before { content: "\e72f"; }
+
+.icon-putui:before { content: "\e730"; }
+
+.icon-shoutui:before { content: "\e731"; }
+
+.icon-biantui:before { content: "\e732"; }
+
+.icon-reduzhi:before { content: "\e70c"; }
+
+.icon-tips-2:before { content: "\e70d"; }
+
+.icon-tips-1:before { content: "\e70e"; }
+
+.icon-tips-1-copy:before { content: "\e75f"; }
+
+.icon-tips-2-copy:before { content: "\e760"; }
+
+.icon-uitm:before { content: "\e70f"; }
+
+.icon-qq1:before { content: "\e738"; }
+
+.icon-xushigandong:before { content: "\e710"; }
+
+.icon-ruweijiang:before { content: "\e711"; }
+
+.icon-jiangbei:before { content: "\e712"; }
+
+.icon-shangchuan:before { content: "\e714"; }
+
+.icon-renqi:before { content: "\e715"; }
+
+.icon-chuangyijiang:before { content: "\e716"; }
+
+.icon-tuandui:before { content: "\e733"; }
+
+.icon-jishujiang:before { content: "\e734"; }
+
+.icon-zuzhi:before { content: "\e713"; }
+
+.icon-bizhi:before { content: "\e735"; }
+
+.icon-r:before { content: "\e736"; }
+
+.icon-dingding:before { content: "\e737"; }
+
+.icon-PDF:before { content: "\e741"; }
+
+.icon-zhuyi:before { content: "\e749"; }
+
+.icon-heiti1:before { content: "\e74a"; }
+
+.icon-fangsong1:before { content: "\e74b"; }
+
+.icon-lishu1:before { content: "\e74c"; }
+
+.icon-kaiti1:before { content: "\e74d"; }
+
+.icon-chuangyi1:before { content: "\e74e"; }
+
+.icon-shuxie1:before { content: "\e74f"; }
+
+.icon-songti1:before { content: "\e750"; }
+
diff --git a/ssr/css/normalize.css b/ssr/css/normalize.css
new file mode 100644
index 0000000..77feb20
--- /dev/null
+++ b/ssr/css/normalize.css
@@ -0,0 +1 @@
+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;-ms-text-size-adjust:100%;-webkit-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;}
\ No newline at end of file
diff --git a/ssr/css/reg.css b/ssr/css/reg.css
new file mode 100644
index 0000000..98485de
--- /dev/null
+++ b/ssr/css/reg.css
@@ -0,0 +1,346 @@
+@charset "utf-8";
+body{
+ background-color: #3895e8;
+}
+.wrap{
+ box-sizing: border-box;
+ height: 100vh;
+ background: url("../img/bj.jpg") no-repeat center;
+ background-size: auto 100vh;
+ position: relative;
+}
+.form-data{
+ background-color: #ffffff;
+ width: 460px;
+ left: 50%;
+ margin-left: -230px;
+ border-radius: 5px;
+ box-shadow: 0 0 30px rgba(0,0,0,.1);
+ padding: 65px 0 30px 0;
+ position: fixed;
+ top: 15%;
+}
+.form-data .tel-warn{
+ position: absolute;
+ color: #ea5d5f;
+ font-size: 12px;
+ right: 0;
+ top: 22px;
+}
+.form-data .tel-warn i{
+ display: inline-block;
+ vertical-align: middle;
+ color: #ea5d5f;
+ font-size: 16px;
+ margin-top: -3px;
+ margin-left: 5px;
+}
+.form-data .p-input,.find_password .p-input{
+ padding: 5px 0;
+ height: 44px;
+ box-sizing: border-box;
+ border-bottom: 1px solid #e5e5e5;
+ width: 340px;
+ margin: 0 auto 16px;
+ line-height: 14px;
+ display: block;
+}
+.form-data .code{
+ width: 340px;
+ margin-left: 60px;
+}
+.form-data .code input{
+ width: 200px;
+}
+.form-data .code img{
+ width: 120px;
+ position: absolute;
+ right: 0;
+ bottom: 2px;
+}
+.form-data .code .img-err{
+ right: 120px;
+ top: 15px
+}
+.form-data .code a{
+ display: inline-block;
+ position: absolute;
+ width: 80px;
+ height: 34px;
+ line-height: 34px;
+ text-align: center;
+ color: #000;
+ left: 320px;
+ bottom: 0;
+}
+.form-data .send{
+ color: #969696;
+ position: absolute;
+ right: 0;
+ top: 24px;
+ z-index: 10;
+}
+.form-data .send:hover{
+ color: #3895e8;
+}
+.form-data .time{
+ color: #969696;
+ position: absolute;
+ right: 0;
+ top: 24px;
+ font-size: 14px;
+}
+.form-data label,.find_password label{
+ font-size: 14px;
+ position: absolute;
+ display: inline-block;
+ color: #cacaca;
+ top: 22px;
+}
+.form-data input,.find_password input{
+ outline: none;
+ border: none;
+ z-index: 5;
+ position: absolute;
+ top: 13px;
+ width: 340px;
+ background-color: transparent;
+ font-size: 20px;
+}
+input[type=number] {
+ -moz-appearance:textfield;
+}
+input[type=number]::-webkit-inner-spin-button,
+input[type=number]::-webkit-outer-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
+}
+.form-data .head-logo{
+ position: absolute;
+ top: -47px;
+ left: 116px;
+}
+.reg_checkboxline{
+ font-size: 14px;
+ color: #cacaca;
+ height: 30px;
+ margin: 20px auto 20px;
+ line-height: 30px;
+ width: 340px;
+}
+.form-data .pass-warn{
+ width: 400px;
+ color: #ea5d5f;
+ font-size: 14px;
+ margin: 0 auto;
+}
+.reg_checkboxline p{
+ line-height: 30px;
+ padding: 0;
+ border-bottom: 0;
+}
+.reg_checkboxline a{
+ color: #9e9e9e;
+}
+.reg_checkboxline a:hover{
+ color: #3895e8;
+}
+.reg_checkboxline i.boxcol {
+ background: #3498db;
+ color: #fff;
+}
+.icon-ok-sign {
+ background: #b8c4ce;
+ border-radius: 2px;
+ margin-right: 5px;
+ cursor: pointer;
+ overflow: hidden;
+ width: 16px;
+ height: 16px;
+ font-size: 12px;
+ display: block;
+ margin-top: 7px;
+ line-height: 16px;
+ text-align: center;
+}
+.form-data .lang-btn{
+ width: 340px;
+ font-size: 18px;
+ font-weight: bold;
+ color: white;
+ height: 50px;
+ line-height: 50px;
+ text-align: center;
+ margin: 20px auto;
+ display: block;
+ border-radius: 5px;
+ cursor: pointer;
+ background-color: #42a5f5;
+}
+.form-data .lang-btn.off{
+ color: #a0a0a0;
+ background-color: #e5e5e5;
+}
+.bottom-info{
+ width: 400px;
+ line-height: 18px;
+ font-size: 14px;
+ color: #cacaca;
+ margin: 0 auto 30px;
+ text-align: center;
+}
+.bottom-info a{
+ color: #42a5f5;
+}
+.form-data .error{
+ color: #ea5d5f;
+ font-size: 14px;
+ top: -5px;
+ right: 0;
+ position: absolute;
+}
+.form-data .r-forget{
+ width: 340px;
+ margin: 0 auto;
+}
+.form-data .r-forget a{
+ font-size: 12px;
+ color: #8d8d8d;
+}
+.form-data .r-forget a:hover{
+ color: #3895e8;
+}
+.form-data .third-party{
+ width: 400px;
+ margin: 0 auto;
+ display: flex;
+ justify-content: space-around;
+}
+.form-data .third-party .icon-qq-round{
+ font-size: 40px;
+ color: #e5e5e5;
+ display: inline-block;
+ vertical-align: middle;
+}
+.form-data .third-party .icon-qq-round:hover{
+ color: #42a5f5;
+}
+.form-data .third-party .icon-weixin:hover{
+ color: #0fccbc;
+}
+.form-data .third-party .icon-sina1:hover{
+ color: #da2a2e;
+}
+.form-data .third-party .icon-weixin{
+ font-size: 40px;
+ color: #e5e5e5;
+ display: inline-block;
+ vertical-align: middle;
+}
+.form-data .third-party .icon-sina1{
+ font-size: 36px;
+ color: #e5e5e5;
+ display: inline-block;
+ vertical-align: middle;
+}
+.form-data .change-login{
+ width: 400px;
+ margin: 0 auto 10px;
+ display: flex;
+ justify-content: space-around;
+ font-size: 14px;
+ color: #cacaca;
+}
+.form-data .change-login p{
+ cursor: pointer;
+}
+.form-data .change-login p.on{
+ color: #76b9f7;
+}
+.find_password{
+ background-color: #ffffff;
+ width: 460px;
+ border-radius: 5px;
+ box-shadow: 0 0 30px rgba(0,0,0,.1);
+ padding: 30px 0;
+ left: 50%;
+ margin-left: -230px;
+ position: fixed;
+ top: 15%;
+}
+.find_password h4{
+ font-size: 18px;
+ color: #42a5f5;
+ text-align: center;
+ width: 400px;
+ margin: 0 auto;
+}
+.find_password .right_now{
+ width: 380px;
+ text-align: right;
+ margin: 20px auto 30px;
+ font-size: 12px;
+ color: #cacaca;
+}
+.find_password .right_now a{
+ color: #42a5f5;
+}
+.find_password .pc-very,.find_password .pc-code{
+ display: none;
+}
+.find_password .very2{
+ font-size: 14px;
+ position: absolute;
+ display: inline-block;
+ color: #cacaca;
+ top: 14px;
+ right: 0;
+}
+#pc_reset,#pc_reset2{
+ width: 280px;
+}
+.pc_reset span{
+ display: inline-block;
+ font-size: 14px;
+ position: absolute;
+ /* color: #cacaca; */
+ top: 14px;
+ right: 0;
+}
+.error-tip{
+ position: absolute;
+ right: 0;
+ top: 15px;
+ color: #ea5d5f;
+ font-size: 14px;
+ /* width: 400px; */
+ margin: 0 auto;
+ display: none;
+}
+.find_password .jihuo_email{
+ width: 400px;
+ text-align: center;
+ font-size: 14px;
+ color: #8d8d8d;
+ margin: 0 auto;
+}
+.find_password .again{
+ width: 400px;
+ color: #cacaca;
+ font-size: 12px;
+ text-align: center;
+ margin: 0 auto;
+}
+.find_password .again a{
+ color: #42a5f5;
+}
+.wrap .right{
+ position: absolute;
+ width: 1180px;
+ bottom: -80px;
+ text-align: center;
+ line-height: 40px;
+ left: 50%;
+ margin-left: -590px;
+ color: rgba(0,0,0,.3);
+}
\ No newline at end of file
diff --git a/ssr/img/_notes/dwsync.xml b/ssr/img/_notes/dwsync.xml
new file mode 100644
index 0000000..d5ac164
--- /dev/null
+++ b/ssr/img/_notes/dwsync.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/ssr/img/bj.jpg b/ssr/img/bj.jpg
new file mode 100644
index 0000000..0478b1b
Binary files /dev/null and b/ssr/img/bj.jpg differ
diff --git a/ssr/img/logo.png b/ssr/img/logo.png
new file mode 100644
index 0000000..d2a028f
Binary files /dev/null and b/ssr/img/logo.png differ
diff --git a/ssr/index.php b/ssr/index.php
new file mode 100644
index 0000000..7e05278
--- /dev/null
+++ b/ssr/index.php
@@ -0,0 +1,254 @@
+window.location.href="./intro.php";';}
+
+?>
+
+
+
+
+
+
+ Yimian SSR
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ssr/intro.php b/ssr/intro.php
new file mode 100644
index 0000000..6b83944
--- /dev/null
+++ b/ssr/intro.php
@@ -0,0 +1,28 @@
+
+
+
+
+
+Yimian SSR
+
+
+
+
+
\ No newline at end of file
diff --git a/ssr/js/_notes/dwsync.xml b/ssr/js/_notes/dwsync.xml
new file mode 100644
index 0000000..fc679a4
--- /dev/null
+++ b/ssr/js/_notes/dwsync.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ssr/js/agree.js b/ssr/js/agree.js
new file mode 100644
index 0000000..08b3c18
--- /dev/null
+++ b/ssr/js/agree.js
@@ -0,0 +1,63 @@
+ $(function(){
+ $(".icon-ok-sign").click(function(){
+ verify = $(this).hasClass('boxcol') ? 0 : 1;
+ $(this).toggleClass('boxcol');
+ ob = $('input[name=agree]');
+ ob.val(ob.val()==0?1:0);
+ ob.val(ob.val() !== verify ? verify : ob.val());
+
+ ob.val() == 0 ? $('#errormsg').removeClass('hide').addClass('show') : $('#errormsg').removeClass('show').addClass('hide');
+ });
+ //输入框输入时模拟placeholder效果
+ var oInput = $(".form-data input");
+ oInput.focus(function () {
+ $(this).siblings("label").hide();
+ });
+ oInput.blur(function () {
+ if($(this).val()==""){
+ $(this).siblings("label").show();
+ }
+ });
+ // 输入框内容变化按钮颜色发生变化
+ oInput.keyup(function () {
+ if($(this).val()!="jquery.js"){
+ $(".log-btn").removeClass("off")
+ }else{
+ $(".log-btn").addClass("off")
+ }
+ });
+
+
+ $(".form-data").delegate(".send","click",function () {
+ var oTime = $(".form-data .time"),
+ oSend = $(".form-data .send"),
+ num = parseInt(oTime.text()),
+ oEm = $(".form-data .time em");
+ $(this).hide();
+ oTime.removeClass("hide");
+ var timer = setInterval(function () {
+ var num2 = num-=1;
+ oEm.text(num2);
+ if(num2==0){
+ clearInterval(timer);
+ oSend.text("重新发送验证码");
+ oSend.show();
+ oEm.text("60");
+ oTime.addClass("hide");
+ }
+ },1000);
+ });
+ $(".message").click(function () {
+ $(this).addClass("on");
+ $(".account_number").removeClass("on");
+ $(".form2").removeClass("hide");
+ $(".form1").addClass("hide")
+ });
+ $(".account_number").click(function () {
+ $(this).addClass("on");
+ $(".message").removeClass("on");
+ $(".form2").addClass("hide");
+ $(".form1").removeClass("hide")
+ })
+ });
+
\ No newline at end of file
diff --git a/ssr/js/jquery-1.11.0.min.js b/ssr/js/jquery-1.11.0.min.js
new file mode 100644
index 0000000..046e93a
--- /dev/null
+++ b/ssr/js/jquery-1.11.0.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v1.11.0 | (c) 2005, 2014 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="".trim,l={},m="1.11.0",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!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));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||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return a-parseFloat(a)>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(l.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},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:k&&!k.call("\ufeff\xa0")?function(a){return null==a?"":k.call(a)}: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){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[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&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||n.guid++,e):void 0},now:function(){return+new Date},support:l}),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=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="sizzle"+-new Date,t=a.document,u=0,v=0,w=eb(),x=eb(),y=eb(),z=function(a,b){return a===b&&(j=!0),0},A="undefined",B=1<<31,C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=D.indexOf||function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]===a)return b;return-1},J="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",K="[\\x20\\t\\r\\n\\f]",L="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",M=L.replace("w","w#"),N="\\["+K+"*("+L+")"+K+"*(?:([*^$|!~]?=)"+K+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+M+")|)|)"+K+"*\\]",O=":("+L+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+N.replace(3,8)+")*)|.*)\\)|)",P=new RegExp("^"+K+"+|((?:^|[^\\\\])(?:\\\\.)*)"+K+"+$","g"),Q=new RegExp("^"+K+"*,"+K+"*"),R=new RegExp("^"+K+"*([>+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(O),U=new RegExp("^"+M+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L.replace("w","w*")+")"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=/'|\\/g,ab=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),bb=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)};try{G.apply(D=H.call(t.childNodes),t.childNodes),D[t.childNodes.length].nodeType}catch(cb){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function db(a,b,d,e){var f,g,h,i,j,m,p,q,u,v;if((b?b.ownerDocument||b:t)!==l&&k(b),b=b||l,d=d||[],!a||"string"!=typeof a)return d;if(1!==(i=b.nodeType)&&9!==i)return[];if(n&&!e){if(f=Z.exec(a))if(h=f[1]){if(9===i){if(g=b.getElementById(h),!g||!g.parentNode)return d;if(g.id===h)return d.push(g),d}else if(b.ownerDocument&&(g=b.ownerDocument.getElementById(h))&&r(b,g)&&g.id===h)return d.push(g),d}else{if(f[2])return G.apply(d,b.getElementsByTagName(a)),d;if((h=f[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(h)),d}if(c.qsa&&(!o||!o.test(a))){if(q=p=s,u=b,v=9===i&&a,1===i&&"object"!==b.nodeName.toLowerCase()){m=ob(a),(p=b.getAttribute("id"))?q=p.replace(_,"\\$&"):b.setAttribute("id",q),q="[id='"+q+"'] ",j=m.length;while(j--)m[j]=q+pb(m[j]);u=$.test(a)&&mb(b.parentNode)||b,v=m.join(",")}if(v)try{return G.apply(d,u.querySelectorAll(v)),d}catch(w){}finally{p||b.removeAttribute("id")}}}return xb(a.replace(P,"$1"),b,d,e)}function eb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function fb(a){return a[s]=!0,a}function gb(a){var b=l.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function hb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function ib(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||B)-(~a.sourceIndex||B);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function jb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function kb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function lb(a){return fb(function(b){return b=+b,fb(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 mb(a){return a&&typeof a.getElementsByTagName!==A&&a}c=db.support={},f=db.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},k=db.setDocument=function(a){var b,e=a?a.ownerDocument||a:t,g=e.defaultView;return e!==l&&9===e.nodeType&&e.documentElement?(l=e,m=e.documentElement,n=!f(e),g&&g!==g.top&&(g.addEventListener?g.addEventListener("unload",function(){k()},!1):g.attachEvent&&g.attachEvent("onunload",function(){k()})),c.attributes=gb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=gb(function(a){return a.appendChild(e.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(e.getElementsByClassName)&&gb(function(a){return a.innerHTML="
",a.firstChild.className="i",2===a.getElementsByClassName("i").length}),c.getById=gb(function(a){return m.appendChild(a).id=s,!e.getElementsByName||!e.getElementsByName(s).length}),c.getById?(d.find.ID=function(a,b){if(typeof b.getElementById!==A&&n){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ab,bb);return function(a){var c=typeof a.getAttributeNode!==A&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return typeof b.getElementsByTagName!==A?b.getElementsByTagName(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 typeof b.getElementsByClassName!==A&&n?b.getElementsByClassName(a):void 0},p=[],o=[],(c.qsa=Y.test(e.querySelectorAll))&&(gb(function(a){a.innerHTML=" ",a.querySelectorAll("[t^='']").length&&o.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||o.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll(":checked").length||o.push(":checked")}),gb(function(a){var b=e.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&o.push("name"+K+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||o.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),o.push(",.*:")})),(c.matchesSelector=Y.test(q=m.webkitMatchesSelector||m.mozMatchesSelector||m.oMatchesSelector||m.msMatchesSelector))&&gb(function(a){c.disconnectedMatch=q.call(a,"div"),q.call(a,"[s!='']:x"),p.push("!=",O)}),o=o.length&&new RegExp(o.join("|")),p=p.length&&new RegExp(p.join("|")),b=Y.test(m.compareDocumentPosition),r=b||Y.test(m.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},z=b?function(a,b){if(a===b)return j=!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===e||a.ownerDocument===t&&r(t,a)?-1:b===e||b.ownerDocument===t&&r(t,b)?1:i?I.call(i,a)-I.call(i,b):0:4&d?-1:1)}:function(a,b){if(a===b)return j=!0,0;var c,d=0,f=a.parentNode,g=b.parentNode,h=[a],k=[b];if(!f||!g)return a===e?-1:b===e?1:f?-1:g?1:i?I.call(i,a)-I.call(i,b):0;if(f===g)return ib(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)k.unshift(c);while(h[d]===k[d])d++;return d?ib(h[d],k[d]):h[d]===t?-1:k[d]===t?1:0},e):l},db.matches=function(a,b){return db(a,null,null,b)},db.matchesSelector=function(a,b){if((a.ownerDocument||a)!==l&&k(a),b=b.replace(S,"='$1']"),!(!c.matchesSelector||!n||p&&p.test(b)||o&&o.test(b)))try{var d=q.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return db(b,l,null,[a]).length>0},db.contains=function(a,b){return(a.ownerDocument||a)!==l&&k(a),r(a,b)},db.attr=function(a,b){(a.ownerDocument||a)!==l&&k(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!n):void 0;return void 0!==f?f:c.attributes||!n?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},db.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},db.uniqueSort=function(a){var b,d=[],e=0,f=0;if(j=!c.detectDuplicates,i=!c.sortStable&&a.slice(0),a.sort(z),j){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return i=null,a},e=db.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=db.selectors={cacheLength:50,createPseudo:fb,match:V,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(ab,bb),a[3]=(a[4]||a[5]||"").replace(ab,bb),"~="===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]||db.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]&&db.error(a[0]),a},PSEUDO:function(a){var b,c=!a[5]&&a[2];return V.CHILD.test(a[0])?null:(a[3]&&void 0!==a[4]?a[2]=a[4]:c&&T.test(c)&&(b=ob(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(ab,bb).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=w[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&w(a,function(a){return b.test("string"==typeof a.className&&a.className||typeof a.getAttribute!==A&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=db.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+" ").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(),t=!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&&t){k=q[s]||(q[s]={}),j=k[a]||[],n=j[0]===u&&j[1],m=j[0]===u&&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]=[u,n,m];break}}else if(t&&(j=(b[s]||(b[s]={}))[a])&&j[0]===u)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&&(t&&((l[s]||(l[s]={}))[a]=[u,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()]||db.error("unsupported pseudo: "+a);return e[s]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?fb(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I.call(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:fb(function(a){var b=[],c=[],d=g(a.replace(P,"$1"));return d[s]?fb(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),!c.pop()}}),has:fb(function(a){return function(b){return db(a,b).length>0}}),contains:fb(function(a){return function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:fb(function(a){return U.test(a||"")||db.error("unsupported lang: "+a),a=a.replace(ab,bb).toLowerCase(),function(b){var c;do if(c=n?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===m},focus:function(a){return a===l.activeElement&&(!l.hasFocus||l.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 X.test(a.nodeName)},input:function(a){return W.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:lb(function(){return[0]}),last:lb(function(a,b){return[b-1]}),eq:lb(function(a,b,c){return[0>c?c+b:c]}),even:lb(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:lb(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:lb(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:lb(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function qb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=v++;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=[u,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[s]||(b[s]={}),(h=i[d])&&h[0]===u&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function rb(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 sb(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 tb(a,b,c,d,e,f){return d&&!d[s]&&(d=tb(d)),e&&!e[s]&&(e=tb(e,f)),fb(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||wb(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:sb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=sb(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?I.call(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=sb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ub(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],i=g||d.relative[" "],j=g?1:0,k=qb(function(a){return a===b},i,!0),l=qb(function(a){return I.call(b,a)>-1},i,!0),m=[function(a,c,d){return!g&&(d||c!==h)||((b=c).nodeType?k(a,c,d):l(a,c,d))}];f>j;j++)if(c=d.relative[a[j].type])m=[qb(rb(m),c)];else{if(c=d.filter[a[j].type].apply(null,a[j].matches),c[s]){for(e=++j;f>e;e++)if(d.relative[a[e].type])break;return tb(j>1&&rb(m),j>1&&pb(a.slice(0,j-1).concat({value:" "===a[j-2].type?"*":""})).replace(P,"$1"),c,e>j&&ub(a.slice(j,e)),f>e&&ub(a=a.slice(e)),f>e&&pb(a))}m.push(c)}return rb(m)}function vb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,i,j,k){var m,n,o,p=0,q="0",r=f&&[],s=[],t=h,v=f||e&&d.find.TAG("*",k),w=u+=null==t?1:Math.random()||.1,x=v.length;for(k&&(h=g!==l&&g);q!==x&&null!=(m=v[q]);q++){if(e&&m){n=0;while(o=a[n++])if(o(m,g,i)){j.push(m);break}k&&(u=w)}c&&((m=!o&&m)&&p--,f&&r.push(m))}if(p+=q,c&&q!==p){n=0;while(o=b[n++])o(r,s,g,i);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=E.call(j));s=sb(s)}G.apply(j,s),k&&!f&&s.length>0&&p+b.length>1&&db.uniqueSort(j)}return k&&(u=w,h=t),r};return c?fb(f):f}g=db.compile=function(a,b){var c,d=[],e=[],f=y[a+" "];if(!f){b||(b=ob(a)),c=b.length;while(c--)f=ub(b[c]),f[s]?d.push(f):e.push(f);f=y(a,vb(e,d))}return f};function wb(a,b,c){for(var d=0,e=b.length;e>d;d++)db(a,b[d],c);return c}function xb(a,b,e,f){var h,i,j,k,l,m=ob(a);if(!f&&1===m.length){if(i=m[0]=m[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&c.getById&&9===b.nodeType&&n&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(ab,bb),b)||[])[0],!b)return e;a=a.slice(i.shift().value.length)}h=V.needsContext.test(a)?0:i.length;while(h--){if(j=i[h],d.relative[k=j.type])break;if((l=d.find[k])&&(f=l(j.matches[0].replace(ab,bb),$.test(i[0].type)&&mb(b.parentNode)||b))){if(i.splice(h,1),a=f.length&&pb(i),!a)return G.apply(e,f),e;break}}}return g(a,m)(f,b,!n,e,$.test(a)&&mb(b.parentNode)||b),e}return c.sortStable=s.split("").sort(z).join("")===s,c.detectDuplicates=!!j,k(),c.sortDetached=gb(function(a){return 1&a.compareDocumentPosition(l.createElement("div"))}),gb(function(a){return a.innerHTML=" ","#"===a.firstChild.getAttribute("href")})||hb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&gb(function(a){return a.innerHTML=" ",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||hb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),gb(function(a){return null==a.getAttribute("disabled")})||hb(J,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),db}(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 n.inArray(a,b)>=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=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},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=a.document,A=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,B=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:A.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:z,!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}if(d=z.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return y.find(a);this.length=1,this[0]=d}return this.context=z,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))};B.prototype=n.fn,y=n(z);var C=/^(?:parents|prev(?:Until|All))/,D={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!n(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];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,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))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?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):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 E(a,b){do a=a[b];while(a&&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 E(a,"nextSibling")},prev:function(a){return E(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 n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document: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&&(D[a]||(e=n.unique(e)),C.test(a)&&(e=e.reverse())),this.pushStack(e)}});var F=/\S+/g,G={};function H(a){var b=G[a]={};return n.each(a.match(F)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?G[a]||H(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(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&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&n.each(arguments,function(a,c){var d;while((d=n.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};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 I;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){if(a===!0?!--n.readyWait:!n.isReady){if(!z.body)return setTimeout(n.ready);n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(z,[n]),n.fn.trigger&&n(z).trigger("ready").off("ready"))}}});function J(){z.addEventListener?(z.removeEventListener("DOMContentLoaded",K,!1),a.removeEventListener("load",K,!1)):(z.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(z.addEventListener||"load"===event.type||"complete"===z.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===z.readyState)setTimeout(n.ready);else if(z.addEventListener)z.addEventListener("DOMContentLoaded",K,!1),a.addEventListener("load",K,!1);else{z.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&z.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!n.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}J(),n.ready()}}()}return I.promise(b)};var L="undefined",M;for(M in n(l))break;l.ownLast="0"!==M,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c=z.getElementsByTagName("body")[0];c&&(a=z.createElement("div"),a.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",b=z.createElement("div"),c.appendChild(a).appendChild(b),typeof b.style.zoom!==L&&(b.style.cssText="border:0;margin:0;width:1px;padding:1px;display:inline;zoom:1",(l.inlineBlockNeedsLayout=3===b.offsetWidth)&&(c.style.zoom=1)),c.removeChild(a),a=b=null)}),function(){var a=z.createElement("div");if(null==l.deleteExpando){l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}}a=null}(),n.acceptData=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(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){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(n.acceptData(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f
+}}function S(a,b,c){if(n.acceptData(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),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=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d]));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(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 n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;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},X=/^(?:checkbox|radio)$/i;!function(){var a=z.createDocumentFragment(),b=z.createElement("div"),c=z.createElement("input");if(b.setAttribute("className","t"),b.innerHTML=" a ",l.leadingWhitespace=3===b.firstChild.nodeType,l.tbody=!b.getElementsByTagName("tbody").length,l.htmlSerialize=!!b.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==z.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,a.appendChild(c),l.appendChecked=c.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,a.appendChild(b),b.innerHTML=" ",l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){l.noCloneEvent=!1}),b.cloneNode(!0).click()),null==l.deleteExpando){l.deleteExpando=!0;try{delete b.test}catch(d){l.deleteExpando=!1}}a=b=c=null}(),function(){var b,c,d=z.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),l[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var Y=/^(?:input|select|textarea)$/i,Z=/^key/,$=/^(?:mouse|contextmenu)|click/,_=/^(?:focusinfocus|focusoutblur)$/,ab=/^([^.]*)(?:\.(.+)|)$/;function bb(){return!0}function cb(){return!1}function db(){try{return z.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=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof n===L||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(F)||[""],h=b.length;while(h--)f=ab.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=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(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(F)||[""],j=b.length;while(j--)if(h=ab.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=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,m,o=[d||z],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||z,3!==d.nodeType&&8!==d.nodeType&&!_.test(p+n.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[n.expando]?b:new n.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),k=n.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!n.isWindow(d)){for(i=k.delegateType||p,_.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||z)&&o.push(l.defaultView||l.parentWindow||a)}m=0;while((h=o[m++])&&!b.isPropagationStopped())b.type=m>1?i:k.bindType||p,f=(n._data(h,"events")||{})[b.type]&&n._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&n.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&n.acceptData(d)&&g&&d[p]&&!n.isWindow(d)){l=d[g],l&&(d[g]=null),n.event.triggered=p;try{d[p]()}catch(r){}n.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(n._data(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,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((n.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!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(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?n(c,this).index(i)>=0:n.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h ]","i"),ib=/^\s+/,jb=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,kb=/<([\w:]+)/,lb=/\s*$/g,sb={option:[1,""," "],legend:[1,""," "],area:[1,""," "],param:[1,""," "],thead:[1,""],tr:[2,""],col:[2,""],td:[3,""],_default:l.htmlSerialize?[0,"",""]:[1,"X","
"]},tb=eb(z),ub=tb.appendChild(z.createElement("div"));sb.optgroup=sb.option,sb.tbody=sb.tfoot=sb.colgroup=sb.caption=sb.thead,sb.th=sb.td;function vb(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==L?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==L?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,vb(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function wb(a){X.test(a.type)&&(a.defaultChecked=a.checked)}function xb(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 yb(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function zb(a){var b=qb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ab(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}function Bb(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Cb(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(yb(b).text=a.text,zb(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&X.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}n.extend({clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!hb.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ub.innerHTML=a.outerHTML,ub.removeChild(f=ub.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=vb(f),h=vb(a),g=0;null!=(e=h[g]);++g)d[g]&&Cb(e,d[g]);if(b)if(c)for(h=h||vb(a),d=d||vb(f),g=0;null!=(e=h[g]);g++)Bb(e,d[g]);else Bb(a,f);return d=vb(f,"script"),d.length>0&&Ab(d,!i&&vb(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k,m=a.length,o=eb(b),p=[],q=0;m>q;q++)if(f=a[q],f||0===f)if("object"===n.type(f))n.merge(p,f.nodeType?[f]:f);else if(mb.test(f)){h=h||o.appendChild(b.createElement("div")),i=(kb.exec(f)||["",""])[1].toLowerCase(),k=sb[i]||sb._default,h.innerHTML=k[1]+f.replace(jb,"<$1>$2>")+k[2],e=k[0];while(e--)h=h.lastChild;if(!l.leadingWhitespace&&ib.test(f)&&p.push(b.createTextNode(ib.exec(f)[0])),!l.tbody){f="table"!==i||lb.test(f)?""!==k[1]||lb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)n.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}n.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),l.appendChecked||n.grep(vb(p,"input"),wb),q=0;while(f=p[q++])if((!d||-1===n.inArray(f,d))&&(g=n.contains(f.ownerDocument,f),h=vb(o.appendChild(f),"script"),g&&Ab(h),c)){e=0;while(f=h[e++])pb.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.deleteExpando,m=n.event.special;null!=(d=a[h]);h++)if((b||n.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k?delete d[i]:typeof d.removeAttribute!==L?d.removeAttribute(i):d[i]=null,c.push(f))}}}),n.fn.extend({text:function(a){return W(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||z).createTextNode(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=xb(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=xb(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(vb(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&Ab(vb(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(vb(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}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 W(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(gb,""):void 0;if(!("string"!=typeof a||nb.test(a)||!l.htmlSerialize&&hb.test(a)||!l.leadingWhitespace&&ib.test(a)||sb[(kb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(jb,"<$1>$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(vb(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(vb(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,k=this.length,m=this,o=k-1,p=a[0],q=n.isFunction(p);if(q||k>1&&"string"==typeof p&&!l.checkClone&&ob.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(k&&(i=n.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=n.map(vb(i,"script"),yb),f=g.length;k>j;j++)d=i,j!==o&&(d=n.clone(d,!0,!0),f&&n.merge(g,vb(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,n.map(g,zb),j=0;f>j;j++)d=g[j],pb.test(d.type||"")&&!n._data(d,"globalEval")&&n.contains(h,d)&&(d.src?n._evalUrl&&n._evalUrl(d.src):n.globalEval((d.text||d.textContent||d.innerHTML||"").replace(rb,"")));i=c=null}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=0,e=[],g=n(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Db,Eb={};function Fb(b,c){var d=n(c.createElement(b)).appendTo(c.body),e=a.getDefaultComputedStyle?a.getDefaultComputedStyle(d[0]).display:n.css(d[0],"display");return d.detach(),e}function Gb(a){var b=z,c=Eb[a];return c||(c=Fb(a,b),"none"!==c&&c||(Db=(Db||n("")).appendTo(b.documentElement),b=(Db[0].contentWindow||Db[0].contentDocument).document,b.write(),b.close(),c=Fb(a,b),Db.detach()),Eb[a]=c),c}!function(){var a,b,c=z.createElement("div"),d="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";c.innerHTML=" a ",a=c.getElementsByTagName("a")[0],a.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(a.style.opacity),l.cssFloat=!!a.style.cssFloat,c.style.backgroundClip="content-box",c.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===c.style.backgroundClip,a=c=null,l.shrinkWrapBlocks=function(){var a,c,e,f;if(null==b){if(a=z.getElementsByTagName("body")[0],!a)return;f="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",c=z.createElement("div"),e=z.createElement("div"),a.appendChild(c).appendChild(e),b=!1,typeof e.style.zoom!==L&&(e.style.cssText=d+";width:1px;padding:1px;zoom:1",e.innerHTML="
",e.firstChild.style.width="5px",b=3!==e.offsetWidth),a.removeChild(c),a=c=e=null}return b}}();var Hb=/^margin/,Ib=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Jb,Kb,Lb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Jb=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),Ib.test(g)&&Hb.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+""}):z.documentElement.currentStyle&&(Jb=function(a){return a.currentStyle},Kb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Jb(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ib.test(g)&&!Lb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Mb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h=z.createElement("div"),i="border:0;width:0;height:0;position:absolute;top:0;left:-9999px",j="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;padding:0;margin:0;border:0";h.innerHTML=" a ",b=h.getElementsByTagName("a")[0],b.style.cssText="float:left;opacity:.5",l.opacity=/^0.5/.test(b.style.opacity),l.cssFloat=!!b.style.cssFloat,h.style.backgroundClip="content-box",h.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===h.style.backgroundClip,b=h=null,n.extend(l,{reliableHiddenOffsets:function(){if(null!=c)return c;var a,b,d,e=z.createElement("div"),f=z.getElementsByTagName("body")[0];if(f)return e.setAttribute("className","t"),e.innerHTML=" a ",a=z.createElement("div"),a.style.cssText=i,f.appendChild(a).appendChild(e),e.innerHTML="",b=e.getElementsByTagName("td"),b[0].style.cssText="padding:0;margin:0;border:0;display:none",d=0===b[0].offsetHeight,b[0].style.display="",b[1].style.display="none",c=d&&0===b[0].offsetHeight,f.removeChild(a),e=f=null,c},boxSizing:function(){return null==d&&k(),d},boxSizingReliable:function(){return null==e&&k(),e},pixelPosition:function(){return null==f&&k(),f},reliableMarginRight:function(){var b,c,d,e;if(null==g&&a.getComputedStyle){if(b=z.getElementsByTagName("body")[0],!b)return;c=z.createElement("div"),d=z.createElement("div"),c.style.cssText=i,b.appendChild(c).appendChild(d),e=d.appendChild(z.createElement("div")),e.style.cssText=d.style.cssText=j,e.style.marginRight=e.style.width="0",d.style.width="1px",g=!parseFloat((a.getComputedStyle(e,null)||{}).marginRight),b.removeChild(c)}return g}});function k(){var b,c,h=z.getElementsByTagName("body")[0];h&&(b=z.createElement("div"),c=z.createElement("div"),b.style.cssText=i,h.appendChild(b).appendChild(c),c.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:absolute;display:block;padding:1px;border:1px;width:4px;margin-top:1%;top:1%",n.swap(h,null!=h.style.zoom?{zoom:1}:{},function(){d=4===c.offsetWidth}),e=!0,f=!1,g=!0,a.getComputedStyle&&(f="1%"!==(a.getComputedStyle(c,null)||{}).top,e="4px"===(a.getComputedStyle(c,null)||{width:"4px"}).width),h.removeChild(b),c=h=null)}}(),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 Nb=/alpha\([^)]*\)/i,Ob=/opacity\s*=\s*([^)]*)/,Pb=/^(none|table(?!-c[ea]).+)/,Qb=new RegExp("^("+T+")(.*)$","i"),Rb=new RegExp("^([+-])=("+T+")","i"),Sb={position:"absolute",visibility:"hidden",display:"block"},Tb={letterSpacing:0,fontWeight:400},Ub=["Webkit","O","Moz","ms"];function Vb(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ub.length;while(e--)if(b=Ub[e]+c,b in a)return b;return d}function Wb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&V(d)&&(f[g]=n._data(d,"olddisplay",Gb(d.nodeName)))):f[g]||(e=V(d),(c&&"none"!==c||!e)&&n._data(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}function Xb(a,b,c){var d=Qb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Yb(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+U[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+U[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+U[f]+"Width",!0,e))):(g+=n.css(a,"padding"+U[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+U[f]+"Width",!0,e)));return g}function Zb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Jb(a),g=l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Kb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ib.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Yb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Kb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":l.cssFloat?"cssFloat":"styleFloat"},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;if(b=n.cssProps[h]||(n.cssProps[h]=Vb(i,h)),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Rb.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"),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]="",i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Vb(a.style,h)),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Kb(a,b,d)),"normal"===f&&b in Tb&&(f=Tb[b]),""===c||c?(e=parseFloat(f),c===!0||n.isNumeric(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?0===a.offsetWidth&&Pb.test(n.css(a,"display"))?n.swap(a,Sb,function(){return Zb(a,b,d)}):Zb(a,b,d):void 0},set:function(a,c,d){var e=d&&Jb(a);return Xb(a,c,d?Yb(a,b,d,l.boxSizing()&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Ob.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Nb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Nb.test(f)?f.replace(Nb,e):f+" "+e)}}),n.cssHooks.marginRight=Mb(l.reliableMarginRight,function(a,b){return b?n.swap(a,{display:"inline-block"},Kb,[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+U[d]+b]=f[d]||f[d-2]||f[0];return e}},Hb.test(a)||(n.cssHooks[a+b].set=Xb)}),n.fn.extend({css:function(a,b){return W(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Jb(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 Wb(this,!0)},hide:function(){return Wb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){V(this)?n(this).show():n(this).hide()})}});function $b(a,b,c,d,e){return new $b.prototype.init(a,b,c,d,e)}n.Tween=$b,$b.prototype={constructor:$b,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=$b.propHooks[this.prop];return a&&a.get?a.get(this):$b.propHooks._default.get(this)},run:function(a){var b,c=$b.propHooks[this.prop];return this.pos=b=this.options.duration?n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):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):$b.propHooks._default.set(this),this}},$b.prototype.init.prototype=$b.prototype,$b.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}}},$b.propHooks.scrollTop=$b.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=$b.prototype.init,n.fx.step={};var _b,ac,bc=/^(?:toggle|show|hide)$/,cc=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),dc=/queueHooks$/,ec=[jc],fc={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=cc.exec(b),f=e&&e[3]||(n.cssNumber[a]?"":"px"),g=(n.cssNumber[a]||"px"!==f&&+d)&&cc.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 gc(){return setTimeout(function(){_b=void 0}),_b=n.now()}function hc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=U[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function ic(a,b,c){for(var d,e=(fc[b]||[]).concat(fc["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function jc(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&V(a),r=n._data(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++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k=Gb(a.nodeName),"none"===j&&(j=k),"inline"===j&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==k?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],bc.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}if(!n.isEmptyObject(o)){r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=ic(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function kc(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 lc(a,b,c){var d,e,f=0,g=ec.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=_b||gc(),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:_b||gc(),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(kc(k,j.opts.specialEasing);g>f;f++)if(d=ec[f].call(j,a,k,j.opts))return d;return n.map(k,ic,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(lc,{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],fc[c]=fc[c]||[],fc[c].unshift(b)},prefilter:function(a,b){b?ec.unshift(a):ec.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(V).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=lc(this,n.extend({},a),f);(e||n._data(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=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&dc.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=n._data(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(hc(b,!0),a,d,e)}}),n.each({slideDown:hc("show"),slideUp:hc("hide"),slideToggle:hc("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=n.timers,c=0;for(_b=n.now();ca ",a=e.getElementsByTagName("a")[0],c=z.createElement("select"),d=c.appendChild(z.createElement("option")),b=e.getElementsByTagName("input")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==e.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=d.selected,l.enctype=!!z.createElement("form").enctype,c.disabled=!0,l.optDisabled=!d.disabled,b=z.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value,a=b=c=d=e=null}();var mc=/\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(mc,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b: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||(l.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--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),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}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var nc,oc,pc=n.expr.attrHandle,qc=/^(?:checked|selected)$/i,rc=l.getSetAttribute,sc=l.input;n.fn.extend({attr:function(a,b){return W(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===L?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),d=n.attrHooks[b]||(n.expr.match.bool.test(b)?oc:nc)),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(F);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?sc&&rc||!qc.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(rc?c:d)},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),oc={set:function(a,b,c){return b===!1?n.removeAttr(a,c):sc&&rc||!qc.test(c)?a.setAttribute(!rc&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=pc[b]||n.find.attr;pc[b]=sc&&rc||!qc.test(b)?function(a,b,d){var e,f;return d||(f=pc[b],pc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,pc[b]=f),e}:function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),sc&&rc||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):nc&&nc.set(a,b,c)}}),rc||(nc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},pc.id=pc.name=pc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:nc.set},n.attrHooks.contenteditable={set:function(a,b,c){nc.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var tc=/^(?:input|select|textarea|button|object)$/i,uc=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return W(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),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){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):tc.test(a.nodeName)||uc.test(a.nodeName)&&a.href?0:-1}}}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var vc=/[\t\r\n\f]/g;n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):" ")){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,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(F)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(vc," "):"")){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(F)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===L||"boolean"===c)&&(this.className&&n._data(this,"__className__",this.className),this.className=this.className||a===!1?"":n._data(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(vc," ").indexOf(b)>=0)return!0;return!1}}),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 wc=n.now(),xc=/\?/,yc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(yc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var zc,Ac,Bc=/#.*$/,Cc=/([?&])_=[^&]*/,Dc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Ec=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Fc=/^(?:GET|HEAD)$/,Gc=/^\/\//,Hc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ic={},Jc={},Kc="*/".concat("*");try{Ac=location.href}catch(Lc){Ac=z.createElement("a"),Ac.href="",Ac=Ac.href}zc=Hc.exec(Ac.toLowerCase())||[];function Mc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(F)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Nc(a,b,c,d){var e={},f=a===Jc;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 Oc(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Pc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Qc(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:Ac,type:"GET",isLocal:Ec.test(zc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Kc,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?Oc(Oc(a,n.ajaxSettings),b):Oc(n.ajaxSettings,a)},ajaxPrefilter:Mc(Ic),ajaxTransport:Mc(Jc),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(!j){j={};while(b=Dc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f: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 i&&i.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||Ac)+"").replace(Bc,"").replace(Gc,zc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=n.trim(k.dataType||"*").toLowerCase().match(F)||[""],null==k.crossDomain&&(c=Hc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===zc[1]&&c[2]===zc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(zc[3]||("http:"===zc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=n.param(k.data,k.traditional)),Nc(Ic,k,b,v),2===t)return v;h=k.global,h&&0===n.active++&&n.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Fc.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(xc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Cc.test(e)?e.replace(Cc,"$1_="+wc++):e+(xc.test(e)?"&":"?")+"_="+wc++)),k.ifModified&&(n.lastModified[e]&&v.setRequestHeader("If-Modified-Since",n.lastModified[e]),n.etag[e]&&v.setRequestHeader("If-None-Match",n.etag[e])),(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]?", "+Kc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Nc(Jc,k,b,v)){v.readyState=1,h&&m.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Pc(k,v,c)),u=Qc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(n.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(n.etag[e]=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,h&&m.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(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.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),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){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var 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.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return 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||!l.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||n.css(a,"display"))},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var Rc=/%20/g,Sc=/\[\]$/,Tc=/\r?\n/g,Uc=/^(?:submit|button|image|reset|file)$/i,Vc=/^(?:input|select|textarea|keygen)/i;function Wc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||Sc.test(a)?d(a,e):Wc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Wc(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)Wc(c,a[c],b,e);return d.join("&").replace(Rc,"+")},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")&&Vc.test(this.nodeName)&&!Uc.test(a)&&(this.checked||!X.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(Tc,"\r\n")}}):{name:b.name,value:c.replace(Tc,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&$c()||_c()}:$c;var Xc=0,Yc={},Zc=n.ajaxSettings.xhr();a.ActiveXObject&&n(a).on("unload",function(){for(var a in Yc)Yc[a](void 0,!0)}),l.cors=!!Zc&&"withCredentials"in Zc,Zc=l.ajax=!!Zc,Zc&&n.ajaxTransport(function(a){if(!a.crossDomain||l.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Xc;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)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Yc[g],b=void 0,f.onreadystatechange=n.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Yc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function $c(){try{return new a.XMLHttpRequest}catch(b){}}function _c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}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",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=z.head||n("head")[0]||z.documentElement;return{send:function(d,e){b=z.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var ad=[],bd=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=ad.pop()||n.expando+"_"+wc++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(bd.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&bd.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(bd,"$1"+e):b.jsonp!==!1&&(b.url+=(xc.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,ad.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||z;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 cd=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&cd)return cd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=a.slice(h,a.length),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&n.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?n("").append(n.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};var dd=a.document.documentElement;function ed(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}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)&&n.inArray("auto",[f,i])>-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={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?(typeof e.getBoundingClientRect!==L&&(d=e.getBoundingClientRect()),c=ed(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||dd;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||dd})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return W(this,function(a,d,e){var f=ed(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Mb(l.pixelPosition,function(a,c){return c?(c=Kb(a,b),Ib.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 W(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 fd=a.jQuery,gd=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=gd),b&&a.jQuery===n&&(a.jQuery=fd),n},typeof b===L&&(a.jQuery=a.$=n),n});
\ No newline at end of file
diff --git a/ssr/js/jquery.js b/ssr/js/jquery.js
new file mode 100644
index 0000000..644d35e
--- /dev/null
+++ b/ssr/js/jquery.js
@@ -0,0 +1,4 @@
+/*! jQuery v3.2.1 | (c) JS Foundation and other contributors | jquery.org/license */
+!function(a,b){"use strict";"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){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.2.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c
0&&b-1 in a)}var x=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={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.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=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$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("fieldset");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=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;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 function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(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 qa(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},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=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),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){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML=" ",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML=" ";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.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===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(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,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):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(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!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&&C.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.escape=function(a){return(a+"").replace(ba,ca)},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:V,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(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===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 V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.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(_,aa).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("(^|"+K+")"+a+"("+K+"|$)"))&&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(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},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,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/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=I(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(P,"$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(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).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:oa(!1),disabled:oa(!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 X.test(a.nodeName)},input:function(a){return W.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:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(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}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};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=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML=" ","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML=" ",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext;function B(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()}var C=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,D=/^.[^:#\[\.,]*$/;function E(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):D.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(E(this,a||[],!1))},not:function(a){return this.pushStack(E(this,a||[],!0))},is:function(a){return!!E(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var F,G=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,H=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||F,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:G.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),C.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};H.prototype=r.fn,F=r(d);var I=/^(?:parents|prev(?:Until|All))/,J={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function K(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return K(a,"nextSibling")},prev:function(a){return K(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return B(a,"iframe")?a.contentDocument:(B(a,"template")&&(a=a.content||a),r.merge([],a.childNodes))}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(J[a]||r.uniqueSort(e),I.test(a)&&e.reverse()),this.pushStack(e)}});var L=/[^\x20\t\r\n\f]+/g;function M(a){var b={};return r.each(a.match(L)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?M(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=e||a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function N(a){return a}function O(a){throw a}function P(a,b,c,d){var e;try{a&&r.isFunction(e=a.promise)?e.call(a).done(b).fail(c):a&&r.isFunction(e=a.then)?e.call(a,b,c):b.apply(void 0,[a].slice(d))}catch(a){c.apply(void 0,[a])}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==O&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:N,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:N)),c[2][3].add(g(0,a,r.isFunction(d)?d:O))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(P(a,g.done(h(c)).resolve,g.reject,!b),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)P(e[c],h(c),g.reject);return g.promise()}});var Q=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&Q.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var R=r.Deferred();r.fn.ready=function(a){return R.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||R.resolveWith(d,[r]))}}),r.ready.then=R.then;function S(){d.removeEventListener("DOMContentLoaded",S),
+a.removeEventListener("load",S),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",S),a.addEventListener("load",S));var T=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)T(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){X.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=W.get(a,b),c&&(!d||Array.isArray(c)?d=W.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.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 W.get(a,c)||W.access(a,c,{empty:r.Callbacks("once memory").add(function(){W.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,la=/^$|\/(?:java|ecma)script/i,ma={option:[1,""," "],thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};ma.optgroup=ma.option,ma.tbody=ma.tfoot=ma.colgroup=ma.caption=ma.thead,ma.th=ma.td;function na(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&B(a,b)?r.merge([a],c):c}function oa(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=na(l.appendChild(f),"script"),j&&oa(g),c){k=0;while(f=g[k++])la.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var ra=d.documentElement,sa=/^key/,ta=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ua=/^([^.]*)(?:\.(.+)|)/;function va(){return!0}function wa(){return!1}function xa(){try{return d.activeElement}catch(a){}}function ya(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ya(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=wa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(ra,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(L)||[""],j=b.length;while(j--)h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),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),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=W.hasData(a)&&W.get(a);if(q&&(i=q.events)){b=(b||"").match(L)||[""],j=b.length;while(j--)if(h=ua.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==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,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&W.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(W.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,Aa=/";}
+
+$row = $result->fetch_assoc();
+
+return ($row);
+
+}
+
+function array_orderby()
+{
+ $args = func_get_args();
+ $data = array_shift($args);
+ foreach ($args as $n => $field) {
+ if (is_string($field)) {
+ $tmp = array();
+ foreach ($data as $key => $row)
+ $tmp[$key] = $row[$field];
+ $args[$n] = $tmp;
+ }
+ }
+ $args[] = &$data;
+ call_user_func_array('array_multisort', $args);
+ return array_pop($args);
+}
+
+?>
+
diff --git a/ssr/login_name.php b/ssr/login_name.php
new file mode 100644
index 0000000..70bda9d
--- /dev/null
+++ b/ssr/login_name.php
@@ -0,0 +1,324 @@
+query($sql);
+///禁止非法访问
+if ($result->num_rows > 0) {
+$row=sql_data($conn,'user','tel',$tel);
+$cnt=$row['count'];
+$port=$row['ssr'];
+$cnt++;
+
+$sql1="UPDATE user SET count=$cnt,ip='$ip' WHERE tel='$tel'";
+ if ($conn->query($sql1) === TRUE) {}
+
+ echo "";}else{}
+
+
+
+
+
+
+?>
+
+
+
+
+
+connect_error)
+{
+ die("连接失败: " . $conn->connect_error);
+}
+
+return ($conn);
+}
+
+
+//fnct of get table row number::(data_cnnct var,table name) ::(row number)
+function sql_rowNum($conn,$tableSql)
+{
+$row_count = $conn->query("SELECT COUNT(*) FROM $tableSql");
+list($row_num) = $row_count->fetch_row();
+return ($row_num);
+}
+
+//fnct of getting row data from database::(data_cnnct var, table name,column name, column value)::(row info)
+function sql_data($conn,$table,$clmnName,$value)
+{
+$sql = "SELECT * FROM $table where $clmnName=$value";
+
+$result = $conn->query($sql);
+///禁止非法访问
+if ($result->num_rows > 0) {}else{echo "";}
+
+$row = $result->fetch_assoc();
+
+return ($row);
+
+}
+
+function array_orderby()
+{
+ $args = func_get_args();
+ $data = array_shift($args);
+ foreach ($args as $n => $field) {
+ if (is_string($field)) {
+ $tmp = array();
+ foreach ($data as $key => $row)
+ $tmp[$key] = $row[$field];
+ $args[$n] = $tmp;
+ }
+ }
+ $args[] = &$data;
+ call_user_func_array('array_multisort', $args);
+ return array_pop($args);
+}
+
+?>
+
+
+
+
+
+
+
+ Yimian SSR
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ssr/ssr_key.php b/ssr/ssr_key.php
new file mode 100644
index 0000000..7dc774c
--- /dev/null
+++ b/ssr/ssr_key.php
@@ -0,0 +1,190 @@
+window.location.href="/404.php";';}
+
+$port=$_COOKIE['port'];
+
+$conn=database_cnnct();
+
+$row=sql_data($conn,'ssr','port',$port);
+
+$passwd=$row['passwd'];
+
+$str="aes-256-cfb:$passwd@ssr.yimian.xyz:$port";
+
+$str=base64_encode($str);
+?>
+
+
+
+
+connect_error)
+{
+ die("连接失败: " . $conn->connect_error);
+}
+
+return ($conn);
+}
+
+
+//fnct of get table row number::(data_cnnct var,table name) ::(row number)
+function sql_rowNum($conn,$tableSql)
+{
+$row_count = $conn->query("SELECT COUNT(*) FROM $tableSql");
+list($row_num) = $row_count->fetch_row();
+return ($row_num);
+}
+
+//fnct of getting row data from database::(data_cnnct var, table name,column name, column value)::(row info)
+function sql_data($conn,$table,$clmnName,$value)
+{
+$sql = "SELECT * FROM $table where $clmnName=$value";
+
+$result = $conn->query($sql);
+///禁止非法访问
+if ($result->num_rows > 0) {}else{echo "";}
+
+$row = $result->fetch_assoc();
+
+return ($row);
+
+}
+
+function array_orderby()
+{
+ $args = func_get_args();
+ $data = array_shift($args);
+ foreach ($args as $n => $field) {
+ if (is_string($field)) {
+ $tmp = array();
+ foreach ($data as $key => $row)
+ $tmp[$key] = $row[$field];
+ $args[$n] = $tmp;
+ }
+ }
+ $args[] = &$data;
+ call_user_func_array('array_multisort', $args);
+ return array_pop($args);
+}
+
+?>
+
+
+
+
+
+
+
+
+ss://
+
+
+点击复制
+已复制
+
+
\ No newline at end of file
diff --git a/test.php b/test.php
new file mode 100644
index 0000000..b8b80b4
--- /dev/null
+++ b/test.php
@@ -0,0 +1,61 @@
+connect_error)
+{
+ die("连接失败: " . $conn->connect_error);
+}
+
+
+$sql = "SELECT * FROM ssr where port=0";
+
+$result = $conn->query($sql);
+///禁止非法访问
+if ($result->num_rows > 0) {}else{echo "";}
+
+
+
+$row = $result->fetch_assoc();
+
+
+$logFile= file_get_contents("log/ssr.log");
+
+$logFile_Array=array();
+$logFile_Name=array();
+
+$ssr_limit=$row['passwd'];
+
+for($i=8889;$i<=$ssr_limit;$i++)
+{
+$file_tmp=substr($logFile,strrpos($logFile,"TCP/$i:"),70);
+
+$logFile_Array[$i]=substr($file_tmp,strpos($file_tmp,"s,")+3,strpos($file_tmp,"bytes")-1-(strpos($file_tmp,"s,")+3));
+
+$logFile_Array[$i]+=0;
+if($logFile_Array[$i]!=0)
+{
+$sql = "SELECT * FROM user where ssr='$i'";
+
+$result = $conn->query($sql);
+///禁止非法访问
+
+$row = $result->fetch_assoc();
+
+$logFile_Name[$i]=$row['name'];
+}
+$logFile_Array[$i]= number_format($logFile_Array[$i]/(1025*1025),2);
+}
+
+
+
diff --git a/video.php b/video.php
new file mode 100644
index 0000000..a4f267e
--- /dev/null
+++ b/video.php
@@ -0,0 +1,319 @@
+
+
+
+
+
+
+
+
+connect_error)
+{
+ die("连接失败: " . $conn->connect_error);
+}
+
+return ($conn);
+}
+
+
+//fnct of get table row number::(data_cnnct var,table name) ::(row number)
+function sql_rowNum($conn,$tableSql)
+{
+$row_count = $conn->query("SELECT COUNT(*) FROM $tableSql");
+list($row_num) = $row_count->fetch_row();
+return ($row_num);
+}
+
+//fnct of getting row data from database::(data_cnnct var, table name,column name, column value)::(row info)
+function sql_data($conn,$table,$clmnName,$value)
+{
+$sql = "SELECT * FROM $table where $clmnName=$value";
+
+$result = $conn->query($sql);
+///禁止非法访问
+if ($result->num_rows > 0) {}else{echo "";}
+
+$row = $result->fetch_assoc();
+
+return ($row);
+
+}
+
+function array_orderby()
+{
+ $args = func_get_args();
+ $data = array_shift($args);
+ foreach ($args as $n => $field) {
+ if (is_string($field)) {
+ $tmp = array();
+ foreach ($data as $key => $row)
+ $tmp[$key] = $row[$field];
+ $args[$n] = $tmp;
+ }
+ }
+ $args[] = &$data;
+ call_user_func_array('array_multisort', $args);
+ return array_pop($args);
+}
+
+?>
+
+
+
+
+
+
+
+
+
+
+ Yimian Video
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Download Click Here! Click here to go back~
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/video/acg.php b/video/acg.php
new file mode 100644
index 0000000..0c35aa1
--- /dev/null
+++ b/video/acg.php
@@ -0,0 +1,259 @@
+
+
+
+query($sql);
+?>
+
+
+
+
+connect_error)
+{
+ die("连接失败: " . $conn->connect_error);
+}
+
+return ($conn);
+}
+
+
+//fnct of get table row number::(data_cnnct var,table name) ::(row number)
+function sql_rowNum($conn,$tableSql)
+{
+$row_count = $conn->query("SELECT COUNT(*) FROM $tableSql");
+list($row_num) = $row_count->fetch_row();
+return ($row_num);
+}
+
+//fnct of getting row data from database::(data_cnnct var, table name,column name, column value)::(row info)
+function sql_data($conn,$table,$clmnName,$value)
+{
+$sql = "SELECT * FROM $table where $clmnName=$value";
+
+$result = $conn->query($sql);
+///禁止非法访问
+if ($result->num_rows > 0) {}else{echo "";}
+
+$row = $result->fetch_assoc();
+
+return ($row);
+
+}
+
+function array_orderby()
+{
+ $args = func_get_args();
+ $data = array_shift($args);
+ foreach ($args as $n => $field) {
+ if (is_string($field)) {
+ $tmp = array();
+ foreach ($data as $key => $row)
+ $tmp[$key] = $row[$field];
+ $args[$n] = $tmp;
+ }
+ }
+ $args[] = &$data;
+ call_user_func_array('array_multisort', $args);
+ return array_pop($args);
+}
+
+?>
+
+
+
+
+
+
+ Yimian Video
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Share video with the one you love!
+
+num_rows > 0) {
+ // 输出数据
+ while($row = $result->fetch_assoc()) {
+ echo '
'.$row['comment'].'
';
+
+
+ }
+} else {
+ echo "404 No Found!";
+}?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/video/ckplayer/ckplayer.js b/video/ckplayer/ckplayer.js
new file mode 100644
index 0000000..e43f0a1
--- /dev/null
+++ b/video/ckplayer/ckplayer.js
@@ -0,0 +1,8176 @@
+/*
+ 软件名称:ckplayer
+ 软件版本:X1
+ 软件作者:http://www.ckplayer.com
+ --------------------------------------------------------------------------------------------------------------------
+ 开发说明:
+ 使用的主要程序语言:javascript(js)及actionscript3.0(as3.0)(as3.0主要用于flashplayer部分的开发,不在该页面呈现)
+ 功能:播放视频
+ 特点:兼容HTML5-VIDEO(优先)以及FlashPlayer
+ =====================================================================================================================
+*/
+function ckplayerConfig() {
+ return {
+ flashvars: {},//用来补充flashvars里的对象
+ languagePath: '',//语言包文件地址
+ stylePath: '',//风格包文件地址
+ config: {
+ fullInteractive: true,//是否开启交互功能
+ delay: 30,//延迟加载视频,单位:毫秒
+ timeFrequency: 100,//计算当前播放时间和加载量的时间频率,单位:毫秒
+ autoLoad: true,//视频是否自动加载
+ loadNext: 0,//多段视频预加载的段数,设置成0则全部加载
+ definition: true,//是否使用清晰度组件
+ smartRemove: true,//是否使用智能清理,使用该功能则在多段时当前播放段之前的段都会被清除出内存,减少对内存的使用
+ bufferTime: 200,//缓存区的长度,单位:毫秒,不要小于10
+ click: true,//是否支持屏幕单击暂停
+ doubleClick: true,//是否支持屏幕双击全屏
+ doubleClickInterval: 200,//判断双击的标准,即二次单击间隔的时间差之内判断为是双击,单位:毫秒
+ keyDown: {
+ space: true,//是否启用空格键切换播放/暂停
+ left: true,//是否启用左方向键快退
+ right: true,//是否启用右方向键快进
+ up: true,//是否支持上方向键增加音量
+ down: true //是否支持下方向键减少音量
+ },
+ timeJump: 10,//快进快退时的秒数
+ volumeJump: 0.1,//音量调整的数量,大于0小于1的小数
+ timeScheduleAdjust: 1,//是否可调节调节栏,0不启用,1是启用,2是只能前进(向右拖动),3是只能后退,4是只能前进但能回到第一次拖动时的位置,5是看过的地方可以随意拖动
+ previewDefaultLoad: true,//预览图片是否默认加载,优点是鼠标第一次经过进度条即可显示预览图片
+ promptSpotTime: false,//提示点文字是否在前面加上对应时间
+ buttonMode: {
+ player: false,//鼠标在播放器上是否显示可点击形态
+ controlBar: false,//鼠标在控制栏上是否显示可点击形态
+ timeSchedule: true,//鼠标在时间进度条上是否显示可点击形态
+ volumeSchedule: true //鼠标在音量调节栏上是否显示可点击形态
+ },
+ liveAndVod: { //直播+点播=回播功能
+ open: false,//是否开启,开启该功能需要设置flashvars里live=true
+ vodTime: 2,//可以回看的整点数
+ start: 'start' //回看请求参数
+ },
+ errorNum: 3,//错误重连次数
+ playCorrect: false,//是否需要错误修正,这是针对rtmp的
+ timeCorrect: true,//http视频播放时间错误纠正,有些因为视频格式的问题导致视频没有实际播放结束视频文件就返回了stop命令
+ m3u8Definition: { //m3u8自动清晰度时按关键字来进行判断
+ //tags:['200k','110k','400k','600k','1000k']
+ },
+ m3u8MaxBufferLength: 30,//m3u8每次缓冲时间,单位:秒数
+ split: '|',//当视频地址采用字符形式并且需要使用逗号或其它符号来切割数组里定义
+ timeStamp: '',//一个地址,用来请求当前时间戳,用于播放器内部时间效准
+ mobileVolumeBarShow: false,//在移动端是否显示音量调节按钮
+ addCallback: 'adPlay,adPause,playOrPause,videoPlay,videoPause,videoMute,videoEscMute,videoClear,changeVolume,fastBack,fastNext,videoSeek,newVideo,getMetaDate,videoRotation,videoBrightness,videoContrast,videoSaturation,videoHue,videoZoom,videoProportion,videoError,addListener,removeListener,addElement,getElement,deleteElement,elementShow,animate,animateResume,animatePause,deleteAnimate,changeConfig,getConfig,openUrl,fullScreen,quitFullScreen,switchFull,screenshot,custom,changeControlBarShow,getCurrentSrc,changeDefinition'//需要支持的事件
+ },
+ menu: { //版权名称支持
+ ckkey: 'ckplayer15151515151515151515151515151515',
+ name: 'Yimian',
+ link: 'https://www.yimian.xyz',
+ version: '15',
+ domain: 'yimian.xyz',
+ more: []
+ },
+ style: { //风格部分内容配置,这里主要配置loading和logo以及广告的部分内容
+
+ logo: { //显示在右上角的logo图片,如果不需要可以删除该属性
+ file: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAbCAQAAAAgn+LLAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAHdElNRQfiCgIWCiigEF+xAAAFx0lEQVRYw9WYe5DVZRnHP+/vnD3L3hfYuFMJXtLRIR3AEYlpdCTMgMpy0JEmMGoQEZsUG42pJin9J9FBVCrQrmSMBloTE1nTrDI12w2jQXZ3QF2EFhZdD3v2wp7z6Y/97eUcdlm0MbfvP+e9Pb/v832f9/K8JzAshIgEkCMLYXiD9wRJEBJMIIGcoK3QUaGKNcwHdvAg3e+1w2eAOM5d/s0/+w1HiwN7cIzftFnVJyzyv+D5XwiZ5AE71A43WGN/O05yox1qzn+6yGikC0l5iavNqK/5MYO97ef7lF3mfNVnndvbPoIh4jR32qHutMaelkt93qya8cuW/B/IiIXgue5QW1xj0vO8zG+bUzM+5rS+GBV5kVNGtCQx4U0eVv/g5f7QJk+oJ7yv5wAQg/O8x33udIaptxshEUe52MWWvat7TcQSt5k1619tUrXJ2yzri0bktzxsVv2HDznhbQtJutpWj7vdJabebSlXWG8vct7TTyjiaGf4tJ1qvefGUQqGAaUwVKTEpCvdbVo94mrL7f9uGGj9ziSGfDKq+Sp3UAxAjtt5pH+IAGOZyiV8ljEs5SDFrORifsc2pvEFxiARjWylmQTvoxjopplTodc6YjTL+AoTqONGGgJCivlcF5MEWthKAw6dPwil1ACBN2nt9y5ZMK6KGSSQAISBvQLM4m6y/Jz7OMnrQJKFXMUkuvkcHycCIEOKB7iGNdQQOMwqXun5HIEPcQ772coFPMmrIBRzM/dyTh9NN5O5ndY83kCIQwclXM7VXEsgsIcHaRgq/GNd6b2+oGqtM/sDLUY+ZM6sGVfF27/U36idpu32lJl4SW70BhvttlN9y7WW2mP/EV8wbdoNVhvFS/Uuj6mdft/Ndqi62zHm+3Sl6/2OX7TKStd61Iwn7dYeP3qRF5EALT5KxDjmAH+hriDEEYFAmuN5rSlSdPNTmrkTgE/zGcZTy4vcQQXXsIUMAB9mNkmglAy5gLCCdZTTzH4eo4IbKeYUhzhVML9TWMZE2jifLLcSeJwdrGcOyYEbo2BpCVBEEsgNueue5pn+6YpLB3mAj8blicAbbKcdgSy5uL3n9xC7yYIwk09STo7tfI1WriLQxWbuJ13At5N53EoZqwl0sJ5HydFS6FQ0iKMLuBb4O9uGENJFV7zmJ1MBQBubaBiwCpv4Pc8QSADlTMyzfpnnyAIwmyuAl3iSN4gYT0SCcT2bIp6liVYAVTFLiiQv8SNaybCFw/m+DyZkKh8AjnOAMyPJLcwGpJZfUcPsmL+Njaykif3sA2Zx86DWU5kFQAsHSLGUdZSQYBbVBEeZ8oPcwibWUsECPhHb/JY7OQpk2cfJQmdOR5YcEdGwb6gKJlME5HiOehawCID93E8tzUAtO7mIFBN4v1mOFFhfzOJYeDkruJuxAIzn8+xlETkmMod2qvkBxZQB7Rzjx+yB0PPU6zvThxaSY3CEOH6JuL4wnqlDHASO8C/m0sGv+QXtASHL44xhOZ/iag5yU0zbO0Gvs4+5wGjuYhkRu0hzKdNZTSdVADTydZ7naDy+jts4OMCXQMRlXG8RDdSFQYQUUT6EkCw7mAE8G9erqQBy/JLdwF5WMYe32EV7DxN4mHW8SCXXUUNEOxkqaYsF7eUJplHDhYzlGFvYTJqZzGMJ1bSS5ifUsoduIEFAmnmFdOj35QilXM9SsnyXutOe4MKVfI8Lgd0soSXk90VMQw6RDQiLWU6SRh6mcZi7eApV1FPNlziPTfwpllLDBdxAxM9oo55MfM9PpxRop74vI1jICt7kEerI9h4DjGI6pcxnLg1s5OVwOqkLbI0vppozZT1iykorLTnb7Egstqw/F4vT1BKHs0pZaVkhi7098UspOYglMOjFlIcAXXSdlYJ+i0468+r0LMN3whMgrycafASvsWFgxjPycbqQNP8Giugauf9hnQXEYpf7R59y6oh+0J6GQbZ7nFpkz3QSjTz8BxwLJ4B3vFY7AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE4LTEwLTAyVDIyOjEwOjQwKzA4OjAwIL/v2QAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxOC0xMC0wMlQyMjoxMDo0MCswODowMFHiV2UAAABOdEVYdHNvZnR3YXJlAEltYWdlTWFnaWNrIDYuOS4xLTEwIFExNiB4ODZfNjQgMjAxOC0wOS0yOSBodHRwOi8vd3d3LmltYWdlbWFnaWNrLm9yZ6R/1PMAAAAYdEVYdFRodW1iOjpEb2N1bWVudDo6UGFnZXMAMaf/uy8AAAAXdEVYdFRodW1iOjpJbWFnZTo6SGVpZ2h0ADQ1+dH7kAAAABd0RVh0VGh1bWI6OkltYWdlOjpXaWR0aAAxNjckXslIAAAAGXRFWHRUaHVtYjo6TWltZXR5cGUAaW1hZ2UvcG5nP7JWTgAAABd0RVh0VGh1bWI6Ok1UaW1lADE1Mzg0ODk0NDAzbiGnAAAAEnRFWHRUaHVtYjo6U2l6ZQAyLjVLQkLnFOWDAAAAQnRFWHRUaHVtYjo6VVJJAGZpbGU6Ly8vdG1wL2ltYWdlbGMvaW1ndmlldzJfN18xNTM4MjIwMzUwMDQxOTE0Ml85Nl9bMF0rASxUAAAAAElFTkSuQmCC',
+ align: 'right',
+ vAlign: 'top',
+ offsetX: -100,
+ offsetY: 10
+ },
+ advertisement: { //广告相关的配置
+ time: 0,//广告默认播放时长以及多个广告时每个广告默认播放时间,单位:秒
+ method: 'get',//广告监测地址默认请求方式,get/post
+ videoForce: false,//视频广告是否强制播放结束
+ videoVolume: 0.8,//视频音量
+ skipButtonShow: true,//是否显示跳过广告按钮
+ linkButtonShow: true,//是否显示广告链接按钮,如果选择显示,只有在提供了广告链接地址时才会显示
+ muteButtonShow: true,//是否在视频广告时显示静音按钮
+ closeButtonShow: true,//暂停时是否显示关闭广告按钮
+ closeOtherButtonShow: true,//其它广告是否需要关闭广告按钮
+ frontSkipButtonDelay: 1,//前置广告跳过广告按钮延时显示的时间,单位:秒
+ insertSkipButtonDelay: 0,//插入广告跳过广告按钮延时显示的时间,单位:秒
+ endSkipButtonDelay: 0,//后置广告跳过广告按钮延时显示的时间,单位:秒
+ frontStretched: 2,//前置广告拉伸方式,0=原始大小,1=自动缩放,2=只有当广告的宽或高大于播放器宽高时才进行缩放,3=参考播放器宽高,4=宽度参考播放器宽、高度自动,5=高度参考播放器高、宽度自动
+ insertStretched: 2,//插入广告拉伸方式,0=原始大小,1=自动缩放,2=只有当广告的宽或高大于播放器宽高时才进行缩放,3=参考播放器宽高,4=宽度参考播放器宽、高度自动,5=高度参考播放器高、宽度自动
+ pauseStretched: 2,//暂停广告拉伸方式,0=原始大小,1=自动缩放,2=只有当广告的宽或高大于播放器宽高时才进行缩放,3=参考播放器宽高,4=宽度参考播放器宽、高度自动,5=高度参考播放器高、宽度自动
+ endStretched: 2 //结束广告拉伸方式,0=原始大小,1=自动缩放,2=只有当广告的宽或高大于播放器宽高时才进行缩放,3=参考播放器宽高,4=宽度参考播放器宽、高度自动,5=高度参考播放器高、宽度自动
+ },
+ video: { //视频的默认比例,当视频元数据里没有宽和高属性时默认使用该宽高
+ defaultWidth: 4,//宽度
+ defaultHeight: 3 //高度
+ }
+ }
+ };
+}
+! (function() {
+ var javascriptPath = '';
+ !function() {
+ var scriptList = document.scripts,
+ thisPath = scriptList[scriptList.length - 1].src;
+ javascriptPath = thisPath.substring(0, thisPath.lastIndexOf('/') + 1);
+ } ();
+ var ckplayer = function(obj) {
+ /*
+ javascript部分开发所用的注释说明:
+ 1:初始化-程序调用时即运行的代码部分
+ 2:定义样式-定义容器(div,p,canvas等)的样式表,即css
+ 3:监听动作-监听元素节点(单击-click,鼠标进入-mouseover,鼠标离开-mouseout,鼠标移动-mousemove等)事件
+ 4:监听事件-监听视频的状态(播放,暂停,全屏,音量调节等)事件
+ 5:共用函数-这类函数在外部也可以使用
+ 6:全局变量-定义成全局使用的变量
+ 7:其它相关注释
+ 全局变量说明:
+ 在本软件中所使用到的全局变量(变量(类型)包括Boolean,String,Int,Object(包含元素对象和变量对象),Array,Function等)
+ 下面列出重要的全局变量:
+ V:Object:视频对象
+ VA:Array:视频列表(包括视频地址,类型,清晰度说明)
+ ID:String:视频ID
+ CB:Object:控制栏各元素的集合对象
+ PD:Object:内部视频容器对象
+ ---------------------------------------------------------------------------------------------
+ 程序开始
+ 下面为需要初始化配置的全局变量
+ 初始化配置
+ config:全局变量定义一些基本配置
+ */
+ this.config = {
+ videoDbClick: true,//是否支持双击全屏/退出全屏动作
+ errorTime: 100,//延迟判断失败的时间,单位:毫秒
+ videoDrawImage: false,//是否使用视频drawImage功能,注意,该功能在移动端表现不了
+ adSkipClick: 'javaScript->adjump' //h5环境中点击跳过广告按钮触发的功能
+ };
+ //全局变量:播放器默认配置,在外部传递过来相应配置后,则进行相关替换
+ this.varsConfig = {
+ playerID: '',//播放器ID
+ container: '',//视频容器的ID
+ variable: 'ckplayer',//播放函数(变量)名称
+ volume: 0.8,//默认音量,范围0-1
+ poster: '',//封面图片地址
+ autoplay: false,//是否自动播放
+ loop: false,//是否需要循环播放
+ live: false,//是否是直播
+ duration: 0,//指定总时间
+ seek: 0,//默认需要跳转的秒数
+ drag: '',//拖动时支持的前置参数
+ front: '',//前一集按钮动作
+ next: 'next1',//下一集按钮动作
+ loaded: '',//加载播放器后调用的函数
+ flashplayer: false,//设置成true则强制使用flashplayer
+ html5m3u8: false,//PC平台上是否使用h5播放器播放m3u8
+ track: null,//字幕轨道
+ cktrack: null,//ck字幕
+ preview: null,//预览图片对象
+ prompt: null,//提示点功能
+ video: null,//视频地址
+ config: '',//调用配置函数名称
+ type: '',//视频格式
+ crossorigin: '',//设置html5视频的crossOrigin属性
+ crossdomain: '',//安全策略文件地址
+ unescape: false,//默认flashplayer里需要解码
+ mobileCkControls: false,//移动端h5显示控制栏
+ mobileAutoFull: true,//移动端是否默认全屏播放
+ playbackrate: 1,//默认倍速
+ h5container: '',//h5环境中使用自定义容器
+ debug: true,//是否开启调试模式
+ //以下为广告相关配置
+ adfront: '',
+ adfronttime: '',
+ adfrontlink: '',
+ adpause: '',
+ adpausetime: '',
+ adpauselink: '',
+ adinsert: '',
+ adinserttime: '',
+ adinsertlink: '',
+ inserttime: '',
+ adend: '',
+ adendtime: '',
+ adendlink: '',
+ advertisements: ''
+ };
+ this.vars = {};//全局变量:语言配置
+ this.language = {
+ volume: '音量:',
+ play: '点击播放',
+ pause: '点击暂停',
+ full: '点击全屏',
+ escFull: '退出全屏',
+ mute: '点击静音',
+ escMute: '取消静音',
+ front: '上一集',
+ next: '下一集',
+ definition: '点击选择清晰度',
+ playbackRate: '点击选择速度',
+ error: '加载出错',
+ adTime: '广告{$second}秒',
+ skipAd: '跳过广告',
+ skipAdTime: '{$second}秒后可跳过广告',
+ adLink: '查看详情'
+ };
+ //全局变量:右键菜单:[菜单标题,类型(link:链接,default:灰色,function:调用函数,javascript:调用js函数),执行内容(包含链接地址,函数名称),[line(间隔线)]]
+ this.contextMenu = [['ckplayer', 'link', 'http://www.ckplayer.com', '_blank'], ['version:X1', 'default', 'line']];
+ //全局变量:错误提示列表
+ this.errorList = [['000', 'Object does not exist'], ['001', 'Variables type is not a object'], ['002', 'Video object does not exist'], ['003', 'Video object format error'], ['004', 'Video object format error'], ['005', 'Video object format error'], ['006', '[error] does not exist '], ['007', 'Ajax error'], ['008', 'Ajax error'], ['009', 'Ajax object format error'], ['010', 'Ajax.status:[error]']];
+ //全局变量:HTML5变速播放的值数组/如果不需要可以设置成null
+ this.playbackRateArr = [[0.5, '0.5倍'], [1, '正常'], [1.25, '1.25倍'], [1.5, '1.5倍'], [2, '2倍速'], [4, '4倍速']];
+ //全局变量:HTML5默认变速播放的值
+ this.playbackRateDefault = 1;
+ //全局变量:定义logo
+ this.logo = '';
+ //全局变量:是否加载了播放器
+ this.loaded = false;
+ //全局变量:计时器,监听视频加载出错的状态
+ this.timerError = null;
+ //全局变量:是否出错
+ this.error = false;
+ //全局变量:出错地址的数组
+ this.errorUrl = [];
+ //全局变量:计时器,监听全屏与非全屏状态
+ this.timerFull = null;
+ //全局变量:是否全屏状态
+ this.full = false;
+ //全局变量:计时器,监听当前的月/日 时=分=秒
+ this.timerTime = null;
+ //全局变量:计时器,监听视频加载
+ this.timerBuffer = null;
+ //全局变量:设置进度按钮及进度条是否跟着时间变化,该属性主要用来在按下进度按钮时暂停进度按钮移动和进度条的长度变化
+ this.isTimeButtonMove = true;
+ //全局变量:进度栏是否有效,如果是直播,则不需要监听时间让进度按钮和进度条变化
+ this.isTimeButtonDown = false;
+ //全局变量:用来模拟双击功能的判断
+ this.isClick = false;
+ //全局变量:计时器,用来模拟双击功能的计时器
+ this.timerClick = null;
+ //全局变量:计时器,旋转loading
+ this.timerLoading = null;
+ //全局变量:计时器,监听鼠标在视频上移动显示控制栏
+ this.timerCBar = null;
+ //全局变量:播放视频时如果该变量的值大于0,则进行跳转后设置该值为0
+ this.needSeek = 0;
+ //全局变量:当前音量
+ this.volume = 0;
+ //全局变量:静音时保存临时音量
+ this.volumeTemp = 0;
+ //全局变量/变量类型:Number/功能:当前播放时间
+ this.time = 0;
+ //全局变量:定义首次调用
+ this.isFirst = true;
+ //全局变量:是否使用HTML5-VIDEO播放
+ this.html5Video = true;
+ //全局变量记录视频容器节点的x;y
+ this.pdCoor = {
+ x: 0,
+ y: 0
+ };
+ //全局变量:判断当前使用的播放器类型,html5video或flashplayer
+ this.playerType = '';
+ //全局变量:加载进度条的长度
+ this.loadTime = 0;
+ //全局变量:body对象
+ this.body = document.body || document.documentElement;
+ //全局变量:播放器
+ this.V = null;
+ //全局变量:保存外部js监听事件数组
+ this.listenerJsArr = [];
+ //全局变量:保存控制栏显示元素的总宽度
+ this.buttonLen = 0;
+ //全局变量:保存控制栏显示元素的数组
+ this.buttonArr = [];
+ //全局变量:保存按钮元素的宽
+ this.buttonWidth = {};
+ //全局变量:保存播放器上新增元件的数组
+ this.elementArr = [];
+ //全局变量:保存播放器上弹幕的临时数组
+ this.elementTempArr = [];
+ //全局变量:字幕内容
+ this.track = [];
+ //全局变量:字幕索引
+ this.trackIndex = 0;
+ //全局变量:当前显示的字幕内容
+ this.nowTrackShow = {
+ sn: ''
+ };
+ //全局变量:保存字幕元件数组
+ this.trackElement = [];
+ //全局变量:将视频转换为图片
+ this.timerVCanvas = null;
+ //全局变量:animate,缓动对象数组
+ this.animateArray = [];
+ //全局变量:保存animate的元件
+ this.animateElementArray = [];
+ //全局变量:保存需要在暂停时停止缓动的数组
+ this.animatePauseArray = [];
+ //全局变量:预览图片加载状态/0=没有加载,1=正在加载,2=加载完成
+ this.previewStart = 0;
+ //全局变量:预览图片容器
+ this.previewDiv = null;
+ //全局变量:预览框
+ this.previewTop = null;
+ //全局变量:预览框的宽
+ this.previewWidth = 120;
+ //全局变量:预览图片容器缓动函数
+ this.previewTween = null;
+ //全局变量:是否是m3u8格式,是的话则可以加载hls.js
+ this.isM3u8 = false;
+ //全局变量:保存提示点数组
+ this.promptArr = [];
+ //全局变量:显示提示点文件的容器
+ this.promptElement = null;
+ //全局变量:配置文件函数
+ this.ckplayerConfig = {};
+ //全局变量:控制栏是否显示
+ this.showFace = true;
+ //全局变量:是否监听过h5的错误
+ this.errorAdd = false;
+ //全局变量:是否发送了错误
+ this.errorSend = false;
+ //全局变量:控制栏是否隐藏
+ this.controlBarIsShow = true;
+ //全局变量,保存当前缩放比例
+ this.videoScale = 1;
+ //全局变量:设置字体
+ this.fontFamily = '"Microsoft YaHei"; YaHei; "\5FAE\8F6F\96C5\9ED1"; SimHei; "\9ED1\4F53";Arial';
+ //全局变量:记录第一次拖动进度按钮时的位置
+ this.timeSliderLeftTemp = 0;
+ //全局变量:判断是否记录了总时间
+ this.durationSendJS = false;
+ //全局变量:初始化广告分析是否结束设置
+ this.adAnalysisEnd = false;
+ //全局变量:广告变量
+ this.advertisements = {};
+ //全局变量:是否是第一次播放视频
+ this.isFirstTimePlay = true;
+ //全局变量:当前需要播放的广告类型
+ this.adType = '';
+ //全局变量:播放广告计数
+ this.adI = 0;
+ //全局变量:要播放的临时地址
+ this.videoTemp = {
+ src: '',
+ source: '',
+ currentSrc: '',
+ loop: false
+ };
+ //全局变量:当前要播放的广告组总时间
+ this.adTimeAllTotal = 0;
+ //全局变量:肖前要播放的广告时间
+ this.adTimeTotal = 0;
+ //全局变量:用来做倒计时
+ this.adCountDownObj = null;
+ //全局变量:前置,中插,结尾广告是否已开始运行
+ this.adPlayStart = false;
+ //全局变量:目前是否在播放广告
+ this.adPlayerPlay = false;
+ //全局变量:当前广告是否暂停
+ this.adIsPause = false;
+ //全局变量:视频广告是否静音
+ this.adVideoMute = false;
+ //全局变量:是否需要记录当前播放的时间供广告播放结束后进行跳转
+ this.adIsVideoTime = false;
+ //全局变量:后置广告是否播放
+ this.endAdPlay = false;
+ //全局变量:暂停广告是否在显示
+ this.adPauseShow = false;
+ //全局变量:是否需要重置广告以实现重新播放时再播放一次
+ this.adReset = false;
+ //全局变量:是否在播放广告时播放过视频广告
+ this.adVideoPlay = false;
+ if (obj) {
+ this.embed(obj);
+ }
+ };
+ ckplayer.prototype = {
+ /*
+ 主要函数部分开始
+ 主接口函数:
+ 调用播放器需初始化该函数
+ */
+ embed: function(c) {
+ //c:Object:是调用接口传递的属性对象
+ if (window.location.href.substr(0, 7) == 'file://') {//如果是使用的file协议打网页则弹出提示
+ alert('Please use the HTTP protocol to open the page');
+ return;
+ }
+ if (c == undefined || !c) {
+ this.eject(this.errorList[0]);
+ return;
+ }
+ if (typeof(c) != 'object') {
+ this.eject(this.errorList[1]);
+ }
+ this.vars = this.standardization(this.varsConfig, c);
+ if (!this.vars['mobileCkControls'] && this.isMobile()) {
+ this.vars['flashplayer'] = false;
+ this.showFace = false;
+ }
+ var videoString = this.vars['video'];
+ if (!videoString) {
+ this.eject(this.errorList[2]);
+ return;
+ }
+ if (typeof(videoString) == 'string') {
+ if (videoString.substr(0, 3) == 'CK:' || videoString.substr(0, 3) == 'CE:' || videoString.substr(8, 3) == 'CK:' || videoString.substr(8, 3) == 'CE:') {
+ this.vars['flashplayer'] = true;
+ }
+ }
+ if (typeof(videoString) == 'object') {
+ if (videoString.length > 1) {
+ if (videoString[0][0].substr(0, 3) == 'CK:' || videoString[0][0].substr(0, 3) == 'CE:' || videoString[0][0].substr(8, 3) == 'CK:' || videoString[0][0].substr(8, 3) == 'CE:') {
+ this.vars['flashplayer'] = true;
+ }
+ }
+ }
+ if (this.vars['config']) {
+ this.ckplayerConfig = eval(this.vars['config'] + '()');
+ } else {
+ this.ckplayerConfig = ckplayerConfig();
+ }
+ if ((!this.supportVideo() && this.vars['flashplayer'] != '') || (this.vars['flashplayer'] && this.uploadFlash()) || !this.isMsie()) {
+ this.html5Video = false;
+ this.getVideo();
+ } else if (videoString) {
+ //判断视频数据类型
+ this.analysedVideoUrl(videoString);
+ return this;
+ } else {
+ this.eject(this.errorList[2]);
+ }
+ },
+ /*
+ 内部函数
+ 根据外部传递过来的video开始分析视频地址
+ */
+ analysedVideoUrl: function(video) {
+ var i = 0,
+ y = 0;
+ var thisTemp = this;
+ this.VA = [];//定义全局变量VA:视频列表(包括视频地址,类型,清晰度说明)
+ if (typeof(video) == 'string') { //如果是字符形式的则判断后缀进行填充
+ if (video.substr(0, 8) != 'website:') {
+ this.VA = [[video, '', '', 0]];
+ var fileExt = this.getFileExt(video);
+ switch (fileExt) {
+ case '.mp4':
+ this.VA[0][1] = 'video/mp4';
+ break;
+ case '.ogg':
+ this.VA[0][1] = 'video/ogg';
+ break;
+ case '.webm':
+ this.VA[0][1] = 'video/webm';
+ break;
+ default:
+ break;
+ }
+ this.getVideo();
+ } else {
+ if (this.html5Video) {
+ var ajaxObj = {
+ url: video.substr(8),
+ success: function(data) {
+ if (data) {
+ thisTemp.analysedUrl(data);
+ } else {
+ thisTemp.eject(thisTemp.errorList[5]);
+ this.VA = video;
+ thisTemp.getVideo();
+ }
+ }
+ };
+ this.ajax(ajaxObj);
+ } else {
+ this.VA = video;
+ this.getVideo();
+ }
+
+ }
+ } else if (typeof(video) == 'object') { //如果视频地址是对象或数组
+ if (!this.isUndefined(typeof(video.length))) { //如果视频地址是数组
+ if (!this.isUndefined(typeof(video[0].length))) { //如果视频地址是二维数组
+ this.VA = video;
+ }
+ this.getVideo();
+ } else {
+ /*
+ 如果video格式是对象形式,则分二种
+ 如果video对象里包含type,则直接播放
+ */
+ if (!this.isUndefined(video['type'])) {
+ this.VA.push([video['file'], video['type'], '', 0]);
+ this.getVideo();
+ } else {
+ this.eject(this.errorList[5]);
+ }
+ }
+ } else {
+ this.eject(this.errorList[4]);
+ }
+ },
+ /*
+ 对请求到的视频地址进行重新分析
+ */
+ analysedUrl: function(data) {
+ this.vars = this.standardization(this.vars, data);
+ if (!this.isUndefined(data['video'])) {
+ this.vars['video'] = data['video'];
+ }
+ this.analysedVideoUrl(this.vars['video']);
+ },
+ /*
+ 内部函数
+ 检查浏览器支持的视频格式,如果是则将支持的视频格式重新分组给播放列表
+ */
+ getHtml5Video: function() {
+ var va = this.VA;
+ var nva = [];
+ var mobile = false;
+ var video = document.createElement('video');
+ var codecs = function(type) {
+ var cod = '';
+ switch (type) {
+ case 'video/mp4':
+ cod = 'avc1.4D401E, mp4a.40.2';
+ break;
+ case 'video/ogg':
+ cod = 'theora, vorbis';
+ break;
+ case 'video/webm':
+ cod = 'vp8.0, vorbis';
+ break;
+ default:
+ break;
+ }
+ return cod;
+ };
+ var supportType = function(vidType, codType) {
+ if (!video.canPlayType) {
+ this.html5Video = false;
+ return;
+ }
+ var isSupp = video.canPlayType(vidType + ';codecs="' + codType + '"');
+ if (isSupp == '') {
+ return false
+ }
+ return true;
+ };
+ if (this.vars['flashplayer'] || !this.isMsie()) {
+ this.html5Video = false;
+ return;
+ }
+ if (this.isMobile()) {
+ mobile = true;
+ }
+ for (var i = 0; i < va.length; i++) {
+ var v = va[i];
+ if (v) {
+ if (v[1] != '' && !mobile && supportType(v[1], codecs(v[1])) && v[0].substr(0, 4) != 'rtmp') {
+ nva.push(v);
+ }
+ if ((this.getFileExt(v[0]) == '.m3u8' || this.vars['type'] == 'video/m3u8' || this.vars['type'] == 'm3u8' || v[1] == 'video/m3u8' || v[1] == 'm3u8') && this.vars['html5m3u8']) {
+ this.isM3u8 = true;
+ nva.push(v);
+ }
+ }
+ }
+ if (nva.length > 0) {
+ this.VA = nva;
+ } else {
+ if (!mobile) {
+ this.html5Video = false;
+ }
+ }
+ },
+ /*
+ 内部函数
+ 根据视频地址开始构建播放器
+ */
+ getVideo: function() {
+ var thisTemp = this;
+ var v = this.vars;
+ //如果存在广告字段则开始分析广告
+ if (!this.adAnalysisEnd && (v['adfront'] != '' || v['adpause'] != '' || v['adinsert'] != '' || v['adend'] != '' || v['advertisements'] != '')) {
+ this.adAnalysisEnd = true;
+ this.adAnalysis();
+ return;
+ }
+ //如果存在字幕则加载
+ if (this.V) { //如果播放器已存在,则认为是从newVideo函数发送过来的请求
+ this.changeVideo();
+ return;
+ }
+ if (this.vars['cktrack']) {
+ this.loadTrack();
+ }
+ if (this.supportVideo() && !this.vars['flashplayer']) {
+ this.getHtml5Video(); //判断浏览器支持的视频格式
+ }
+ var src = '',
+ source = '',
+ poster = '',
+ loop = '',
+ autoplay = '',
+ track = '';
+ var video = v['video'];
+ var i = 0;
+ this.CD = this.getByElement(v['container']);
+ volume = v['volume'];
+ if (!this.CD) {
+ this.eject(this.errorList[6], v['container']);
+ return false;
+ }
+ //开始构建播放器容器
+ this.V = undefined;
+ var thisPd = null;
+ if (v['h5container'] != '') {
+ thisPd = this.getByElement(v['h5container']);
+ if (this.isUndefined(thisPd)) {
+ thisPd = null;
+ }
+ }
+ var isVideoH5 = null; //isUndefined thisPd
+ if (v['playerID'] != '') {
+ isVideoH5 = this.getByElement('#' + v['playerID']);
+ if (this.isUndefined(isVideoH5)) {
+ isVideoH5 = null;
+ }
+ }
+ if (thisPd != null && isVideoH5 != null) {
+ this.PD = thisPd; //PD:定义播放器容器对象全局变量
+ } else {
+ var playerID = 'ckplayer' + this.randomString();
+ var playerDiv = document.createElement('div');
+ playerDiv.className = playerID;
+ this.CD.innerHTML = '';
+ this.CD.appendChild(playerDiv);
+ this.PD = this.getByElement(playerID); //PD:定义播放器容器对象全局变量
+ }
+ this.css(this.CD, {
+ backgroundColor: '#000000',
+ overflow: 'hidden',
+ position: 'relative'
+ });
+ this.css(this.PD, {
+ backgroundColor: '#000000',
+ width: '100%',
+ height: '100%',
+ fontFamily: this.fontFamily
+ });
+ if (this.html5Video) { //如果支持HTML5-VIDEO则默认使用HTML5-VIDEO播放器
+ //禁止播放器容器上鼠标选择文本
+ this.PD.onselectstart = this.PD.ondrag = function() {
+ return false;
+ };
+ //播放器容器构建完成并且设置好样式
+ //构建播放器
+ if (this.VA.length == 1) {
+ this.videoTemp['src'] = decodeURIComponent(this.VA[0][0]);
+ src = ' src="' + this.videoTemp['src'] + '"';
+
+ } else {
+ var videoArr = this.VA.slice(0);
+ videoArr = this.arrSort(videoArr);
+ for (i = 0; i < videoArr.length; i++) {
+ var type = '';
+ var va = videoArr[i];
+ if (va[1]) {
+ type = ' type="' + va[1] + '"';
+ if (type == ' type="video/m3u8"' || type == ' type="m3u8"') {
+ type = '';
+ }
+ }
+ source += '';
+ }
+ this.videoTemp['source'] = source;
+ }
+ //分析视频地址结束
+ if (v['autoplay']) {
+ autoplay = ' autoplay="autoplay"';
+ }
+ if (v['poster']) {
+ poster = ' poster="' + v['poster'] + '"';
+ }
+ if (v['loop']) {
+ loop = ' loop="loop"';
+ }
+ if (v['seek'] > 0) {
+ this.needSeek = v['seek'];
+ }
+ if (v['track'] != null && v['cktrack'] == null) {
+ var trackArr = v['track'];
+ var trackDefault = '';
+ var defaultHave = false;
+ for (i = 0; i < trackArr.length; i++) {
+ var trackObj = trackArr[i];
+ if (trackObj['default'] && !defaultHave) {
+ trackDefault = ' default';
+ defaultHave = true;
+ } else {
+ trackDefault = '';
+ }
+ track += '';
+ }
+ }
+ var autoLoad = this.ckplayerConfig['config']['autoLoad'];
+ var preload = '';
+ if (!autoLoad) {
+ preload = ' preload="meta"';
+ }
+ var vid = this.randomString();
+ var controls = '';
+ if (!this.showFace) {
+ controls = ' controls="controls"';
+ }
+ var mobileAutoFull = v['mobileAutoFull'];
+ var mobileautofull = '';
+ if (!mobileAutoFull) {
+ mobileautofull = ' x-webkit-airplay="true" playsinline webkit-playsinline="true" x5-video-player-type="h5"';
+ }
+ if (isVideoH5 != null && thisPd != null) {
+ this.V = isVideoH5;
+ if (v['poster']) {
+ this.V.poster = v['poster'];
+ }
+ } else {
+ var html = '';
+ if (!this.isM3u8) {
+ html = '' + source + ' ';
+ } else {
+ html = ' ';
+ }
+ this.PD.innerHTML = html;
+ this.V = this.getByElement('#' + vid); //V:定义播放器对象全局变量
+ }
+ if (this.vars['crossorigin']) {
+ this.V.crossOrigin = this.vars['crossorigin'];
+ }
+ try {
+ this.V.volume = volume; //定义音量
+ if (this.playbackRateArr && this.vars['playbackrate'] > -1) {
+ if (this.vars['playbackrate'] < this.playbackRateArr.length) {
+ this.playbackRateDefault = this.vars['playbackrate'];
+ }
+ this.V.playbackRate = this.playbackRateArr[this.playbackRateDefault][0]; //定义倍速
+ }
+ } catch(error) {}
+ this.css(this.V, {
+ width: '100%',
+ height: '100%'
+ });
+ if (this.isM3u8) {
+ var loadJsHandler = function() {
+ thisTemp.embedHls(thisTemp.VA[0][0], v['autoplay']);
+ };
+ this.loadJs(javascriptPath + 'hls/hls.min.js', loadJsHandler);
+ }
+ this.css(this.V, 'backgroundColor', '#000000');
+ //创建一个画布容器
+ if (this.config['videoDrawImage']) {
+ var canvasID = 'vcanvas' + this.randomString();
+ var canvasDiv = document.createElement('div');
+ canvasDiv.className = canvasID;
+ this.PD.appendChild(canvasDiv);
+ this.MD = this.getByElement(canvasID); //定义画布存储容器
+ this.css(this.MD, {
+ backgroundColor: '#000000',
+ width: '100%',
+ height: '100%',
+ position: 'absolute',
+ display: 'none',
+ cursor: 'pointer',
+ left: '0px',
+ top: '0px',
+ zIndex: '10'
+ });
+ var cvid = 'ccanvas' + this.randomString();
+ this.MD.innerHTML = this.newCanvas(cvid, this.PD.offsetWidth, this.PD.offsetHeight);
+ this.MDC = this.getByElement(cvid + '-canvas');
+ this.MDCX = this.MDC.getContext('2d');
+ }
+ this.playerType = 'html5video';
+ //播放器构建完成并且设置好样式
+ //建立播放器的监听函数,包含操作监听及事件监听
+ this.addVEvent();
+ //根据清晰度的值构建清晰度切换按钮
+ if (this.showFace) {
+ this.definition();
+ if (!this.vars['live'] && this.playbackRateArr && this.vars['playbackrate'] > -1) {
+ this.playbackRate();
+ }
+ if (v['autoplay']) {
+ this.loadingStart(true);
+ }
+ }
+ this.playerLoad();
+ } else { //如果不支持HTML5-VIDEO则调用flashplayer
+ this.embedSWF();
+ }
+ },
+ /*
+ 分析广告数据
+ */
+ adAnalysis: function() {
+ var thisTemp = this;
+ var v = this.vars;
+ var isAdvShow = [];
+ var i = 0;
+ if (v['advertisements'] != '' && v['advertisements'].substr(0, 8) == 'website:') {
+ var ajaxObj = {
+ url: v['advertisements'].substr(8),
+ success: function(data) {
+ if (data) {
+ var newData = {};
+ var val = null;
+ //对广告进行分析
+ try {
+ if (!thisTemp.isUndefined(data['front'])) {
+ val = thisTemp.arrayDel(data['front']);
+ if (!thisTemp.isUndefined(val)) {
+ newData['front'] = val;
+ }
+ val = thisTemp.arrayDel(data['pause']);
+ if (!thisTemp.isUndefined(val)) {
+ newData['pause'] = val;
+ }
+ val = thisTemp.arrayDel(data['insert']);
+ if (!thisTemp.isUndefined(val)) {
+ newData['insert'] = val;
+ if (!thisTemp.isUndefined(data['inserttime'])) {
+ newData['inserttime'] = thisTemp.arrayInt(data['inserttime']);
+ isAdvShow = [];
+ for (i = 0; i < newData['inserttime'].length; i++) {
+ isAdvShow.push(false);
+ }
+ newData['insertPlay'] = isAdvShow;
+ }
+ }
+ val = thisTemp.arrayDel(data['end']);
+ if (!thisTemp.isUndefined(val)) {
+ newData['end'] = val;
+ }
+ val = thisTemp.arrayDel(data['other']);
+ if (!thisTemp.isUndefined(val)) {
+ newData['other'] = val;
+ isAdvShow = [];
+ var arrTemp = [];
+ for (i = 0; i < val.length; i++) {
+ isAdvShow.push(false);
+ arrTemp.push(parseInt('0' + val[i]['startTime']));
+ }
+ newData['othertime'] = arrTemp;
+ newData['otherPlay'] = isAdvShow;
+ }
+ }
+ } catch(event) {
+ thisTemp.log(event)
+ }
+ thisTemp.advertisements = newData;
+ //对广告进行分析结束
+ }
+ thisTemp.getVideo();
+ }
+ };
+ this.ajax(ajaxObj);
+ } else {
+ //根据广告分析
+ this.adAnalysisOne('front', 'adfront', 'adfronttime', 'adfrontlink', 'adfronttype');
+ this.adAnalysisOne('pause', 'adpause', 'adpausetime', 'adpauselink', 'adpausetype');
+ this.adAnalysisOne('insert', 'adinsert', 'adinserttime', 'adinsertlink', 'adinserttype');
+ this.adAnalysisOne('end', 'adend', 'adendtime', 'adendlink', 'adendtype');
+ if (!this.isUndefined(this.advertisements['insert'])) {
+ if (!this.isUndefined(v['inserttime'])) {
+ thisTemp.advertisements['inserttime'] = v['inserttime'];
+ }
+ }
+ if (!this.isUndefined(thisTemp.advertisements['inserttime'])) {
+ thisTemp.advertisements['inserttime'] = thisTemp.arrayInt(thisTemp.advertisements['inserttime']);
+ isInsert = [];
+ for (i = 0; i < thisTemp.advertisements['inserttime'].length; i++) {
+ isInsert.push(false);
+ }
+ thisTemp.advertisements['insertPlay'] = isInsert;
+ }
+ thisTemp.getVideo();
+ }
+ },
+ /*
+ 将广告数组数据里不是视频和图片的去除
+ */
+ arrayDel: function(arr) {
+ if (arr.length == 0) {
+ return null;
+ }
+ var newArr = [];
+ for (var i = 0; i < arr.length; i++) {
+ var type = arr[i]['type'];
+ if (type == 'mp4' || type == 'mov' || this.isStrImage(type)) {
+ newArr.push(arr[i]);
+ }
+ }
+ if (newArr.length > 0) {
+ return newArr;
+ }
+ return null;
+ },
+ /*分析单个类型的广告*/
+ adAnalysisOne: function(adType, adName, adTime, adLink, adStype) {
+ var v = this.vars;
+ if (this.isUndefined(v[adName])) {
+ v[adName] = '';
+ }
+ if (this.isUndefined(v[adTime])) {
+ v[adTime] = '';
+ }
+ if (this.isUndefined(v[adLink])) {
+ v[adLink] = '';
+ }
+ if (this.isUndefined(v[adStype])) {
+ v[adStype] = '';
+ }
+ if (v[adName] != '') {
+ var adList = [];
+ var ad = v[adName].split(',');
+ var adtime = v[adTime].split(',');
+ var adlink = v[adLink].split(',');
+ var adstype = v[adStype].split(',');
+ var i = 0;
+ if (ad.length > 0) {
+ var adLinkLen = adlink.length,
+ adTimeLen = adtime.length;
+ if (v[adLink] == '') {
+ adLinkLen = 0;
+ adlink = [];
+ }
+ if (v[adTime] == '') {
+ adTimeLen = 0;
+ adtime = [];
+ }
+ if (adLinkLen < ad.length) {
+ for (i = adLinkLen; i < ad.length; i++) {
+ adlink.push('');
+ }
+ }
+ if (adTimeLen < ad.length) {
+ for (i = adTimeLen; i < ad.length; i++) {
+ adtime.push('');
+ }
+ }
+ var adstypeLen = adstype.length;
+ if (v[adStype] == '') {
+ adstypeLen = 0;
+ adstype = [];
+ }
+ if (adstypeLen < ad.length) {
+ for (i = adstypeLen; i < ad.length; i++) {
+ adstype.push(this.getFileExt(ad[i]).replace('.', ''));
+ }
+ }
+ for (i = 0; i < ad.length; i++) {
+ var type = adstype[i];
+ if (type == 'mp4' || type == 'mov' || this.isStrImage(type)) {
+ var obj = {
+ file: ad[i],
+ type: type,
+ time: parseInt(adtime[i]) > 0 ? parseInt(adtime[i]) : this.ckplayerConfig['style']['advertisement']['time'],
+ link: adlink[i]
+ };
+ adList.push(obj);
+ }
+
+ }
+ if (this.isUndefined(this.advertisements)) {
+ this.advertisements = {};
+ }
+ if (adList.length > 0) {
+ this.advertisements[adType] = adList;
+ }
+ }
+ }
+ },
+ /*
+ 内部函数
+ 发送播放器加载成功的消息
+ */
+ playerLoad: function() {
+ var thisTemp = this;
+ if (this.isFirst) {
+ this.isFirst = false;
+ setTimeout(function() {
+ thisTemp.loadedHandler();
+ },1);
+ }
+ },
+ /*
+ 内部函数
+ 建立播放器的监听函数,包含操作监听及事件监听
+ */
+ addVEvent: function() {
+ var thisTemp = this;
+ //监听视频单击事件
+ var eventVideoClick = function(event) {
+ thisTemp.videoClick();
+ };
+ this.addListenerInside('click', eventVideoClick);
+ this.addListenerInside('click', eventVideoClick, this.MDC);
+ //延迟计算加载失败事件
+ this.timerErrorFun();
+ //监听视频加载到元数据事件
+ var eventJudgeIsLive = function(event) {
+ thisTemp.sendJS('loadedmetadata');
+ if (typeof(thisTemp.V.duration) == 'number' && thisTemp.V.duration > 1) {
+ thisTemp.sendJS('duration', thisTemp.V.duration);
+ thisTemp.formatInserttime(thisTemp.V.duration);
+ if (thisTemp.adPlayerPlay) {
+ thisTemp.advertisementsTime(thisTemp.V.duration + 1);
+ }
+ thisTemp.durationSendJS = true;
+ }
+ thisTemp.judgeIsLive();
+ };
+ this.addListenerInside('loadedmetadata', eventJudgeIsLive);
+ //监听视频播放事件
+ var eventPlaying = function(event) {
+ thisTemp.playingHandler();
+ thisTemp.sendJS('play');
+ thisTemp.sendJS('paused', false);
+ if (!thisTemp.durationSendJS && typeof(thisTemp.V.duration) == 'number' && thisTemp.V.duration > 0) {
+ thisTemp.durationSendJS = true;
+ thisTemp.sendJS('duration', thisTemp.V.duration);
+ thisTemp.formatInserttime(thisTemp.V.duration);
+ }
+ };
+ this.addListenerInside('playing', eventPlaying);
+ //监听视频暂停事件
+ var eventPause = function(event) {
+ thisTemp.pauseHandler();
+ thisTemp.sendJS('pause');
+ thisTemp.sendJS('paused', true);
+ };
+ this.addListenerInside('pause', eventPause);
+ //监听视频播放结束事件
+ var eventEnded = function(event) {
+ thisTemp.endedHandler();
+ };
+ this.addListenerInside('ended', eventEnded);
+ //监听视频播放时间事件
+ var eventTimeupdate = function(event) {
+ if (thisTemp.timerLoading != null) {
+ thisTemp.loadingStart(false);
+ }
+ if (thisTemp.time) {
+ if (!thisTemp.adPlayerPlay) {
+ thisTemp.sendJS('time', thisTemp.time);
+ //监听中间插入广告是否需要播放
+ if (!thisTemp.isUndefined(thisTemp.advertisements['insert'])) {
+ thisTemp.checkAdInsert(thisTemp.time);
+ }
+ //监听其它广告
+ if (!thisTemp.isUndefined(thisTemp.advertisements['other'])) {
+ thisTemp.checkAdOther(thisTemp.time);
+ }
+ if (thisTemp.time < 3 && thisTemp.adReset) {
+ thisTemp.adReset = false;
+ thisTemp.endedAdReset();
+ }
+ } else { //如果是广告则进行广告倒计时
+ thisTemp.adPlayerTimeHandler(thisTemp.time);
+ }
+
+ }
+ };
+ this.addListenerInside('timeupdate', eventTimeupdate);
+ //监听视频缓冲事件
+ var eventWaiting = function(event) {
+ thisTemp.loadingStart(true);
+ };
+ this.addListenerInside('waiting', eventWaiting);
+ //监听视频seek开始事件
+ var eventSeeking = function(event) {
+ thisTemp.sendJS('seek', 'start');
+ };
+ this.addListenerInside('seeking', eventSeeking);
+ //监听视频seek结束事件
+ var eventSeeked = function(event) {
+ thisTemp.seekedHandler();
+ thisTemp.sendJS('seek', 'ended');
+ };
+ this.addListenerInside('seeked', eventSeeked);
+ //监听视频音量
+ var eventVolumeChange = function(event) {
+ try {
+ thisTemp.volumechangeHandler();
+ thisTemp.sendJS('volume', thisTemp.volume || thisTemp.V.volume);
+ } catch(event) {}
+ };
+ this.addListenerInside('volumechange', eventVolumeChange);
+ //监听全屏事件
+ var eventFullChange = function(event) {
+ var fullState = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen;
+ thisTemp.sendJS('full', fullState);
+ };
+ this.addListenerInside('fullscreenchange', eventFullChange);
+ this.addListenerInside('webkitfullscreenchange', eventFullChange);
+ this.addListenerInside('mozfullscreenchange', eventFullChange);
+ //建立界面
+ if (this.showFace) {
+ this.interFace();
+ }
+ },
+ /*
+ 内部函数
+ 重置界面元素
+ */
+ resetPlayer: function() {
+ this.timeTextHandler();
+ if (this.showFace) {
+ this.timeProgress(0, 1); //改变时间进度条宽
+ this.changeLoad(0);
+ this.initPlayPause(); //判断显示播放或暂停按钮
+ this.definition(); //构建清晰度按钮
+ this.showFrontNext(); //构建上一集下一集按钮
+ this.deletePrompt(); //删除提示点
+ this.deletePreview(); //删除预览图
+ this.trackHide(); //重置字幕
+ this.resetTrack();
+ this.trackElement = [];
+ this.track = [];
+ }
+ },
+ /*
+ 内部函数
+ 构建界面元素
+ */
+ interFace: function() {
+ this.showFace = true;
+ var thisTemp = this;
+ var html = ''; //控制栏内容
+ var i = 0;
+ var bWidth = 38,//按钮的宽
+ bHeight = 38; //按钮的高
+ var bBgColor = '#FFFFFF',//按钮元素默认颜色
+ bOverColor = '#0782F5'; //按钮元素鼠标经过时的颜色
+ var timeInto = this.formatTime(0) + ' / ' + this.formatTime(this.vars['duration']); //时间显示框默认显示内容
+ var randomS = this.randomString(10); //获取一个随机字符串
+ /*
+ 以下定义界面各元素的ID,统一以ID结束
+ */
+ var controlBarBgID = 'controlbgbar' + randomS,//控制栏背景
+ controlBarID = 'controlbar' + randomS,//控制栏容器
+ timeProgressBgID = 'timeprogressbg' + randomS,//播放进度条背景
+ loadProgressID = 'loadprogress' + randomS,//加载进度条
+ timeProgressID = 'timeprogress' + randomS,//播放进度条
+ timeBOBGID = 'timebobg' + randomS,//播放进度按钮容器,该元素为一个透明覆盖在播放进度条上
+ timeBOID = 'timebo' + randomS,//播放进度可拖动按钮外框
+ timeBWID = 'timebw' + randomS,//播放进度可拖动按钮内框
+ timeTextID = 'timetext' + randomS,//时间文本框
+ playID = 'play' + randomS,//播放按钮
+ pauseID = 'pause' + randomS,//暂停按钮
+ frontID = 'front' + randomS,//前一集按钮
+ nextID = 'next' + randomS,//下一集按钮
+ fullID = 'full' + randomS,//全屏按钮
+ escFullID = 'escfull' + randomS,//退出全屏按钮
+ muteID = 'mute' + randomS,//静音按钮
+ escMuteID = 'escmute' + randomS,//取消静音按钮
+ volumeID = 'volume' + randomS,//音量调节框容器
+ volumeDbgID = 'volumedbg' + randomS,//音量调节框容器背景
+ volumeBgID = 'volumebg' + randomS,//音量调节框背景层
+ volumeUpID = 'volumeup' + randomS,//音量调节框可变宽度层
+ volumeBOID = 'volumebo' + randomS,//音量调节按钮外框
+ volumeBWID = 'volumebw' + randomS,//音量调节按钮内框
+ definitionID = 'definition' + randomS,//清晰度容器
+ definitionPID = 'definitionp' + randomS,//清晰度列表容器
+ playbackRateID = 'playbackrate' + randomS,//清晰度容器
+ playbackRatePID = 'playbackratep' + randomS,//清晰度列表容器
+ promptBgID = 'promptbg' + randomS,//提示框背景
+ promptID = 'prompt' + randomS,//提示框
+ dlineID = 'dline' + randomS,//分隔线共用前缀
+ menuID = 'menu' + randomS,//右键容器
+ pauseCenterID = 'pausecenter' + randomS,//中间暂停按钮
+ loadingID = 'loading' + randomS,//缓冲
+ errorTextID = 'errortext' + randomS,//错误文本框
+ logoID = 'logo' + randomS,//logo
+ adBackgroundID = 'background' + randomS,//广告背景图片
+ adElementID = 'adelement' + randomS,//广告容器
+ adBarID = 'adBar' + randomS,//广告顶部倒计时,跳过广告,静音按钮容器
+ adSkipID = 'adskip' + randomS,//跳过广告按钮
+ adTimeID = 'adtime' + randomS,//倒计时按钮
+ adLinkID = 'adlink' + randomS,//广告链接按钮
+ adMuteID = 'admute' + randomS,//广告静音按钮
+ adEscMuteID = 'adescmute' + randomS,//广告取消静音按钮
+ adPauseCloseID = 'adpauseclose' + randomS; //暂停广场的关闭按钮
+ /*
+ 构建一些PD(播放器容器)里使用的元素
+ */
+ var controlBarBg = document.createElement('div'),
+ controlBar = document.createElement('div'),
+ timeProgressBg = document.createElement('div'),
+ timeBoBg = document.createElement('div'),
+ pauseCenter = document.createElement('div'),
+ errorText = document.createElement('div'),
+ promptBg = document.createElement('div'),
+ prompt = document.createElement('div'),
+ menuDiv = document.createElement('div'),
+ definitionP = document.createElement('div'),
+ playbackrateP = document.createElement('div'),
+ loading = document.createElement('div'),
+ logo = document.createElement('div'),
+ adBackground = document.createElement('div'),
+ adElement = document.createElement('div'),
+ adBar = document.createElement('div'),
+ adLink = document.createElement('div'),
+ adPauseClose = document.createElement('div');
+ /*
+ 定义各节点的样式
+ */
+ controlBarBg.className = controlBarBgID;
+ controlBar.className = controlBarID;
+ timeProgressBg.className = timeProgressBgID;
+ timeBoBg.className = timeBOBGID;
+ promptBg.className = promptBgID;
+ prompt.className = promptID;
+ menuDiv.className = menuID;
+ definitionP.className = definitionPID;
+ playbackrateP.className = playbackRatePID;
+ pauseCenter.className = pauseCenterID;
+ loading.className = loadingID;
+ logo.className = logoID;
+ errorText.className = errorTextID;
+ adBackground.className = adBackgroundID;
+ adElement.className = adElementID;
+ adBar.className = adBarID;
+ adLink.className = adLinkID;
+ adPauseClose.className = adPauseCloseID;
+ /*
+ 加载节点到播放器容器中
+ */
+ this.PD.appendChild(controlBarBg);
+ this.PD.appendChild(controlBar);
+ this.PD.appendChild(timeProgressBg);
+ this.PD.appendChild(timeBoBg);
+ this.PD.appendChild(promptBg);
+ this.PD.appendChild(prompt);
+ this.PD.appendChild(definitionP);
+ this.PD.appendChild(playbackrateP);
+ this.PD.appendChild(pauseCenter);
+ this.PD.appendChild(loading);
+ this.PD.appendChild(errorText);
+ this.PD.appendChild(logo);
+ this.PD.appendChild(adBackground);
+ this.PD.appendChild(adElement);
+ this.PD.appendChild(adBar);
+ this.PD.appendChild(adLink);
+ this.PD.appendChild(adPauseClose);
+ this.body.appendChild(menuDiv);
+ if (this.vars['live']) { //如果是直播,时间显示文本框里显示当前系统时间
+ timeInto = this.getNowDate();
+ }
+ /*
+ 构建控制栏的内容
+ */
+ html += '' + this.newCanvas(playID, bWidth, bHeight) + '
'; //播放按钮
+ html += '' + this.newCanvas(pauseID, bWidth, bHeight) + '
'; //暂停按钮
+ html += '
'; //分隔线
+ html += '' + this.newCanvas(frontID, bWidth, bHeight) + '
'; //前一集按钮
+ html += '
'; //分隔线
+ html += '' + this.newCanvas(nextID, bWidth, bHeight) + '
'; //下一集按钮
+ html += '
'; //分隔线
+ html += '' + timeInto + '
'; //时间文本
+ html += '' + this.newCanvas(fullID, bWidth, bHeight) + '
'; //全屏按钮
+ html += '' + this.newCanvas(escFullID, bWidth, bHeight) + '
'; //退出全屏按钮
+ html += '
'; //分隔线
+ html += '
'; //清晰度容器
+ html += '
'; //分隔线
+ html += '
'; //倍速
+ html += '
'; //分隔线
+ html += ''; //音量调节框,音量调节按钮
+ html += '' + this.newCanvas(muteID, bWidth, bHeight) + '
'; //静音按钮
+ html += '' + this.newCanvas(escMuteID, bWidth, bHeight) + '
'; //退出静音按钮
+ html += '
'; //分隔线
+ this.getByElement(controlBarID).innerHTML = html;
+ //构建进度条内容
+ this.getByElement(timeProgressBgID).innerHTML = '
';
+ this.getByElement(timeBOBGID).innerHTML = '';
+ //构建进度条内容结束
+ this.getByElement(pauseCenterID).innerHTML = this.newCanvas(pauseCenterID, 80, 80); //构建中间暂停按钮
+ this.getByElement(loadingID).innerHTML = this.newCanvas(loadingID, 60, 60); //构建中间缓冲时显示的图标
+ this.getByElement(errorTextID).innerHTML = this.language['error']; //构建错误时显示的文本框
+ //构建广告相关
+ html = '' + this.language['adTime'].replace('{$second}', 0) + '
';
+ html += '' + this.newCanvas(adMuteID, 30, 30) + '
';
+ html += '' + this.newCanvas(adEscMuteID, 30, 30) + '
';
+ html += '
';
+ this.getByElement(adBarID).innerHTML = html;
+ this.getByElement(adLinkID).innerHTML = this.language['adLink'];
+ this.getByElement(adPauseCloseID).innerHTML = this.newCanvas(adPauseCloseID, 20, 20);
+ if (this.ckplayerConfig['style']['logo']) {
+ if (this.ckplayerConfig['style']['logo']['file']) {
+ var logoFile = this.ckplayerConfig['style']['logo']['file'];
+ if (logoFile.substr(0, 15) == 'data:image/png;' || logoFile.substr(0, 15) == 'data:image/jpg;' || logoFile.substr(0, 16) == 'data:image/jpeg;') {
+ this.getByElement(logoID).innerHTML = ' '; //构建logo
+ }
+ }
+ } else {
+ this.getByElement(logoID).innerHTML = this.vars['logo'] || this.logo || ''; //构建logo
+ }
+ var pd = this.PD;
+ //CB:Object:全局变量,将一些全局需要用到的元素统一放在CB对象里
+ this.CB = {
+ controlBarBg: this.getByElement(controlBarBgID, pd),
+ controlBar: this.getByElement(controlBarID, pd),
+ promptBg: this.getByElement(promptBgID, pd),
+ prompt: this.getByElement(promptID, pd),
+ timeProgressBg: this.getByElement(timeProgressBgID, pd),
+ loadProgress: this.getByElement(loadProgressID, pd),
+ timeProgress: this.getByElement(timeProgressID, pd),
+ timeBoBg: this.getByElement(timeBOBGID, pd),
+ timeButton: this.getByElement(timeBOID, pd),
+ timeText: this.getByElement(timeTextID, pd),
+ play: this.getByElement(playID, pd),
+ front: this.getByElement(frontID, pd),
+ next: this.getByElement(nextID, pd),
+ pause: this.getByElement(pauseID, pd),
+ definition: this.getByElement(definitionID, pd),
+ definitionP: this.getByElement(definitionPID, pd),
+ definitionLine: this.getByElement(dlineID + '-rb', pd),
+ playbackrate: this.getByElement(playbackRateID, pd),
+ playbackrateP: this.getByElement(playbackRatePID, pd),
+ playbackrateLine: this.getByElement(dlineID + '-rc', pd),
+ full: this.getByElement(fullID, pd),
+ escFull: this.getByElement(escFullID, pd),
+ mute: this.getByElement(muteID, pd),
+ escMute: this.getByElement(escMuteID, pd),
+ volume: this.getByElement(volumeID, pd),
+ volumeBg: this.getByElement(volumeBgID, pd),
+ volumeUp: this.getByElement(volumeUpID, pd),
+ volumeBO: this.getByElement(volumeBOID, pd),
+ pauseCenter: this.getByElement(pauseCenterID, pd),
+ menu: this.getByElement(menuID),
+ loading: this.getByElement(loadingID, pd),
+ loadingCanvas: this.getByElement(loadingID + '-canvas', pd),
+ errorText: this.getByElement(errorTextID, pd),
+ logo: this.getByElement(logoID, pd),
+ playLine: this.getByElement(dlineID + '-la', pd),
+ frontLine: this.getByElement(dlineID + '-lb', pd),
+ nextLine: this.getByElement(dlineID + '-lc', pd),
+ fullLine: this.getByElement(dlineID + '-ra'),
+ definitionLine: this.getByElement(dlineID + '-rb', pd),
+ muteLine: this.getByElement(dlineID + '-rd', pd),
+ adBackground: this.getByElement(adBackgroundID, pd),
+ adElement: this.getByElement(adElementID, pd),
+ adBar: this.getByElement(adBarID, pd),
+ adSkip: this.getByElement(adSkipID, pd),
+ adTime: this.getByElement(adTimeID, pd),
+ adLink: this.getByElement(adLinkID, pd),
+ adMute: this.getByElement(adMuteID, pd),
+ adEscMute: this.getByElement(adEscMuteID, pd),
+ adPauseClose: this.getByElement(adPauseCloseID, pd)
+ };
+ this.buttonWidth = {
+ play: bWidth,
+ full: bWidth,
+ front: bWidth,
+ next: bWidth,
+ mute: bWidth
+ };
+ //定义界面元素的样式
+ //控制栏背景
+ this.css(controlBarBgID, {
+ width: '100%',
+ height: bHeight + 'px',
+ backgroundColor: '#000000',
+ position: 'absolute',
+ bottom: '0px',
+ filter: 'alpha(opacity:0.8)',
+ opacity: '0.8',
+ zIndex: '990'
+ });
+ //控制栏容器
+ this.css(controlBarID, {
+ width: '100%',
+ height: bHeight + 'px',
+ position: 'absolute',
+ bottom: '0px',
+ zIndex: '990'
+ });
+ //中间暂停按钮
+ this.css(pauseCenterID, {
+ width: '80px',
+ height: '80px',
+ borderRadius: '50%',
+ position: 'absolute',
+ display: 'none',
+ cursor: 'pointer',
+ zIndex: '996'
+ });
+ //loading
+ this.css(loadingID, {
+ width: '60px',
+ height: '60px',
+ position: 'absolute',
+ display: 'none',
+ zIndex: '996'
+ });
+ //出错文本框
+ this.css(errorTextID, {
+ width: '120px',
+ height: '30px',
+ lineHeight: '30px',
+ color: '#FFFFFF',
+ fontSize: '14px',
+ textAlign: 'center',
+ position: 'absolute',
+ display: 'none',
+ zIndex: '101',
+ cursor: 'default',
+ zIndex: '996'
+ });
+ //定义logo文字的样式
+ this.css(logoID, {
+ height: '30px',
+ lineHeight: '30px',
+ color: '#FFFFFF',
+ fontFamily: 'Arial',
+ fontSize: '28px',
+ textAlign: 'center',
+ position: 'absolute',
+ float: 'left',
+ left: '-1000px',
+ top: '20px',
+ zIndex: '996',
+ filter: 'alpha(opacity:0.8)',
+ opacity: '0.8',
+ cursor: 'default'
+ });
+
+ this.css(this.CB['loadingCanvas'], {
+ transform: 'rotate(0deg)',
+ msTransform: 'rotate(0deg)',
+ mozTransform: 'rotate(0deg)',
+ webkitTransform: 'rotate(0deg)',
+ oTransform: 'rotate(0deg)'
+ });
+ //定义提示语的样式
+ this.css([promptBgID, promptID], {
+ height: '30px',
+ lineHeight: '30px',
+ color: '#FFFFFF',
+ fontSize: '14px',
+ textAlign: 'center',
+ position: 'absolute',
+ borderRadius: '5px',
+ paddingLeft: '5px',
+ paddingRight: '5px',
+ bottom: '0px',
+ display: 'none',
+ zIndex: '995'
+ });
+ this.css(promptBgID, {
+ backgroundColor: '#000000',
+ filter: 'alpha(opacity:0.5)',
+ opacity: '0.5'
+ });
+ //时间进度条背景容器
+ this.css(timeProgressBgID, {
+ width: '100%',
+ height: '6px',
+ backgroundColor: '#3F3F3F',
+ overflow: 'hidden',
+ position: 'absolute',
+ bottom: '38px',
+ zIndex: '888'
+ });
+ //加载进度和时间进度
+ this.css([loadProgressID, timeProgressID], {
+ width: '1px',
+ height: '6px',
+ position: 'absolute',
+ bottom: '38px',
+ top: '0px',
+ zIndex: '991'
+ });
+ this.css(loadProgressID, 'backgroundColor', '#6F6F6F');
+ this.css(timeProgressID, 'backgroundColor', bOverColor);
+ //时间进度按钮
+ this.css(timeBOBGID, {
+ width: '100%',
+ height: '14px',
+ overflow: 'hidden',
+ position: 'absolute',
+ bottom: '34px',
+ cursor: 'pointer',
+ zIndex: '992'
+ });
+ this.css(timeBOID, {
+ width: '14px',
+ height: '14px',
+ overflow: 'hidden',
+ borderRadius: '50%',
+ backgroundColor: bBgColor,
+ cursor: 'pointer',
+ position: 'absolute',
+ top: '0px',
+ zIndex: '200'
+ });
+ this.css(timeBWID, {
+ width: '8px',
+ height: '8px',
+ overflow: 'hidden',
+ borderRadius: '50%',
+ position: 'absolute',
+ backgroundColor: bOverColor,
+ left: '3px',
+ top: '3px'
+ });
+ this.css(timeTextID, {
+ lineHeight: bHeight + 'px',
+ color: '#FFFFFF',
+ fontFamily: 'arial',
+ fontSize: '16px',
+ paddingLeft: '10px',
+ float: 'left',
+ overflow: 'hidden',
+ cursor: 'default'
+ });
+ //分隔线
+ this.css([dlineID + '-la', dlineID + '-lb', dlineID + '-lc', dlineID + '-ra', dlineID + '-rb', dlineID + '-rc', dlineID + '-rd'], {
+ width: '0px',
+ height: bHeight + 'px',
+ overflow: 'hidden',
+ borderLeft: '1px solid #303030',
+ borderRight: '1px solid #151515',
+ filter: 'alpha(opacity:0.9)',
+ opacity: '0.9'
+ });
+ this.css([dlineID + '-la', dlineID + '-lb', dlineID + '-lc'], 'float', 'left');
+ this.css([dlineID + '-ra', dlineID + '-rb', dlineID + '-rc', dlineID + '-rd'], 'float', 'right');
+ this.css([dlineID + '-lb', dlineID + '-lc', dlineID + '-rb', dlineID + '-rc'], 'display', 'none');
+ //播放/暂停/上一集/下一集按钮
+ this.css([playID, pauseID, frontID, nextID], {
+ width: bWidth + 'px',
+ height: bHeight + 'px',
+ float: 'left',
+ overflow: 'hidden',
+ cursor: 'pointer'
+ });
+ this.css([frontID, nextID], 'display', 'none');
+ //初始化判断播放/暂停按钮隐藏项
+ this.initPlayPause();
+
+ //设置静音/取消静音的按钮样式
+ this.css([muteID, escMuteID], {
+ width: bWidth + 'px',
+ height: bHeight + 'px',
+ float: 'right',
+ overflow: 'hidden',
+ cursor: 'pointer'
+ });
+ if (this.vars['volume'] > 0) {
+ this.css(escMuteID, 'display', 'none');
+ } else {
+ this.css(muteID, 'display', 'none');
+ }
+ if (!this.ckplayerConfig['config']['mobileVolumeBarShow'] && this.isMobile()) {
+ this.css([muteID, escMuteID, volumeID, volumeDbgID, dlineID + '-rd'], {
+ display: 'none'
+ });
+ }
+ //音量调节框
+ this.css([volumeID, volumeDbgID], {
+ width: '110px',
+ height: bHeight + 'px',
+ overflow: 'hidden',
+ float: 'right'
+ });
+ this.css(volumeDbgID, {
+ position: 'absolute'
+ });
+ this.css([volumeBgID, volumeUpID], {
+ width: '100px',
+ height: '6px',
+ overflow: 'hidden',
+ borderRadius: '5px',
+ cursor: 'pointer'
+ });
+ this.css(volumeBgID, {
+ position: 'absolute',
+ top: '16px'
+ });
+ this.css(volumeBgID, 'backgroundColor', '#666666');
+ this.css(volumeUpID, 'backgroundColor', bOverColor);
+ this.buttonWidth['volume'] = 100;
+ //音量调节按钮
+ this.css(volumeBOID, {
+ width: '12px',
+ height: '12px',
+ overflow: 'hidden',
+ borderRadius: '50%',
+ position: 'absolute',
+ backgroundColor: bBgColor,
+ top: '13px',
+ left: '0px',
+ cursor: 'pointer'
+ });
+ this.css(volumeBWID, {
+ width: '6px',
+ height: '6px',
+ overflow: 'hidden',
+ borderRadius: '50%',
+ position: 'absolute',
+ backgroundColor: bOverColor,
+ left: '3px',
+ top: '3px'
+ });
+ //清晰度容器
+ this.css(definitionID, {
+ lineHeight: bHeight + 'px',
+ color: '#FFFFFF',
+ float: 'right',
+ fontSize: '14px',
+ textAlign: 'center',
+ overflow: 'hidden',
+ display: 'none',
+ cursor: 'pointer'
+ });
+ this.css(definitionPID, {
+ lineHeight: (bHeight - 8) + 'px',
+ color: '#FFFFFF',
+ overflow: 'hidden',
+ position: 'absolute',
+ bottom: '4px',
+ backgroundColor: '#000000',
+ textAlign: 'center',
+ zIndex: '995',
+ cursor: 'pointer',
+ display: 'none'
+ });
+ //倍速容器
+ this.css(playbackRateID, {
+ lineHeight: bHeight + 'px',
+ color: '#FFFFFF',
+ float: 'right',
+ fontSize: '14px',
+ textAlign: 'center',
+ overflow: 'hidden',
+ display: 'none',
+ cursor: 'pointer'
+ });
+ this.css(playbackRatePID, {
+ lineHeight: (bHeight - 8) + 'px',
+ color: '#FFFFFF',
+ overflow: 'hidden',
+ position: 'absolute',
+ bottom: '4px',
+ backgroundColor: '#000000',
+ textAlign: 'center',
+ zIndex: '995',
+ cursor: 'pointer',
+ display: 'none'
+ });
+ //设置全屏/退出全屏按钮样式
+ this.css([fullID, escFullID], {
+ width: bWidth + 'px',
+ height: bHeight + 'px',
+ float: 'right',
+ overflow: 'hidden',
+ cursor: 'pointer'
+ });
+ this.css(escFullID, 'display', 'none');
+ //设置广告背景层样式
+ this.css(adBackgroundID, {
+ width: '100%',
+ height: '100%',
+ backgroundColor: '#000000',
+ position: 'absolute',
+ top: '0px',
+ zIndex: '997',
+ display: 'none'
+ });
+ this.css(adElementID, {
+ position: 'absolute',
+ overflow: 'hidden',
+ top: '0px',
+ zIndex: '998',
+ float: 'center',
+ display: 'none'
+ });
+ this.css(adBarID, {
+ position: 'absolute',
+ overflow: 'hidden',
+ top: '10px',
+ right: '10px',
+ zIndex: '999',
+ textAlign: 'right',
+ display: 'none'
+ });
+ this.css(adTimeID, {
+ backgroundColor: '#000000',
+ color: '#FF0000',
+ paddingLeft: '10px',
+ paddingRight: '10px',
+ lineHeight: (bHeight - 8) + 'px',
+ marginLeft: '5px',
+ float: 'right',
+ cursor: 'pointer'
+ });
+ this.css([adMuteID, adEscMuteID], {
+ backgroundColor: '#000000',
+ width: '30px',
+ height: '30px',
+ marginLeft: '5px',
+ float: 'right',
+ display: 'none',
+ cursor: 'pointer'
+ });
+ this.css(adSkipID, {
+ backgroundColor: '#000000',
+ lineHeight: (bHeight - 8) + 'px',
+ color: '#FFFFFF',
+ paddingLeft: '10px',
+ paddingRight: '10px',
+ float: 'right',
+ display: 'none',
+ cursor: 'pointer'
+ });
+ this.css(adLinkID, {
+ backgroundColor: '#ea5503',
+ lineHeight: (bHeight - 8) + 'px',
+ color: '#FFFFFF',
+ paddingLeft: '10px',
+ paddingRight: '10px',
+ position: 'absolute',
+ overflow: 'hidden',
+ bottom: '10px',
+ right: '10px',
+ zIndex: '999',
+ display: 'none'
+ });
+ this.css(adPauseCloseID, {
+ backgroundColor: '#f7f7f7',
+ //f8f7f7
+ widht: '20px',
+ height: '20px',
+ position: 'absolute',
+ overflow: 'hidden',
+ zIndex: '999',
+ top: '60px',
+ left: '30px',
+ borderRadius: '20px',
+ display: 'none',
+ cursor: 'pointer'
+ });
+ //构建各按钮的形状
+ //播放按钮
+ var cPlay = this.getByElement(playID + '-canvas').getContext('2d');
+ var cPlayFillRect = function() {
+ thisTemp.canvasFill(cPlay, [[12, 10], [29, 19], [12, 28]]);
+ };
+ cPlay.fillStyle = bBgColor;
+ cPlayFillRect();
+ var cPlayOver = function(event) {
+ cPlay.clearRect(0, 0, bWidth, bHeight);
+ cPlay.fillStyle = bOverColor;
+ cPlayFillRect();
+ };
+ var cPlayOut = function(event) {
+ cPlay.clearRect(0, 0, bWidth, bHeight);
+ cPlay.fillStyle = bBgColor;
+ cPlayFillRect();
+ };
+
+ this.addListenerInside('mouseover', cPlayOver, this.getByElement(playID + '-canvas'));
+ this.addListenerInside('mouseout', cPlayOut, this.getByElement(playID + '-canvas'));
+ //暂停按钮
+ var cPause = this.getByElement(pauseID + '-canvas').getContext('2d');
+ var cPauseFillRect = function() {
+ thisTemp.canvasFillRect(cPause, [[10, 10, 5, 18], [22, 10, 5, 18]]);
+ };
+ cPause.fillStyle = bBgColor;
+ cPauseFillRect();
+ var cPauseOver = function(event) {
+ cPause.clearRect(0, 0, bWidth, bHeight);
+ cPause.fillStyle = bOverColor;
+ cPauseFillRect();
+ };
+ var cPauseOut = function(event) {
+ cPause.clearRect(0, 0, bWidth, bHeight);
+ cPause.fillStyle = bBgColor;
+ cPauseFillRect();
+ };
+ this.addListenerInside('mouseover', cPauseOver, this.getByElement(pauseID + '-canvas'));
+ this.addListenerInside('mouseout', cPauseOut, this.getByElement(pauseID + '-canvas'));
+ //前一集按钮
+ var cFront = this.getByElement(frontID + '-canvas').getContext('2d');
+ var cFrontFillRect = function() {
+ thisTemp.canvasFill(cFront, [[16, 19], [30, 10], [30, 28]]);
+ thisTemp.canvasFillRect(cFront, [[8, 10, 5, 18]]);
+ };
+ cFront.fillStyle = bBgColor;
+ cFrontFillRect();
+ var cFrontOver = function(event) {
+ cFront.clearRect(0, 0, bWidth, bHeight);
+ cFront.fillStyle = bOverColor;
+ cFrontFillRect();
+ };
+ var cFrontOut = function(event) {
+ cFront.clearRect(0, 0, bWidth, bHeight);
+ cFront.fillStyle = bBgColor;
+ cFrontFillRect();
+ };
+
+ this.addListenerInside('mouseover', cFrontOver, this.getByElement(frontID + '-canvas'));
+ this.addListenerInside('mouseout', cFrontOut, this.getByElement(frontID + '-canvas'));
+ //下一集按钮
+ var cNext = this.getByElement(nextID + '-canvas').getContext('2d');
+ var cNextFillRect = function() {
+ thisTemp.canvasFill(cNext, [[8, 10], [22, 19], [8, 28]]);
+ thisTemp.canvasFillRect(cNext, [[25, 10, 5, 18]]);
+ };
+ cNext.fillStyle = bBgColor;
+ cNextFillRect();
+ var cNextOver = function(event) {
+ cNext.clearRect(0, 0, bWidth, bHeight);
+ cNext.fillStyle = bOverColor;
+ cNextFillRect();
+ };
+ var cNextOut = function(event) {
+ cNext.clearRect(0, 0, bWidth, bHeight);
+ cNext.fillStyle = bBgColor;
+ cNextFillRect();
+ };
+ this.addListenerInside('mouseover', cNextOver, this.getByElement(nextID + '-canvas'));
+ this.addListenerInside('mouseout', cNextOut, this.getByElement(nextID + '-canvas'));
+ //全屏按钮
+ var cFull = this.getByElement(fullID + '-canvas').getContext('2d');
+ var cFullFillRect = function() {
+ thisTemp.canvasFillRect(cFull, [[19, 10, 9, 3], [25, 13, 3, 6], [10, 19, 3, 9], [13, 25, 6, 3]]);
+ };
+ cFull.fillStyle = bBgColor;
+ cFullFillRect();
+ var cFullOver = function() {
+ cFull.clearRect(0, 0, bWidth, bHeight);
+ cFull.fillStyle = bOverColor;
+ cFullFillRect();
+ };
+ var cFullOut = function() {
+ cFull.clearRect(0, 0, bWidth, bHeight);
+ cFull.fillStyle = bBgColor;
+ cFullFillRect();
+ };
+ this.addListenerInside('mouseover', cFullOver, this.getByElement(fullID + '-canvas'));
+ this.addListenerInside('mouseout', cFullOut, this.getByElement(fullID + '-canvas'));
+ //定义退出全屏按钮样式
+ var cEscFull = this.getByElement(escFullID + '-canvas').getContext('2d');
+ var cEscFullFillRect = function() {
+ thisTemp.canvasFillRect(cEscFull, [[20, 9, 3, 9], [23, 15, 6, 3], [9, 20, 9, 3], [15, 23, 3, 6]]);
+ };
+ cEscFull.fillStyle = bBgColor;
+ cEscFullFillRect();
+ var cEscFullOver = function() {
+ cEscFull.clearRect(0, 0, bWidth, bHeight);
+ cEscFull.fillStyle = bOverColor;
+ cEscFullFillRect();
+ };
+ var cEscFullOut = function() {
+ cEscFull.clearRect(0, 0, bWidth, bHeight);
+ cEscFull.fillStyle = bBgColor;
+ cEscFullFillRect();
+ };
+ this.addListenerInside('mouseover', cEscFullOver, this.getByElement(escFullID + '-canvas'));
+ this.addListenerInside('mouseout', cEscFullOut, this.getByElement(escFullID + '-canvas'));
+ //定义静音按钮的样式
+ var cMute = this.getByElement(muteID + '-canvas').getContext('2d');
+ var cMuteFillRect = function() {
+ thisTemp.canvasFill(cMute, [[10, 15], [15, 15], [21, 10], [21, 28], [15, 23], [10, 23]]);
+ thisTemp.canvasFillRect(cMute, [[23, 15, 2, 8], [27, 10, 2, 18]]);
+ };
+ cMute.fillStyle = bBgColor;
+ cMuteFillRect();
+ var cMuteOver = function() {
+ cMute.clearRect(0, 0, bWidth, bHeight);
+ cMute.fillStyle = bOverColor;
+ cMuteFillRect();
+ };
+ var cMuteOut = function() {
+ cMute.clearRect(0, 0, bWidth, bHeight);
+ cMute.fillStyle = bBgColor;
+ cMuteFillRect();
+ };
+ this.addListenerInside('mouseover', cMuteOver, this.getByElement(muteID + '-canvas'));
+ this.addListenerInside('mouseout', cMuteOut, this.getByElement(muteID + '-canvas'));
+ //定义取消广告静音按钮样式
+ var cEscMute = this.getByElement(escMuteID + '-canvas').getContext('2d');
+ var cEscMuteFillRect = function() {
+ thisTemp.canvasFill(cEscMute, [[10, 15], [15, 15], [21, 10], [21, 28], [15, 23], [10, 23]]);
+ thisTemp.canvasFill(cEscMute, [[23, 13], [24, 13], [33, 25], [32, 25]]);
+ thisTemp.canvasFill(cEscMute, [[32, 13], [33, 13], [24, 25], [23, 25]]);
+ };
+ cEscMute.fillStyle = bBgColor;
+ cEscMuteFillRect();
+ var cEscMuteOver = function() {
+ cEscMute.clearRect(0, 0, bWidth, bHeight);
+ cEscMute.fillStyle = bOverColor;
+ cEscMuteFillRect();
+ };
+ var cEscMuteOut = function() {
+ cEscMute.clearRect(0, 0, bWidth, bHeight);
+ cEscMute.fillStyle = bBgColor;
+ cEscMuteFillRect();
+ };
+ this.addListenerInside('mouseover', cEscMuteOver, this.getByElement(escMuteID + '-canvas'));
+ this.addListenerInside('mouseout', cEscMuteOut, this.getByElement(escMuteID + '-canvas'));
+ //定义广告静音按钮的样式
+ var cAdMute = this.getByElement(adMuteID + '-canvas').getContext('2d');
+ var cAdMuteFillRect = function() {
+ thisTemp.canvasFill(cAdMute, [[8, 12], [12, 12], [16, 8], [16, 21], [12, 18], [8, 18]]);
+ thisTemp.canvasFillRect(cAdMute, [[18, 12, 2, 6], [21, 8, 2, 14]]);
+ };
+ cAdMute.fillStyle = bBgColor;
+ cAdMuteFillRect();
+ var cAdMuteOver = function() {
+ cAdMute.clearRect(0, 0, bWidth, bHeight);
+ cAdMute.fillStyle = bOverColor;
+ cAdMuteFillRect();
+ };
+ var cAdMuteOut = function() {
+ cAdMute.clearRect(0, 0, bWidth, bHeight);
+ cAdMute.fillStyle = bBgColor;
+ cAdMuteFillRect();
+ };
+ this.addListenerInside('mouseover', cAdMuteOver, this.getByElement(adMuteID + '-canvas'));
+ this.addListenerInside('mouseout', cAdMuteOut, this.getByElement(adMuteID + '-canvas'));
+ //定义取消静音广告按钮样式
+ var cAdEscMute = this.getByElement(adEscMuteID + '-canvas').getContext('2d');
+ var cAdEscMuteFillRect = function() {
+ thisTemp.canvasFill(cAdEscMute, [[8, 12], [12, 12], [16, 8], [16, 21], [12, 18], [8, 18]]);
+ thisTemp.canvasFill(cAdEscMute, [[18, 10], [20, 10], [26, 20], [24, 20]]);
+ thisTemp.canvasFill(cAdEscMute, [[25, 10], [27, 10], [20, 20], [18, 20]]);
+ };
+ cAdEscMute.fillStyle = bBgColor;
+ cAdEscMuteFillRect();
+ var cAdEscMuteOver = function() {
+ cAdEscMute.clearRect(0, 0, bWidth, bHeight);
+ cAdEscMute.fillStyle = bOverColor;
+ cAdEscMuteFillRect();
+ };
+ var cAdEscMuteOut = function() {
+ cAdEscMute.clearRect(0, 0, bWidth, bHeight);
+ cAdEscMute.fillStyle = bBgColor;
+ cAdEscMuteFillRect();
+ };
+ this.addListenerInside('mouseover', cAdEscMuteOver, this.getByElement(adEscMuteID + '-canvas'));
+ this.addListenerInside('mouseout', cAdEscMuteOut, this.getByElement(adEscMuteID + '-canvas'));
+ //定义暂停广告关闭按钮
+ var adPauseClose = this.getByElement(adPauseCloseID + '-canvas').getContext('2d');
+ var adPauseCloseFillRect = function() {
+ thisTemp.canvasFill(adPauseClose, [[4, 6], [6, 6], [16, 15], [14, 15]]);
+ thisTemp.canvasFill(adPauseClose, [[14, 6], [16, 6], [6, 15], [4, 15]]);
+ };
+ adPauseClose.fillStyle = '#404856';
+ adPauseCloseFillRect();
+ var adPauseCloseOver = function() {
+ adPauseClose.clearRect(0, 0, bWidth, bHeight);
+ adPauseClose.fillStyle = bOverColor;
+ adPauseCloseFillRect();
+ };
+ var adPauseCloseOut = function() {
+ adPauseClose.clearRect(0, 0, bWidth, bHeight);
+ adPauseClose.fillStyle = '#404856';
+ adPauseCloseFillRect();
+ };
+ this.addListenerInside('mouseover', adPauseCloseOver, this.getByElement(adPauseCloseID + '-canvas'));
+ this.addListenerInside('mouseout', adPauseCloseOut, this.getByElement(adPauseCloseID + '-canvas'));
+ //定义loading样式
+ var cLoading = this.getByElement(loadingID + '-canvas').getContext('2d');
+ var cLoadingFillRect = function() {
+ cLoading.save();
+ var grad = cLoading.createLinearGradient(0, 0, 60, 60);
+ grad.addColorStop(0, bBgColor);
+ var grad2 = cLoading.createLinearGradient(0, 0, 80, 60);
+ grad2.addColorStop(1, bOverColor);
+ var grad3 = cLoading.createLinearGradient(0, 0, 80, 60);
+ grad3.addColorStop(1, '#FF9900');
+ var grad4 = cLoading.createLinearGradient(0, 0, 80, 60);
+ grad4.addColorStop(1, '#CC3300');
+ cLoading.strokeStyle = grad; //设置描边样式
+ cLoading.lineWidth = 8; //设置线宽
+ cLoading.beginPath(); //路径开始
+ cLoading.arc(30, 30, 25, 0, 0.4 * Math.PI, false); //用于绘制圆弧context.arc(x坐标,y坐标,半径,起始角度,终止角度,顺时针/逆时针)
+ cLoading.stroke(); //绘制
+ cLoading.closePath(); //路径结束
+ cLoading.beginPath(); //路径开始
+ cLoading.strokeStyle = grad2; //设置描边样式
+ cLoading.arc(30, 30, 25, 0.5 * Math.PI, 0.9 * Math.PI, false); //用于绘制圆弧context.arc(x坐标,y坐标,半径,起始角度,终止角度,顺时针/逆时针)
+ cLoading.stroke(); //绘制
+ cLoading.beginPath(); //路径开始
+ cLoading.strokeStyle = grad3; //设置描边样式
+ cLoading.arc(30, 30, 25, Math.PI, 1.4 * Math.PI, false); //用于绘制圆弧context.arc(x坐标,y坐标,半径,起始角度,终止角度,顺时针/逆时针)
+ cLoading.stroke(); //绘制
+ cLoading.beginPath(); //路径开始
+ cLoading.strokeStyle = grad4; //设置描边样式
+ cLoading.arc(30, 30, 25, 1.5 * Math.PI, 1.9 * Math.PI, false); //用于绘制圆弧context.arc(x坐标,y坐标,半径,起始角度,终止角度,顺时针/逆时针)
+ cLoading.stroke(); //绘制
+ cLoading.closePath(); //路径结束
+ cLoading.restore();
+ };
+ cLoading.fillStyle = bBgColor;
+ cLoadingFillRect();
+ //定义中间暂停按钮的样式
+ var cPauseCenter = this.getByElement(pauseCenterID + '-canvas').getContext('2d');
+ var cPauseCenterFillRect = function() {
+ thisTemp.canvasFill(cPauseCenter, [[28, 22], [59, 38], [28, 58]]);
+ /* 指定几个颜色 */
+ cPauseCenter.save();
+ cPauseCenter.lineWidth = 5; //设置线宽
+ cPauseCenter.beginPath(); //路径开始
+ cPauseCenter.arc(40, 40, 35, 0, 2 * Math.PI, false); //用于绘制圆弧context.arc(x坐标,y坐标,半径,起始角度,终止角度,顺时针/逆时针)
+ cPauseCenter.stroke(); //绘制
+ cPauseCenter.closePath(); //路径结束
+ cPauseCenter.restore();
+ };
+ cPauseCenter.fillStyle = bBgColor;
+ cPauseCenter.strokeStyle = bBgColor;
+ cPauseCenterFillRect();
+ var cPauseCenterOver = function() {
+ cPauseCenter.clearRect(0, 0, 80, 80);
+ cPauseCenter.fillStyle = bOverColor;
+ cPauseCenter.strokeStyle = bOverColor;
+ cPauseCenterFillRect();
+ };
+ var cPauseCenterOut = function() {
+ cPauseCenter.clearRect(0, 0, 80, 80);
+ cPauseCenter.fillStyle = bBgColor;
+ cPauseCenter.strokeStyle = bBgColor;
+ cPauseCenterFillRect();
+ };
+ this.addListenerInside('mouseover', cPauseCenterOver, this.getByElement(pauseCenterID + '-canvas'));
+ this.addListenerInside('mouseout', cPauseCenterOut, this.getByElement(pauseCenterID + '-canvas'));
+
+ //鼠标经过/离开音量调节按钮
+ var volumeBOOver = function() {
+ thisTemp.css(volumeBOID, 'backgroundColor', bOverColor);
+ thisTemp.css(volumeBWID, 'backgroundColor', bBgColor);
+ };
+ var volumeBOOut = function() {
+ thisTemp.css(volumeBOID, 'backgroundColor', bBgColor);
+ thisTemp.css(volumeBWID, 'backgroundColor', bOverColor);
+ };
+ this.addListenerInside('mouseover', volumeBOOver, this.getByElement(volumeBOID));
+ this.addListenerInside('mouseout', volumeBOOut, this.getByElement(volumeBOID));
+ //鼠标经过/离开进度按钮
+ var timeBOOver = function() {
+ thisTemp.css(timeBOID, 'backgroundColor', bOverColor);
+ thisTemp.css(timeBWID, 'backgroundColor', bBgColor);
+ };
+ var timeBOOut = function() {
+ thisTemp.css(timeBOID, 'backgroundColor', bBgColor);
+ thisTemp.css(timeBWID, 'backgroundColor', bOverColor);
+ };
+ this.addListenerInside('mouseover', timeBOOver, this.getByElement(timeBOID));
+ this.addListenerInside('mouseout', timeBOOut, this.getByElement(timeBOID));
+
+ this.addButtonEvent(); //注册按钮及音量调节,进度操作事件
+ this.newMenu(); //单独设置右键的样式和事件
+ this.controlBarHide(); //单独注册控制栏隐藏事件
+ this.keypress(); //单独注册键盘事件
+ //初始化音量调节框
+ this.changeVolume(this.vars['volume']);
+ //初始化判断是否需要显示上一集和下一集按钮
+ this.showFrontNext();
+ setTimeout(function() {
+ thisTemp.elementCoordinate(); //调整中间暂停按钮/loading的位置/error的位置
+ },
+ 100);
+ this.checkBarWidth();
+ var resize = function() {
+ thisTemp.elementCoordinate();
+ thisTemp.timeUpdateHandler();
+ thisTemp.changeLoad();
+ thisTemp.checkBarWidth();
+ thisTemp.changeElementCoor(); //修改新加元件的坐标
+ thisTemp.changePrompt();
+ thisTemp.adPauseCoor();
+ thisTemp.adOtherCoor();
+ };
+ this.addListenerInside('resize', resize, window);
+ },
+ /*
+ 内部函数
+ 创建按钮,使用canvas画布
+ */
+ newCanvas: function(id, width, height) {
+ return ' ';
+ },
+ /*
+ 内部函数
+ 注册按钮,音量调节框,进度操作框事件
+ */
+ addButtonEvent: function() {
+ var thisTemp = this;
+ //定义按钮的单击事件
+ var playClick = function(event) {
+ thisTemp.videoPlay();
+ thisTemp.sendJS('clickEvent', 'actionScript->videoPlay');
+ };
+ this.addListenerInside('click', playClick, this.CB['play']);
+ this.addListenerInside('click', playClick, this.CB['pauseCenter']);
+ var pauseClick = function(event) {
+ thisTemp.videoPause();
+ thisTemp.sendJS('clickEvent', 'actionScript->videoPause');
+ };
+ this.addListenerInside('click', pauseClick, this.CB['pause']);
+ var frontClick = function(event) {
+ if (thisTemp.vars['front']) {
+ eval(thisTemp.vars['front'] + '()');
+ thisTemp.sendJS('clickEvent', 'actionScript->' + thisTemp.vars['front']);
+ }
+ };
+ this.addListenerInside('click', frontClick, this.CB['front']);
+ var nextClick = function(event) {
+ if (thisTemp.vars['next']) {
+ eval(thisTemp.vars['next'] + '()');
+ thisTemp.sendJS('clickEvent', 'actionScript->' + thisTemp.vars['next']);
+ }
+ };
+ this.addListenerInside('click', nextClick, this.CB['next']);
+ var muteClick = function(event) {
+ thisTemp.videoMute();
+ thisTemp.sendJS('clickEvent', 'actionScript->videoMute');
+ };
+ this.addListenerInside('click', muteClick, this.CB['mute']);
+ var escMuteClick = function(event) {
+ thisTemp.videoEscMute();
+ thisTemp.sendJS('clickEvent', 'actionScript->videoEscMute');
+ };
+ this.addListenerInside('click', escMuteClick, this.CB['escMute']);
+ var fullClick = function(event) {
+ thisTemp.fullScreen();
+ thisTemp.sendJS('clickEvent', 'actionScript->fullScreen');
+ };
+ this.addListenerInside('click', fullClick, this.CB['full']);
+ var escFullClick = function(event) {
+ thisTemp.quitFullScreen();
+ thisTemp.sendJS('clickEvent', 'actionScript->quitFullScreen');
+ };
+ this.addListenerInside('click', escFullClick, this.CB['escFull']);
+ var adSkipClick = function(event) {
+ if (thisTemp.CB['adSkip'].innerHTML == thisTemp.language['skipAd']) {
+ thisTemp.runFunction(thisTemp.config['adSkipClick']);
+ }
+ };
+ this.addListenerInside('click', adSkipClick, this.CB['adSkip']);
+ var adMuteClick = function(event) {
+ thisTemp.adMuteFunction();
+ };
+ this.addListenerInside('click', adMuteClick, this.CB['adMute']);
+ var adEscMuteClick = function(event) {
+ thisTemp.adEscMuteFunction();
+ };
+ this.addListenerInside('click', adEscMuteClick, this.CB['adEscMute']);
+ var adPauseCloseClick = function(event) {
+ thisTemp.adPauseCloseFunction();
+ };
+ this.addListenerInside('click', adPauseCloseClick, this.CB['adPauseClose']);
+ //定义各个按钮的鼠标经过/离开事件
+ var promptHide = function(event) {
+ thisTemp.promptShow(false);
+ };
+ var playOver = function(event) {
+ thisTemp.promptShow(thisTemp.CB['play']);
+ };
+ this.addListenerInside('mouseover', playOver, this.CB['play']);
+ this.addListenerInside('mouseout', promptHide, this.CB['play']);
+ var pauseOver = function(event) {
+ thisTemp.promptShow(thisTemp.CB['pause']);
+ };
+ this.addListenerInside('mouseover', pauseOver, this.CB['pause']);
+ this.addListenerInside('mouseout', promptHide, this.CB['pause']);
+ var frontOver = function(event) {
+ thisTemp.promptShow(thisTemp.CB['front']);
+ };
+ this.addListenerInside('mouseover', frontOver, this.CB['front']);
+ this.addListenerInside('mouseout', promptHide, this.CB['front']);
+ var nextOver = function(event) {
+ thisTemp.promptShow(thisTemp.CB['next']);
+ };
+ this.addListenerInside('mouseover', nextOver, this.CB['next']);
+ this.addListenerInside('mouseout', promptHide, this.CB['next']);
+ var muteOver = function(event) {
+ thisTemp.promptShow(thisTemp.CB['mute']);
+ };
+ this.addListenerInside('mouseover', muteOver, this.CB['mute']);
+ this.addListenerInside('mouseout', promptHide, this.CB['mute']);
+ var escMuteOver = function(event) {
+ thisTemp.promptShow(thisTemp.CB['escMute']);
+ };
+ this.addListenerInside('mouseover', escMuteOver, this.CB['escMute']);
+ this.addListenerInside('mouseout', promptHide, this.CB['escMute']);
+ var fullOver = function(event) {
+ thisTemp.promptShow(thisTemp.CB['full']);
+ };
+ this.addListenerInside('mouseover', fullOver, this.CB['full']);
+ this.addListenerInside('mouseout', promptHide, this.CB['full']);
+ var escFullOver = function(event) {
+ thisTemp.promptShow(thisTemp.CB['escFull']);
+ };
+ this.addListenerInside('mouseover', escFullOver, this.CB['escFull']);
+ this.addListenerInside('mouseout', promptHide, this.CB['escFull']);
+ var definitionOver = function(event) {
+ thisTemp.promptShow(thisTemp.CB['definition']);
+ };
+ this.addListenerInside('mouseover', definitionOver, this.CB['definition']);
+ this.addListenerInside('mouseout', promptHide, this.CB['definition']);
+ var playbackrateOver = function(event) {
+ thisTemp.promptShow(thisTemp.CB['playbackrate']);
+ };
+ this.addListenerInside('mouseover', playbackrateOver, this.CB['playbackrate']);
+ this.addListenerInside('mouseout', promptHide, this.CB['playbackrate']);
+ //定义音量和进度按钮的滑块事件
+ var volumePrompt = function(vol) {
+ var volumeBOXY = thisTemp.getCoor(thisTemp.CB['volumeBO']);
+ var promptObj = {
+ title: thisTemp.language['volume'] + vol + '%',
+ x: volumeBOXY['x'] + thisTemp.CB['volumeBO'].offsetWidth * 0.5,
+ y: volumeBOXY['y']
+ };
+ thisTemp.promptShow(false, promptObj);
+ };
+ var volumeObj = {
+ slider: this.CB['volumeBO'],
+ follow: this.CB['volumeUp'],
+ refer: this.CB['volumeBg'],
+ grossValue: 'volume',
+ pd: true,
+ startFun: function(vol) {},
+ monitorFun: function(vol) {
+ thisTemp.changeVolume(vol * 0.01, false, false);
+ volumePrompt(vol);
+ },
+ endFun: function(vol) {},
+ overFun: function(vol) {
+ volumePrompt(vol);
+ }
+ };
+ this.slider(volumeObj);
+ var volumeClickObj = {
+ refer: this.CB['volumeBg'],
+ grossValue: 'volume',
+ fun: function(vol) {
+ thisTemp.changeVolume(vol * 0.01, true, true);
+ }
+ };
+ this.progressClick(volumeClickObj);
+ this.timeButtonMouseDown(); //用单击的函数来判断是否需要建立控制栏监听
+ //鼠标经过/离开音量调节框时的
+ var volumeBgMove = function(event) {
+ var volumeBgXY = thisTemp.getCoor(thisTemp.CB['volumeBg']);
+ var eventX = thisTemp.client(event)['x'];
+ var eventVolume = parseInt((eventX - volumeBgXY['x']) * 100 / thisTemp.CB['volumeBg'].offsetWidth);
+ var buttonPromptObj = {
+ title: thisTemp.language['volume'] + eventVolume + '%',
+ x: eventX,
+ y: volumeBgXY['y']
+ };
+ thisTemp.promptShow(false, buttonPromptObj);
+ };
+ this.addListenerInside('mousemove', volumeBgMove, this.CB['volumeBg']);
+ this.addListenerInside('mouseout', promptHide, this.CB['volumeBg']);
+ this.addListenerInside('mouseout', promptHide, this.CB['volumeBO']);
+ //注册清晰度相关事件
+ this.addDefListener();
+ //注册倍速相关事件
+ this.addPlaybackrate();
+ },
+ /*
+ 内部函数
+ 注册单击视频动作
+ */
+ videoClick: function() {
+ var thisTemp = this;
+ var clearTimerClick = function() {
+ if (thisTemp.timerClick != null) {
+ if (thisTemp.timerClick.runing) {
+ thisTemp.timerClick.stop();
+ }
+ thisTemp.timerClick = null;
+ }
+ };
+ var timerClickFun = function() {
+ clearTimerClick();
+ thisTemp.isClick = false;
+ if (thisTemp.adPlayerPlay) {
+ var ad = thisTemp.getNowAdvertisements();
+ try {
+ if (ad['link'] != '') {
+ window.open(ad['link']);
+ }
+ thisTemp.ajaxSuccessNull(ad['clickMonitor']);
+ } catch(event) {}
+ } else {
+ if (thisTemp.ckplayerConfig['config']['click']) {
+ thisTemp.playOrPause();
+ }
+ }
+
+ };
+ clearTimerClick();
+ if (this.isClick) {
+ this.isClick = false;
+ if (thisTemp.ckplayerConfig['config']['doubleClick']) {
+ if (!this.full) {
+ thisTemp.fullScreen();
+ } else {
+ thisTemp.quitFullScreen();
+ }
+ }
+
+ } else {
+ this.isClick = true;
+ this.timerClick = new this.timer(300, timerClickFun, 1)
+ //this.timerClick.start();
+ }
+
+ },
+ /*
+ 内部函数
+ 注册鼠标经过进度滑块的事件
+ */
+ timeButtonMouseDown: function() {
+ var thisTemp = this;
+ var timePrompt = function(time) {
+ if (isNaN(time)) {
+ time = 0;
+ }
+ var timeButtonXY = thisTemp.getCoor(thisTemp.CB['timeButton']);
+ var promptObj = {
+ title: thisTemp.formatTime(time),
+ x: timeButtonXY['x'] - thisTemp.pdCoor['x'] + thisTemp.CB['timeButton'].offsetWidth * 0.5,
+ y: timeButtonXY['y'] - thisTemp.pdCoor['y']
+ };
+ thisTemp.promptShow(false, promptObj);
+ };
+ var timeObj = {
+ slider: this.CB['timeButton'],
+ follow: this.CB['timeProgress'],
+ refer: this.CB['timeBoBg'],
+ grossValue: 'time',
+ pd: false,
+ startFun: function(time) {
+ thisTemp.isTimeButtonMove = false;
+ },
+ monitorFun: function(time) {},
+ endFun: function(time) {
+ if (thisTemp.V) {
+ if (thisTemp.V.duration > 0) {
+ thisTemp.needSeek = 0;
+ thisTemp.videoSeek(parseInt(time));
+ }
+ }
+ },
+ overFun: function(time) {
+ timePrompt(time);
+ }
+ };
+ var timeClickObj = {
+ refer: this.CB['timeBoBg'],
+ grossValue: 'time',
+ fun: function(time) {
+ if (thisTemp.V) {
+ if (thisTemp.V.duration > 0) {
+ thisTemp.needSeek = 0;
+ thisTemp.videoSeek(parseInt(time));
+ }
+ }
+ }
+ };
+ var timeBoBgmousemove = function(event) {
+ var timeBoBgXY = thisTemp.getCoor(thisTemp.CB['timeBoBg']);
+ var eventX = thisTemp.client(event)['x'];
+ var eventTime = parseInt((eventX - timeBoBgXY['x']) * thisTemp.V.duration / thisTemp.CB['timeBoBg'].offsetWidth);
+ var buttonPromptObj = {
+ title: thisTemp.formatTime(eventTime),
+ x: eventX,
+ y: timeBoBgXY['y']
+ };
+ thisTemp.promptShow(false, buttonPromptObj);
+ var def = false;
+ if (!thisTemp.isUndefined(thisTemp.CB['definitionP'])) {
+ if (thisTemp.css(thisTemp.CB['definitionP'], 'display') != 'block') {
+ def = true;
+ }
+ }
+ if (thisTemp.vars['preview'] != null && def) {
+ buttonPromptObj['time'] = eventTime;
+ thisTemp.preview(buttonPromptObj);
+ }
+ };
+ var promptHide = function(event) {
+ thisTemp.promptShow(false);
+ if (thisTemp.previewDiv != null) {
+ thisTemp.css([thisTemp.previewDiv, thisTemp.previewTop], 'display', 'none');
+ }
+ };
+ if (!this.vars['live']) { //如果不是直播
+ this.isTimeButtonDown = true;
+ this.addListenerInside('mousemove', timeBoBgmousemove, this.CB['timeBoBg']);
+ this.addListenerInside('mouseout', promptHide, this.CB['timeBoBg']);
+ } else {
+ this.isTimeButtonDown = false;
+ timeObj['removeListenerInside'] = true;
+ timeClickObj['removeListenerInside'] = true;
+ }
+ this.slider(timeObj);
+ this.progressClick(timeClickObj);
+
+ },
+ /*
+ 内部函数
+ 注册调节框上单击事件,包含音量调节框和播放时度调节框
+ */
+ progressClick: function(obj) {
+ /*
+ refer:参考对象
+ fun:返回函数
+ refer:参考元素,即背景
+ grossValue:调用的参考值类型
+ pd:
+ */
+ //建立参考元素的mouseClick事件,用来做为鼠标在其上按下时触发的状态
+ var thisTemp = this;
+ var referMouseClick = function(event) {
+ var referX = thisTemp.client(event)['x'] - thisTemp.getCoor(obj['refer'])['x'];
+ var rWidth = obj['refer'].offsetWidth;
+ var grossValue = 0;
+ if (obj['grossValue'] == 'volume') {
+ grossValue = 100;
+ } else {
+ if (thisTemp.V) {
+ grossValue = thisTemp.V.duration;
+ }
+ }
+ var nowZ = parseInt(referX * grossValue / rWidth);
+ if (obj['fun']) {
+ if (obj['grossValue'] === 'time') {
+ var sliderXY = thisTemp.getCoor(thisTemp.CB['timeButton']);
+ sliderLeft = sliderXY['x'];
+ if (!thisTemp.checkSlideLeft(referX, sliderLeft, rWidth)) {
+ return;
+ }
+ var bimeButtonWB = thisTemp.CB['timeButton'].offsetWidth * 0.5;
+ thisTemp.css(thisTemp.CB['timeButton'], 'left', (referX - bimeButtonWB) + 'px');
+ thisTemp.css(thisTemp.CB['timeProgress'], 'width', (referX) + 'px');
+ }
+ obj['fun'](nowZ);
+ }
+ };
+ if (this.isUndefined(obj['removeListenerInside'])) {
+ this.addListenerInside('click', referMouseClick, obj['refer']);
+ } else {
+ this.removeListenerInside('click', referMouseClick, obj['refer']);
+ }
+
+ },
+
+ /*
+ 内部函数
+ 共用的注册滑块事件
+ */
+ slider: function(obj) {
+ /*
+ obj={
+ slider:滑块元素
+ follow:跟随滑块的元素
+ refer:参考元素,即背景
+ grossValue:调用的参考值类型
+ startFun:开始调用的元素
+ monitorFun:监听函数
+ endFun:结束调用的函数
+ overFun:鼠标放上去后调用的函数
+ pd:是否需要修正
+ }
+ */
+ var thisTemp = this;
+ var clientX = 0,
+ criterionWidth = 0,
+ sliderLeft = 0,
+ referLeft = 0;
+ var value = 0;
+ var calculation = function() { //根据滑块的left计算百分比
+ var sLeft = parseInt(thisTemp.css(obj['slider'], 'left'));
+ var rWidth = obj['refer'].offsetWidth - obj['slider'].offsetWidth;
+ var grossValue = 0;
+ if (thisTemp.isUndefined(sLeft) || isNaN(sLeft)) {
+ sLeft = 0;
+ }
+ if (obj['grossValue'] == 'volume') {
+ grossValue = 100;
+ } else {
+ if (thisTemp.V) {
+ grossValue = thisTemp.V.duration;
+ }
+ }
+ return parseInt(sLeft * grossValue / rWidth);
+ };
+ var mDown = function(event) {
+ thisTemp.addListenerInside('mousemove', mMove, document);
+ thisTemp.addListenerInside('mouseup', mUp, document);
+ var referXY = thisTemp.getCoor(obj['refer']);
+ var sliderXY = thisTemp.getCoor(obj['slider']);
+ clientX = thisTemp.client(event)['x'];
+ referLeft = referXY['x'];
+ sliderLeft = sliderXY['x'];
+ criterionWidth = clientX - sliderLeft;
+ if (obj['startFun']) {
+ obj['startFun'](calculation());
+ }
+ };
+ var mMove = function(event) {
+ clientX = thisTemp.client(event)['x'];
+ var newX = clientX - criterionWidth - referLeft;
+ if (newX < 0) {
+ newX = 0;
+ }
+ if (newX > obj['refer'].offsetWidth - obj['slider'].offsetWidth) {
+ newX = obj['refer'].offsetWidth - obj['slider'].offsetWidth;
+ }
+ if (obj['slider'] === thisTemp.CB['timeButton']) {
+ if (!thisTemp.checkSlideLeft(newX, sliderLeft, obj['refer'].offsetWidth)) {
+ return;
+ }
+ }
+ thisTemp.css(obj['slider'], 'left', newX + 'px');
+ thisTemp.css(obj['follow'], 'width', (newX + obj['slider'].offsetWidth * 0.5) + 'px');
+ var nowZ = calculation();
+ if (obj['monitorFun']) {
+ obj['monitorFun'](nowZ);
+ }
+ };
+ var mUp = function(event) {
+ thisTemp.removeListenerInside('mousemove', mMove, document);
+ thisTemp.removeListenerInside('mouseup', mUp, document);
+ if (obj['endFun']) {
+ obj['endFun'](calculation());
+ }
+ };
+ var mOver = function(event) {
+ if (obj['overFun']) {
+ obj['overFun'](calculation());
+ }
+
+ };
+ if (this.isUndefined(obj['removeListenerInside'])) {
+ this.addListenerInside('mousedown', mDown, obj['slider']);
+ this.addListenerInside('mouseover', mOver, obj['slider']);
+ } else {
+ this.removeListenerInside('mousedown', mDown, obj['slider']);
+ this.removeListenerInside('mouseover', mOver, obj['slider']);
+ }
+ },
+ /*
+ 内部函数
+ 判断是否可以拖动进度按钮或点击进度栏
+ */
+ checkSlideLeft: function(newX, sliderLeft, refer) {
+ var timeSA = this.ckplayerConfig['config']['timeScheduleAdjust'];
+ switch (timeSA) {
+ case 0:
+ return false;
+ break;
+ case 2:
+ if (newX < sliderLeft) {
+ return false;
+ }
+ break;
+ case 3:
+ if (newX > sliderLeft) {
+ return false;
+ }
+ break;
+ case 4:
+ if (!this.timeSliderLeftTemp) {
+ this.timeSliderLeftTemp = sliderLeft / refer;
+ }
+ if (newX < this.timeSliderLeftTemp * refer) {
+ return false;
+ }
+ break;
+ case 5:
+ if (!this.timeSliderLeftTemp) {
+ this.timeSliderLeftTemp = sliderLeft / refer;
+ } else {
+ var timeSliderMax = sliderLeft / refer;
+ if (timeSliderMax > this.timeSliderLeftTemp) {
+ this.timeSliderLeftTemp = timeSliderMax;
+ }
+ }
+ if (newX > this.timeSliderLeftTemp * refer) {
+ return false;
+ }
+ break;
+ default:
+ return true;
+ break;
+ }
+ return true;
+ },
+ /*
+ 内部函数
+ 显示loading
+ */
+ loadingStart: function(rot) {
+ var thisTemp = this;
+ if (this.isUndefined(rot)) {
+ rot = true;
+ }
+ if (this.showFace) {
+ this.css(thisTemp.CB['loading'], 'display', 'none');
+ }
+ if (this.timerLoading != null) {
+ if (this.timerLoading.runing) {
+ this.timerLoading.stop();
+ }
+ this.timerLoading = null;
+ }
+ var buffer = 0;
+ var loadingFun = function() {
+ var nowRotate = '0';
+ try {
+ nowRotate = thisTemp.css(thisTemp.CB['loadingCanvas'], 'transform') || thisTemp.css(thisTemp.CB['loadingCanvas'], '-ms-transform') || thisTemp.css(thisTemp.CB['loadingCanvas'], '-moz-transform') || thisTemp.css(thisTemp.CB['loadingCanvas'], '-webkit-transform') || thisTemp.css(thisTemp.CB['loadingCanvas'], '-o-transform') || '0';
+ } catch(event) {}
+ nowRotate = parseInt(nowRotate.replace('rotate(', '').replace('deg);', ''));
+ nowRotate += 4;
+ if (nowRotate > 360) {
+ nowRotate = 0;
+ }
+ if (thisTemp.showFace) {
+ thisTemp.css(thisTemp.CB['loadingCanvas'], {
+ transform: 'rotate(' + nowRotate + 'deg)',
+ msTransform: 'rotate(' + nowRotate + 'deg)',
+ mozTransform: 'rotate(' + nowRotate + 'deg)',
+ webkitTransform: 'rotate(' + nowRotate + 'deg)',
+ oTransform: 'rotate(' + nowRotate + 'deg)'
+ });
+ }
+ buffer++;
+ if (buffer >= 99) {
+ buffer = 99;
+ }
+ thisTemp.sendJS('buffer', buffer);
+ };
+ if (rot) {
+ this.timerLoading = new this.timer(10, loadingFun);
+ //this.timerLoading.start();
+ if (this.showFace) {
+ this.css(thisTemp.CB['loading'], 'display', 'block');
+ }
+ } else {
+ thisTemp.sendJS('buffer', 100);
+ }
+ },
+ /*
+ 内部函数
+ 判断是否需要显示上一集和下一集
+ */
+ showFrontNext: function() {
+ if (!this.showFace) {
+ return;
+ }
+ if (this.vars['front']) {
+ this.css([this.CB['front'], this.CB['frontLine']], 'display', 'block');
+ } else {
+ this.css([this.CB['front'], this.CB['frontLine']], 'display', 'none');
+ }
+ if (this.vars['next']) {
+ this.css([this.CB['next'], this.CB['nextLine']], 'display', 'block');
+ } else {
+ this.css([this.CB['next'], this.CB['nextLine']], 'display', 'none');
+ }
+ },
+ /*
+ 内部函数
+ 显示提示语
+ */
+ promptShow: function(ele, data) {
+ if (!this.showFace) {
+ return;
+ }
+ var obj = {};
+ if (ele || data) {
+ if (!this.isUndefined(data)) {
+ obj = data;
+ } else {
+ var offsetCoor = this.getCoor(ele);
+ obj = {
+ title: this.getDataset(ele, 'title'),
+ x: offsetCoor['x'] + ele.offsetWidth * 0.5,
+ y: offsetCoor['y']
+ };
+ }
+ this.CB['prompt'].innerHTML = obj['title'];
+ this.css(this.CB['prompt'], 'display', 'block');
+ var promoptWidth = this.getStringLen(obj['title']) * 10;
+ this.css(this.CB['promptBg'], 'width', promoptWidth + 'px');
+ this.css(this.CB['prompt'], 'width', promoptWidth + 'px');
+ promoptWidth += 10;
+ var x = obj['x'] - (promoptWidth * 0.5);
+ var y = this.PD.offsetHeight - obj['y'] + 8;
+ if (x < 0) {
+ x = 0;
+ }
+ if (x > this.PD.offsetWidth - promoptWidth) {
+ x = this.PD.offsetWidth - promoptWidth;
+ }
+ this.css([this.CB['promptBg'], this.CB['prompt']], {
+ display: 'block',
+ left: x + 'px',
+ bottom: y + 'px'
+ });
+ } else {
+ this.css([this.CB['promptBg'], this.CB['prompt']], {
+ display: 'none'
+ });
+ }
+ },
+ /*
+ 内部函数
+ 监听错误
+ */
+ timerErrorFun: function() {
+ var thisTemp = this;
+ this.errorSend = false;
+ var clearIntervalError = function(event) {
+ if (thisTemp.timerError != null) {
+ if (thisTemp.timerError.runing) {
+ thisTemp.timerError.stop();
+ }
+ thisTemp.timerError = null;
+ }
+ };
+ var errorFun = function(event) {
+ clearIntervalError();
+ thisTemp.error = true;
+ //提取错误播放地址
+ thisTemp.errorUrl = thisTemp.getVideoUrl();
+ //提取错误播放地址结束
+ if (!thisTemp.errorSend) {
+ thisTemp.errorSend = true;
+ thisTemp.sendJS('error');
+ }
+ if (thisTemp.showFace) {
+ thisTemp.css(thisTemp.CB['errorText'], 'display', 'block');
+ thisTemp.css(thisTemp.CB['pauseCenter'], 'display', 'none');
+ thisTemp.css(thisTemp.CB['loading'], 'display', 'none');
+ }
+ thisTemp.V.removeAttribute('poster');
+ thisTemp.resetPlayer();
+ };
+ var errorListenerFun = function(event) {
+ setTimeout(function() {
+ if (isNaN(thisTemp.V.duration)) {
+ errorFun(event);
+ }
+ },
+ 500);
+
+ };
+ if (!this.errorAdd) {
+ this.errorAdd = true;
+ this.addListenerInside('error', errorListenerFun, this.V);
+ }
+ clearIntervalError();
+ var timerErrorFun = function() {
+ if (thisTemp.V && parseInt(thisTemp.V.networkState) == 3) {
+ errorFun();
+ }
+ };
+ this.timerError = new this.timer(this.config['errorTime'], timerErrorFun);
+ //this.timerError.start();
+ },
+ /*
+ 内部函数
+ 构建判断全屏还是非全屏的判断
+ */
+ judgeFullScreen: function() {
+ var thisTemp = this;
+ if (this.timerFull != null) {
+ if (this.timerFull.runing) {
+ this.timerFull.stop();
+ }
+ this.timerFull = null;
+ }
+ var fullFun = function() {
+ thisTemp.isFullScreen();
+ };
+ this.timerFull = new this.timer(20, fullFun);
+ },
+ /*
+ 内部函数
+ 判断是否是全屏
+ */
+ isFullScreen: function() {
+ if (!this.showFace) {
+ return;
+ }
+ var fullState = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen || document.msFullscreenElement;
+ if (fullState && !this.full) {
+ this.full = true;
+ this.sendJS('full', true);
+ this.elementCoordinate();
+ this.css(this.CB['full'], 'display', 'none');
+ this.css(this.CB['escFull'], 'display', 'block');
+ if (this.vars['live'] == 0) {
+ this.timeUpdateHandler();
+ }
+ this.PD.appendChild(this.CB['menu']);
+ }
+ if (!fullState && this.full) {
+ this.full = false;
+ this.sendJS('full', false);
+ this.elementCoordinate();
+ this.css(this.CB['full'], 'display', 'block');
+ this.css(this.CB['escFull'], 'display', 'none');
+ if (this.timerFull != null) {
+ if (this.timerFull.runing) {
+ this.timerFull.stop();
+ }
+ this.timerFull = null;
+ }
+ if (this.vars['live'] == 0) {
+ this.timeUpdateHandler();
+ }
+ this.body.appendChild(this.CB['menu']);
+ }
+ },
+ /*
+ 内部函数
+ 构建右键内容及注册相关动作事件
+ */
+ newMenu: function() {
+ var thisTemp = this;
+ var i = 0;
+ this.css(this.CB['menu'], {
+ backgroundColor: '#FFFFFF',
+ padding: '5px',
+ position: 'absolute',
+ left: '10px',
+ top: '20px',
+ display: 'none',
+ zIndex: '999',
+ color: '#A1A9BE',
+ boxShadow: '2px 2px 3px #AAAAAA'
+ });
+ var mArr = this.contextMenu;
+ var cMenu = this.ckplayerConfig['menu'];
+ if (cMenu['name']) {
+ if (cMenu['link']) {
+ mArr[0] = [cMenu['name'], 'link', cMenu['link']];
+ } else {
+ mArr[0] = [cMenu['name'], 'default'];
+ }
+ }
+ if (cMenu['version']) {
+ mArr[1] = [cMenu['version'], 'default', 'line'];
+ }
+ if (cMenu['more']) {
+ if (typeof(cMenu['more']) == 'object') {
+ if (cMenu['more'].length > 0) {
+ var moreArr = cMenu['more'];
+ for (i = 0; i < moreArr.length; i++) {
+ var mTemp = moreArr[i];
+ var arrTemp = [];
+ if (mTemp['name']) {
+ arrTemp.push(mTemp['name']);
+ }
+ if (mTemp['clickEvent'] && mTemp['clickEvent'] != 'none') {
+ var eveObj = this.clickEvent(mTemp['clickEvent']);
+ arrTemp.push(eveObj['type']);
+ if (eveObj['fun']) {
+ arrTemp.push(eveObj['fun']);
+ }
+ if (eveObj['link']) {
+ arrTemp.push(eveObj['link']);
+ }
+ if (eveObj['target']) {
+ arrTemp.push(' target="' + eveObj['target'] + '"');
+ }
+ }
+ if (mTemp['separatorBefore']) {
+ arrTemp.push('line');
+ }
+ mArr.push(arrTemp);
+ }
+ }
+ }
+ }
+ var html = '';
+ for (i = 0; i < mArr.length; i++) {
+ var me = mArr[i];
+ switch (me[1]) {
+ case 'default':
+ html += '' + me[0] + '
';
+ break;
+ case 'link':
+ if (me[3]) {
+ me[3] = 'target="' + me[3] + '"';
+ }
+ html += '' + me[0] + '
';
+ break;
+ case 'javaScript':
+ html += '' + me[0] + '
';
+ break;
+ case 'actionScript':
+ html += '' + me[0] + '
';
+ break;
+ default:
+ break;
+ }
+ }
+ this.CB['menu'].innerHTML = html;
+ var pArr = this.CB['menu'].childNodes;
+ for (i = 0; i < pArr.length; i++) {
+ this.css(pArr[i], {
+ height: '30px',
+ lineHeight: '30px',
+ margin: '0px',
+ fontFamily: this.fontFamily,
+ fontSize: '12px',
+ paddingLeft: '10px',
+ paddingRight: '30px'
+ });
+ if (mArr[i][mArr[i].length - 1] == 'line') {
+ this.css(pArr[i], 'borderBottom', '1px solid #e9e9e9');
+ }
+ var aArr = pArr[i].childNodes;
+ for (var n = 0; n < aArr.length; n++) {
+ if (aArr[n].localName == 'a') {
+ this.css(aArr[n], {
+ color: '#000000',
+ textDecoration: 'none'
+ });
+ }
+ }
+ }
+ this.PD.oncontextmenu = function(event) {
+ var eve = event || window.event;
+ var client = thisTemp.client(event);
+ if (eve.button == 2) {
+ eve.returnvalue = false;
+ var x = client['x'] + thisTemp.pdCoor['x'] - 2;
+ var y = client['y'] + thisTemp.pdCoor['y'] - 2;
+ thisTemp.css(thisTemp.CB['menu'], {
+ display: 'block',
+ left: x + 'px',
+ top: y + 'px'
+ });
+ return false;
+ }
+ return true;
+ };
+ var setTimeOutPClose = function() {
+ if (setTimeOutP) {
+ window.clearTimeout(setTimeOutP);
+ setTimeOutP = null;
+ }
+ };
+ var setTimeOutP = null;
+ var mouseOut = function(event) {
+ setTimeOutPClose();
+ setTimeOutP = setTimeout(function(event) {
+ thisTemp.css(thisTemp.CB['menu'], 'display', 'none');
+ },
+ 500);
+ };
+ this.addListenerInside('mouseout', mouseOut, thisTemp.CB['menu']);
+ var mouseOver = function(event) {
+ setTimeOutPClose();
+ };
+ this.addListenerInside('mouseover', mouseOver, thisTemp.CB['menu']);
+
+ },
+ /*
+ 内部函数
+ 构建控制栏隐藏事件
+ */
+ controlBarHide: function(hide) {
+ var thisTemp = this;
+ var client = {
+ x: 0,
+ y: 0
+ },
+ oldClient = {
+ x: 0,
+ y: 0
+ };
+ var cShow = true,
+ force = false;
+ var oldCoor = [0, 0];
+ var controlBarShow = function(show) {
+ if (show && !cShow && thisTemp.controlBarIsShow) {
+ cShow = true;
+ thisTemp.sendJS('controlBar', true);
+ thisTemp.css(thisTemp.CB['controlBarBg'], 'display', 'block');
+ thisTemp.css(thisTemp.CB['controlBar'], 'display', 'block');
+ thisTemp.css(thisTemp.CB['timeProgressBg'], 'display', 'block');
+ thisTemp.css(thisTemp.CB['timeBoBg'], 'display', 'block');
+ thisTemp.changeVolume(thisTemp.volume);
+ thisTemp.changeLoad();
+ if (!thisTemp.timerBuffer) {
+ thisTemp.bufferEdHandler();
+ }
+ } else {
+ if (cShow) {
+ cShow = false;
+ var paused = thisTemp.getMetaDate()['paused'];
+ if (force) {
+ paused = false;
+ }
+ if (!paused) {
+ thisTemp.sendJS('controlBar', false);
+ thisTemp.css(thisTemp.CB['controlBarBg'], 'display', 'none');
+ thisTemp.css(thisTemp.CB['controlBar'], 'display', 'none');
+ thisTemp.css(thisTemp.CB['timeProgressBg'], 'display', 'none');
+ thisTemp.css(thisTemp.CB['timeBoBg'], 'display', 'none');
+ thisTemp.promptShow(false);
+
+ }
+ }
+ }
+ };
+ var cbarFun = function(event) {
+ if (client['x'] == oldClient['x'] && client['y'] == oldClient['y']) {
+ var cdH = parseInt(thisTemp.CD.offsetHeight);
+ if ((client['y'] < cdH - 50 || client['y'] > cdH - 2) && cShow && !thisTemp.getMetaDate()['paused']) {
+ controlBarShow(false);
+ }
+ } else {
+ if (!cShow) {
+ controlBarShow(true);
+ }
+ }
+ oldClient = {
+ x: client['x'],
+ y: client['y']
+ }
+ };
+ this.timerCBar = new this.timer(2000, cbarFun);
+ var cdMove = function(event) {
+ var getClient = thisTemp.client(event);
+ client['x'] = getClient['x'];
+ client['y'] = getClient['y'];
+ if (!cShow) {
+ controlBarShow(true);
+ }
+ };
+ this.addListenerInside('mousemove', cdMove, thisTemp.CD);
+ this.addListenerInside('ended', cdMove);
+ this.addListenerInside('resize', cdMove, window);
+ if (hide === true) {
+ cShow = true;
+ force = true;
+ controlBarShow(false);
+ }
+ if (hide === false) {
+ cShow = false;
+ force = true;
+ controlBarShow(true);
+ }
+ },
+
+ /*
+ 内部函数
+ 注册键盘按键事件
+ */
+ keypress: function() {
+ var thisTemp = this;
+ var keyDown = function(eve) {
+ var keycode = eve.keyCode || eve.which;
+ if (this.adPlayerPlay) {
+ return;
+ }
+ switch (keycode) {
+ case 32:
+ thisTemp.playOrPause();
+ break;
+ case 37:
+ thisTemp.fastBack();
+ break;
+ case 39:
+ thisTemp.fastNext();
+ break;
+ case 38:
+ now = thisTemp.volume + thisTemp.ckplayerConfig['config']['volumeJump'];
+ thisTemp.changeVolume(now > 1 ? 1 : now);
+ break;
+ case 40:
+ now = thisTemp.volume - thisTemp.ckplayerConfig['config']['volumeJump'];
+ thisTemp.changeVolume(now < 0 ? 0 : now);
+ break;
+ default:
+ break;
+ }
+ };
+ this.addListenerInside('keydown', keyDown, window || document);
+ },
+ /*
+ 内部函数
+ 注册倍速相关
+ */
+ playbackRate: function() {
+ if (!this.showFace) {
+ return;
+ }
+ var thisTemp = this;
+ var vArr = this.playbackRateArr;
+ var html = '';
+ var nowD = ''; //当前的清晰度
+ var i = 0;
+ if (!nowD) {
+ nowD = vArr[this.playbackRateDefault][1];
+ }
+ if (vArr.length > 1) {
+ var zlen = 0;
+ for (i = 0; i < vArr.length; i++) {
+ html = '' + vArr[i][1] + '
' + html;
+ var dlen = this.getStringLen(vArr[i][1]);
+ if (dlen > zlen) {
+ zlen = dlen;
+ }
+ }
+ if (html) {
+ html += '' + nowD + '
';
+ }
+ this.CB['playbackrate'].innerHTML = nowD;
+ this.CB['playbackrateP'].innerHTML = html;
+ this.css([this.CB['playbackrate'], this.CB['playbackrateLine']], 'display', 'block');
+ var pArr = this.CB['playbackrateP'].childNodes;
+ for (var i = 0; i < pArr.length; i++) {
+ var fontColor = '#FFFFFF';
+ if (pArr[i].innerHTML == nowD) {
+ fontColor = '#0782F5';
+ }
+ this.css(pArr[i], {
+ color: fontColor,
+ margin: '0px',
+ padding: '0px',
+ fontSize: '14px'
+ });
+ if (i < pArr.length - 1) {
+ this.css(pArr[i], 'borderBottom', '1px solid #282828')
+ }
+ var defClick = function(event) {
+ if (nowD != this.innerHTML) {
+ thisTemp.css(thisTemp.CB['playbackrateP'], 'display', 'none');
+ thisTemp.newPlaybackrate(this.innerHTML);
+ thisTemp.sendJS('clickEvent', 'actionScript->newPlaybackrate');
+ }
+ };
+ this.addListenerInside('click', defClick, pArr[i]);
+
+ }
+ var pW = (zlen * 10) + 20;
+ this.css(this.CB['playbackrateP'], {
+ width: pW + 'px'
+ });
+ this.css(this.CB['playbackrate'], {
+ width: pW + 'px'
+ });
+ this.buttonWidth['playbackrate'] = this.CB['playbackrate'].offsetWidth;
+ } else {
+ this.CB['playbackrate'].innerHTML = '';
+ this.CB['playbackrateP'].innerHTML = '';
+ this.css([this.CB['playbackrate'], this.CB['playbackrateLine']], 'display', 'none');
+ }
+ },
+ /*
+ 内部函数
+ 注册切换倍速播放相关事件
+ */
+ addPlaybackrate: function() {
+ var thisTemp = this;
+ var setTimeOutP = null;
+ var defClick = function(event) {
+ thisTemp.css(thisTemp.CB['playbackrateP'], {
+ left: thisTemp.getCoor(thisTemp.CB['playbackrate'])['x'] + 'px',
+ display: 'block'
+ });
+ };
+ this.addListenerInside('click', defClick, this.CB['playbackrate']);
+ var defMouseOut = function(event) {
+ if (setTimeOutP) {
+ window.clearTimeout(setTimeOutP);
+ setTimeOutP = null;
+ }
+ setTimeOutP = setTimeout(function(event) {
+ thisTemp.css(thisTemp.CB['playbackrateP'], 'display', 'none');
+ },
+ 500);
+ };
+ this.addListenerInside('mouseout', defMouseOut, thisTemp.CB['playbackrateP']);
+ var defMouseOver = function(event) {
+ if (setTimeOutP) {
+ window.clearTimeout(setTimeOutP);
+ setTimeOutP = null;
+ }
+ };
+ this.addListenerInside('mouseover', defMouseOver, thisTemp.CB['playbackrateP']);
+ },
+ /*
+ 内部函数
+ 切换倍速后发生的动作
+ */
+ newPlaybackrate: function(title) {
+ var vArr = this.playbackRateArr;
+ var nVArr = [];
+ var i = 0;
+ for (i = 0; i < vArr.length; i++) {
+ var v = vArr[i];
+ if (v[1] == title) {
+ this.playbackRateDefault = i;
+ this.V.playbackRate = v[0];
+ if (this.showFace) {
+ this.CB['playbackrate'].innerHTML = v[1];
+ this.playbackRate();
+ }
+ this.sendJS('playbackRate', v);
+ }
+ }
+ },
+
+ /*
+ 内部函数
+ 构建清晰度按钮及切换事件(Click事件)
+ */
+ definition: function() {
+ if (!this.showFace) {
+ return;
+ }
+ var thisTemp = this;
+ var vArr = this.VA;
+ var dArr = [];
+ var html = '';
+ var nowD = ''; //当前的清晰度
+ var i = 0;
+ for (i = 0; i < vArr.length; i++) {
+ var d = vArr[i][2];
+ if (dArr.indexOf(d) == -1) {
+ dArr.push(d);
+ }
+ if (this.V) {
+ if (vArr[i][0] == this.V.currentSrc) {
+ nowD = d;
+ }
+ }
+ }
+ if (!nowD) {
+ nowD = dArr[0];
+ }
+ if (dArr.length > 1) {
+ var zlen = 0;
+ for (i = dArr.length - 1; i > -1; i--) {
+ html = '' + dArr[i] + '
' + html;
+ var dlen = this.getStringLen(dArr[i]);
+ if (dlen > zlen) {
+ zlen = dlen;
+ }
+ }
+ if (html) {
+ html += '' + nowD + '
';
+ }
+ this.CB['definition'].innerHTML = nowD;
+ this.CB['definitionP'].innerHTML = html;
+ this.css([this.CB['definition'], this.CB['definitionLine']], 'display', 'block');
+ var pArr = this.CB['definitionP'].childNodes;
+ for (var i = 0; i < pArr.length; i++) {
+ var fontColor = '#FFFFFF';
+ if (pArr[i].innerHTML == nowD) {
+ fontColor = '#0782F5';
+ }
+ this.css(pArr[i], {
+ color: fontColor,
+ margin: '0px',
+ padding: '0px',
+ fontSize: '14px'
+ });
+ if (i < pArr.length - 1) {
+ this.css(pArr[i], 'borderBottom', '1px solid #282828')
+ }
+ var defClick = function() {
+ if (nowD != this.innerHTML) {
+ thisTemp.css(thisTemp.CB['definitionP'], 'display', 'none');
+ thisTemp.newDefinition(this.innerHTML);
+ }
+ };
+ this.addListenerInside('click', defClick, pArr[i]);
+
+ }
+ var pW = (zlen * 10) + 20;
+ this.css(this.CB['definitionP'], {
+ width: pW + 'px'
+ });
+ this.css(this.CB['definition'], {
+ width: pW + 'px'
+ });
+ this.buttonWidth['definition'] = this.CB['definition'].offsetWidth;
+ } else {
+ this.CB['definition'].innerHTML = '';
+ this.CB['definitionP'].innerHTML = '';
+ this.css([this.CB['definition'], this.CB['definitionLine']], 'display', 'none');
+ }
+ },
+ /*
+ 内部函数
+ 注册清晰度相关事件
+ */
+ addDefListener: function() {
+ var thisTemp = this;
+ var setTimeOutP = null;
+ var defClick = function(event) {
+ thisTemp.css(thisTemp.CB['definitionP'], {
+ left: thisTemp.getCoor(thisTemp.CB['definition'])['x'] + 'px',
+ display: 'block'
+ });
+ };
+ this.addListenerInside('click', defClick, this.CB['definition']);
+ var defMouseOut = function(event) {
+ if (setTimeOutP) {
+ window.clearTimeout(setTimeOutP);
+ setTimeOutP = null;
+ }
+ setTimeOutP = setTimeout(function(event) {
+ thisTemp.css(thisTemp.CB['definitionP'], 'display', 'none');
+ },
+ 500);
+ };
+ this.addListenerInside('mouseout', defMouseOut, thisTemp.CB['definitionP']);
+ var defMouseOver = function(event) {
+ if (setTimeOutP) {
+ window.clearTimeout(setTimeOutP);
+ setTimeOutP = null;
+ }
+ };
+ this.addListenerInside('mouseover', defMouseOver, thisTemp.CB['definitionP']);
+ },
+ /*
+ 接口函数
+ 提供给外部api
+ */
+ changeDefinition: function(n) {
+ if (!this.loaded || n < 0) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.changeDefinition(n);
+ return;
+ }
+ if (this.VA.length > n) {
+ var arr = this.VA[n];
+ if (arr.length > 3) {
+ var title = arr[2];
+ if (title) {
+ this.newDefinition(title);
+ }
+ }
+ }
+ },
+ /*
+ 内部函数
+ 切换清晰度后发生的动作
+ */
+ newDefinition: function(title) {
+ var vArr = this.VA;
+ var nVArr = [];
+ var i = 0;
+ for (i = 0; i < vArr.length; i++) {
+ var v = vArr[i];
+ if (v[2] == title) {
+ nVArr.push(v);
+ this.sendJS('definitionChange', i + '');
+ }
+ }
+ if (nVArr.length < 1) {
+ return;
+ }
+ if (this.V != null && this.needSeek == 0) {
+ this.needSeek = this.V.currentTime;
+ }
+ if (this.getFileExt(nVArr[0][0]) != '.m3u8') {
+ this.isM3u8 = false;
+ }
+ if (!this.isM3u8) {
+ if (nVArr.length == 1) {
+ this.V.innerHTML = '';
+ this.V.src = nVArr[0][0];
+ this.V.currentSrc = nVArr[0][0];
+ } else {
+ var source = '';
+ nVArr = this.arrSort(nVArr);
+ for (i = 0; i < nVArr.length; i++) {
+ var type = '';
+ var va = nVArr[i];
+ if (va[1]) {
+ type = ' type="' + va[1] + '"';
+ }
+ source += '';
+ }
+ this.V.removeAttribute('src');
+ this.V.innerHTML = source;
+ this.V.currentSrc = nVArr[0][0];
+ }
+ } else {
+ this.embedHls(vArr[0][0], this.vars['autoplay']);
+ }
+ this.V.autoplay = 'autoplay';
+ this.V.load();
+ this.timerErrorFun();
+ },
+ /*
+ 内置函数
+ 播放hls
+ */
+ embedHls: function(url, autoplay) {
+ var thisTemp = this;
+ if (Hls.isSupported()) {
+ var hls = new Hls();
+ hls.loadSource(url);
+ hls.attachMedia(this.V);
+ hls.on(Hls.Events.MANIFEST_PARSED,
+ function() {
+ thisTemp.playerLoad();
+ if (autoplay) {
+ thisTemp.videoPlay();
+ }
+ });
+ }
+ },
+ /*
+ 内部函数
+ 构建提示点
+ */
+ prompt: function() {
+ if (!this.showFace) {
+ return;
+ }
+ var thisTemp = this;
+ var prompt = this.vars['promptSpot'];
+ if (prompt == null || this.promptArr.length > 0) {
+ return;
+ }
+ var showPrompt = function(event) {
+ if (thisTemp.promptElement == null) {
+ var random2 = 'prompte' + thisTemp.randomString(5);
+ var ele2 = document.createElement('div');
+ ele2.className = random2;
+ thisTemp.PD.appendChild(ele2);
+ thisTemp.promptElement = thisTemp.getByElement(random2);
+ thisTemp.css(thisTemp.promptElement, {
+ overflowX: 'hidden',
+ lineHeight: '22px',
+ fontSize: '14px',
+ color: '#FFFFFF',
+ position: 'absolute',
+ display: 'block',
+ zIndex: '90'
+ });
+ }
+ var pcon = thisTemp.getPromptTest();
+ var pW = pcon['pW'],
+ pT = pcon['pT'],
+ pL = parseInt(thisTemp.css(this, 'left')) - parseInt(pW * 0.5);
+ if (pcon['pL'] > 10) {
+ pL = pcon['pL'];
+ }
+ if (pL < 0) {
+ pL = 0;
+ }
+ thisTemp.css(thisTemp.promptElement, {
+ width: pW + 'px',
+ left: ( - pW - 10) + 'px',
+ display: 'block'
+ });
+ thisTemp.promptElement.innerHTML = thisTemp.getDataset(this, 'words');
+ thisTemp.css(thisTemp.promptElement, {
+ left: pL + 'px',
+ top: (pT - thisTemp.promptElement.offsetHeight - 10) + 'px'
+ });
+ };
+ var hidePrompt = function(event) {
+ if (thisTemp.promptElement != null) {
+ thisTemp.css(thisTemp.promptElement, {
+ display: 'none'
+ });
+ }
+ };
+ var i = 0;
+ for (i = 0; i < prompt.length; i++) {
+ var pr = prompt[i];
+ var words = pr['words'];
+ var time = pr['time'];
+ var random = 'prompt' + this.randomString(5);
+ var ele = document.createElement('div');
+ ele.className = random;
+ this.CB['timeBoBg'].appendChild(ele);
+ var div = this.getByElement(random);
+ div.setAttribute('data-time', time);
+ div.setAttribute('data-words', words);
+ this.css(div, {
+ width: '6px',
+ height: '6px',
+ backgroundColor: '#FFFFFF',
+ position: 'absolute',
+ top: '4px',
+ left: '-100px',
+ display: 'none',
+ zIndex: '1',
+ borderRadius: '6px'
+ });
+
+ this.addListenerInside('mouseover', showPrompt, div);
+ this.addListenerInside('mouseout', hidePrompt, div);
+ this.promptArr.push(div);
+ }
+ this.changePrompt();
+ },
+ /*
+ 内部函数
+ 计算提示文本的位置
+ */
+ getPromptTest: function() {
+ var pW = this.previewWidth,
+ pT = this.getCoor(this.CB['timeButton'])['y'],
+ pL = 0;
+ if (this.previewTop != null) {
+ pT -= parseInt(this.css(this.previewTop, 'height'));
+ pL = parseInt(this.css(this.previewTop, 'left'));
+ } else {
+ pT -= 35;
+ }
+ pL += 2;
+ if (pL < 0) {
+ pL = 0;
+ }
+ if (pL > this.PD.offsetWidth - pW) {
+ pL = this.PD.offsetWidth - pW;
+ }
+ return {
+ pW: pW,
+ pT: pT,
+ pL: pL
+ };
+ },
+ /*
+ 内部函数
+ 删除提示点
+ */
+ deletePrompt: function() {
+ var arr = this.promptArr;
+ if (arr.length > 0) {
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i]) {
+ this.deleteChild(arr[i]);
+ }
+ }
+ }
+ this.promptArr = [];
+ },
+ /*
+ 内部函数
+ 计算提示点坐标
+ */
+ changePrompt: function() {
+ if (this.promptArr.length == 0) {
+ return;
+ }
+ var arr = this.promptArr;
+ var duration = this.getMetaDate()['duration'];
+ var bw = this.CB['timeBoBg'].offsetWidth;
+ for (var i = 0; i < arr.length; i++) {
+ var time = parseInt(this.getDataset(arr[i], 'time'));
+ var left = parseInt(time * bw / duration) - parseInt(arr[i].offsetWidth * 0.5);
+ if (left < 0) {
+ left = 0;
+ }
+ if (left > bw - parseInt(arr[i].offsetWidth * 0.5)) {
+ left = bw - parseInt(arr[i].offsetWidth * 0.5);
+ }
+ this.css(arr[i], {
+ left: left + 'px',
+ display: 'block'
+ });
+ }
+ },
+ /*
+ 内部函数
+ 构建预览图片效果
+ */
+ preview: function(obj) {
+ var thisTemp = this;
+ var preview = {
+ file: null,
+ scale: 0
+ };
+ preview = this.standardization(preview, this.vars['preview']);
+ if (preview['file'] == null || preview['scale'] <= 0) {
+ return;
+ }
+ var srcArr = preview['file'];
+ if (this.previewStart == 0) { //如果还没有构建,则先进行构建
+ this.previewStart = 1;
+ if (srcArr.length > 0) {
+ var i = 0;
+ var imgW = 0,
+ imgH = 0;
+ var random = thisTemp.randomString(10);
+ var loadNum = 0;
+ var loadImg = function(i) {
+ srcArr[i] = thisTemp.getNewUrl(srcArr[i]);
+ var n = 0;
+ var img = new Image();
+ img.src = srcArr[i];
+ img.className = random + i;
+ img.onload = function(event) {
+ loadNum++;
+ if (thisTemp.previewDiv == null) { //如果没有建立DIV,则建
+ imgW = img.width;
+ imgH = img.height;
+ thisTemp.previewWidth = parseInt(imgW * 0.1);
+ var ele = document.createElement('div');
+ ele.className = random;
+ thisTemp.PD.appendChild(ele);
+ thisTemp.previewDiv = thisTemp.getByElement(random);
+ var eleTop = (obj['y'] - parseInt(imgH * 0.1) + 2);
+ thisTemp.css(thisTemp.previewDiv, {
+ width: srcArr.length * imgW * 10 + 'px',
+ height: parseInt(imgH * 0.1) + 'px',
+ backgroundColor: '#000000',
+ position: 'absolute',
+ left: '0px',
+ top: eleTop + 'px',
+ display: 'none',
+ zIndex: '80'
+ });
+ ele.setAttribute('data-x', '0');
+ ele.setAttribute('data-y', eleTop);
+ var ele2 = document.createElement('div');
+ ele2.className = random + 'd2';
+ thisTemp.PD.appendChild(ele2);
+ thisTemp.previewTop = thisTemp.getByElement(ele2.className);
+ thisTemp.css(thisTemp.previewTop, {
+ width: parseInt(imgW * 0.1) + 'px',
+ height: parseInt(imgH * 0.1) + 'px',
+ position: 'absolute',
+ border: '5px solid ' + thisTemp.css(thisTemp.CB['timeProgress'], 'backgroundColor'),
+ left: '0px',
+ top: (obj['y'] - parseInt(imgH * 0.1) + 2) + 'px',
+ display: 'none',
+ zIndex: '81'
+ });
+ var html = '';
+ for (n = 0; n < srcArr.length; n++) {
+ html += thisTemp.newCanvas(random + n, imgW * 10, parseInt(imgH * 0.1))
+ }
+ thisTemp.previewDiv.innerHTML = html;
+ }
+ thisTemp.previewDiv.appendChild(img);
+ var cimg = thisTemp.getByElement(img.className);
+ var canvas = thisTemp.getByElement(img.className + '-canvas');
+ var context = canvas.getContext('2d');
+ var sx = 0,
+ sy = 0,
+ x = 0,
+ h = parseInt(imgH * 0.1);
+ for (n = 0; n < 100; n++) {
+ x = parseInt(n * imgW * 0.1);
+ context.drawImage(cimg, sx, sy, parseInt(imgW * 0.1), h, x, 0, parseInt(imgW * 0.1), h);
+ sx += parseInt(imgW * 0.1);
+ if (sx >= imgW) {
+ sx = 0;
+ sy += h;
+ }
+ thisTemp.css(cimg, 'display', 'none');
+ }
+ if (loadNum == srcArr.length) {
+ thisTemp.previewStart = 2;
+ } else {
+ i++;
+ loadImg(i);
+ }
+ };
+ };
+ }
+ loadImg(i);
+ return;
+ }
+ if (this.previewStart == 2) {
+ var isTween = true;
+ var nowNum = parseInt(obj['time'] / this.vars['preview']['scale']);
+ var numTotal = parseInt(thisTemp.getMetaDate()['duration'] / this.vars['preview']['scale']);
+ if (thisTemp.css(thisTemp.previewDiv, 'display') == 'none') {
+ isTween = false;
+ }
+ thisTemp.css(thisTemp.previewDiv, 'display', 'block');
+ var imgWidth = thisTemp.previewDiv.offsetWidth * 0.01 / srcArr.length;
+ var left = (imgWidth * nowNum) - obj['x'] + parseInt(imgWidth * 0.5),
+ top = obj['y'] - thisTemp.previewDiv.offsetHeight;
+ thisTemp.css(thisTemp.previewDiv, 'top', top + 2 + 'px');
+ var topLeft = obj['x'] - parseInt(imgWidth * 0.5);
+ var timepieces = 0;
+ if (topLeft < 0) {
+ topLeft = 0;
+ timepieces = obj['x'] - topLeft - imgWidth * 0.5;
+ }
+ if (topLeft > thisTemp.PD.offsetWidth - imgWidth) {
+ topLeft = thisTemp.PD.offsetWidth - imgWidth;
+ timepieces = obj['x'] - topLeft - imgWidth * 0.5;
+ }
+ if (left < 0) {
+ left = 0;
+ }
+ if (left > numTotal * imgWidth - thisTemp.PD.offsetWidth) {
+ left = numTotal * imgWidth - thisTemp.PD.offsetWidth;
+ }
+ thisTemp.css(thisTemp.previewTop, {
+ left: topLeft + 'px',
+ top: top + 2 + 'px',
+ display: 'block'
+ });
+ if (thisTemp.previewTop.offsetHeight > thisTemp.previewDiv.offsetHeight) {
+ thisTemp.css(thisTemp.previewTop, {
+ height: thisTemp.previewDiv.offsetHeight - (thisTemp.previewTop.offsetHeight - thisTemp.previewDiv.offsetHeight) + 'px'
+ });
+ }
+ if (this.previewTween != null) {
+ this.animatePause(this.previewTween);
+ this.previewTween = null
+ }
+ var nowLeft = parseInt(thisTemp.css(thisTemp.previewDiv, 'left'));
+ var leftC = nowLeft + left;
+ if (nowLeft == -(left + timepieces)) {
+ return;
+ }
+ if (isTween) {
+ var obj = {
+ element: thisTemp.previewDiv,
+ start: null,
+ end: -(left + timepieces),
+ speed: 0.3
+ };
+ this.previewTween = this.animate(obj);
+ } else {
+ thisTemp.css(thisTemp.previewDiv, 'left', -(left + timepieces) + 'px')
+ }
+ }
+ },
+ /*
+ 内部函数
+ 删除预览图节点
+ */
+ deletePreview: function() {
+ if (this.previewDiv != null) {
+ this.deleteChild(this.previewDiv);
+ this.previewDiv = null;
+ this.previewStart = 0;
+ }
+ },
+ /*
+ 内部函数
+ 修改视频地址,属性
+ */
+ changeVideo: function() {
+ if (!this.html5Video) {
+ this.getVarsObject();
+ this.V.newVideo(this.vars);
+ return;
+ }
+ var vArr = this.VA;
+ var v = this.vars;
+ var i = 0;
+ if (vArr.length < 1) {
+ return;
+ }
+ if (this.V != null && this.needSeek == 0) {
+ this.needSeek = this.V.currentTime;
+ }
+ if (v['poster']) {
+ this.V.poster = v['poster'];
+ } else {
+ this.V.removeAttribute('poster');
+ }
+ if (v['loop']) {
+ this.V.loop = 'loop';
+ } else {
+ this.V.removeAttribute('loop');
+ }
+ if (v['seek'] > 0) {
+ this.needSeek = v['seek'];
+ } else {
+ this.needSeek = 0;
+ }
+ if (this.getFileExt(vArr[0][0]) != '.m3u8') {
+ this.isM3u8 = false;
+ }
+ if (!this.isM3u8) {
+ if (vArr.length == 1) {
+ this.V.innerHTML = '';
+ this.V.src = vArr[0][0];
+ } else {
+ var source = '';
+ vArr = this.arrSort(vArr);
+ for (i = 0; i < vArr.length; i++) {
+ var type = '';
+ var va = vArr[i];
+ if (va[1]) {
+ type = ' type="' + va[1] + '"';
+ }
+ source += '';
+ }
+ this.V.removeAttribute('src');
+ this.V.innerHTML = source;
+ }
+ //分析视频地址结束
+ if (v['autoplay']) {
+ this.V.autoplay = 'autoplay';
+ } else {
+ this.V.removeAttribute('autoplay');
+ }
+ this.V.load();
+ } else {
+ this.embedHls(vArr[0][0], v['autoplay']);
+ }
+ if (!this.isUndefined(v['volume'])) {
+ this.changeVolume(v['volume']);
+ }
+ this.resetPlayer(); //重置界面元素
+ this.timerErrorFun();
+ //如果存在字幕则加载
+ if (this.vars['cktrack']) {
+ this.loadTrack();
+ }
+ },
+ /*
+ 内部函数
+ 调整中间暂停按钮,缓冲loading,错误提示文本框的位置
+ */
+ elementCoordinate: function() {
+ this.pdCoor = this.getXY(this.PD);
+ try {
+ this.css(this.CB['pauseCenter'], {
+ left: parseInt((this.PD.offsetWidth - 80) * 0.5) + 'px',
+ top: parseInt((this.PD.offsetHeight - 80) * 0.5) + 'px'
+ });
+ } catch(event) {}
+ try {
+ this.css(this.CB['loading'], {
+ left: parseInt((this.PD.offsetWidth - 60) * 0.5) + 'px',
+ top: parseInt((this.PD.offsetHeight - 60) * 0.5) + 'px'
+ });
+ } catch(event) {}
+ try {
+ this.css(this.CB['errorText'], {
+ left: parseInt((this.PD.offsetWidth - 120) * 0.5) + 'px',
+ top: parseInt((this.PD.offsetHeight - 30) * 0.5) + 'px'
+ });
+ } catch(event) {}
+ try {
+ this.css(this.CB['logo'], {
+ left: parseInt(this.PD.offsetWidth - this.CB['logo'].offsetWidth - 20) + 'px',
+ top: '20px'
+ });
+ } catch(event) {}
+ this.checkBarWidth();
+ },
+ /*
+ 内部函数
+ 当播放器尺寸变化时,显示和隐藏相关节点
+ */
+ checkBarWidth: function() {
+ if (!this.showFace) {
+ return;
+ }
+ var controlBarW = this.CB['controlBar'].offsetWidth;
+ var ele = [];
+ ele.push([[this.CB['full'], this.CB['escFull'], this.CB['fullLine']], this.buttonWidth['full'] + 2, 'full']);
+ if (this.vars['front'] != '') {
+ ele.push([[this.CB['front'], this.CB['frontLine']], this.buttonWidth['front'] + 2]);
+ }
+ if (this.vars['next'] != '') {
+ ele.push([[this.CB['next'], this.CB['nextLine']], this.buttonWidth['next'] + 2]);
+ }
+ if (this.CB['definition'].innerHTML != '') {
+ ele.push([[this.CB['definition'], this.CB['definitionLine']], this.buttonWidth['definition'] + 2]);
+ }
+ if ((this.ckplayerConfig['config']['mobileVolumeBarShow'] || !this.isMobile()) && this.css(this.CB['volume'], 'display') == 'block') {
+ ele.push([[this.CB['volume']], this.buttonWidth['volume']]);
+ ele.push([[this.CB['mute'], this.CB['escMute'], this.CB['muteLine']], this.buttonWidth['mute'] + 2, 'mute']);
+ }
+ ele.push([[this.CB['timeText']], this.buttonWidth['timeText']]);
+ ele.push([[this.CB['play'], this.CB['pause'], this.CB['playLine']], this.buttonWidth['play'] + 2, 'play']);
+
+ var i = 0;
+ var len = 0;
+ var isc = true;
+ //计算所有要显示的节点的总宽度
+ for (var i = 0; i < ele.length; i++) {
+ var nlen = ele[i][1];
+ if (nlen > 2) {
+ len += nlen;
+ } else {
+ isc = false;
+ }
+ }
+ if (isc) {
+ this.buttonLen = len;
+ this.buttonArr = ele;
+ }
+ len = this.buttonLen;
+ ele = this.buttonArr;
+ for (var i = 0; i < ele.length; i++) {
+ if (len > controlBarW) {
+ len -= ele[i][1];
+ this.css(ele[i][0], 'display', 'none');
+ } else {
+ this.css(ele[i][0], 'display', 'block');
+ if (ele[i].length == 3) {
+ var name = ele[i][2];
+ switch (name) {
+ case 'mute':
+ if (this.volume == 0) {
+ this.css(this.CB['mute'], 'display', 'none');
+ } else {
+ this.css(this.CB['escMute'], 'display', 'none');
+ }
+ break;
+ case 'play':
+ this.playShow(this.V.paused ? false: true);
+ break;
+ case 'full':
+ if (this.full) {
+ this.css(this.CB['full'], 'display', 'none');
+ } else {
+ this.css(this.CB['escFull'], 'display', 'none');
+ }
+ break;
+ }
+ }
+ }
+ }
+ },
+ /*
+ 内部函数
+ 初始化暂停或播放按钮
+ */
+ initPlayPause: function() {
+ if (!this.showFace) {
+ return;
+ }
+ if (this.vars['autoplay']) {
+ this.css([this.CB['play'], this.CB['pauseCenter']], 'display', 'none');
+ this.css(this.CB['pause'], 'display', 'block');
+ } else {
+ this.css(this.CB['play'], 'display', 'block');
+ if (this.css(this.CB['errorText'], 'display') == 'none') {
+ this.css(this.CB['pauseCenter'], 'display', 'block');
+ }
+ this.css(this.CB['pause'], 'display', 'none');
+ }
+ },
+
+ /*
+ 下面为监听事件
+ 内部函数
+ 监听元数据已加载
+ */
+ loadedHandler: function() {
+ this.loaded = true;
+ if (this.vars['loaded'] != '') {
+ try {
+ eval(this.vars['loaded'] + '()');
+ } catch(event) {
+ this.log(event);
+ }
+ }
+ },
+ /*
+ 内部函数
+ 监听播放
+ */
+ playingHandler: function() {
+ this.playShow(true);
+ //如果是第一次播放
+ if (this.isFirstTimePlay && !this.isUndefined(this.advertisements['front'])) {
+ this.isFirstTimePlay = false;
+ //调用播放前置广告组件
+ this.adI = 0;
+ this.adType = 'front';
+ this.adMuteInto();
+ this.adIsVideoTime = true;
+ this.adPlayStart = true;
+ this.adVideoPlay = false;
+ this.videoPause();
+ this.advertisementsTime();
+ this.advertisementsPlay();
+ this.adSkipButtonShow();
+ //调用播放前置广告组件结束
+ return;
+ }
+ if (this.adPlayerPlay) {
+ return;
+ }
+ //判断第一次播放结束
+ if (this.needSeek > 0) {
+ this.videoSeek(this.needSeek);
+ this.needSeek = 0;
+ }
+ if (this.animatePauseArray.length > 0) {
+ this.animateResume('pause');
+ }
+ if (this.playerType == 'html5video' && this.V != null && this.config['videoDrawImage']) {
+ this.sendVCanvas();
+ }
+ if (!this.isUndefined(this.advertisements['pause']) && !this.adPlayStart) { //如果存在暂停广告
+ this.adPauseCloseFunction();
+ }
+ },
+ /*暂停时播放暂停广告*/
+ adPausePlayer: function() {
+ this.adI = 0;
+ this.adType = 'pause';
+ this.adPauseShow = true;
+ this.loadAdPause();
+ },
+ loadAdPause: function() {
+ var ad = this.getNowAdvertisements();
+ var type = ad['type'];
+ var thisTemp = this;
+ var width = this.PD.offsetWidth,
+ height = this.PD.offsetHeight;
+ if (this.isStrImage(type) && this.adPauseShow) {
+ this.css(this.CB['adElement'], 'display', 'block');
+ var imgClass = 'adimg' + this.randomString(10);
+ var imgHtml = ' ';
+ if (ad['link']) {
+ imgHtml = '' + imgHtml + ' ';
+ }
+ this.CB['adElement'].innerHTML = imgHtml;
+ this.addListenerInside('load',
+ function() {
+ var imgObj = new Image();
+ imgObj.src = this.src;
+ var imgWH = thisTemp.adjustmentWH(imgObj.width, imgObj.height);
+ thisTemp.css([thisTemp.getByElement(imgClass), thisTemp.CB['adElement']], {
+ width: imgWH['width'] + 'px',
+ height: imgWH['height'] + 'px',
+ border: '0px'
+ });
+ if (thisTemp.ckplayerConfig['style']['advertisement']['closeButtonShow'] && thisTemp.adPauseShow) {
+ thisTemp.css(thisTemp.CB['adPauseClose'], {
+ display: 'block'
+ });
+ }
+ thisTemp.ajaxSuccessNull(ad['exhibitionMonitor']);
+ thisTemp.adPauseCoor();
+ },
+ this.getByElement(imgClass));
+ this.addListenerInside('click',
+ function() {
+ thisTemp.ajaxSuccessNull(ad['clickMonitor']);
+ },
+ this.CB['adElement']);
+ var newI = this.adI;
+ if (this.adI < this.advertisements['pause'].length - 1) {
+ newI++;
+ } else {
+ newI = 0;
+ }
+ if (ad['time'] > 0) {
+ setTimeout(function() {
+ if (thisTemp.adPauseShow) {
+ thisTemp.adI = newI;
+ thisTemp.loadAdPause();
+ }
+ },
+ ad['time'] * 1000);
+ }
+ }
+ },
+ /*调整暂停广告的位置*/
+ adPauseCoor: function() {
+ if (this.css(this.CB['adElement'], 'display') == 'block') {
+ var w = this.CB['adElement'].offsetWidth,
+ h = this.CB['adElement'].offsetHeight;
+ var pw = this.PD.offsetWidth,
+ ph = this.PD.offsetHeight;
+ this.css(this.CB['adElement'], {
+ top: (ph - h) * 0.5 + 'px',
+ left: (pw - w) * 0.5 + 'px'
+ });
+ if (this.css(this.CB['adPauseClose'], 'display') == 'block') {
+ this.css(this.CB['adPauseClose'], {
+ top: (ph - h) * 0.5 - 10 + 'px',
+ left: (pw - w) * 0.5 + w - 10 + 'px',
+ });
+ }
+ }
+ },
+ /*
+ 关闭暂停广告
+ */
+ adPauseCloseFunction: function() {
+ this.CB['adElement'].innerHTML = '';
+ this.css([this.CB['adElement'], this.CB['adPauseClose']], 'display', 'none');
+ this.adPauseShow = false;
+ },
+ /*计算广告时间*/
+ advertisementsTime: function(nt) {
+ if (this.isUndefined(nt)) {
+ nt = 0;
+ }
+ var ad = this.advertisements[this.adType];
+ if (nt > 0) {
+ ad[this.adI]['time'] = Math.ceil(nt);
+ }
+ this.adTimeAllTotal = 0;
+ for (var i = this.adI; i < ad.length; i++) {
+ if (!this.isUndefined(ad[i]['time'])) {
+ this.adTimeAllTotal += Math.ceil(ad[i]['time']);
+ }
+ }
+ if (this.adTimeAllTotal > 0) {
+ this.CB['adTime'].innerHTML = this.language['adTime'].replace('{$second}', this.adTimeAllTotal > 9 ? this.adTimeAllTotal: '0' + this.adTimeAllTotal);
+ }
+ if (this.adPauseShow) {
+ this.adPauseCloseFunction();
+ }
+ this.adOtherCloseAll();
+ this.adTimeTotal = -1;
+ },
+ /*判断是否需要显示跳过广告按钮*/
+ adSkipButtonShow: function() {
+ var thisTemp = this;
+ var skipConfig = this.ckplayerConfig['style']['advertisement'];
+ var delayTimeTemp = skipConfig[this.adType + 'SkipButtonDelay'];
+ var timeFun = function() {
+ if (delayTimeTemp >= 0) {
+ thisTemp.CB['adSkip'].innerHTML = thisTemp.language['skipAdTime'].replace('{$second}', delayTimeTemp > 9 ? delayTimeTemp: '0' + delayTimeTemp);
+ setTimeout(timeFun, 1000);
+ } else {
+ thisTemp.CB['adSkip'].innerHTML = thisTemp.language['skipAd'];
+ }
+ delayTimeTemp--;
+ };
+ if (skipConfig['skipButtonShow']) {
+ this.css(thisTemp.CB['adSkip'], 'display', 'block');
+ if (skipConfig[this.adType + 'SkipButtonDelay'] > 0 && this.isUndefined(this.adSkipButtonTime)) {
+ timeFun();
+ } else {
+ thisTemp.css(thisTemp.CB['adSkip'], 'display', 'block');
+ thisTemp.CB['adSkip'].innerHTML = this.language['skipAd'];
+ }
+ }
+ },
+ /*播放广告*/
+ advertisementsPlay: function() {
+ this.css([this.CB['adBackground'], this.CB['adElement'], this.CB['adBar'], this.CB['adLink']], 'display', 'none');
+ this.adPlayerPlay = false;
+ var ad = this.advertisements[this.adType];
+ if (this.adI == 0 && (this.adType == 'front' || this.adType == 'insert' || this.adType == 'end')) {
+ this.sendJS('process', this.adType + ' ad play')
+ }
+ this.trackHide();
+ if (this.adI < ad.length) {
+ if (!this.isUndefined(ad[this.adI]['time'])) {
+ this.adTimeTotal = parseInt(ad[this.adI]['time']);
+ }
+ this.loadAdvertisements();
+ } else {
+ this.adEnded();
+ }
+ },
+ /*清除当前所有广告*/
+ eliminateAd: function() {
+ if (this.adType) {
+ var ad = this.advertisements[this.adType];
+ this.adI = ad.length;
+ this.advertisementsPlay();
+ }
+
+ },
+ /*广告播放结束*/
+ adEnded: function() {
+ var thisTemp = this;
+ this.adPlayStart = false;
+ this.adPlayerPlay = false;
+ if (this.adVideoPlay) {
+ if (this.videoTemp['src'] != '') {
+ this.V.src = this.videoTemp['src'];
+ } else {
+ if (this.V.src) {
+ this.V.removeAttribute('src');
+ }
+ }
+ if (this.videoTemp['source'] != '') {
+ this.V.innerHTML = this.videoTemp['source'];
+ }
+ if (this.videoTemp['currentSrc'] != '') {
+ this.V.src = this.videoTemp['currentSrc'];
+ this.V.currentSrc = this.videoTemp['currentSrc'];
+ }
+ if (this.videoTemp['loop']) {
+ this.V.loop = true;
+ this.videoTemp['loop'] = false;
+ }
+ if (this.adType == 'end') {
+ this.endedHandler();
+ } else {
+ this.videoPlay();
+ }
+ } else {
+ this.videoPlay();
+ }
+ this.changeVolume(this.vars['volume']);
+ this.sendJS('process', this.adType + ' ad ended');
+ this.changeControlBarShow(true);
+ },
+ /*加载广告*/
+ loadAdvertisements: function() {
+ //this.videoTemp
+ var ad = this.getNowAdvertisements();
+ var type = ad['type'];
+ var thisTemp = this;
+ var width = this.PD.offsetWidth,
+ height = this.PD.offsetHeight;
+ this.changeControlBarShow(false);
+ this.adPlayerPlay = true;
+ if (this.isStrImage(type)) {
+ this.css([this.CB['adBackground'], this.CB['adElement'], this.CB['adBar']], 'display', 'block');
+ this.css([this.CB['adMute'], this.CB['adEscMute']], 'display', 'none');
+ var imgClass = 'adimg' + this.randomString(10);
+ var imgHtml = ' ';
+ if (ad['link']) {
+ imgHtml = '' + imgHtml + ' ';
+ }
+ this.CB['adElement'].innerHTML = imgHtml;
+ this.addListenerInside('load',
+ function() {
+ var imgObj = new Image();
+ imgObj.src = this.src;
+ var imgWH = thisTemp.adjustmentWH(imgObj.width, imgObj.height);
+ thisTemp.css(thisTemp.getByElement(imgClass), {
+ width: imgWH['width'] + 'px',
+ height: imgWH['height'] + 'px',
+ border: '0px'
+ });
+ thisTemp.css(thisTemp.CB['adElement'], {
+ width: imgWH['width'] + 'px',
+ height: imgWH['height'] + 'px',
+ top: (height - imgWH['height']) * 0.5 + 'px',
+ left: (width - imgWH['width']) * 0.5 + 'px',
+ });
+ thisTemp.ajaxSuccessNull(ad['exhibitionMonitor']);
+ },
+ this.getByElement(imgClass));
+ this.addListenerInside('click',
+ function() {
+ thisTemp.ajaxSuccessNull(ad['clickMonitor']);
+ },
+ this.CB['adElement']);
+ if (!this.isUndefined(ad['time'])) {
+ this.adCountDown();
+ }
+ } else {
+ this.css(this.CB['adBar'], 'display', 'block');
+ //判断是否静音
+ if (this.adVideoMute) {
+ this.css(this.CB['adEscMute'], 'display', 'block');
+ this.css(this.CB['adMute'], 'display', 'none');
+ } else {
+ this.css(this.CB['adEscMute'], 'display', 'none');
+ this.css(this.CB['adMute'], 'display', 'block');
+ }
+ this.CB['adElement'].innerHTML = '';
+ if (this.videoTemp['currentSrc'] == '') {
+ this.videoTemp['currentSrc'] = this.getCurrentSrc();
+ }
+ if (this.V.loop) {
+ this.videoTemp['loop'] = true;
+ this.V.loop = false;
+ }
+ if (this.V != null && this.V.currentTime > 0 && this.adIsVideoTime) { //当有视频广告时而又没有记录下已播放的时间则进行记录
+ this.adIsVideoTime = false;
+ this.needSeek = this.V.currentTime;
+ }
+ this.V.src = ad['file'];
+ this.V.currentSrc = ad['file'];
+ this.V.innerHTML = '';
+ this.V.play();
+ this.adVideoPlay = true;
+ this.ajaxSuccessNull(ad['exhibitionMonitor']);
+ if (!this.adVideoMute) {
+ this.adEscMuteFunction();
+ }
+ }
+ if (ad['link']) {
+ this.css(this.CB['adLink'], 'display', 'block');
+ var link = '' + this.language['adLink'] + ' ';
+ this.CB['adLink'].innerHTML = link;
+ this.css(this.getByElement('ckadmorelink'), {
+ color: '#FFFFFF',
+ textDecoration: 'none'
+ });
+ this.addListenerInside('click',
+ function() {
+ thisTemp.ajaxSuccessNull(ad['clickMonitor']);
+ },
+ this.CB['adLink']);
+ } else {
+ this.css(this.CB['adLink'], 'display', 'none');
+ }
+
+ },
+ /*普通广告倒计时*/
+ adCountDown: function() {
+ var thisTemp = this;
+ if (this.adTimeTotal > 0) {
+ if (!this.adIsPause) {
+ this.adTimeTotal--;
+ this.showAdTime();
+ this.adCountDownObj = null;
+ this.adCountDownObj = setTimeout(function() {
+ thisTemp.adCountDown();
+ },
+ 1000);
+ }
+ } else {
+ this.adI++;
+ this.advertisementsPlay();
+ }
+ },
+ /*视频广告倒计时*/
+ adPlayerTimeHandler: function(time) {
+ var ad = this.getNowAdvertisements();
+ var type = ad['type'];
+ if (this.isStrImage(type)) {
+ return;
+ }
+ if (this.adTimeTotal != parseInt(time)) {
+ this.adTimeTotal = parseInt(time);
+ this.showAdTime();
+ }
+ },
+ /*格式化广告倒计时显示*/
+ showAdTime: function() {
+ this.adTimeAllTotal--;
+ var n = this.adTimeAllTotal;
+ if (n < 0) {
+ n = 0;
+ }
+ this.CB['adTime'].innerHTML = this.language['adTime'].replace('{$second}', n < 10 ? '0' + n: n);
+ },
+ /*
+ 单独监听其它广告
+ */
+ checkAdOther: function(t) {
+ if (this.adPlayerPlay) {
+ return;
+ }
+ var adTime = this.advertisements['othertime'];
+ var adPlay = this.advertisements['otherPlay'];
+ for (var i = 0; i < adTime.length; i++) {
+ if (t >= adTime[i] && !adPlay[i]) { //如果播放时间大于广告时间而该广告还没有播放,则开始播放
+ adPlay[i] = true;
+ this.newAdOther(i);
+ }
+ }
+ },
+ /*
+ 新建其它广告
+ */
+ newAdOther: function(i) {
+ var thisTemp = this;
+ var ad = this.advertisements['other'][i];
+ var randomS = this.randomString(10); //获取一个随机字符串
+ var adDivID = 'adother' + randomS; //广告容器
+ imgClassName = 'adimgother' + randomS;
+ var adDiv = document.createElement('div');
+ adDiv.className = adDivID;
+ this.PD.appendChild(adDiv);
+ ad['div'] = adDivID;
+ ad['element'] = imgClassName;
+ this.getByElement(adDivID).innerHTML = ' ';
+ this.css(adDivID, {
+ position: 'absolute',
+ overflow: 'hidden',
+ zIndex: '996',
+ top: '60px',
+ left: '30px',
+ cursor: 'pointer'
+ });
+ if (this.ckplayerConfig['style']['advertisement']['closeOtherButtonShow']) {
+ var closeAdDivID = 'adotherclose' + randomS; //广告容器
+ var closeAdDiv = document.createElement('div');
+ closeAdDiv.className = closeAdDivID;
+ this.PD.appendChild(closeAdDiv);
+ this.getByElement(closeAdDivID).innerHTML = this.newCanvas(closeAdDivID, 20, 20);
+ ad['closeDiv'] = closeAdDivID;
+ ad['close'] = false;
+ this.css(closeAdDivID, {
+ backgroundColor: '#f7f7f7',
+ //f8f7f7
+ widht: '20px',
+ height: '20px',
+ position: 'absolute',
+ overflow: 'hidden',
+ zIndex: '997',
+ top: '60px',
+ left: '30px',
+ borderRadius: '20px',
+ cursor: 'pointer'
+ });
+ var adOtherClose = this.getByElement(closeAdDivID + '-canvas').getContext('2d');
+ var adOtherCloseFillRect = function() {
+ thisTemp.canvasFill(adOtherClose, [[4, 6], [6, 6], [16, 15], [14, 15]]);
+ thisTemp.canvasFill(adOtherClose, [[14, 6], [16, 6], [6, 15], [4, 15]]);
+ };
+ adOtherClose.fillStyle = '#404856';
+ adOtherCloseFillRect();
+ var adOtherCloseOver = function() {
+ adOtherClose.clearRect(0, 0, 20, 20);
+ adOtherClose.fillStyle = '#0782F5';
+ adOtherCloseFillRect();
+ };
+ var adOtherCloseOut = function() {
+ adOtherClose.clearRect(0, 0, 20, 20);
+ adOtherClose.fillStyle = '#404856';
+ adOtherCloseFillRect();
+ };
+ this.addListenerInside('mouseover', adOtherCloseOver, this.getByElement(closeAdDivID + '-canvas'));
+ this.addListenerInside('mouseout', adOtherCloseOut, this.getByElement(closeAdDivID + '-canvas'));
+ }
+ this.addListenerInside('load',
+ function() {
+ var imgObj = new Image();
+ imgObj.src = this.src;
+ var imgWH = thisTemp.adjustmentWH(imgObj.width, imgObj.height);
+ thisTemp.css([thisTemp.getByElement(imgClassName), thisTemp.getByElement(adDivID)], {
+ width: imgWH['width'] + 'px',
+ height: imgWH['height'] + 'px',
+ border: '0px'
+ });
+ thisTemp.advertisements['other'][i] = ad;
+ thisTemp.ajaxSuccessNull(ad['exhibitionMonitor']);
+ thisTemp.adOtherCoor();
+ },
+ this.getByElement(imgClassName));
+ this.addListenerInside('click',
+ function() {
+ thisTemp.adOtherClose(i);
+ },
+ this.getByElement(closeAdDivID));
+ this.addListenerInside('click',
+ function() {
+ thisTemp.ajaxSuccessNull(ad['clickMonitor']);
+ },
+ this.getByElement(imgClassName));
+ if (ad['time'] > 0) {
+ setTimeout(function() {
+ thisTemp.adOtherClose(i);
+ },
+ ad['time'] * 1000);
+ }
+ },
+ /*
+ 关闭其它广告
+ */
+ adOtherClose: function(i) {
+ var ad = this.advertisements['other'][i];
+ if (!this.isUndefined(ad['close'])) {
+ if (!ad['close']) {
+ ad['close'] = true;
+ this.PD.removeChild(this.getByElement(ad['div']));
+ this.PD.removeChild(this.getByElement(ad['closeDiv']));
+ }
+ }
+ },
+ adOtherCloseAll: function() {
+ if (!this.isUndefined(this.advertisements['other'])) {
+ var ad = this.advertisements['other'];
+ for (var i = 0; i < ad.length; i++) {
+ this.adOtherClose(i);
+ }
+ }
+ },
+ /*
+ 计算其它广告的坐标
+ */
+ adOtherCoor: function() {
+ if (!this.isUndefined(this.advertisements['other'])) {
+ var arr = this.advertisements['other'];
+ for (var i = 0; i < arr.length; i++) {
+ var ad = arr[i];
+ if (!this.isUndefined(ad['close'])) {
+ if (!ad['close']) {
+ var coor = this.getPosition(ad);
+ var x = coor['x'],
+ y = coor['y'],
+ cx = x + this.getByElement(ad['div']).offsetWidth - 10,
+ cy = y - 10;
+ this.css(this.getByElement(ad['div']), {
+ left: x + 'px',
+ top: y + 'px'
+ });
+ if (!this.isUndefined(ad['closeDiv'])) {
+ this.css(this.getByElement(ad['closeDiv']), {
+ left: cx + 'px',
+ top: cy + 'px'
+ });
+ }
+ }
+ }
+ }
+ }
+ },
+ /*
+ 单独监听中间插入广告
+ */
+ checkAdInsert: function(t) {
+ if (this.adPlayerPlay) {
+ return;
+ }
+ var adTime = this.advertisements['inserttime'];
+ var adPlay = this.advertisements['insertPlay'];
+ var duration = this.getMetaDate()['duration'];
+ for (var i = adTime.length - 1; i > -1; i--) {
+ if (t >= adTime[i] && t < duration - 2 && t > 1 && !adPlay[i]) { //如果播放时间大于广告时间而该广告还没有播放,则开始播放
+ this.adI = 0;
+ this.adType = 'insert';
+ this.adMuteInto();
+ this.adIsVideoTime = true;
+ this.adPlayStart = true;
+ this.adVideoPlay = false;
+ this.videoPause();
+ this.advertisementsTime();
+ this.advertisementsPlay();
+ this.adSkipButtonShow();
+ adPlay[i] = true;
+ for (var n = 0; n < i + 1; n++) {
+ adPlay[n] = true;
+ }
+ break;
+ }
+ }
+ },
+ /*格式化中间插入广告的播放时间*/
+ formatInserttime: function(duration) {
+ if (!this.isUndefined(this.advertisements['inserttime'])) {
+ var arr = this.advertisements['inserttime'];
+ var newArr = [];
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i].toString().substr( - 1) == '%') {
+ newArr.push(parseInt(duration * parseInt(arr[i]) * 0.01));
+ } else {
+ newArr.push(parseInt(arr[i]));
+ }
+ }
+ this.advertisements['inserttime'] = newArr;
+ }
+ },
+ /*获取当前的广告*/
+ getNowAdvertisements: function() {
+ if (this.adI == -1) {
+ return {
+ file: '',
+ time: 0,
+ link: ''
+ };
+ }
+ return this.advertisements[this.adType][this.adI];
+ },
+ /*根据元件尺寸和播放器尺寸调整大小*/
+ adjustmentWH: function(w, h) {
+ var width = this.PD.offsetWidth,
+ height = this.PD.offsetHeight;
+ var nw = 0,
+ nh = 0;
+ if (w >= width || h >= height) {
+ if (width / w > height / h) {
+ nh = height - 20;
+ nw = w * nh / h;
+ } else {
+ nw = width - 20;
+ nh = h * nw / w;
+ }
+ } else {
+ nw = w;
+ nh = h;
+ }
+ return {
+ width: nw,
+ height: nh
+ }
+ },
+ /*单独请求一次地址,但不处理返回的数据*/
+ ajaxSuccessNull: function(url) {
+ if (!this.isUndefined(url)) {
+ var ajaxObj = {
+ url: url,
+ success: function(data) {}
+ };
+ this.ajax(ajaxObj);
+ }
+ },
+ /*
+ 内部函数
+ 运行指定函数
+ */
+ runFunction: function(s) {
+ try {
+ var arr = s.split('->');
+ switch (arr[0]) {
+ case 'javaScript':
+ eval(arr[1] + '()');
+ break;
+ case 'actionScript':
+ eval('this.' + arr[1] + '()');
+ break;
+ }
+ } catch(event) {}
+ },
+ /*
+ 内部函数
+ 使用画布附加视频
+ */
+ sendVCanvas: function() {
+ if (this.timerVCanvas == null) {
+ this.css(this.V, 'display', 'none');
+ this.css(this.MD, 'display', 'block');
+ var thisTemp = this;
+ var videoCanvas = function() {
+ if (thisTemp.MDCX.width != thisTemp.PD.offsetWidth) {
+ thisTemp.MDC.width = thisTemp.PD.offsetWidth;
+ }
+ if (thisTemp.MDCX.height != thisTemp.PD.offsetHeight) {
+ thisTemp.MDC.height = thisTemp.PD.offsetHeight;
+ }
+ thisTemp.MDCX.clearRect(0, 0, thisTemp.MDCX.width, thisTemp.MDCX.height);
+ var coor = thisTemp.getProportionCoor(thisTemp.PD.offsetWidth, thisTemp.PD.offsetHeight, thisTemp.V.videoWidth, thisTemp.V.videoHeight);
+ thisTemp.MDCX.drawImage(thisTemp.V, 0, 0, thisTemp.V.videoWidth, thisTemp.V.videoHeight, coor['x'], coor['y'], coor['width'], coor['height']);
+ };
+ this.timerVCanvas = new this.timer(0, videoCanvas);
+ }
+ },
+ /*
+ 内部函数
+ 监听暂停
+ */
+ pauseHandler: function() {
+ var thisTemp = this;
+ this.playShow(false);
+ if (this.animatePauseArray.length > 0) {
+ this.animatePause('pause');
+ }
+ if (this.playerType == 'html5video' && this.V != null && this.config['videoDrawImage']) {
+ this.stopVCanvas();
+ }
+ if (!this.isUndefined(this.advertisements['pause']) && !this.adPlayStart && !this.adPauseShow) { //如果存在暂停广告
+ setTimeout(function() {
+ if (!thisTemp.isUndefined(thisTemp.advertisements['pause']) && !thisTemp.adPlayStart && !thisTemp.adPauseShow && thisTemp.time > 1) { //如果存在暂停广告
+ thisTemp.adPausePlayer();
+ }
+ },
+ 300);
+ }
+ },
+ /*
+ 内部函数
+ 停止画布
+ */
+ stopVCanvas: function() {
+ if (this.timerVCanvas != null) {
+ this.css(this.V, 'display', 'block');
+ this.css(this.MD, 'display', 'none');
+ if (this.timerVCanvas.runing) {
+ this.timerVCanvas.stop();
+ }
+ this.timerVCanvas = null;
+ }
+ },
+ /*
+ 内部函数
+ 根据当前播放还是暂停确认图标显示
+ */
+ playShow: function(b) {
+ if (!this.showFace) {
+ return;
+ }
+ if (b) {
+ this.css(this.CB['play'], 'display', 'none');
+ this.css(this.CB['pauseCenter'], 'display', 'none');
+ this.css(this.CB['pause'], 'display', 'block');
+ } else {
+ this.css(this.CB['play'], 'display', 'block');
+ if (this.css(this.CB['errorText'], 'display') == 'none') {
+ if (!this.adPlayerPlay) {
+ this.css(this.CB['pauseCenter'], 'display', 'block');
+ }
+
+ } else {
+ this.css(this.CB['pauseCenter'], 'display', 'none');
+ }
+ this.css(this.CB['pause'], 'display', 'none');
+ }
+ },
+ /*
+ 内部函数
+ 监听seek结束
+ */
+ seekedHandler: function() {
+ this.resetTrack();
+ this.isTimeButtonMove = true;
+ if (this.V.paused) {
+ this.videoPlay();
+ }
+ },
+ /*
+ 内部函数
+ 监听播放结束
+ */
+ endedHandler: function() {
+ if (this.adPlayerPlay) {
+ this.adI++;
+ this.advertisementsPlay();
+ return;
+ }
+ if (!this.endAdPlay && !this.isUndefined(this.advertisements['end'])) {
+ this.endAdPlay = true;
+ this.adI = 0;
+ this.adType = 'end';
+ this.adMuteInto();
+ this.adIsVideoTime = true;
+ this.adPlayStart = true;
+ this.adVideoPlay = false;
+ this.videoPause();
+ this.advertisementsTime();
+ this.advertisementsPlay();
+ this.adSkipButtonShow();
+ this.adReset = true;
+ return;
+ }
+ this.sendJS('ended');
+ this.endedAdReset();
+ if (!this.vars['loop']) {
+ this.videoSeek(0);
+ }
+ },
+ /*
+ 重置结束后相关的设置
+ */
+ endedAdReset: function() {
+ var arr = [];
+ var i = 0;
+ if (!this.isUndefined(this.advertisements['insertPlay'])) {
+ arr = this.advertisements['insertPlay'];
+ for (i = 0; i < arr.length; i++) {
+ this.advertisements['insertPlay'][i] = false;
+ }
+ }
+ if (!this.isUndefined(this.advertisements['otherPlay'])) {
+ arr = this.advertisements['otherPlay'];
+ for (i = 0; i < arr.length; i++) {
+ this.advertisements['otherPlay'][i] = false;
+ }
+ }
+ //this.endAdPlay=false;
+ },
+ /*
+ 内部函数
+ 监听音量改变
+ */
+ volumechangeHandler: function() {
+ if (!this.showFace) {
+ return;
+ }
+ if ((this.ckplayerConfig['config']['mobileVolumeBarShow'] || !this.isMobile()) && this.css(this.CB['volume'], 'display') == 'block') {
+ try {
+ if (this.V.volume > 0) {
+ this.css(this.CB['mute'], 'display', 'block');
+ this.css(this.CB['escMute'], 'display', 'none');
+ } else {
+ this.css(this.CB['mute'], 'display', 'none');
+ this.css(this.CB['escMute'], 'display', 'block');
+ }
+ } catch(event) {}
+ }
+ },
+ /*
+ 内部函数
+ 监听播放时间调节进度条
+ */
+ timeUpdateHandler: function() {
+ var duration = 0;
+ if (this.playerType == 'html5video') {
+ try {
+ duration = this.V.duration;
+ } catch(event) {}
+ }
+ if (duration > 0) {
+ this.time = this.V.currentTime;
+ this.timeTextHandler();
+ this.trackShowHandler();
+ if (this.isTimeButtonMove) {
+ this.timeProgress(this.time, duration);
+ }
+ }
+ },
+ /*
+ 内部函数
+ 按时间改变进度条
+ */
+ timeProgress: function(time, duration) {
+ if (!this.showFace) {
+ return;
+ }
+ var timeProgressBgW = this.CB['timeProgressBg'].offsetWidth;
+ var timeBOW = parseInt((time * timeProgressBgW / duration) - (this.CB['timeButton'].offsetWidth * 0.5));
+ if (timeBOW > timeProgressBgW - this.CB['timeButton'].offsetWidth) {
+ timeBOW = timeProgressBgW - this.CB['timeButton'].offsetWidth;
+ }
+ if (timeBOW < 0) {
+ timeBOW = 0;
+ }
+ this.css(this.CB['timeProgress'], 'width', timeBOW + 'px');
+ this.css(this.CB['timeButton'], 'left', parseInt(timeBOW) + 'px');
+ },
+ /*
+ 内部函数
+ 监听播放时间改变时间显示文本框
+ */
+ timeTextHandler: function() { //显示时间/总时间
+ if (!this.showFace) {
+ return;
+ }
+ var duration = this.V.duration;
+ var time = this.V.currentTime;
+ if (isNaN(duration) || parseInt(duration) < 0.2) {
+ duration = this.vars['duration'];
+ }
+ this.CB['timeText'].innerHTML = this.formatTime(time) + ' / ' + this.formatTime(duration);
+ if (this.CB['timeText'].offsetWidth > 0) {
+ this.buttonWidth['timeText'] = this.CB['timeText'].offsetWidth;
+ }
+ },
+ /*
+ 内部函数
+ 监听是否是缓冲状态
+ */
+ bufferEdHandler: function() {
+ if (!this.showFace || this.playerType == 'flashplayer') {
+ return;
+ }
+ var thisTemp = this;
+ var clearTimerBuffer = function() {
+ if (thisTemp.timerBuffer != null) {
+ if (thisTemp.timerBuffer.runing) {
+ thisTemp.sendJS('buffer', 100);
+ thisTemp.timerBuffer.stop();
+ }
+ thisTemp.timerBuffer = null;
+ }
+ };
+ clearTimerBuffer();
+ var bufferFun = function() {
+ if (!thisTemp.isUndefined(thisTemp.V) && thisTemp.V.buffered.length > 0) {
+ var duration = thisTemp.V.duration;
+ var len = thisTemp.V.buffered.length;
+ var bufferStart = thisTemp.V.buffered.start(len - 1);
+ var bufferEnd = thisTemp.V.buffered.end(len - 1);
+ var loadTime = bufferStart + bufferEnd;
+ var loadProgressBgW = thisTemp.CB['timeProgressBg'].offsetWidth;
+ var timeButtonW = thisTemp.CB['timeButton'].offsetWidth;
+ var loadW = parseInt((loadTime * loadProgressBgW / duration) + timeButtonW);
+ if (loadW >= loadProgressBgW) {
+ loadW = loadProgressBgW;
+ clearTimerBuffer();
+ }
+ thisTemp.changeLoad(loadTime);
+ }
+ };
+ this.timerBuffer = new this.timer(200, bufferFun);
+ },
+ /*
+ 内部函数
+ 单独计算加载进度
+ */
+ changeLoad: function(loadTime) {
+ if (this.V == null) {
+ return;
+ }
+ if (!this.showFace) {
+ return;
+ }
+ var loadProgressBgW = this.CB['timeProgressBg'].offsetWidth;
+ var timeButtonW = this.CB['timeButton'].offsetWidth;
+ var duration = this.V.duration;
+ if (this.isUndefined(loadTime)) {
+ loadTime = this.loadTime;
+ } else {
+ this.loadTime = loadTime;
+ }
+ var loadW = parseInt((loadTime * loadProgressBgW / duration) + timeButtonW);
+ this.css(this.CB['loadProgress'], 'width', loadW + 'px');
+ },
+ /*
+ 内部函数
+ 判断是否是直播
+ */
+ judgeIsLive: function() {
+ var thisTemp = this;
+ if (this.timerError != null) {
+ if (this.timerError.runing) {
+ this.timerError.stop();
+ }
+ this.timerError = null;
+ }
+ this.error = false;
+ if (this.showFace) {
+ this.css(this.CB['errorText'], 'display', 'none');
+ }
+ var timeupdate = function(event) {
+ thisTemp.timeUpdateHandler();
+ };
+ if (!this.vars['live']) {
+ if (this.V != null && this.playerType == 'html5video') {
+ this.addListenerInside('timeupdate', timeupdate);
+ thisTemp.timeTextHandler();
+ thisTemp.prompt(); //添加提示点
+ setTimeout(function() {
+ thisTemp.bufferEdHandler();
+ },
+ 200);
+ }
+ } else {
+ this.removeListenerInside('timeupdate', timeupdate);
+ if (this.timerTime != null) {
+ window.clearInterval(this.timerTime);
+ timerTime = null;
+ }
+ if (this.timerTime != null) {
+ if (this.timerTime.runing) {
+ this.timerTime.stop();
+ }
+ this.timerTime = null;
+ }
+ var timeFun = function() {
+ if (thisTemp.V != null && !thisTemp.V.paused && thisTemp.showFace) {
+ thisTemp.CB['timeText'].innerHTML = thisTemp.getNowDate();
+ }
+ };
+ this.timerTime = new this.timer(1000, timeFun);
+ //timerTime.start();
+ }
+ this.definition();
+ },
+ /*
+ 内部函数
+ 加载字幕
+ */
+ loadTrack: function() {
+ if (this.playerType == 'flashplayer' || this.vars['flashplayer'] == true) {
+ return;
+ }
+ var thisTemp = this;
+ var track = this.vars['cktrack'];
+ var obj = {
+ method: 'get',
+ dataType: 'text',
+ url: track,
+ charset: 'utf-8',
+ success: function(data) {
+ thisTemp.track = thisTemp.parseSrtSubtitles(data);
+ thisTemp.trackIndex = 0;
+ thisTemp.nowTrackShow = {
+ sn: ''
+ };
+ }
+ };
+ this.ajax(obj);
+ },
+ /*
+ 内部函数
+ 重置字幕
+ */
+ resetTrack: function() {
+ this.trackIndex = 0;
+ this.nowTrackShow = {
+ sn: ''
+ };
+ },
+ /*
+ 内部函数
+ 根据时间改变读取显示字幕
+ */
+ trackShowHandler: function() {
+ if (!this.showFace || this.adPlayerPlay) {
+ return;
+ }
+ if (this.track.length < 1) {
+ return;
+ }
+ if (this.trackIndex >= this.track.length) {
+ this.trackIndex = 0;
+ }
+ var nowTrack = this.track[this.trackIndex]; //当前编号对应的字幕内容
+ /*
+ this.nowTrackShow=当前显示在界面上的内容
+ 如果当前时间正好在nowTrack时间内,则需要判断
+ */
+ if (this.time >= nowTrack['startTime'] && this.time <= nowTrack['endTime']) {
+ /*
+ 如果当前显示的内容不等于当前需要显示的内容时,则需要显示正确的内容
+ */
+ var nowShow = this.nowTrackShow;
+ if (nowShow['sn'] != nowTrack['sn']) {
+ this.trackHide();
+ this.trackShow(nowTrack);
+ }
+ } else {
+ /*
+ * 如果当前播放时间不在当前编号字幕内,则需要先清空当前的字幕内容,再显示新的字幕内容
+ */
+ this.trackHide();
+ this.checkTrack();
+ }
+ },
+ /*
+ 内部函数
+ 显示字幕内容
+ */
+ trackShow: function(track) {
+ this.nowTrackShow = track;
+ var arr = track['content'];
+ for (var i = 0; i < arr.length; i++) {
+ var obj = {
+ list: [{
+ type: 'text',
+ text: arr[i],
+ color: '#FFFFFF',
+ size: 16,
+ font: this.fontFamily,
+ lineHeight: 30
+ }],
+ position: [1, 2, null, -(arr.length - i) * 30 - 50]
+ };
+ var ele = this.addElement(obj);
+ this.trackElement.push(ele);
+ }
+ },
+ /*
+ 内部函数
+ 隐藏字字幕内容
+ */
+ trackHide: function() {
+ for (var i = 0; i < this.trackElement.length; i++) {
+ this.deleteElement(this.trackElement[i]);
+ }
+ this.trackElement = [];
+ },
+ /*
+ 内部函数
+ 重新计算字幕的编号
+ */
+ checkTrack: function() {
+ var num = this.trackIndex;
+ var arr = this.track;
+ var i = 0;
+ for (i = num; i < arr.length; i++) {
+ if (this.time >= arr[i]['startTime'] && this.time <= arr[i]['endTime']) {
+ this.trackIndex = i;
+ break;
+ }
+ }
+ },
+ /*
+ -----------------------------------------------------------------------------接口函数开始
+ 接口函数
+ 在播放和暂停之间切换
+ */
+ playOrPause: function() {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.V == null) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.playOrPause();
+ return;
+ }
+ if (this.V.paused) {
+ this.videoPlay();
+ } else {
+ this.videoPause();
+ }
+ },
+ /*
+ 接口函数
+ 播放动作
+ */
+ videoPlay: function() {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.videoPlay();
+ return;
+ }
+ if (this.adPlayerPlay) {
+ this.eliminateAd(); //清除广告
+ return;
+ }
+ try {
+ if (this.V.currentSrc) {
+ this.V.play();
+ }
+ } catch(event) {}
+ },
+ /*
+ 接口函数
+ 暂停动作
+ */
+ videoPause: function() {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.videoPause();
+ return;
+ }
+ try {
+ this.V.pause();
+ } catch(event) {}
+ },
+ /*
+ 接口函数
+ 跳转时间动作
+ */
+ videoSeek: function(time) {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.videoSeek(time);
+ return;
+ }
+ var duration = this.getMetaDate()['duration'];
+ if (duration > 0 && time > duration) {
+ time = duration;
+ }
+ if (time >= 0) {
+ this.V.currentTime = time;
+ this.sendJS('seekTime', time);
+ }
+ },
+ /*
+ 接口函数
+ 调节音量/获取音量
+ */
+ changeVolume: function(vol, bg, button) {
+ if (this.loaded) {
+ if (this.playerType == 'flashplayer') {
+ this.V.changeVolume(time);
+ return;
+ }
+ }
+ if (isNaN(vol) || this.isUndefined(vol)) {
+ vol = 0;
+ }
+ if (!this.loaded) {
+ this.vars['volume'] = vol;
+ }
+ if (!this.html5Video) {
+ this.V.changeVolume(vol);
+ return;
+ }
+ try {
+ if (this.isUndefined(bg)) {
+ bg = true;
+ }
+ } catch(e) {}
+ try {
+ if (this.isUndefined(button)) {
+ button = true;
+ }
+ } catch(e) {}
+ if (!vol) {
+ vol = 0;
+ }
+ if (vol < 0) {
+ vol = 0;
+ }
+ if (vol > 1) {
+ vol = 1;
+ }
+ try {
+ this.V.volume = vol;
+ } catch(error) {}
+ this.volume = vol;
+ if (bg && this.showFace) {
+ var bgW = vol * this.CB['volumeBg'].offsetWidth;
+ if (bgW < 0) {
+ bgW = 0;
+ }
+ if (bgW > this.CB['volumeBg'].offsetWidth) {
+ bgW = this.CB['volumeBg'].offsetWidth;
+ }
+ this.css(this.CB['volumeUp'], 'width', bgW + 'px');
+ }
+
+ if (button && this.showFace) {
+ var buLeft = parseInt(this.CB['volumeUp'].offsetWidth - (this.CB['volumeBO'].offsetWidth * 0.5));
+ if (buLeft > this.CB['volumeBg'].offsetWidth - this.CB['volumeBO'].offsetWidth) {
+ buLeft = this.CB['volumeBg'].offsetWidth - this.CB['volumeBO'].offsetWidth
+ }
+ if (buLeft < 0) {
+ buLeft = 0;
+ }
+ this.css(this.CB['volumeBO'], 'left', buLeft + 'px');
+ }
+ },
+ /*
+ 接口函数
+ 静音
+ */
+ videoMute: function() {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.videoMute();
+ return;
+ }
+ this.volumeTemp = this.V ? (this.V.volume > 0 ? this.V.volume: this.vars['volume']) : this.vars['volume'];
+ this.changeVolume(0);
+ },
+ /*
+ 接口函数
+ 取消静音
+ */
+ videoEscMute: function() {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.videoEscMute();
+ return;
+ }
+ this.changeVolume(this.volumeTemp > 0 ? this.volumeTemp: this.vars['volume']);
+ },
+ /*
+ 接口函数
+ 视频广告静音
+ */
+ adMuteFunction: function() {
+ if (!this.loaded) {
+ return;
+ }
+ this.changeVolume(0);
+ this.adVideoMute = true;
+ this.css(this.CB['adEscMute'], 'display', 'block');
+ this.css(this.CB['adMute'], 'display', 'none');
+ },
+ /*
+ 接口函数
+ 视频广告取消静音
+ */
+ adEscMuteFunction: function() {
+ if (!this.loaded) {
+ return;
+ }
+ var v = this.ckplayerConfig['style']['advertisement']['videoVolume'];
+ this.changeVolume(v);
+ this.adMuteInto();
+ },
+ /*
+ 初始化广告的音量按钮
+ */
+ adMuteInto: function() {
+ this.adVideoMute = false;
+ this.css(this.CB['adEscMute'], 'display', 'none');
+ this.css(this.CB['adMute'], 'display', 'block');
+ },
+ /*
+ 接口函数
+ 快退
+ */
+ fastBack: function() {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.fastBack();
+ return;
+ }
+ var time = this.time - this.ckplayerConfig['config']['timeJump'];
+ if (time < 0) {
+ time = 0;
+ }
+ this.videoSeek(time);
+ },
+ /*
+ 接口函数
+ 快进
+ */
+ fastNext: function() {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.fastNext();
+ return;
+ }
+ var time = this.time + this.ckplayerConfig['config']['timeJump'];
+ if (time > this.V.duration) {
+ time = this.V.duration;
+ }
+ this.videoSeek(time);
+ },
+ /*
+ 接口函数
+ 获取当前播放的地址
+ */
+ getCurrentSrc: function() {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ return this.V.getCurrentSrc();
+ }
+ return this.V.currentSrc;
+ },
+ /*
+ 内置函数
+ 全屏/退出全屏动作,该动作只能是用户操作才可以触发,比如用户点击按钮触发该事件
+ */
+ switchFull: function() {
+ if (this.full) {
+ this.quitFullScreen();
+ } else {
+ this.fullScreen();
+ }
+ },
+ /*
+ 内置函数
+ 全屏动作,该动作只能是用户操作才可以触发,比如用户点击按钮触发该事件
+ */
+ fullScreen: function() {
+ if (this.html5Video && this.playerType == 'html5video') {
+ var element = this.PD;
+ if (element.requestFullscreen) {
+ element.requestFullscreen();
+ } else if (element.mozRequestFullScreen) {
+ element.mozRequestFullScreen();
+ } else if (element.webkitRequestFullscreen) {
+ element.webkitRequestFullscreen();
+ } else if (element.msRequestFullscreen) {
+ element.msRequestFullscreen();
+ } else if (element.oRequestFullscreen) {
+ element.oRequestFullscreen();
+ }
+ this.judgeFullScreen();
+ } else {
+ //this.V.fullScreen();
+ }
+ },
+ /*
+ 接口函数
+ 退出全屏动作
+ */
+ quitFullScreen: function() {
+ if (this.html5Video && this.playerType == 'html5video') {
+ if (document.exitFullscreen) {
+ document.exitFullscreen();
+ } else if (document.msExitFullscreen) {
+ document.msExitFullscreen();
+ } else if (document.mozCancelFullScreen) {
+ document.mozCancelFullScreen();
+ } else if (document.oRequestFullscreen) {
+ document.oCancelFullScreen();
+ } else if (document.requestFullscreen) {
+ document.requestFullscreen();
+ } else if (document.webkitExitFullscreen) {
+ document.webkitExitFullscreen();
+ } else {
+ this.css(document.documentElement, 'cssText', '');
+ this.css(document.document.body, 'cssText', '');
+ this.css(this.PD, 'cssText', '');
+ }
+ this.judgeFullScreen();
+ }
+ },
+ /*
+ 下面列出只有flashplayer里支持的
+ */
+ videoRotation: function(n) {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.videoRotation(n);
+ return;
+ }
+ if (this.isUndefined(n)) {
+ n = 0;
+ }
+ var tf = this.css(this.V, 'transform');
+ if (this.isUndefined(tf) && !tf) {
+ tf = 'rotate(0deg)';
+ }
+ var reg = tf.match(/rotate\([^)]+\)/);
+ reg = reg ? reg[0].replace('rotate(', '').replace('deg)', '') : '';
+ if (reg == '') {
+ reg = 0;
+ } else {
+ reg = parseInt(reg);
+ }
+ if (n == -1) {
+ reg -= 90;
+ } else if (n == 1) {
+ reg += 90;
+ } else {
+ if (n != 90 && n != 180 && n != 270 && n != -90 && n != -180 && n != -270) {
+ reg = 0;
+ } else {
+ reg = n;
+ }
+ }
+ n = reg;
+ var y90 = n % 90,
+ y180 = n % 180,
+ y270 = n % 270;
+ var ys = false;
+ if (y90 == 0 && y180 == 90 && y270 == 90) {
+ ys = true;
+ }
+ if (y90 == 0 && y180 == 90 && y270 == 0) {
+ ys = true;
+ }
+ if (y90 == -0 && y180 == -90 && y270 == -90) {
+ ys = true;
+ }
+ if (y90 == -0 && y180 == -90 && y270 == -0) {
+ ys = true;
+ }
+ tf = tf.replace(/rotate\([^)]+\)/, '').replace(/scale\([^)]+\)/, '') + ' rotate(' + n + 'deg)';
+ var cdW = this.CD.offsetWidth,
+ cdH = this.CD.offsetHeight,
+ vW = this.V.videoWidth,
+ vH = this.V.videoHeight;
+ if (vW > 0 && vH > 0) {
+ if (ys) {
+ if (cdW / cdH > vH / vW) {
+ nH = cdH;
+ nW = vH * nH / vW;
+ } else {
+ nW = cdW;
+ nH = vW * nW / vH;
+ }
+ this.css(this.V, 'transform', 'rotate(0deg)');
+ this.css(this.V, 'transform', 'scale(' + nH / cdW + ',' + nW / cdH + ')' + tf);
+ } else {
+ this.css(this.V, 'transform', tf);
+ }
+ } else {
+ this.css(this.V, 'transform', tf);
+ }
+ return;
+ },
+ videoBrightness: function(n) {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.videoBrightness(n);
+ return;
+ }
+ },
+ videoContrast: function(n) {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.videoContrast(n);
+ return;
+ }
+ },
+ videoSaturation: function(n) {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.videoSaturation(n);
+ return;
+ }
+ },
+ videoHue: function(n) {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.videoHue(n);
+ return;
+ }
+ },
+ videoZoom: function(n) {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.videoZoom(n);
+ return;
+ }
+ if (this.isUndefined(n)) {
+ n = 1;
+ }
+ if (n < 0) {
+ n = 0;
+ }
+ if (n > 2) {
+ n = 2;
+ }
+ var tf = this.css(this.V, 'transform');
+ tf = tf.replace(/scale\([^)]+\)/, '') + ' scale(' + n + ')';
+ this.videoScale = n;
+ this.css(this.V, 'transform', tf);
+ return;
+ },
+ videoProportion: function(w, h) {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.videoProportion(w, h);
+ return;
+ }
+ },
+ adPlay: function() {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.adPlay();
+ return;
+ }
+ if (this.adPlayerPlay) {
+ this.adIsPause = false;
+ if (this.adPlayerPlay) {
+ var ad = this.getNowAdvertisements();
+ var type = ad['type'];
+ if (this.isStrImage(type)) {
+ this.adCountDown();
+ } else {
+ this.V.play();
+ }
+ }
+ }
+ },
+ adPause: function() {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.adPause();
+ return;
+ }
+ if (this.adPlayerPlay) {
+ this.adIsPause = true;
+ var ad = this.getNowAdvertisements();
+ var type = ad['type'];
+ if (type != 'jpg' && type != 'jpeg' && type != 'png' && type != 'svg' && type != 'gif') {
+ this.videoPause();
+ }
+ }
+ },
+ videoError: function(n) {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.videoError(n);
+ return;
+ }
+ },
+ changeConfig: function() {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.changeConfig(arguments);
+ return;
+ }
+ var obj = this.ckplayerConfig;
+ var arg = arguments;
+ for (var i = 0; i < arg.length - 1; i++) {
+ if (obj.hasOwnProperty(arg[i])) {
+ obj = obj[arg[i]];
+ } else {
+ return;
+ }
+ }
+ var val = arg[arg.length - 1];
+ switch (arg.length) {
+ case 2:
+ this.ckplayerConfig[arg[0]] = val;
+ break;
+ case 3:
+ this.ckplayerConfig[arg[0]][arg[1]] = val;
+ break;
+ case 4:
+ this.ckplayerConfig[arg[0]][arg[1]][arg[2]] = val;
+ break;
+ case 5:
+ this.ckplayerConfig[arg[0]][arg[1]][arg[2]][arg[3]] = val;
+ break;
+ case 6:
+ this.ckplayerConfig[arg[0]][arg[1]][arg[2]][arg[3]][arg[4]] = val;
+ break;
+ case 7:
+ this.ckplayerConfig[arg[0]][arg[1]][arg[2]][arg[3]][arg[4]][arg[5]] = val;
+ break;
+ case 8:
+ this.ckplayerConfig[arg[0]][arg[1]][arg[2]][arg[3]][arg[4]][arg[5]][arg[6]] = val;
+ break;
+ case 9:
+ this.ckplayerConfig[arg[0]][arg[1]][arg[2]][arg[3]][arg[4]][arg[5]][arg[6]][arg[7]] = val;
+ break;
+ case 10:
+ this.ckplayerConfig[arg[0]][arg[1]][arg[2]][arg[3]][arg[4]][arg[5]][arg[6]][arg[7]][arg[8]] = val;
+ break;
+ default:
+ return;
+ break;
+ }
+ this.sendJS('configChange', this.ckplayerConfig);
+ },
+ custom: function() {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.custom(arguments);
+ return;
+ }
+ },
+ getConfig: function() {
+ if (!this.loaded) {
+ return null;
+ }
+ if (this.playerType == 'flashplayer') {
+ return this.V.getConfig(arguments);
+ }
+ },
+ openUrl: function(n) {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.openUrl(n);
+ return;
+ }
+ },
+ /*
+ 接口函数
+ 清除视频
+ */
+ videoClear: function() {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.videoClear();
+ return;
+ }
+ },
+ /*
+ 接口函数
+ 向播放器传递新的视频地址
+ */
+ newVideo: function(c) {
+ if (this.playerType == 'flashplayer') {
+ this.V.newVideo(c);
+ return;
+ } else {
+ this.embed(c);
+ }
+ },
+ /*
+ 接口函数
+ 截图
+ */
+ screenshot: function(obj, save, name) {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ try {
+ this.V.screenshot(obj, save, name);
+ } catch(error) {
+ this.log(error);
+ }
+ return;
+ }
+ if (obj == 'video') {
+ var newCanvas = document.createElement('canvas');
+ newCanvas.width = this.V.videoWidth;
+ newCanvas.height = this.V.videoHeight;
+ newCanvas.getContext('2d').drawImage(this.V, 0, 0, this.V.videoWidth, this.V.videoHeight);
+ try {
+ var base64 = newCanvas.toDataURL('image/jpeg');
+ this.sendJS('screenshot', {
+ object: obj,
+ save: save,
+ name: name,
+ base64: base64
+ });
+ } catch(error) {
+ this.log(error);
+ }
+ }
+ },
+ /*
+ 接口函数
+ 改变播放器尺寸
+ */
+ changeSize: function(w, h) {
+ if (this.isUndefined(w)) {
+ w = 0;
+ }
+ if (this.isUndefined(h)) {
+ h = 0;
+ }
+ if (w > 0) {
+ this.css(this.CD, 'width', w + 'px');
+ }
+ if (h > 0) {
+ this.css(this.CD, 'height', h + 'px');
+ }
+ if (this.html5Video) {
+ this.elementCoordinate();
+ }
+ },
+ /*
+ 接口函数
+ 改变视频播放速度
+ */
+ changePlaybackRate: function(n) {
+ if (this.html5Video) {
+ var arr = this.playbackRateArr;
+ n = parseInt(n);
+ if (n < arr.length) {
+ this.newPlaybackrate(arr[n][1]);
+ }
+ }
+ },
+ /*
+ 内部函数
+ 注册控制控制栏显示与隐藏函数
+ */
+ changeControlBarShow: function(show) {
+ if (!this.loaded) {
+ return;
+ }
+ if (this.playerType == 'flashplayer') {
+ this.V.changeControlBarShow(show);
+ return;
+ }
+ if (show) {
+ this.controlBarIsShow = true;
+ this.controlBarHide(false);
+ } else {
+ this.controlBarIsShow = false;
+ this.controlBarHide(true);
+ }
+ },
+ /*
+ -----------------------------------------------------------------------
+ 调用flashplayer
+ */
+ embedSWF: function() {
+ var vid = this.randomString();
+ var flashvars = this.getFlashVars();
+ var param = this.getFlashplayerParam();
+ var flashplayerUrl = 'http://www.macromedia.com/go/getflashplayer';
+ var html = '',
+ src = javascriptPath + 'ckplayer.swf';
+ id = 'id="' + vid + '" name="' + vid + '" ';
+ html += '';
+ html += param['v'];
+ html += ' ';
+ html += ' ';
+ html += ' ';
+ html += ' ';
+ html += ' ';
+ this.PD.innerHTML = html;
+ this.V = this.getObjectById(vid); //V:定义播放器对象全局变量
+ this.playerType = 'flashplayer';
+ //this.loaded=true;
+ },
+ /*
+ 内置函数
+ 将vars对象转换成字符
+ */
+ getFlashVars: function() {
+ this.getVarsObject();
+ var v = this.vars;
+ var z = '';
+ for (k in v) {
+ if (k != 'flashplayer' && k != 'container' && v[k] != '') {
+ if (z != '') {
+ z += '&';
+ }
+ var vk = v[k];
+ if (vk == true) {
+ vk = 1;
+ }
+ if (vk == false) {
+ vk = 0;
+ }
+ z += k + '=' + vk;
+ }
+
+ }
+ if (!v.hasOwnProperty('volume') || !v['volume']) {
+ if (z != '') {
+ z += '&';
+ }
+ z += 'volume=0';
+ }
+ return z;
+ },
+ /*判断字符串是否是图片*/
+ isStrImage: function(s) {
+ if (s == 'jpg' || s == 'jpeg' || s == 'png' || s == 'svg' || s == 'gif') {
+ return true;
+ }
+ return false;
+ },
+ /*
+ 内置函数
+ 将vars格式化成flash能接受的对象。再由getFlashVars函数转化成字符串或由newVideo直接使用
+ */
+ getVarsObject: function() {
+ var v = this.vars;
+ var f = '',
+ d = '',
+ w = ''; //f=视频地址,d=清晰度地址,w=权重,z=最终地址
+ var arr = this.VA;
+ var prompt = v['promptSpot'];
+ var i = 0;
+ var video = this.vars['video'];
+ if (typeof(video) == 'object') { //对象或数组
+ if (!this.isUndefined(typeof(video.length))) { //说明是数组
+ var arr = video;
+ for (i = 0; i < arr.length; i++) {
+ var arr2 = arr[i];
+ if (arr2) {
+ if (f != '') {
+ f += this.ckplayerConfig['config']['split'];
+ d += ',';
+ w += ',';
+ v['type'] += this.ckplayerConfig['config']['split'];
+ }
+ f += encodeURIComponent(decodeURIComponent(arr2[0]));
+ d += arr2[2];
+ w += arr2[3];
+ v['type'] += arr2[1].replace('video/', '');
+ }
+ }
+ } else {
+ f = encodeURIComponent(decodeURIComponent(video['file']));
+ if (!this.isUndefined(video['type'])) {
+ v['type'] = video['type'];
+ }
+ d = '';
+ w = '';
+ }
+ } else {
+ f = encodeURIComponent(decodeURIComponent(video));
+ }
+ if (v['preview'] != null) {
+ v['previewscale'] = v['preview']['scale'];
+ v['preview'] = v['preview']['file'].join(',');
+
+ }
+ if (prompt != null) {
+ v['promptspot'] = '';
+ v['promptspottime'] = '';
+ for (i = 0; i < prompt.length; i++) {
+ if (v['promptspot'] != '') {
+ v['promptspot'] += ',';
+ v['promptspottime'] += ',';
+ }
+ v['promptspot'] += prompt[i]['words'];
+ v['promptspottime'] += prompt[i]['time'];
+ }
+
+ }
+ if (f != '') {
+ v['video'] = f;
+ v['definition'] = d;
+ v['weight'] = w;
+ }
+ if (!v['volume']) {
+ v['volume'] = 0;
+ }
+ var newV = {};
+
+ for (var k in v) {
+ if (v[k] != null) {
+ newV[k] = v[k];
+ }
+ if (k == 'type') {
+ newV[k] = v[k].replace('video/m3u8', 'm3u8');
+ }
+ }
+
+ this.vars = newV;
+ },
+ /*
+ 内置函数
+ 将embedSWF里的param的对象进行转换
+ */
+ getFlashplayerParam: function() {
+ var w = '',
+ v = '',
+ o = {
+ allowScriptAccess: 'always',
+ allowFullScreen: true,
+ quality: 'high',
+ bgcolor: '#000'
+ };
+ for (var e in o) {
+ w += e + '="' + o[e] + '" ';
+ v += ' ';
+ }
+ w = w.replace('movie=', 'src=');
+ return {
+ w: w,
+ v: v
+ };
+ },
+
+ /*
+ 操作动作结束
+ -----------------------------------------------------------------------
+
+ 接口函数
+ 获取元数据部分
+ */
+ getMetaDate: function() {
+ if (!this.loaded || this.V == null) {
+ return false;
+ }
+ if (this.playerType == 'html5video') {
+ var duration = 0;
+ try {
+ duration = !isNaN(this.V.duration) ? this.V.duration: 0;
+ } catch(event) {
+ this.log(event);
+ }
+ var data = {
+ duration: duration,
+ volume: this.V.volume,
+ playbackRate: this.V.playbackRate,
+ width: this.PD.offsetWidth || this.V.offsetWidth || this.V.width,
+ height: this.PD.offsetHeight || this.V.offsetHeight || this.V.height,
+ streamWidth: this.V.videoWidth,
+ streamHeight: this.V.videoHeight,
+ videoWidth: this.V.offsetWidth,
+ videoHeight: this.V.offsetHeight,
+ paused: this.V.paused
+ };
+ return data;
+ } else {
+ try {
+ return this.V.getMetaDate();
+ } catch(event) {
+ this.log(event);
+ }
+ }
+ return false;
+ },
+ /*
+ 接口函数
+ 取当前提供给播放器播放的视频列表
+ */
+ getVideoUrl: function() {
+ if (this.playerType == 'flashplayer') {
+ return this.V.getVideoUrl();
+ }
+ var arr = [];
+ if (this.V.src) {
+ arr.push(this.V.src);
+ } else {
+ var uArr = this.V.childNodes;
+ for (var i = 0; i < uArr.length; i++) {
+ arr.push(uArr[i].src);
+ }
+ }
+ return arr;
+ },
+ /*
+ 内置函数
+ 格式化函数
+ */
+ clickEvent: function(call) {
+ if (call == 'none' || call == '' || call == null) {
+ return {
+ type: 'none'
+ };
+ }
+ var callArr = call.split('->');
+ var type = '',
+ fun = '',
+ link = '',
+ target = '';
+ if (callArr.length == 2) {
+ var callM = callArr[0];
+ var callE = callArr[1];
+ if (!callE) {
+ return {
+ type: 'none'
+ };
+ }
+ var val = '';
+ var eArr = [];
+ type = callM;
+ switch (callM) {
+ case 'actionScript':
+ //trace(THIS.hasOwnProperty(callE));
+ if (callE.indexOf('(') > -1) {
+ eArr = callE.split('(');
+ callE = eArr[0];
+ val = eArr[1].replace(')', '');
+ }
+ if (val == '') {
+ fun = 'thisTemp.' + callE + '()';
+ } else {
+ fun = 'thisTemp.' + callE + '(' + val + ')';
+ }
+ break;
+ case 'javaScript':
+ if (callE.substr(0, 11) == '[flashvars]') {
+ callE = callE.substr(11);
+ if (this.vars.hasOwnProperty(callE)) {
+ callE = this.vars[callE];
+ } else {
+ break;
+ }
+
+ }
+ if (callE.indexOf('(') > -1) {
+ eArr = callE.split('(');
+ callE = eArr[0];
+ val = eArr[1].replace(')', '');
+ }
+ if (val == '') {
+ fun = callE + '()';
+ } else {
+ fun = callE + '(' + val + ')';
+ }
+ break;
+ case "link":
+ var callLink = (callE + ',').split(',');
+ if (callLink[0].substr(0, 11) == '[flashvars]') {
+ var fl = callLink[0].replace('[flashvars]', '');
+ if (this.vars.hasOwnProperty(fl)) {
+ callLink[0] = this.vars[fl];
+ } else {
+ break;
+ }
+ }
+ if (!callLink[1]) {
+ callLink[1] = '_blank';
+ }
+ link = callLink[0];
+ target = callLink[1];
+ break;
+ }
+ }
+ return {
+ type: type,
+ fun: fun,
+ link: link,
+ target: target
+ }
+ },
+ /*
+ 内置函数
+ 根据指定的align,valign,offsetX,offsetY计算坐标
+ */
+ getPosition: function(obj) {
+ /*
+ {
+ "align": "right",
+ "vAlign": "right",
+ "offsetX": -60,
+ "offsetY": -60
+ }
+ */
+ var pw = this.PD.offsetWidth,
+ ph = this.PD.offsetHeight;
+ var x = 0,
+ y = 0;
+ switch (obj['align']) {
+ case 'left':
+ x = obj['offsetX'];
+ break;
+ case 'center':
+ x = pw * 0.5 + obj['offsetX'];
+ break;
+ case 'right':
+ x = pw + obj['offsetX'];
+ break;
+ }
+ switch (obj['vAlign']) {
+ case 'top':
+ y = obj['offsetY'];
+ break;
+ case 'middle':
+ y = ph * 0.5 + obj['offsetY'];
+ break;
+ case 'bottom':
+ y = ph + obj['offsetY'];
+ break;
+ }
+ return {
+ x: x,
+ y: y
+ };
+ },
+ /*
+ 内置函数
+ 向播放器界面添加一个文本
+ */
+ addElement: function(attribute) {
+ var thisTemp = this;
+ if (this.playerType == 'flashplayer') {
+ return this.V.addElement(attribute);
+ }
+ var i = 0;
+ var obj = {
+ list: null,
+ x: '100%',
+ y: "50%",
+ position: null,
+ alpha: 1,
+ backgroundColor: '',
+ backAlpha: 1,
+ backRadius: 0,
+ clickEvent: ''
+ };
+ obj = this.standardization(obj, attribute);
+ var list = obj['list'];
+ if (list == null) {
+ return '';
+ }
+ var id = 'element' + this.randomString(10);
+ var ele = document.createElement('div');
+ ele.className = id;
+ if (obj['x']) {
+ ele.setAttribute('data-x', obj['x']);
+ }
+ if (obj['y']) {
+ ele.setAttribute('data-y', obj['y']);
+ }
+ if (obj['position'] != null) {
+ ele.setAttribute('data-position', obj['position'].join(','));
+ }
+
+ this.PD.appendChild(ele);
+ var eid = this.getByElement(id);
+ this.css(eid, {
+ position: 'absolute',
+ filter: 'alpha(opacity:' + obj['alpha'] + ')',
+ opacity: obj['alpha'].toString(),
+ width: '800px',
+ zIndex: '20'
+ });
+ var bgid = 'elementbg' + this.randomString(10);
+ var bgAlpha = obj['alpha'].toString();
+ var bgColor = obj['backgroundColor'].replace('0x', '#');
+ var html = '';
+ var idArr = [];
+ var clickArr = [];
+ if (!this.isUndefined(list) && list.length > 0) {
+ var textObj, returnObj, clickEvent;
+ for (i = 0; i < list.length; i++) {
+ var newEleid = 'elementnew' + this.randomString(10);
+ switch (list[i]['type']) {
+ case 'image':
+ case 'png':
+ case 'jpg':
+ case 'jpeg':
+ case 'gif':
+ textObj = {
+ type: 'image',
+ file: '',
+ radius: 0,
+ //圆角弧度
+ width: 30,
+ //定义宽,必需要定义
+ height: 30,
+ //定义高,必需要定义
+ alpha: 1,
+ //透明度
+ paddingLeft: 0,
+ //左边距离
+ paddingRight: 0,
+ //右边距离
+ paddingTop: 0,
+ paddingBottom: 0,
+ marginLeft: 0,
+ marginRight: 0,
+ marginTop: 0,
+ marginBottom: 0,
+ backgroundColor: '',
+ clickEvent: ''
+ };
+
+ list[i] = this.standardization(textObj, list[i]);
+ clickEvent = this.clickEvent(list[i]['clickEvent']);
+ clickArr.push(clickEvent);
+ if (clickEvent['type'] == 'link') {
+ html += '';
+ } else {
+ html += '';
+ }
+ break;
+ case 'text':
+ textObj = {
+ type: 'text',
+ //说明是文本
+ text: '',
+ //文本内容
+ color: '0xFFFFFF',
+ size: 14,
+ font: this.fontFamily,
+ leading: 0,
+ alpha: 1,
+ //透明度
+ paddingLeft: 0,
+ //左边距离
+ paddingRight: 0,
+ //右边距离
+ paddingTop: 0,
+ paddingBottom: 0,
+ marginLeft: 0,
+ marginRight: 0,
+ marginTop: 0,
+ marginBottom: 0,
+ backgroundColor: '',
+ backAlpha: 1,
+ backRadius: 0,
+ //背景圆角弧度,支持数字统一设置,也支持分开设置[30,20,20,50],对应上左,上右,下右,下左
+ clickEvent: ''
+ };
+ list[i] = this.standardization(textObj, list[i]);
+ clickEvent = this.clickEvent(list[i]['clickEvent']);
+ clickArr.push(clickEvent);
+ if (clickEvent['type'] == 'link') {
+ html += '';
+ } else {
+ html += '';
+ }
+ break;
+ default:
+ break;
+ }
+ idArr.push(newEleid);
+ }
+ }
+ var objClickEvent = this.clickEvent(obj['clickEvent']);
+ /*if(objClickEvent['type']=='link'){
+ html = '' + html + ' ';
+ }*/
+ eid.innerHTML = '
' + html + '
';
+ if (objClickEvent['type'] == 'javaScript' || objClickEvent['type'] == 'actionScript') {
+ var objClickHandler = function() {
+ eval(objClickEvent['fun']);
+ thisTemp.sendJS('clickEvent', clk['type'] + '->' + clk['fun'].replace('thisTemp.', '').replace('()', ''));
+ };
+ this.addListenerInside('click', objClickHandler, this.getByElement(bgid + '_c'))
+ }
+ this.css(bgid + '_c', {
+ position: 'absolute',
+ zIndex: '2'
+ });
+ for (i = 0; i < idArr.length; i++) {
+ var clk = clickArr[i];
+
+ if (clk['type'] == 'javaScript' || clk['type'] == 'actionScript') {
+ var clickHandler = function() {
+ clk = clickArr[this.getAttribute('data-i')];
+ eval(clk['fun']);
+ thisTemp.sendJS('clickEvent', clk['type'] + '->' + clk['fun'].replace('thisTemp.', '').replace('()', ''));
+ };
+ this.addListenerInside('click', clickHandler, this.getByElement(idArr[i]))
+ }
+ switch (list[i]['type']) {
+ case 'image':
+ case 'png':
+ case 'jpg':
+ case 'jpeg':
+ case 'gif':
+ this.css(idArr[i], {
+ float: 'left',
+ width: list[i]['width'] + 'px',
+ height: list[i]['height'] + 'px',
+ filter: 'alpha(opacity:' + list[i]['alpha'] + ')',
+ opacity: list[i]['alpha'].toString(),
+ marginLeft: list[i]['marginLeft'] + 'px',
+ marginRight: list[i]['marginRight'] + 'px',
+ marginTop: list[i]['marginTop'] + 'px',
+ marginBottom: list[i]['marginBottom'] + 'px',
+ borderRadius: list[i]['radius'] + 'px',
+ cursor: 'pointer'
+ });
+ this.css(idArr[i] + '_image', {
+ width: list[i]['width'] + 'px',
+ height: list[i]['height'] + 'px',
+ borderRadius: list[i]['radius'] + 'px'
+ });
+ break;
+ case 'text':
+ this.css(idArr[i] + '_text', {
+ filter: 'alpha(opacity:' + list[i]['alpha'] + ')',
+ opacity: list[i]['alpha'].toString(),
+ borderRadius: list[i]['radius'] + 'px',
+ fontFamily: list[i]['font'],
+ fontSize: list[i]['size'] + 'px',
+ color: list[i]['color'].replace('0x', '#'),
+ lineHeight: list[i]['leading'] > 0 ? list[i]['leading'] + 'px': '',
+ paddingLeft: list[i]['paddingLeft'] + 'px',
+ paddingRight: list[i]['paddingRight'] + 'px',
+ paddingTop: list[i]['paddingTop'] + 'px',
+ paddingBottom: list[i]['paddingBottom'] + 'px',
+ whiteSpace: 'nowrap',
+ position: 'absolute',
+ zIndex: '3',
+ cursor: 'pointer'
+ });
+ this.css(idArr[i], {
+ float: 'left',
+ width: this.getByElement(idArr[i] + '_text').offsetWidth + 'px',
+ height: this.getByElement(idArr[i] + '_text').offsetHeight + 'px',
+ marginLeft: list[i]['marginLeft'] + 'px',
+ marginRight: list[i]['marginRight'] + 'px',
+ marginTop: list[i]['marginTop'] + 'px',
+ marginBottom: list[i]['marginBottom'] + 'px'
+ });
+ this.css(idArr[i] + '_bg', {
+ width: this.getByElement(idArr[i] + '_text').offsetWidth + 'px',
+ height: this.getByElement(idArr[i] + '_text').offsetHeight + 'px',
+ filter: 'alpha(opacity:' + list[i]['backAlpha'] + ')',
+ opacity: list[i]['backAlpha'].toString(),
+ borderRadius: list[i]['backRadius'] + 'px',
+ backgroundColor: list[i]['backgroundColor'].replace('0x', '#'),
+ position: 'absolute',
+ zIndex: '2'
+ });
+ break;
+ default:
+ break;
+ }
+ }
+ this.css(bgid, {
+ width: this.getByElement(bgid + '_c').offsetWidth + 'px',
+ height: this.getByElement(bgid + '_c').offsetHeight + 'px',
+ position: 'absolute',
+ filter: 'alpha(opacity:' + bgAlpha + ')',
+ opacity: bgAlpha,
+ backgroundColor: bgColor.replace('0x', '#'),
+ borderRadius: obj['backRadius'] + 'px',
+ zIndex: '1'
+ });
+ this.css(eid, {
+ width: this.getByElement(bgid).offsetWidth + 'px',
+ height: this.getByElement(bgid).offsetHeight + 'px'
+ });
+ var eidCoor = this.calculationCoor(eid);
+ this.css(eid, {
+ left: eidCoor['x'] + 'px',
+ top: eidCoor['y'] + 'px'
+ });
+
+ this.elementArr.push(eid.className);
+ return eid;
+ },
+ /*
+ 内置函数
+ 获取元件的属性,包括x,y,width,height,alpha
+ */
+ getElement: function(element) {
+ if (this.playerType == 'flashplayer') {
+ return this.V.getElement(element);
+ }
+ var ele = element;
+ if (typeof(element) == 'string') {
+ ele = this.getByElement(element);
+ }
+ var coor = this.getCoor(ele);
+ return {
+ x: coor['x'],
+ y: coor['y'],
+ width: ele.offsetWidth,
+ height: ele.offsetHeight,
+ alpha: !this.isUndefined(this.css(ele, 'opacity')) ? parseFloat(this.css(ele, 'opacity')) : 1,
+ show: this.css(ele, 'display') == 'none' ? false: true
+ };
+ },
+ /*
+ 内置函数
+ 控制元件显示和隐藏
+ */
+ elementShow: function(element, show) {
+ if (this.playerType == 'flashplayer') {
+ this.V.elementShow(element, show);
+ return;
+ }
+ if (typeof(element) == 'string') {
+ if (element) {
+ this.css(ele, 'display', show == true ? 'block': 'none');
+ } else {
+ var arr = this.elementTempArr;
+ for (var i = 0; i < arr.length; i++) {
+ this.css(arr[i], 'display', show == true ? 'block': 'none');
+ }
+ }
+ }
+
+ },
+ /*
+ 内置函数
+ 根据节点的x,y计算在播放器里的坐标
+ */
+ calculationCoor: function(ele) {
+ if (this.playerType == 'flashplayer') {
+ return this.V.calculationCoor(ele);
+ }
+ if (ele == []) {
+ return;
+ }
+ var x, y, position = [];
+ var w = this.PD.offsetWidth,
+ h = this.PD.offsetHeight;
+ var ew = ele.offsetWidth,
+ eh = ele.offsetHeight;
+ if (!this.isUndefined(this.getDataset(ele, 'x'))) {
+ x = this.getDataset(ele, 'x');
+ }
+ if (!this.isUndefined(this.getDataset(ele, 'y'))) {
+ y = this.getDataset(ele, 'y');
+ }
+ if (!this.isUndefined(this.getDataset(ele, 'position'))) {
+ try {
+ position = this.getDataset(ele, 'position').toString().split(',');
+ } catch(event) {}
+ }
+ if (position.length > 0) {
+ position.push(null, null, null, null);
+ var i = 0;
+ for (i = 0; i < position.length; i++) {
+ if (this.isUndefined(position[i]) || position[i] == null || position[i] == 'null' || position[i] == '') {
+ position[i] = null;
+ } else {
+ position[i] = parseFloat(position[i]);
+ }
+ }
+
+ if (position[2] == null) {
+ switch (position[0]) {
+ case 0:
+ x = 0;
+ break;
+ case 1:
+ x = parseInt((w - ew) * 0.5);
+ break;
+ default:
+ x = w - ew;
+ break;
+ }
+ } else {
+ switch (position[0]) {
+ case 0:
+ x = position[2];
+ break;
+ case 1:
+ x = parseInt(w * 0.5) + position[2];
+ break;
+ default:
+ x = w + position[2];
+ break;
+ }
+ }
+ if (position[3] == null) {
+ switch (position[1]) {
+ case 0:
+ y = 0;
+ break;
+ case 1:
+ y = parseInt((h - eh) * 0.5);
+ break;
+ default:
+ y = h - eh;
+ break;
+ }
+ } else {
+ switch (position[1]) {
+ case 0:
+ y = position[3];
+ break;
+ case 1:
+ y = parseInt(h * 0.5) + position[3];
+ break;
+ default:
+ y = h + position[3];
+ break;
+ }
+ }
+ } else {
+ if (x.substring(x.length - 1, x.length) == '%') {
+ x = Math.floor(parseInt(x.substring(0, x.length - 1)) * w * 0.01);
+ }
+ if (y.substring(y.length - 1, y.length) == '%') {
+ y = Math.floor(parseInt(y.substring(0, y.length - 1)) * h * 0.01);
+ }
+ }
+ return {
+ x: x,
+ y: y
+ }
+
+ },
+ /*
+ 内置函数
+ 修改新增元件的坐标
+ */
+ changeElementCoor: function() {
+ for (var i = 0; i < this.elementArr.length; i++) {
+ if (this.getByElement(this.elementArr[i]) != []) {
+ var c = this.calculationCoor(this.getByElement(this.elementArr[i]));
+ if (c['x'] && c['y']) {
+ this.css(this.elementArr[i], {
+ top: c['y'] + 'px',
+ left: c['x'] + 'px'
+ });
+ }
+ }
+ }
+ },
+ /*
+ 内置函数
+ 缓动效果集
+ */
+ tween: function() {
+ var Tween = {
+ None: { //均速运动
+ easeIn: function(t, b, c, d) {
+ return c * t / d + b;
+ },
+ easeOut: function(t, b, c, d) {
+ return c * t / d + b;
+ },
+ easeInOut: function(t, b, c, d) {
+ return c * t / d + b;
+ }
+ },
+ Quadratic: {
+ easeIn: function(t, b, c, d) {
+ return c * (t /= d) * t + b;
+ },
+ easeOut: function(t, b, c, d) {
+ return - c * (t /= d) * (t - 2) + b;
+ },
+ easeInOut: function(t, b, c, d) {
+ if ((t /= d / 2) < 1) return c / 2 * t * t + b;
+ return - c / 2 * ((--t) * (t - 2) - 1) + b;
+ }
+ },
+ Cubic: {
+ easeIn: function(t, b, c, d) {
+ return c * (t /= d) * t * t + b;
+ },
+ easeOut: function(t, b, c, d) {
+ return c * ((t = t / d - 1) * t * t + 1) + b;
+ },
+ easeInOut: function(t, b, c, d) {
+ if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
+ return c / 2 * ((t -= 2) * t * t + 2) + b;
+ }
+ },
+ Quartic: {
+ easeIn: function(t, b, c, d) {
+ return c * (t /= d) * t * t * t + b;
+ },
+ easeOut: function(t, b, c, d) {
+ return - c * ((t = t / d - 1) * t * t * t - 1) + b;
+ },
+ easeInOut: function(t, b, c, d) {
+ if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
+ return - c / 2 * ((t -= 2) * t * t * t - 2) + b;
+ }
+ },
+ Quintic: {
+ easeIn: function(t, b, c, d) {
+ return c * (t /= d) * t * t * t * t + b;
+ },
+ easeOut: function(t, b, c, d) {
+ return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
+ },
+ easeInOut: function(t, b, c, d) {
+ if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
+ return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
+ }
+ },
+ Sine: {
+ easeIn: function(t, b, c, d) {
+ return - c * Math.cos(t / d * (Math.PI / 2)) + c + b;
+ },
+ easeOut: function(t, b, c, d) {
+ return c * Math.sin(t / d * (Math.PI / 2)) + b;
+ },
+ easeInOut: function(t, b, c, d) {
+ return - c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
+ }
+ },
+ Exponential: {
+ easeIn: function(t, b, c, d) {
+ return (t == 0) ? b: c * Math.pow(2, 10 * (t / d - 1)) + b;
+ },
+ easeOut: function(t, b, c, d) {
+ return (t == d) ? b + c: c * ( - Math.pow(2, -10 * t / d) + 1) + b;
+ },
+ easeInOut: function(t, b, c, d) {
+ if (t == 0) return b;
+ if (t == d) return b + c;
+ if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
+ return c / 2 * ( - Math.pow(2, -10 * --t) + 2) + b;
+ }
+ },
+ Circular: {
+ easeIn: function(t, b, c, d) {
+ return - c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
+ },
+ easeOut: function(t, b, c, d) {
+ return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
+ },
+ easeInOut: function(t, b, c, d) {
+ if ((t /= d / 2) < 1) return - c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
+ return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
+ }
+ },
+ Elastic: {
+ easeIn: function(t, b, c, d, a, p) {
+ if (t == 0) return b;
+ if ((t /= d) == 1) return b + c;
+ if (!p) p = d * .3;
+ if (!a || a < Math.abs(c)) {
+ a = c;
+ var s = p / 4;
+ } else var s = p / (2 * Math.PI) * Math.asin(c / a);
+ return - (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
+ },
+ easeOut: function(t, b, c, d, a, p) {
+ if (t == 0) return b;
+ if ((t /= d) == 1) return b + c;
+ if (!p) p = d * .3;
+ if (!a || a < Math.abs(c)) {
+ a = c;
+ var s = p / 4;
+ } else var s = p / (2 * Math.PI) * Math.asin(c / a);
+ return (a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b);
+ },
+ easeInOut: function(t, b, c, d, a, p) {
+ if (t == 0) return b;
+ if ((t /= d / 2) == 2) return b + c;
+ if (!p) p = d * (.3 * 1.5);
+ if (!a || a < Math.abs(c)) {
+ a = c;
+ var s = p / 4;
+ } else var s = p / (2 * Math.PI) * Math.asin(c / a);
+ if (t < 1) return - .5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
+ return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
+ }
+ },
+ Back: {
+ easeIn: function(t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ return c * (t /= d) * t * ((s + 1) * t - s) + b;
+ },
+ easeOut: function(t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
+ },
+ easeInOut: function(t, b, c, d, s) {
+ if (s == undefined) s = 1.70158;
+ if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
+ return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
+ }
+ },
+ Bounce: {
+ easeIn: function(t, b, c, d) {
+ return c - Tween.Bounce.easeOut(d - t, 0, c, d) + b;
+ },
+ easeOut: function(t, b, c, d) {
+ if ((t /= d) < (1 / 2.75)) {
+ return c * (7.5625 * t * t) + b;
+ } else if (t < (2 / 2.75)) {
+ return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
+ } else if (t < (2.5 / 2.75)) {
+ return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
+ } else {
+ return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
+ }
+ },
+ easeInOut: function(t, b, c, d) {
+ if (t < d / 2) return Tween.Bounce.easeIn(t * 2, 0, c, d) * .5 + b;
+ else return Tween.Bounce.easeOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
+ }
+ }
+ };
+ return Tween;
+ },
+ /*
+ 接口函数
+ 缓动效果
+ ele:Object=需要缓动的对象,
+ parameter:String=需要改变的属性:x,y,width,height,alpha,
+ effect:String=效果名称,
+ start:Int=起始值,
+ end:Int=结束值,
+ speed:Number=运动的总秒数,支持小数
+ */
+ animate: function(attribute) {
+ if (this.playerType == 'flashplayer') {
+ return this.V.animate(attribute);
+ }
+ var thisTemp = this;
+ var animateId = 'animate_' + this.randomString();
+ var obj = {
+ element: null,
+ parameter: 'x',
+ static: false,
+ effect: 'None.easeIn',
+ start: null,
+ end: null,
+ speed: 0,
+ overStop: false,
+ pauseStop: false,
+ //暂停播放时缓动是否暂停
+ callBack: null
+ };
+ obj = this.standardization(obj, attribute);
+ if (obj['element'] == null || obj['speed'] == 0) {
+ return false;
+ }
+ var w = this.PD.offsetWidth,
+ h = this.PD.offsetHeight;
+ var effArr = (obj['effect'] + '.').split('.');
+ var tweenFun = this.tween()[effArr[0]][effArr[1]];
+ var eleCoor = {
+ x: 0,
+ y: 0
+ };
+ if (this.isUndefined(tweenFun)) {
+ return false;
+ }
+ //先将该元件从元件数组里删除,让其不再跟随播放器的尺寸改变而改变位置
+ var def = this.arrIndexOf(this.elementArr, obj['element'].className);
+ if (def > -1) {
+ this.elementTempArr.push(obj['element'].className);
+ this.elementArr.splice(def, 1);
+ }
+ //var run = true;
+ var css = {};
+ //对传递的参数进行转化,x和y转化成left,top
+ var pm = this.getElement(obj['element']); //包含x,y,width,height,alpha属性
+ var t = 0; //当前时间
+ var b = 0; //初始值
+ var c = 0; //变化量
+ var d = obj['speed'] * 1000; //持续时间
+ var timerTween = null;
+ var tweenObj = null;
+ var start = obj['start'] == null ? '': obj['start'].toString();
+ var end = obj['end'] == null ? '': obj['end'].toString();
+ switch (obj['parameter']) {
+ case 'x':
+ if (obj['start'] == null) {
+ b = pm['x'];
+ } else {
+ if (start.substring(start.length - 1, start.length) == '%') {
+ b = parseInt(start) * w * 0.01;
+ } else {
+ b = parseInt(start);
+ }
+
+ }
+ if (obj['end'] == null) {
+ c = pm['x'] - b;
+ } else {
+ if (end.substring(end.length - 1, end.length) == '%') {
+ c = parseInt(end) * w * 0.01 - b;
+ } else if (end.substring(0, 1) == '-' || end.substring(0, 1) == '+') {
+ if (typeof(obj['end']) == 'number') {
+ c = parseInt(obj['end']) - b;
+ } else {
+ c = parseInt(end);
+ }
+
+ } else {
+ c = parseInt(end) - b;
+ }
+ }
+ break;
+ case 'y':
+ if (obj['start'] == null) {
+ b = pm['y'];
+ } else {
+ if (start.substring(start.length - 1, start.length) == '%') {
+ b = parseInt(start) * h * 0.01;
+ } else {
+ b = parseInt(start);
+ }
+
+ }
+ if (obj['end'] == null) {
+ c = pm['y'] - b;
+ } else {
+ if (end.substring(end.length - 1, end.length) == '%') {
+ c = parseInt(end) * h * 0.01 - b;
+ } else if (end.substring(0, 1) == '-' || end.substring(0, 1) == '+') {
+ if (typeof(obj['end']) == 'number') {
+ c = parseInt(obj['end']) - b;
+ } else {
+ c = parseInt(end);
+ }
+ } else {
+ c = parseInt(end) - b;
+ }
+ }
+ break;
+ case 'alpha':
+ if (obj['start'] == null) {
+ b = pm['alpha'] * 100;
+ } else {
+ if (start.substring(start.length - 1, start.length) == '%') {
+ b = parseInt(obj['start']);
+ } else {
+ b = parseInt(obj['start'] * 100);
+ }
+
+ }
+ if (obj['end'] == null) {
+ c = pm['alpha'] * 100 - b;
+ } else {
+ if (end.substring(end.length - 1, end.length) == '%') {
+ c = parseInt(end) - b;
+ } else if (end.substring(0, 1) == '-' || end.substring(0, 1) == '+') {
+ if (typeof(obj['end']) == 'number') {
+ c = parseInt(obj['end']) * 100 - b;
+ } else {
+ c = parseInt(obj['end']) * 100;
+ }
+ } else {
+ c = parseInt(obj['end']) * 100 - b;
+ }
+ }
+ break;
+ }
+ var callBack = function() {
+ var index = thisTemp.arrIndexOf(thisTemp.animateElementArray, animateId);
+ if (index > -1) {
+ thisTemp.animateArray.splice(index, 1);
+ thisTemp.animateElementArray.splice(index, 1);
+ }
+ index = thisTemp.arrIndexOf(thisTemp.animatePauseArray, animateId);
+ if (index > -1) {
+ thisTemp.animatePauseArray.splice(index, 1);
+ }
+ if (obj['callBack'] != null && obj['element'] && obj['callBack'] != 'callBack' && obj['callBack'] != 'tweenX' && obj['tweenY'] != 'callBack' && obj['callBack'] != 'tweenAlpha') {
+ var cb = eval(obj['callBack']);
+ cb(obj['element']);
+ obj['callBack'] = null;
+ }
+ };
+ var stopTween = function() {
+ if (timerTween != null) {
+ if (timerTween.runing) {
+ timerTween.stop();
+ }
+ timerTween = null;
+ }
+ };
+ var tweenX = function() {
+ if (t < d) {
+ t += 10;
+ css = {
+ left: Math.ceil(tweenFun(t, b, c, d)) + 'px'
+ };
+ if (obj['static']) {
+ eleCoor = thisTemp.calculationCoor(obj['element']);
+ css['top'] = eleCoor['y'] + 'px';
+ }
+ thisTemp.css(obj['element'], css);
+
+ } else {
+ stopTween();
+ try {
+ var defX = this.arrIndexOf(this.elementTempArr, obj['element'].className);
+ if (defX > -1) {
+ this.elementTempArr.splice(defX, 1);
+ }
+ } catch(event) {}
+ thisTemp.elementArr.push(obj['element'].className);
+ callBack();
+ }
+ };
+ var tweenY = function() {
+ if (t < d) {
+ t += 10;
+ css = {
+ top: Math.ceil(tweenFun(t, b, c, d)) + 'px'
+ };
+ if (obj['static']) {
+ eleCoor = thisTemp.calculationCoor(obj['element']);
+ css['left'] = eleCoor['x'] + 'px';
+ }
+ thisTemp.css(obj['element'], css);
+ } else {
+ stopTween();
+ try {
+ var defY = this.arrIndexOf(this.elementTempArr, obj['element'].className);
+ if (defY > -1) {
+ this.elementTempArr.splice(defY, 1);
+ }
+ } catch(event) {}
+ thisTemp.elementArr.push(obj['element'].className);
+ callBack();
+ }
+ };
+ var tweenAlpha = function() {
+ if (t < d) {
+ t += 10;
+ eleCoor = thisTemp.calculationCoor(obj['element']);
+ var ap = Math.ceil(tweenFun(t, b, c, d)) * 0.01;
+ css = {
+ filter: 'alpha(opacity:' + ap + ')',
+ opacity: ap.toString()
+ };
+ if (obj['static']) {
+ eleCoor = thisTemp.calculationCoor(obj['element']);
+ css['top'] = eleCoor['y'] + 'px';
+ css['left'] = eleCoor['x'] + 'px';
+ }
+ thisTemp.css(obj['element'], css);
+ } else {
+ stopTween();
+ try {
+ var defA = this.arrIndexOf(this.elementTempArr, obj['element'].className);
+ if (defA > -1) {
+ this.elementTempArr.splice(defA, 1);
+ }
+ } catch(event) {}
+ thisTemp.elementArr.push(obj['element'].className);
+ callBack();
+ }
+ };
+ switch (obj['parameter']) {
+ case 'x':
+ tweenObj = tweenX;
+ break;
+ case 'y':
+ tweenObj = tweenY;
+ break;
+ case 'alpha':
+ tweenObj = tweenAlpha;
+ break;
+ default:
+ break;
+ }
+ timerTween = new thisTemp.timer(10, tweenObj);
+ timerTween.callBackFunction = callBack;
+ if (obj['overStop']) {
+ var mouseOver = function() {
+ if (timerTween != null && timerTween.runing) {
+ timerTween.stop();
+ }
+ };
+ this.addListenerInside('mouseover', mouseOver, obj['element']);
+ var mouseOut = function() {
+ var start = true;
+ if (obj['pauseStop'] && thisTemp.getMetaDate()['paused']) {
+ start = false;
+ }
+ if (timerTween != null && !timerTween.runing && start) {
+ timerTween.start();
+ }
+ };
+ this.addListenerInside('mouseout', mouseOut, obj['element']);
+ }
+
+ this.animateArray.push(timerTween);
+ this.animateElementArray.push(animateId);
+ if (obj['pauseStop']) {
+ this.animatePauseArray.push(animateId);
+ }
+ return animateId;
+ },
+ /*
+ 接口函数函数
+ 继续运行animate
+ */
+ animateResume: function(id) {
+ if (this.playerType == 'flashplayer') {
+ this.V.animateResume(this.isUndefined(id) ? '': id);
+ return;
+ }
+ var arr = [];
+ if (id != '' && !this.isUndefined(id) && id != 'pause') {
+ arr.push(id);
+ } else {
+ if (id === 'pause') {
+ arr = this.animatePauseArray;
+ } else {
+ arr = this.animateElementArray;
+ }
+ }
+ for (var i = 0; i < arr.length; i++) {
+ var index = this.arrIndexOf(this.animateElementArray, arr[i]);
+ if (index > -1) {
+ this.animateArray[index].start();
+ }
+ }
+
+ },
+ /*
+ 接口函数
+ 暂停运行animate
+ */
+ animatePause: function(id) {
+ if (this.playerType == 'flashplayer') {
+ this.V.animatePause(this.isUndefined(id) ? '': id);
+ return;
+ }
+ var arr = [];
+ if (id != '' && !this.isUndefined(id) && id != 'pause') {
+ arr.push(id);
+ } else {
+ if (id === 'pause') {
+ arr = this.animatePauseArray;
+ } else {
+ arr = this.animateElementArray;
+ }
+ }
+ for (var i = 0; i < arr.length; i++) {
+ var index = this.arrIndexOf(this.animateElementArray, arr[i]);
+ if (index > -1) {
+ this.animateArray[index].stop();
+ }
+ }
+ },
+ /*
+ 内置函数
+ 根据ID删除数组里对应的内容
+ */
+ deleteAnimate: function(id) {
+ if (this.playerType == 'flashplayer' && this.V) {
+ try {
+ this.V.deleteAnimate(id);
+ } catch(event) {
+ this.log(event);
+ }
+ return;
+ }
+ var index = this.arrIndexOf(this.animateElementArray, id);
+ if (index > -1) {
+ this.animateArray[index].callBackFunction();
+ this.animateArray.splice(index, 1);
+ this.animateElementArray.splice(index, 1);
+ }
+ },
+ /*
+ 内置函数
+ 删除外部新建的元件
+ */
+ deleteElement: function(ele) {
+ if (this.playerType == 'flashplayer' && this.V) {
+ try {
+ this.V.deleteElement(ele);
+ } catch(event) {}
+ return;
+ }
+ //先将该元件从元件数组里删除,让其不再跟随播放器的尺寸改变而改变位置
+ var def = this.arrIndexOf(this.elementArr, ele.className);
+ if (def > -1) {
+ this.elementArr.splice(def, 1);
+ }
+ try {
+ def = this.arrIndexOf(this.elementTempArr, ele.className);
+ if (def > -1) {
+ this.elementTempArr.splice(def, 1);
+ }
+ } catch(event) {}
+ this.deleteAnimate(ele);
+ this.deleteChild(ele);
+ },
+ /*
+ --------------------------------------------------------------
+ 共用函数部分
+ 以下函数并非只能在本程序中使用,也可以在页面其它项目中使用
+ 根据ID获取元素对象
+ */
+ getByElement: function(obj, parent) {
+ if (this.isUndefined(parent)) {
+ parent = document;
+ }
+ var num = obj.substr(0, 1);
+ var res = [];
+ if (num != '#') {
+ if (num == '.') {
+ obj = obj.substr(1, obj.length);
+ }
+ if (parent.getElementsByClassName) {
+ res = parent.getElementsByClassName(obj);
+ } else {
+ var reg = new RegExp(' ' + obj + ' ', 'i');
+ var ele = parent.getElementsByTagName('*');
+
+ for (var i = 0; i < ele.length; i++) {
+ if (reg.test(' ' + ele[i].className + ' ')) {
+ res.push(ele[i]);
+ }
+ }
+ }
+
+ if (res.length > 0) {
+ return res[0];
+ } else {
+ return res;
+ }
+ } else {
+ if (num == '#') {
+ obj = obj.substr(1, obj.length);
+ }
+ return document.getElementById(obj);
+ }
+ },
+ /*
+ 共用函数
+ 功能:修改样式或获取指定样式的值,
+ elem:ID对象或ID对应的字符,如果多个对象一起设置,则可以使用数组
+ attribute:样式名称或对象,如果是对象,则省略掉value值
+ value:attribute为样式名称时,定义的样式值
+ 示例一:
+ this.css(ID,'width','100px');
+ 示例二:
+ this.css('id','width','100px');
+ 示例三:
+ this.css([ID1,ID2,ID3],'width','100px');
+ 示例四:
+ this.css(ID,{
+ width:'100px',
+ height:'100px'
+ });
+ 示例五(获取宽度):
+ var width=this.css(ID,'width');
+ */
+ css: function(elem, attribute, value) {
+ var i = 0;
+ var k = '';
+ if (typeof(elem) == 'object') { //对象或数组
+ if (!this.isUndefined(typeof(elem.length))) { //说明是数组
+ for (i = 0; i < elem.length; i++) {
+ var el;
+ if (typeof(elem[i]) == 'string') {
+ el = this.getByElement(elem[i])
+ } else {
+ el = elem[i];
+ }
+ if (typeof(attribute) != 'object') {
+ if (!this.isUndefined(value)) {
+ el.style[attribute] = value;
+ }
+ } else {
+ for (k in attribute) {
+ if (!this.isUndefined(attribute[k])) {
+ try {
+ el.style[k] = attribute[k];
+ } catch(event) {
+ this.log(event);
+ }
+ }
+ }
+ }
+ }
+ return;
+ }
+
+ }
+ if (typeof(elem) == 'string') {
+ elem = this.getByElement(elem);
+ }
+ if (typeof(attribute) != 'object') {
+ if (!this.isUndefined(value)) {
+ elem.style[attribute] = value;
+ } else {
+ if (!this.isUndefined(this.getStyle(elem, attribute))) {
+ return this.getStyle(elem, attribute);
+ } else {
+ return false;
+ }
+ }
+ } else {
+ for (k in attribute) {
+ if (!this.isUndefined(attribute[k])) {
+ elem.style[k] = attribute[k];
+ }
+ }
+ }
+
+ },
+ /*
+ 内置函数
+ 兼容型获取style
+ */
+ getStyle: function(obj, attr) {
+ if (!this.isUndefined(obj.style[attr])) {
+ return obj.style[attr];
+ } else {
+ if (obj.currentStyle) {
+ return obj.currentStyle[attr];
+ } else {
+ return getComputedStyle(obj, false)[attr];
+ }
+ }
+ },
+ /*
+ 共用函数
+ 判断变量是否存在或值是否为undefined
+ */
+ isUndefined: function(value) {
+ try {
+ if (value == 'undefined' || value == undefined || value == null) {
+ return true;
+ }
+ } catch(event) {
+ this.log(event);
+ }
+ return false;
+ },
+ /*
+ 共用函数
+ 外部监听函数
+ */
+ addListener: function(name, funName) {
+ if (name && funName) {
+ if (this.playerType == 'flashplayer') {
+ var ff = ''; //定义用来向flashplayer传递的函数字符
+ if (typeof(funName) == 'function') {
+ ff = this.getParameterNames(funName);
+ }
+ this.V.addListener(name, ff);
+ return;
+ }
+ var have = false;
+ for (var i = 0; i < this.listenerJsArr.length; i++) {
+ var arr = this.listenerJsArr[i];
+ if (arr[0] == name && arr[1] == funName) {
+ have = true;
+ break;
+ }
+ }
+ if (!have) {
+ this.listenerJsArr.push([name, funName]);
+ }
+ }
+ },
+ /*
+ 共用函数
+ 外部删除监听函数
+ */
+ removeListener: function(name, funName) {
+ if (name && funName) {
+ if (this.playerType == 'flashplayer') {
+ var ff = ''; //定义用来向flashplayer传递的函数字符
+ if (typeof(funName) == 'function') {
+ ff = this.getParameterNames(funName);
+ }
+ this.V.removeListener(name, ff);
+ return;
+ }
+ for (var i = 0; i < this.listenerJsArr.length; i++) {
+ var arr = this.listenerJsArr[i];
+ if (arr[0] == name && arr[1] == funName) {
+ this.listenerJsArr.splice(i, 1);
+ break;
+ }
+ }
+ }
+ },
+ /*
+ 内部监听函数,调用方式:
+ this.addListenerInside('click',function(event){},[ID]);
+ d值为空时,则表示监听当前的视频播放器
+ */
+ addListenerInside: function(e, f, d, t) {
+ if (this.isUndefined(t)) {
+ t = false;
+ }
+ var o = this.V;
+ if (!this.isUndefined(d)) {
+ o = d;
+ }
+ if (o.addEventListener) {
+ try {
+ o.addEventListener(e, f, t);
+ } catch(event) {}
+ } else if (o.attachEvent) {
+ try {
+ o.attachEvent('on' + e, f);
+ } catch(event) {}
+ } else {
+ o['on' + e] = f;
+ }
+ },
+ /*
+ 删除内部监听函数,调用方式:
+ this.removeListenerInside('click',function(event){}[,ID]);
+ d值为空时,则表示监听当前的视频播放器
+ */
+ removeListenerInside: function(e, f, d, t) {
+ /*if(this.playerType=='flashplayer' && this.getParameterNames(f) && this.isUndefined(d)) {
+ return;
+ }*/
+ if (this.isUndefined(t)) {
+ t = false;
+ }
+ var o = this.V;
+ if (!this.isUndefined(d)) {
+ o = d;
+ }
+ if (o.removeEventListener) {
+ try {
+ this.addNum--;
+ o.removeEventListener(e, f, t);
+ } catch(e) {}
+ } else if (o.detachEvent) {
+ try {
+ o.detachEvent('on' + e, f);
+ } catch(e) {}
+ } else {
+ o['on' + e] = null;
+ }
+ },
+ /*
+ 共用函数
+ 统一分配监听,以达到跟as3同样效果
+ */
+ sendJS: function(name, val) {
+ if (this.adPlayerPlay && name.substr( - 2) != 'Ad') {
+ return;
+ }
+ var list = this.listenerJsArr;
+ var obj = {
+ variable: this.vars['variable']
+ };
+ if (this.vars['playerID']) {
+ obj['playerID'] = this.vars['playerID'];
+ }
+ for (var i = 0; i < list.length; i++) {
+ var arr = list[i];
+ if (arr[0] == name) {
+ if (val) {
+ switch (arr[1].length) {
+ case 1:
+ arr[1](val);
+ break;
+ case 2:
+ arr[1](val, obj);
+ break;
+ default:
+ arr[1]();
+ break;
+ }
+
+ } else {
+ switch (arr[1].length) {
+ case 1:
+ if (typeof(val) == 'boolean') {
+ arr[1](false);
+ } else {
+ arr[1](obj);
+ }
+ break;
+ default:
+ arr[1]();
+ break;
+ }
+
+ }
+ }
+ }
+ },
+ /*
+ 共用函数
+ 获取函数名称,如 function ckplayer(){} var fun=ckplayer,则getParameterNames(fun)=ckplayer
+ */
+ getParameterNames: function(fn) {
+ if (typeof(fn) !== 'function') {
+ return false;
+ }
+ var COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
+ var code = fn.toString().replace(COMMENTS, '');
+ var result = code.slice(code.indexOf(' ') + 1, code.indexOf('('));
+ return result === null ? false: result;
+ },
+ /*
+ 共用函数
+ 获取当前本地时间
+ */
+ getNowDate: function() {
+ var nowDate = new Date();
+ var month = nowDate.getMonth() + 1;
+ var date = nowDate.getDate();
+ var hours = nowDate.getHours();
+ var minutes = nowDate.getMinutes();
+ var seconds = nowDate.getSeconds();
+ var tMonth = '',
+ tDate = '',
+ tHours = '',
+ tMinutes = '',
+ tSeconds = '',
+ tSeconds = (seconds < 10) ? '0' + seconds: seconds + '',
+ tMinutes = (minutes < 10) ? '0' + minutes: minutes + '',
+ tHours = (hours < 10) ? '0' + hours: hours + '',
+ tDate = (date < 10) ? '0' + date: date + '',
+ tMonth = (month < 10) ? '0' + month: month + '';
+ return tMonth + '/' + tDate + ' ' + tHours + ':' + tMinutes + ':' + tSeconds;
+ },
+ /*
+ 共用函数
+ 格式化时分秒
+ seconds:Int:秒数
+ ishours:Boolean:是否显示小时,如果设置成false,则会显示如80:20,表示1小时20分钟20秒
+ */
+ formatTime: function(seconds, ishours) {
+ var tSeconds = '',
+ tMinutes = '',
+ tHours = '';
+ if (isNaN(seconds)) {
+ seconds = 0;
+ }
+ var s = Math.floor(seconds % 60),
+ m = 0,
+ h = 0;
+ if (ishours) {
+ m = Math.floor(seconds / 60) % 60;
+ h = Math.floor(seconds / 3600);
+ } else {
+ m = Math.floor(seconds / 60);
+ }
+ tSeconds = (s < 10) ? '0' + s: s + '';
+ tMinutes = (m > 0) ? ((m < 10) ? '0' + m + ':': m + ':') : '00:';
+ tHours = (h > 0) ? ((h < 10) ? '0' + h + ':': h + ':') : '';
+ if (ishours) {
+ return tHours + tMinutes + tSeconds;
+ } else {
+ return tMinutes + tSeconds;
+ }
+ },
+ /*
+ 共用函数
+ 获取一个随机字符
+ len:随机字符长度
+ */
+ randomString: function(len) {
+ len = len || 16;
+ var chars = 'abcdefghijklmnopqrstuvwxyz';
+ var maxPos = chars.length;
+ var val = '';
+ for (i = 0; i < len; i++) {
+ val += chars.charAt(Math.floor(Math.random() * maxPos));
+ }
+ return 'ch' + val;
+ },
+ /*
+ 共用函数
+ 获取字符串长度,中文算两,英文数字算1
+ */
+ getStringLen: function(str) {
+ var len = 0;
+ for (var i = 0; i < str.length; i++) {
+ if (str.charCodeAt(i) > 127 || str.charCodeAt(i) == 94) {
+ len += 2;
+ } else {
+ len++;
+ }
+ }
+ return len;
+ },
+ /*
+ 内部函数
+ 用来为ajax提供支持
+ */
+ createXHR: function() {
+ if (window.XMLHttpRequest) {
+ //IE7+、Firefox、Opera、Chrome 和Safari
+ return new XMLHttpRequest();
+ } else if (window.ActiveXObject) {
+ //IE6 及以下
+ try {
+ return new ActiveXObject('Microsoft.XMLHTTP');
+ } catch(event) {
+ try {
+ return new ActiveXObject('Msxml2.XMLHTTP');
+ } catch(event) {
+ this.eject(this.errorList[7]);
+ }
+ }
+ } else {
+ this.eject(this.errorList[8]);
+ }
+ },
+ /*
+ 共用函数
+ ajax调用
+ */
+ ajax: function(cObj) {
+ var thisTemp = this;
+ var callback = null;
+ var obj = {
+ method: 'get',
+ //请求类型
+ dataType: 'json',
+ //请求的数据类型
+ charset: 'utf-8',
+ async: false,
+ //true表示异步,false表示同步
+ url: '',
+ data: null,
+ success: null
+ };
+ if (typeof(cObj) != 'object') {
+ this.eject(this.errorList[9]);
+ return;
+ }
+ obj = this.standardization(obj, cObj);
+ if (obj.dataType === 'json' || obj.dataType === 'text' || obj.dataType === 'html') {
+ var xhr = this.createXHR();
+ callback = function() {
+ //判断http的交互是否成功
+ if (xhr.status == 200) {
+ if (thisTemp.isUndefined(obj.success)) {
+ return;
+ }
+ if (obj.dataType === 'json') {
+ try {
+ obj.success(eval('(' + xhr.responseText + ')')); //回调传递参数
+ } catch(event) {
+ obj.success(null);
+ }
+ } else {
+ obj.success(xhr.responseText); //回调传递参数
+ }
+ } else {
+ thisTemp.eject(thisTemp.errorList[10], 'Ajax.status:' + xhr.status);
+ }
+ };
+ obj.url = obj.url.indexOf('?') == -1 ? obj.url + '?rand=' + this.randomString(6) : obj.url;
+ obj.data = this.formatParams(obj.data); //通过params()将名值对转换成字符串
+ if (obj.method === 'get' && !this.isUndefined(obj.data)) {
+ if (obj.data != '') {
+ if (obj.url.indexOf('?') == -1) {
+ obj.url += '?' + obj.data
+ } else {
+ obj.url += '&' + obj.data;
+ }
+ }
+ }
+ if (obj.async === true) { //true表示异步,false表示同步
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState == 4 && callback != null) { //判断对象的状态是否交互完成
+ callback(); //回调
+ }
+ };
+ }
+ xhr.open(obj.method, obj.url, obj.async);
+ if (obj.method === 'post') {
+ xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ xhr.setRequestHeader('charset', obj['charset']);
+ xhr.send(obj.data);
+ } else {
+ xhr.send(null); //get方式则填null
+ }
+ if (obj.async === false) { //同步
+ callback();
+ }
+
+ } else if (obj.dataType === 'jsonp') {
+ var oHead = document.getElementsByTagName('head')[0];
+ var oScript = document.createElement('script');
+ var callbackName = 'callback' + new Date().getTime();
+ var params = this.formatParams(obj.data) + '&callback=' + callbackName; //按时间戳拼接字符串
+ callback = obj.success;
+ //拼接好src
+ oScript.src = obj.url.split('?') + '?' + params;
+ //插入script标签
+ oHead.insertBefore(oScript, oHead.firstChild);
+ //jsonp的回调函数
+ window[callbackName] = function(json) {
+ callback(json);
+ oHead.removeChild(oScript);
+ };
+ }
+ },
+ /*
+ 内置函数
+ 动态加载js
+ */
+ loadJs: function(path, success) {
+ var oHead = document.getElementsByTagName('HEAD').item(0);
+ var oScript = document.createElement('script');
+ oScript.type = 'text/javascript';
+ oScript.src = this.getNewUrl(path);
+ oHead.appendChild(oScript);
+ oScript.onload = function() {
+ success();
+ }
+ },
+ /*
+ 共用函数
+ 排除IE6-9
+ */
+ isMsie: function() {
+ var browser = navigator.appName;
+ var b_version = navigator.appVersion;
+ var version = b_version.split(';');
+ var trim_Version = '';
+ if (version.length > 1) {
+ trim_Version = version[1].replace(/[ ]/g, '');
+ }
+ if (browser == 'Microsoft Internet Explorer' && (trim_Version == 'MSIE6.0' || trim_Version == 'MSIE7.0' || trim_Version == 'MSIE8.0' || trim_Version == 'MSIE9.0' || trim_Version == 'MSIE10.0')) {
+ return false;
+ }
+ return true;
+ },
+ /*
+ 共用函数
+ 判断是否安装了flashplayer
+ */
+ uploadFlash: function() {
+ var swf;
+ if (navigator.userAgent.indexOf('MSIE') > 0) {
+ try {
+ var swf = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');
+ return true;
+ } catch(e) {
+ return false;
+ }
+ }
+ if (navigator.userAgent.indexOf('Firefox') > 0) {
+ swf = navigator.plugins['Shockwave Flash'];
+ if (swf) {
+ return true
+ } else {
+ return false;
+ }
+ }
+ return true;
+ },
+ /*
+ 共用函数
+ 检测浏览器是否支持HTML5-Video
+ */
+ supportVideo: function() {
+ if (!this.isMsie()) {
+ return false;
+ }
+ if ( !! document.createElement('video').canPlayType) {
+ var vidTest = document.createElement('video');
+ var oggTest;
+ try {
+ oggTest = vidTest.canPlayType('video/ogg; codecs="theora, vorbis"');
+ } catch(error) {
+ oggTest = false;
+ }
+ if (!oggTest) {
+ var h264Test;
+ try {
+ h264Test = vidTest.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
+ } catch(error) {
+ h264Test = false;
+ }
+ if (!h264Test) {
+ return false;
+ } else {
+ if (h264Test == "probably") {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ } else {
+ if (oggTest == "probably") {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+ },
+ /*
+ 共用函数
+ 获取属性值
+ */
+ getDataset: function(ele, z) {
+ try {
+ return ele.dataset[z];
+ } catch(error) {
+ try {
+ return ele.getAttribute('data-' + z)
+ } catch(error) {
+ return false;
+ }
+ }
+ },
+ /*
+ 共用函数
+ 返回flashplayer的对象
+ */
+ getObjectById: function(id) {
+ var x = null;
+ var y = this.getByElement('#' + id);
+ var r = 'embed';
+ if (y && y.nodeName == 'OBJECT') {
+ if (typeof(y.SetVariable) != 'undefined') {
+ x = y;
+ } else {
+ var z = y.getElementsByTagName(r)[0];
+ if (z) {
+ x = z;
+ }
+ }
+ }
+ return x;
+ },
+ /*
+ 共用函数
+ 对象转地址字符串
+ */
+ formatParams: function(data) {
+ var arr = [];
+ for (var i in data) {
+ arr.push(encodeURIComponent(i) + '=' + encodeURIComponent(data[i]));
+ }
+ return arr.join('&');
+ },
+ /*
+ 内置函数
+ 对地址进行冒泡排序
+ */
+ arrSort: function(arr) {
+ var temp = [];
+ for (var i = 0; i < arr.length; i++) {
+ for (var j = 0; j < arr.length - i; j++) {
+ if (!this.isUndefined(arr[j + 1]) && arr[j][3] < arr[j + 1][3]) {
+ temp = arr[j + 1];
+ arr[j + 1] = arr[j];
+ arr[j] = temp;
+ }
+ }
+ }
+ return arr;
+ },
+ /*
+ 内置函数
+ 判断文件后缀
+ */
+ getFileExt: function(filepath) {
+ if (filepath != '' && !this.isUndefined(filepath)) {
+ if (filepath.indexOf('?') > -1) {
+ filepath = filepath.split('?')[0];
+ }
+ var pos = '.' + filepath.replace(/.+\./, '');
+ return pos.toLowerCase();
+ }
+ return '';
+ },
+ /*
+ 内置函数
+ 判断是否是移动端
+ */
+ isMobile: function() {
+ if (navigator.userAgent.match(/(iPhone|iPad|iPod|Android|ios)/i)) {
+ return true;
+ }
+ return false;
+ },
+ /*
+ 内置函数
+ 搜索字符串str是否包含key
+ */
+ isContains: function(str, key) {
+ return str.indexOf(key) > -1;
+ },
+ /*
+ 内置函数
+ 给地址添加随机数
+ */
+ getNewUrl: function(url) {
+ if (this.isContains(url, '?')) {
+ return url += '&' + this.randomString(8) + '=' + this.randomString(8);
+ } else {
+ return url += '?' + this.randomString(8) + '=' + this.randomString(8);
+ }
+ },
+ /*
+ 共用函数
+ 获取clientX和clientY
+ */
+ client: function(event) {
+ var eve = event || window.event;
+ if (this.isUndefined(eve)) {
+ eve = {
+ clientX: 0,
+ clientY: 0
+ };
+ }
+ return {
+ x: eve.clientX + (document.documentElement.scrollLeft || this.body.scrollLeft) - this.pdCoor['x'],
+ y: eve.clientY + (document.documentElement.scrollTop || this.body.scrollTop) - this.pdCoor['y']
+ }
+ },
+ /*
+ 内置函数
+ 获取节点的绝对坐标
+ */
+ getCoor: function(obj) {
+ var coor = this.getXY(obj);
+ return {
+ x: coor['x'] - this.pdCoor['x'],
+ y: coor['y'] - this.pdCoor['y']
+ };
+ },
+ getXY: function(obj) {
+ var parObj = obj;
+ var left = obj.offsetLeft;
+ var top = obj.offsetTop;
+ while (parObj = parObj.offsetParent) {
+ left += parObj.offsetLeft;
+ top += parObj.offsetTop;
+ }
+ return {
+ x: left,
+ y: top
+ };
+ },
+ /*
+ 内置函数
+ 删除本对象的所有属性
+ */
+ removeChild: function() {
+ if (this.playerType == 'html5video') {
+ //删除计时器
+ var i = 0;
+ var timerArr = [this.timerError, this.timerFull, this.timerTime, this.timerBuffer, this.timerClick, this.timerLoading, this.timerCBar, this.timerVCanvas];
+ for (i = 0; i < timerArr.length; i++) {
+ if (timerArr[i] != null) {
+ if (timerArr[i].runing) {
+ timerArr[i].stop();
+ }
+ timerArr[i] = null;
+ }
+ }
+ //删除事件监听
+ var ltArr = this.listenerJsArr;
+ for (i = 0; i < ltArr.length; i++) {
+ this.removeListener(ltArr[i][0], ltArr[i][1]);
+ }
+ }
+ this.playerType == '';
+ this.V = null;
+ if (this.showFace) {
+ this.deleteChild(this.CB['menu']);
+ }
+ this.deleteChild(this.PD);
+ this.CD.innerHTML = '';
+ },
+ /*
+ 内置函数
+ 画封闭的图形
+ */
+ canvasFill: function(name, path) {
+ name.beginPath();
+ for (var i = 0; i < path.length; i++) {
+ var d = path[i];
+ if (i > 0) {
+ name.lineTo(d[0], d[1]);
+ } else {
+ name.moveTo(d[0], d[1]);
+ }
+ }
+ name.closePath();
+ name.fill();
+ },
+ /*
+ 内置函数
+ 画矩形
+ */
+ canvasFillRect: function(name, path) {
+ for (var i = 0; i < path.length; i++) {
+ var d = path[i];
+ name.fillRect(d[0], d[1], d[2], d[3]);
+ }
+ },
+ /*
+ 共用函数
+ 删除容器节点
+ */
+ deleteChild: function(f) {
+ var def = this.arrIndexOf(this.elementArr, f.className);
+ if (def > -1) {
+ this.elementArr.splice(def, 1);
+ }
+ var childs = f.childNodes;
+ for (var i = childs.length - 1; i >= 0; i--) {
+ f.removeChild(childs[i]);
+ }
+
+ if (f && f != null && f.parentNode) {
+ try {
+ if (f.parentNode) {
+ f.parentNode.removeChild(f);
+
+ }
+
+ } catch(event) {}
+ }
+ },
+ /*
+ 内置函数
+ 根据容器的宽高,内部节点的宽高计算出内部节点的宽高及坐标
+ */
+ getProportionCoor: function(stageW, stageH, vw, vh) {
+ var w = 0,
+ h = 0,
+ x = 0,
+ y = 0;
+ if (stageW / stageH < vw / vh) {
+ w = stageW;
+ h = w * vh / vw;
+ } else {
+ h = stageH;
+ w = h * vw / vh;
+ }
+ x = (stageW - w) * 0.5;
+ y = (stageH - h) * 0.5;
+ return {
+ width: parseInt(w),
+ height: parseInt(h),
+ x: parseInt(x),
+ y: parseInt(y)
+ };
+ },
+ /*
+ 共用函数
+ 将字幕文件内容转换成数组
+ */
+ parseSrtSubtitles: function(srt) {
+ var subtitles = [];
+ var textSubtitles = [];
+ var i = 0;
+ var arrs = srt.split('\n');
+ var arr = [];
+ var delHtmlTag = function(str) {
+ return str.replace(/<[^>]+>/g, ''); //去掉所有的html标记
+ };
+ for (i = 0; i < arrs.length; i++) {
+ if (arrs[i].replace(/\s/g, '').length > 0) {
+ arr.push(arrs[i]);
+ } else {
+ if (arr.length > 0) {
+ textSubtitles.push(arr);
+ }
+ arr = [];
+ }
+ }
+ for (i = 0; i < textSubtitles.length; ++i) {
+ var textSubtitle = textSubtitles[i];
+ if (textSubtitle.length >= 2) {
+ var sn = textSubtitle[0]; // 字幕的序号
+ var startTime = this.toSeconds(this.trim(textSubtitle[1].split(' --> ')[0])); // 字幕的开始时间
+ var endTime = this.toSeconds(this.trim(textSubtitle[1].split(' --> ')[1])); // 字幕的结束时间
+ var content = [delHtmlTag(textSubtitle[2])]; // 字幕的内容
+ // 字幕可能有多行
+ if (textSubtitle.length > 2) {
+ for (var j = 3; j < textSubtitle.length; j++) {
+ content.push(delHtmlTag(textSubtitle[j]));
+ }
+ }
+ // 字幕对象
+ var subtitle = {
+ sn: sn,
+ startTime: startTime,
+ endTime: endTime,
+ content: content
+ };
+ subtitles.push(subtitle);
+ }
+ }
+ return subtitles;
+ },
+ /*
+ 共用函数
+ 计时器,该函数模拟as3中的timer原理
+ time:计时时间,单位:毫秒
+ fun:接受函数
+ number:运行次数,不设置则无限运行
+ */
+ timer: function(time, fun, number) {
+ var thisTemp = this;
+ this.time = 10; //运行间隔
+ this.fun = null; //监听函数
+ this.timeObj = null; //setInterval对象
+ this.number = 0; //已运行次数
+ this.numberTotal = null; //总至需要次数
+ this.runing = false; //当前状态
+ this.startFun = function() {
+ thisTemp.number++;
+ thisTemp.fun();
+ if (thisTemp.numberTotal != null && thisTemp.number >= thisTemp.numberTotal) {
+ thisTemp.stop();
+ }
+ };
+ this.start = function() {
+ if (!thisTemp.runing) {
+ thisTemp.runing = true;
+ thisTemp.timeObj = window.setInterval(thisTemp.startFun, time);
+ }
+ };
+ this.stop = function() {
+ if (thisTemp.runing) {
+ thisTemp.runing = false;
+ window.clearInterval(thisTemp.timeObj);
+ thisTemp.timeObj = null;
+ }
+ };
+ if (time) {
+ this.time = time;
+ }
+ if (fun) {
+ this.fun = fun;
+ }
+ if (number) {
+ this.numberTotal = number;
+ }
+ this.start();
+ },
+ /*
+ 共用函数
+ 将时分秒转换成秒
+ */
+ toSeconds: function(t) {
+ var s = 0.0;
+ if (t) {
+ var p = t.split(':');
+ for (i = 0; i < p.length; i++) {
+ s = s * 60 + parseFloat(p[i].replace(',', '.'));
+ }
+ }
+ return s;
+ },
+ /*将字符变成数字形式的数组*/
+ arrayInt: function(str) {
+ var a = str.split(',');
+ var b = [];
+ for (var i = 0; i < a.length; i++) {
+ if (this.isUndefined(a[i])) {
+ a[i] = 0;
+ }
+ if (a[i].substr( - 1) != '%') {
+ a[i] = parseInt(a[i]);
+ }
+ b.push(a[i]);
+ }
+ return b;
+ },
+ /*
+ 共用函数
+ 将对象Object标准化
+ */
+ standardization: function(o, n) { //n替换进o
+ var h = {};
+ var k;
+ for (k in o) {
+ h[k] = o[k];
+ }
+ for (k in n) {
+ var type = typeof(h[k]);
+ switch (type) {
+ case 'number':
+ h[k] = parseFloat(n[k]);
+ break;
+ default:
+ h[k] = n[k];
+ break;
+ }
+
+ }
+ return h;
+ },
+ /*
+ 共用函数
+ 搜索数组
+ */
+ arrIndexOf: function(arr, key) {
+ var re = new RegExp(key, ['']);
+ return (arr.toString().replace(re, '┢').replace(/[^,┢]/g, '')).indexOf('┢');
+ },
+ /*
+ 共用函数
+ 去掉空格
+ */
+ trim: function(str) {
+ if (str != '') {
+ return str.replace(/(^\s*)|(\s*$)/g, '');
+ }
+ return '';
+ },
+ /*
+ 共用函数
+ 输出内容到控制台
+ */
+ log: function(val) {
+ try {
+ console.log(val);
+ } catch(e) {}
+ },
+ /*
+ 共用函数
+ 弹出提示
+ */
+ eject: function(er, val) {
+ if (!this.vars['debug']) {
+ return;
+ }
+ var errorVal = er[1];
+ if (!this.isUndefined(val)) {
+ errorVal = errorVal.replace('[error]', val);
+ }
+ var value = 'error ' + er[0] + ':' + errorVal;
+ try {
+ this.log(value);
+ } catch(e) {}
+ }
+ };
+ window.ckplayer = ckplayer;
+})();
\ No newline at end of file
diff --git a/video/ckplayer/ckplayer.min.js b/video/ckplayer/ckplayer.min.js
new file mode 100644
index 0000000..e6e5533
--- /dev/null
+++ b/video/ckplayer/ckplayer.min.js
@@ -0,0 +1,110 @@
+/*
+ 软件名称:ckplayer
+ 软件版本:X
+ 软件作者:http://www.ckplayer.com
+ ---------------------------------------------------------------------------------------------
+ 开发说明:
+ 使用的主要程序语言:javascript(js)及actionscript3.0(as3.0)(as3.0主要用于flashplayer部分的开发,不在该页面呈现)
+ 功能:播放视频
+ 特点:兼容HTML5-VIDEO(优先)以及FlashPlayer
+ =====================================================================================================================
+*/
+function ckplayerConfig() {
+ return {
+ flashvars: {},
+ languagePath: '',
+ stylePath: '',
+ config: {
+ fullInteractive: true,
+ delay: 30,
+ timeFrequency: 100,
+ autoLoad: true,
+ loadNext: 0,
+ definition: true,
+ smartRemove: true,
+ bufferTime: 200,
+ click: true,
+ doubleClick: true,
+ doubleClickInterval: 200,
+ keyDown: {
+ space: true,
+ left: true,
+ right: true,
+ up: true,
+ down: true
+ },
+ timeJump: 10,
+ volumeJump: 0.1,
+ timeScheduleAdjust: 1,
+ previewDefaultLoad: true,
+ promptSpotTime: false,
+ buttonMode: {
+ player: false,
+ controlBar: false,
+ timeSchedule: true,
+ volumeSchedule: true
+ },
+ liveAndVod: {
+ open: false,
+ vodTime: 2,
+ start: 'start'
+ },
+ errorNum: 3,
+ playCorrect: false,
+ timeCorrect: true,
+ m3u8Definition: {},
+ m3u8MaxBufferLength: 30,
+ split: '|',
+ timeStamp: '',
+ mobileVolumeBarShow: false,
+ addCallback: 'adPlay,adPause,playOrPause,videoPlay,videoPause,videoMute,videoEscMute,videoClear,changeVolume,fastBack,fastNext,videoSeek,newVideo,getMetaDate,videoRotation,videoBrightness,videoContrast,videoSaturation,videoHue,videoZoom,videoProportion,videoError,addListener,removeListener,addElement,getElement,deleteElement,elementShow,animate,animateResume,animatePause,deleteAnimate,changeConfig,getConfig,openUrl,fullScreen,quitFullScreen,switchFull,screenshot,custom,changeControlBarShow,getCurrentSrc,changeDefinition'
+ },
+ menu: {
+ ckkey: '',
+ name: '',
+ link: '',
+ version: '',
+ domain: '',
+ more: []
+ },
+ style: {
+ loading: {
+ file: 'data:image/swf;base64,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',
+ align: 'center',
+ vAlign: 'middle',
+ offsetX: -100,
+ offsetY: -40
+ },
+ logo: {
+ file: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFcAAAAUCAYAAAD4BKGuAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAVTSURBVHja1Fl/aJVVGP4cw/mH5tUWi3I53cA0WbeIzMgaq6lQoVawm0S6glHhIKM/TELICotqCxMSGWQRdFfRLEhc9mMxqA0rbdS2wsV0GkZXuaKUWlHvgeeNh7f3u1du3Ft74eGcnXu+c873vD/Pt0nZbDZyZL2gWZAQTBH8IjggeEjgPZASPIB+g/P7EsGT6J/BfHfjHFIv2Jpjj/+dlDskvCm42Jk7X3C7YJOgw/z2oOBGwdEYRW0RVAjOCZ4ugNggqwU3CTLRBJFyQ+xuwVRY14igB78tE9QKpgmeEHwkGKRnq9AeMesHRWwEsYGUxwSdBZ51ecweE4Lct0DsOVjaZvptA8jfC4JfghWpXIJ2jMY+EDShf1pwh6DvX5x1GtpDE43cNFlfhyFWpQ9xd5FgFo3fRi++C+2nCBNBRgU3O6RsEyyEQv4QLMb4CcE9RlFBLqS1WZ6BZ83A35ofVhuvfE5QJrjWebdgCJOx51qM1QgewbMzsO57MDQrB9DeC8ObHd5Xyb2eiNiQQxmtgkZBr+OuZwV7BIcF1RgbF1wTE2MbEccX48VY9sMzBilhTke/m+b1Q9lefpgruI7OsYhIGzPJuAnn3+6EM7vu1YKl5vkrYRSfCGZivCxoMklk7M5j6eFlXyRNRSAvAoFf0Fo/CC7LkbwuQjsZsf0qwbuI9wlYgIqGl6NEzDYibJ/gbmAfxpKoMDRcaSK8xZzjZbK+NMhSYoNSngV5e+ksKXp+JdqZwDDmdpSbsqa9gNAyi5JalSGv3iQ+dtNK9HvI+sNBh2AhvNYVaH+msRtAdsa4ehoKCuQsoP2PY8+kCSkJ5IRWjD2FZ4/BOFSWYv9KhI40eUKQ31CqdnLM1c1OOnHufKSS+iEZvgHNhji8g1yT5VZKdCnHO+ajvrYK/I7GkuSWjwvq8Mzl5M79NF89aCHaBNXmWv0sQVUUZEDwsDnbr2i9s31lKyGuFs7kITEBC+snJaToRYIFrRN0CeYgoSUxJ23WUm85eB41b4IUuIvGtyIMVMY8lzHGMoYworF7J/onKYk10/wVQL6zXYr+Zq9aOEhuXZPDel8Q3If+HMzTeHPKlForEK+mws3SMfH2UMxNLIJbasKsoIQZwVLbKFkN4T1C3HxUMM+EkCAfgjwNV40Y304KriOP+jIHqa+jvYsqnH/kqzKaGCFZxWnoTqooxky8+dHUsOGwr6Jfi9jmlVVTHGLnot9L3qGWqCToWYYRF5fDa96mtb93yI2g8B0IWxlTHWmi/hOG00D4mEJfJ5WhQX7ySCsDUaNkJeud6+sgXCgs3OLEG2/xdZSh10JBeiB1zQU0HuQdSib60rOdm9kFToIL8hmFiRHzm1YM0ylet5k579OFpcUk4I0oD0/QuJ7tcBy5ERY6ixdrh5uNwN3bUV7pd4E+J958HmPxbRRydqK/in6vxj5aH9din/udEPKtuU1GqBL24xJwBInQWiHLcbQVKBXTzkVpHP0tWHsIpZUqPeWcrScXuX2ImRkqlufBhdQl15ig3WLKH0/SeAmtD+uprBqGx1ThhlWN5LKG4lcNKbDblFDjVDU0wWK7yLLqnPNk6cKzKsfXt1GQmQQXSuwymhd3tr9lkvPJMUV152kc2PsmUEMxtzdPRk2SNX2DQ3Vhr02Is18LXjHVAz/bG0NEK8johus3UBiwyfkYlDkQUyLaWrwZBrbHMaB8Z3PJLaYk8IIVKKPSJdxbv3ecynNzLNr33GKLV1YVW4IyfycXfq0UxP4X5HJdXCqX4Wv0AKqYkkipw4LG6WxMNi+GhAtH+M/K8wVe7wuWvwQYAFT+UsGCXmX3AAAAAElFTkSuQmCC',
+ align: 'right',
+ vAlign: 'top',
+ offsetX: -100,
+ offsetY: 10
+ },
+ advertisement: {
+ time: 5,
+ method: 'get',
+ videoForce: false,
+ videoVolume: 0.8,
+ skipButtonShow: true,
+ linkButtonShow: true,
+ muteButtonShow: true,
+ closeButtonShow: true,
+ closeOtherButtonShow: true,
+ frontSkipButtonDelay: 1,
+ insertSkipButtonDelay: 0,
+ endSkipButtonDelay: 0,
+ frontStretched: 2,
+ insertStretched: 2,
+ pauseStretched: 2,
+ endStretched: 2
+ },
+ video: {
+ defaultWidth: 4,
+ defaultHeight: 3
+ }
+ }
+ }
+}
+!(function(){var javascriptPath='';!function(){var scriptList=document.scripts,thisPath=scriptList[scriptList.length-1].src;javascriptPath=thisPath.substring(0,thisPath.lastIndexOf('/')+1)}();var ckplayer=function(obj){this.config={videoDbClick:true,errorTime:100,videoDrawImage:false,adSkipClick:'javaScript->adjump'};this.varsConfig={playerID:'',container:'',variable:'ckplayer',volume:0.8,poster:'',autoplay:false,loop:false,live:false,duration:0,seek:0,drag:'',front:'',next:'',loaded:'',flashplayer:false,html5m3u8:false,track:null,cktrack:null,preview:null,prompt:null,video:null,config:'',type:'',crossorigin:'',crossdomain:'',unescape:false,mobileCkControls:false,mobileAutoFull:false,playbackrate:1,h5container:'',debug:false,adfront:'',adfronttime:'',adfrontlink:'',adpause:'',adpausetime:'',adpauselink:'',adinsert:'',adinserttime:'',adinsertlink:'',inserttime:'',adend:'',adendtime:'',adendlink:'',advertisements:''};this.vars={};this.language={volume:'音量:',play:'点击播放',pause:'点击暂停',full:'点击全屏',escFull:'退出全屏',mute:'点击静音',escMute:'取消静音',front:'上一集',next:'下一集',definition:'点击选择清晰度',playbackRate:'点击选择速度',error:'加载出错',adTime:'广告{$second}秒',skipAd:'跳过广告',skipAdTime:'{$second}秒后可跳过广告',adLink:'查看详情'};this.contextMenu=[['ckplayer','link','http://www.ckplayer.com','_blank'],['version:X','default','line']];this.errorList=[['000','Object does not exist'],['001','Variables type is not a object'],['002','Video object does not exist'],['003','Video object format error'],['004','Video object format error'],['005','Video object format error'],['006','[error] does not exist '],['007','Ajax error'],['008','Ajax error'],['009','Ajax object format error'],['010','Ajax.status:[error]']];this.playbackRateArr=[[0.5,'0.5倍'],[1,'正常'],[1.25,'1.25倍'],[1.5,'1.5倍'],[2,'2倍速'],[4,'4倍速']];this.playbackRateDefault=1;this.logo='';this.loaded=false;this.timerError=null;this.error=false;this.errorUrl=[];this.timerFull=null;this.full=false;this.timerTime=null;this.timerBuffer=null;this.isTimeButtonMove=true;this.isTimeButtonDown=false;this.isClick=false;this.timerClick=null;this.timerLoading=null;this.timerCBar=null;this.needSeek=0;this.volume=0;this.volumeTemp=0;this.time=0;this.isFirst=true;this.html5Video=true;this.pdCoor={x:0,y:0};this.playerType='';this.loadTime=0;this.body=document.body||document.documentElement;this.V=null;this.listenerJsArr=[];this.buttonLen=0;this.buttonArr=[];this.buttonWidth={};this.elementArr=[];this.elementTempArr=[];this.track=[];this.trackIndex=0;this.nowTrackShow={sn:''};this.trackElement=[];this.timerVCanvas=null;this.animateArray=[];this.animateElementArray=[];this.animatePauseArray=[];this.previewStart=0;this.previewDiv=null;this.previewTop=null;this.previewWidth=120;this.previewTween=null;this.isM3u8=false;this.promptArr=[];this.promptElement=null;this.ckplayerConfig={};this.showFace=true;this.errorAdd=false;this.errorSend=false;this.controlBarIsShow=true;this.videoScale=1;this.fontFamily='"Microsoft YaHei"; YaHei; "\5FAE\8F6F\96C5\9ED1"; SimHei; "\9ED1\4F53";Arial';this.timeSliderLeftTemp=0;this.durationSendJS=false;this.adAnalysisEnd=false;this.advertisements={};this.isFirstTimePlay=true;this.adType='';this.adI=0;this.videoTemp={src:'',source:'',currentSrc:'',loop:false};this.adTimeAllTotal=0;this.adTimeTotal=0;this.adCountDownObj=null;this.adPlayStart=false;this.adPlayerPlay=false;this.adIsPause=false;this.adVideoMute=false;this.adIsVideoTime=false;this.endAdPlay=false;this.adPauseShow=false;this.adReset=false;this.adVideoPlay=false;if(obj){this.embed(obj)}};ckplayer.prototype={embed:function(c){if(window.location.href.substr(0,7)=='file://'){alert('Please use the HTTP protocol to open the page');return}if(c==undefined||!c){this.eject(this.errorList[0]);return}if(typeof(c)!='object'){this.eject(this.errorList[1])}this.vars=this.standardization(this.varsConfig,c);if(!this.vars['mobileCkControls']&&this.isMobile()){this.vars['flashplayer']=false;this.showFace=false}var videoString=this.vars['video'];if(!videoString){this.eject(this.errorList[2]);return}if(typeof(videoString)=='string'){if(videoString.substr(0,3)=='CK:'||videoString.substr(0,3)=='CE:'||videoString.substr(8,3)=='CK:'||videoString.substr(8,3)=='CE:'){this.vars['flashplayer']=true}}if(typeof(videoString)=='object'){if(videoString.length>1){if(videoString[0][0].substr(0,3)=='CK:'||videoString[0][0].substr(0,3)=='CE:'||videoString[0][0].substr(8,3)=='CK:'||videoString[0][0].substr(8,3)=='CE:'){this.vars['flashplayer']=true}}}if(this.vars['config']){this.ckplayerConfig=eval(this.vars['config']+'()')}else{this.ckplayerConfig=ckplayerConfig()}if((!this.supportVideo()&&this.vars['flashplayer']!='')||(this.vars['flashplayer']&&this.uploadFlash())||!this.isMsie()){this.html5Video=false;this.getVideo()}else if(videoString){this.analysedVideoUrl(videoString);return this}else{this.eject(this.errorList[2])}},analysedVideoUrl:function(video){var i=0,y=0;var thisTemp=this;this.VA=[];if(typeof(video)=='string'){if(video.substr(0,8)!='website:'){this.VA=[[video,'','',0]];var fileExt=this.getFileExt(video);switch(fileExt){case'.mp4':this.VA[0][1]='video/mp4';break;case'.ogg':this.VA[0][1]='video/ogg';break;case'.webm':this.VA[0][1]='video/webm';break;default:break}this.getVideo()}else{if(this.html5Video){var ajaxObj={url:video.substr(8),success:function(data){if(data){thisTemp.analysedUrl(data)}else{thisTemp.eject(thisTemp.errorList[5]);this.VA=video;thisTemp.getVideo()}}};this.ajax(ajaxObj)}else{this.VA=video;this.getVideo()}}}else if(typeof(video)=='object'){if(!this.isUndefined(typeof(video.length))){if(!this.isUndefined(typeof(video[0].length))){this.VA=video}this.getVideo()}else{if(!this.isUndefined(video['type'])){this.VA.push([video['file'],video['type'],'',0]);this.getVideo()}else{this.eject(this.errorList[5])}}}else{this.eject(this.errorList[4])}},analysedUrl:function(data){this.vars=this.standardization(this.vars,data);if(!this.isUndefined(data['video'])){this.vars['video']=data['video']}this.analysedVideoUrl(this.vars['video'])},getHtml5Video:function(){var va=this.VA;var nva=[];var mobile=false;var video=document.createElement('video');var codecs=function(type){var cod='';switch(type){case'video/mp4':cod='avc1.4D401E, mp4a.40.2';break;case'video/ogg':cod='theora, vorbis';break;case'video/webm':cod='vp8.0, vorbis';break;default:break}return cod};var supportType=function(vidType,codType){if(!video.canPlayType){this.html5Video=false;return}var isSupp=video.canPlayType(vidType+';codecs="'+codType+'"');if(isSupp==''){return false}return true};if(this.vars['flashplayer']||!this.isMsie()){this.html5Video=false;return}if(this.isMobile()){mobile=true}for(var i=0;i0){this.VA=nva}else{if(!mobile){this.html5Video=false}}},getVideo:function(){var thisTemp=this;var v=this.vars;if(!this.adAnalysisEnd&&(v['adfront']!=''||v['adpause']!=''||v['adinsert']!=''||v['adend']!=''||v['advertisements']!='')){this.adAnalysisEnd=true;this.adAnalysis();return}if(this.V){this.changeVideo();return}if(this.vars['cktrack']){this.loadTrack()}if(this.supportVideo()&&!this.vars['flashplayer']){this.getHtml5Video()}var src='',source='',poster='',loop='',autoplay='',track='';var video=v['video'];var i=0;this.CD=this.getByElement(v['container']);volume=v['volume'];if(!this.CD){this.eject(this.errorList[6],v['container']);return false}this.V=undefined;var thisPd=null;if(v['h5container']!=''){thisPd=this.getByElement(v['h5container']);if(this.isUndefined(thisPd)){thisPd=null}}var isVideoH5=null;if(v['playerID']!=''){isVideoH5=this.getByElement('#'+v['playerID']);if(this.isUndefined(isVideoH5)){isVideoH5=null}}if(thisPd!=null&&isVideoH5!=null){this.PD=thisPd}else{var playerID='ckplayer'+this.randomString();var playerDiv=document.createElement('div');playerDiv.className=playerID;this.CD.innerHTML='';this.CD.appendChild(playerDiv);this.PD=this.getByElement(playerID)}this.css(this.CD,{backgroundColor:'#000000',overflow:'hidden',position:'relative'});this.css(this.PD,{backgroundColor:'#000000',width:'100%',height:'100%',fontFamily:this.fontFamily});if(this.html5Video){this.PD.onselectstart=this.PD.ondrag=function(){return false};if(this.VA.length==1){this.videoTemp['src']=decodeURIComponent(this.VA[0][0]);src=' src="'+this.videoTemp['src']+'"'}else{var videoArr=this.VA.slice(0);videoArr=this.arrSort(videoArr);for(i=0;i'}this.videoTemp['source']=source}if(v['autoplay']){autoplay=' autoplay="autoplay"'}if(v['poster']){poster=' poster="'+v['poster']+'"'}if(v['loop']){loop=' loop="loop"'}if(v['seek']>0){this.needSeek=v['seek']}if(v['track']!=null&&v['cktrack']==null){var trackArr=v['track'];var trackDefault='';var defaultHave=false;for(i=0;i'}}var autoLoad=this.ckplayerConfig['config']['autoLoad'];var preload='';if(!autoLoad){preload=' preload="meta"'}var vid=this.randomString();var controls='';if(!this.showFace){controls=' controls="controls"'}var mobileAutoFull=v['mobileAutoFull'];var mobileautofull='';if(!mobileAutoFull){mobileautofull=' x-webkit-airplay="true" playsinline webkit-playsinline="true" x5-video-player-type="h5"'}if(isVideoH5!=null&&thisPd!=null){this.V=isVideoH5;if(v['poster']){this.V.poster=v['poster']}}else{var html='';if(!this.isM3u8){html=''+source+' '}else{html=' '}this.PD.innerHTML=html;this.V=this.getByElement('#'+vid)}if(this.vars['crossorigin']){this.V.crossOrigin=this.vars['crossorigin']}try{this.V.volume=volume;if(this.playbackRateArr&&this.vars['playbackrate']>-1){if(this.vars['playbackrate']-1){this.playbackRate()}if(v['autoplay']){this.loadingStart(true)}}this.playerLoad()}else{this.embedSWF()}},arrayDel:function(arr){if(arr.length==0){return null}var newArr=[];for(var i=0;i0){return newArr}return null},adAnalysis:function(){var thisTemp=this;var v=this.vars;var isAdvShow=[];var i=0;if(v['advertisements']!=''&&v['advertisements'].substr(0,8)=='website:'){var ajaxObj={url:v['advertisements'].substr(8),success:function(data){if(data){var newData={};var val=null;try{if(!thisTemp.isUndefined(data['front'])){val=thisTemp.arrayDel(data['front']);if(!thisTemp.isUndefined(val)){newData['front']=val}val=thisTemp.arrayDel(data['pause']);if(!thisTemp.isUndefined(val)){newData['pause']=val}val=thisTemp.arrayDel(data['insert']);if(!thisTemp.isUndefined(val)){newData['insert']=val;if(!thisTemp.isUndefined(data['inserttime'])){newData['inserttime']=thisTemp.arrayInt(data['inserttime']);isAdvShow=[];for(i=0;i0){var adLinkLen=adlink.length,adTimeLen=adtime.length;if(v[adLink]==''){adLinkLen=0;adlink=[]}if(v[adTime]==''){adTimeLen=0;adtime=[]}if(adLinkLen0?parseInt(adtime[i]):this.ckplayerConfig['style']['advertisement']['time'],link:adlink[i]};adList.push(obj)}}if(this.isUndefined(this.advertisements)){this.advertisements={}}if(adList.length>0){this.advertisements[adType]=adList}}}},playerLoad:function(){var thisTemp=this;if(this.isFirst){this.isFirst=false;setTimeout(function(){thisTemp.loadedHandler()},1)}},addVEvent:function(){var thisTemp=this;var eventVideoClick=function(event){thisTemp.videoClick()};this.addListenerInside('click',eventVideoClick);this.addListenerInside('click',eventVideoClick,this.MDC);this.timerErrorFun();var eventJudgeIsLive=function(event){thisTemp.sendJS('loadedmetadata');if(typeof(thisTemp.V.duration)=='number'&&thisTemp.V.duration>1){thisTemp.sendJS('duration',thisTemp.V.duration);thisTemp.formatInserttime(thisTemp.V.duration);if(thisTemp.adPlayerPlay){thisTemp.advertisementsTime(thisTemp.V.duration+1)}thisTemp.durationSendJS=true}thisTemp.judgeIsLive()};this.addListenerInside('loadedmetadata',eventJudgeIsLive);var eventPlaying=function(event){thisTemp.playingHandler();thisTemp.sendJS('play');thisTemp.sendJS('paused',false);if(!thisTemp.durationSendJS&&typeof(thisTemp.V.duration)=='number'&&thisTemp.V.duration>0){thisTemp.durationSendJS=true;thisTemp.sendJS('duration',thisTemp.V.duration);thisTemp.formatInserttime(thisTemp.V.duration)}};this.addListenerInside('playing',eventPlaying);var eventPause=function(event){thisTemp.pauseHandler();thisTemp.sendJS('pause');thisTemp.sendJS('paused',true)};this.addListenerInside('pause',eventPause);var eventEnded=function(event){thisTemp.endedHandler()};this.addListenerInside('ended',eventEnded);var eventTimeupdate=function(event){if(thisTemp.timerLoading!=null){thisTemp.loadingStart(false)}if(thisTemp.time){if(!thisTemp.adPlayerPlay){thisTemp.sendJS('time',thisTemp.time);if(!thisTemp.isUndefined(thisTemp.advertisements['insert'])){thisTemp.checkAdInsert(thisTemp.time)}if(!thisTemp.isUndefined(thisTemp.advertisements['other'])){thisTemp.checkAdOther(thisTemp.time)}if(thisTemp.time<3&&thisTemp.adReset){thisTemp.adReset=false;thisTemp.endedAdReset()}}else{thisTemp.adPlayerTimeHandler(thisTemp.time)}}};this.addListenerInside('timeupdate',eventTimeupdate);var eventWaiting=function(event){thisTemp.loadingStart(true)};this.addListenerInside('waiting',eventWaiting);var eventSeeking=function(event){thisTemp.sendJS('seek','start')};this.addListenerInside('seeking',eventSeeking);var eventSeeked=function(event){thisTemp.seekedHandler();thisTemp.sendJS('seek','ended')};this.addListenerInside('seeked',eventSeeked);var eventVolumeChange=function(event){try{thisTemp.volumechangeHandler();thisTemp.sendJS('volume',thisTemp.volume||thisTemp.V.volume)}catch(event){}};this.addListenerInside('volumechange',eventVolumeChange);var eventFullChange=function(event){var fullState=document.fullScreen||document.mozFullScreen||document.webkitIsFullScreen;thisTemp.sendJS('full',fullState)};this.addListenerInside('fullscreenchange',eventFullChange);this.addListenerInside('webkitfullscreenchange',eventFullChange);this.addListenerInside('mozfullscreenchange',eventFullChange);if(this.showFace){this.interFace()}},resetPlayer:function(){this.timeTextHandler();if(this.showFace){this.timeProgress(0,1);this.changeLoad(0);this.initPlayPause();this.definition();this.showFrontNext();this.deletePrompt();this.deletePreview();this.trackHide();this.resetTrack();this.trackElement=[];this.track=[]}},interFace:function(){this.showFace=true;var thisTemp=this;var html='';var i=0;var bWidth=38,bHeight=38;var bBgColor='#FFFFFF',bOverColor='#0782F5';var timeInto=this.formatTime(0)+' / '+this.formatTime(this.vars['duration']);var randomS=this.randomString(10);var controlBarBgID='controlbgbar'+randomS,controlBarID='controlbar'+randomS,timeProgressBgID='timeprogressbg'+randomS,loadProgressID='loadprogress'+randomS,timeProgressID='timeprogress'+randomS,timeBOBGID='timebobg'+randomS,timeBOID='timebo'+randomS,timeBWID='timebw'+randomS,timeTextID='timetext'+randomS,playID='play'+randomS,pauseID='pause'+randomS,frontID='front'+randomS,nextID='next'+randomS,fullID='full'+randomS,escFullID='escfull'+randomS,muteID='mute'+randomS,escMuteID='escmute'+randomS,volumeID='volume'+randomS,volumeDbgID='volumedbg'+randomS,volumeBgID='volumebg'+randomS,volumeUpID='volumeup'+randomS,volumeBOID='volumebo'+randomS,volumeBWID='volumebw'+randomS,definitionID='definition'+randomS,definitionPID='definitionp'+randomS,playbackRateID='playbackrate'+randomS,playbackRatePID='playbackratep'+randomS,promptBgID='promptbg'+randomS,promptID='prompt'+randomS,dlineID='dline'+randomS,menuID='menu'+randomS,pauseCenterID='pausecenter'+randomS,loadingID='loading'+randomS,errorTextID='errortext'+randomS,logoID='logo'+randomS,adBackgroundID='background'+randomS,adElementID='adelement'+randomS,adBarID='adBar'+randomS,adSkipID='adskip'+randomS,adTimeID='adtime'+randomS,adLinkID='adlink'+randomS,adMuteID='admute'+randomS,adEscMuteID='adescmute'+randomS,adPauseCloseID='adpauseclose'+randomS;var controlBarBg=document.createElement('div'),controlBar=document.createElement('div'),timeProgressBg=document.createElement('div'),timeBoBg=document.createElement('div'),pauseCenter=document.createElement('div'),errorText=document.createElement('div'),promptBg=document.createElement('div'),prompt=document.createElement('div'),menuDiv=document.createElement('div'),definitionP=document.createElement('div'),playbackrateP=document.createElement('div'),loading=document.createElement('div'),logo=document.createElement('div'),adBackground=document.createElement('div'),adElement=document.createElement('div'),adBar=document.createElement('div'),adLink=document.createElement('div'),adPauseClose=document.createElement('div');controlBarBg.className=controlBarBgID;controlBar.className=controlBarID;timeProgressBg.className=timeProgressBgID;timeBoBg.className=timeBOBGID;promptBg.className=promptBgID;prompt.className=promptID;menuDiv.className=menuID;definitionP.className=definitionPID;playbackrateP.className=playbackRatePID;pauseCenter.className=pauseCenterID;loading.className=loadingID;logo.className=logoID;errorText.className=errorTextID;adBackground.className=adBackgroundID;adElement.className=adElementID;adBar.className=adBarID;adLink.className=adLinkID;adPauseClose.className=adPauseCloseID;this.PD.appendChild(controlBarBg);this.PD.appendChild(controlBar);this.PD.appendChild(timeProgressBg);this.PD.appendChild(timeBoBg);this.PD.appendChild(promptBg);this.PD.appendChild(prompt);this.PD.appendChild(definitionP);this.PD.appendChild(playbackrateP);this.PD.appendChild(pauseCenter);this.PD.appendChild(loading);this.PD.appendChild(errorText);this.PD.appendChild(logo);this.PD.appendChild(adBackground);this.PD.appendChild(adElement);this.PD.appendChild(adBar);this.PD.appendChild(adLink);this.PD.appendChild(adPauseClose);this.body.appendChild(menuDiv);if(this.vars['live']){timeInto=this.getNowDate()}html+=''+this.newCanvas(playID,bWidth,bHeight)+'
';html+=''+this.newCanvas(pauseID,bWidth,bHeight)+'
';html+='
';html+=''+this.newCanvas(frontID,bWidth,bHeight)+'
';html+='
';html+=''+this.newCanvas(nextID,bWidth,bHeight)+'
';html+='
';html+=''+timeInto+'
';html+=''+this.newCanvas(fullID,bWidth,bHeight)+'
';html+=''+this.newCanvas(escFullID,bWidth,bHeight)+'
';html+='
';html+='
';html+='
';html+='
';html+='
';html+='';html+=''+this.newCanvas(muteID,bWidth,bHeight)+'
';html+=''+this.newCanvas(escMuteID,bWidth,bHeight)+'
';html+='
';this.getByElement(controlBarID).innerHTML=html;this.getByElement(timeProgressBgID).innerHTML='
';this.getByElement(timeBOBGID).innerHTML='';this.getByElement(pauseCenterID).innerHTML=this.newCanvas(pauseCenterID,80,80);this.getByElement(loadingID).innerHTML=this.newCanvas(loadingID,60,60);this.getByElement(errorTextID).innerHTML=this.language['error'];html=''+this.language['adTime'].replace('{$second}',0)+'
';html+=''+this.newCanvas(adMuteID,30,30)+'
';html+=''+this.newCanvas(adEscMuteID,30,30)+'
';html+='
';this.getByElement(adBarID).innerHTML=html;this.getByElement(adLinkID).innerHTML=this.language['adLink'];this.getByElement(adPauseCloseID).innerHTML=this.newCanvas(adPauseCloseID,20,20);if(this.ckplayerConfig['style']['logo']){if(this.ckplayerConfig['style']['logo']['file']){var logoFile=this.ckplayerConfig['style']['logo']['file'];if(logoFile.substr(0,15)=='data:image/png;'||logoFile.substr(0,15)=='data:image/jpg;'||logoFile.substr(0,16)=='data:image/jpeg;'){this.getByElement(logoID).innerHTML=' '}}}else{this.getByElement(logoID).innerHTML=this.vars['logo']||this.logo||''}var pd=this.PD;this.CB={controlBarBg:this.getByElement(controlBarBgID,pd),controlBar:this.getByElement(controlBarID,pd),promptBg:this.getByElement(promptBgID,pd),prompt:this.getByElement(promptID,pd),timeProgressBg:this.getByElement(timeProgressBgID,pd),loadProgress:this.getByElement(loadProgressID,pd),timeProgress:this.getByElement(timeProgressID,pd),timeBoBg:this.getByElement(timeBOBGID,pd),timeButton:this.getByElement(timeBOID,pd),timeText:this.getByElement(timeTextID,pd),play:this.getByElement(playID,pd),front:this.getByElement(frontID,pd),next:this.getByElement(nextID,pd),pause:this.getByElement(pauseID,pd),definition:this.getByElement(definitionID,pd),definitionP:this.getByElement(definitionPID,pd),definitionLine:this.getByElement(dlineID+'-rb',pd),playbackrate:this.getByElement(playbackRateID,pd),playbackrateP:this.getByElement(playbackRatePID,pd),playbackrateLine:this.getByElement(dlineID+'-rc',pd),full:this.getByElement(fullID,pd),escFull:this.getByElement(escFullID,pd),mute:this.getByElement(muteID,pd),escMute:this.getByElement(escMuteID,pd),volume:this.getByElement(volumeID,pd),volumeBg:this.getByElement(volumeBgID,pd),volumeUp:this.getByElement(volumeUpID,pd),volumeBO:this.getByElement(volumeBOID,pd),pauseCenter:this.getByElement(pauseCenterID,pd),menu:this.getByElement(menuID),loading:this.getByElement(loadingID,pd),loadingCanvas:this.getByElement(loadingID+'-canvas',pd),errorText:this.getByElement(errorTextID,pd),logo:this.getByElement(logoID,pd),playLine:this.getByElement(dlineID+'-la',pd),frontLine:this.getByElement(dlineID+'-lb',pd),nextLine:this.getByElement(dlineID+'-lc',pd),fullLine:this.getByElement(dlineID+'-ra'),definitionLine:this.getByElement(dlineID+'-rb',pd),muteLine:this.getByElement(dlineID+'-rd',pd),adBackground:this.getByElement(adBackgroundID,pd),adElement:this.getByElement(adElementID,pd),adBar:this.getByElement(adBarID,pd),adSkip:this.getByElement(adSkipID,pd),adTime:this.getByElement(adTimeID,pd),adLink:this.getByElement(adLinkID,pd),adMute:this.getByElement(adMuteID,pd),adEscMute:this.getByElement(adEscMuteID,pd),adPauseClose:this.getByElement(adPauseCloseID,pd)};this.buttonWidth={play:bWidth,full:bWidth,front:bWidth,next:bWidth,mute:bWidth};this.css(controlBarBgID,{width:'100%',height:bHeight+'px',backgroundColor:'#000000',position:'absolute',bottom:'0px',filter:'alpha(opacity:0.8)',opacity:'0.8',zIndex:'990'});this.css(controlBarID,{width:'100%',height:bHeight+'px',position:'absolute',bottom:'0px',zIndex:'990'});this.css(pauseCenterID,{width:'80px',height:'80px',borderRadius:'50%',position:'absolute',display:'none',cursor:'pointer',zIndex:'996'});this.css(loadingID,{width:'60px',height:'60px',position:'absolute',display:'none',zIndex:'996'});this.css(errorTextID,{width:'120px',height:'30px',lineHeight:'30px',color:'#FFFFFF',fontSize:'14px',textAlign:'center',position:'absolute',display:'none',zIndex:'101',cursor:'default',zIndex:'996'});this.css(logoID,{height:'30px',lineHeight:'30px',color:'#FFFFFF',fontFamily:'Arial',fontSize:'28px',textAlign:'center',position:'absolute',float:'left',left:'-1000px',top:'20px',zIndex:'996',filter:'alpha(opacity:0.8)',opacity:'0.8',cursor:'default'});this.css(this.CB['loadingCanvas'],{transform:'rotate(0deg)',msTransform:'rotate(0deg)',mozTransform:'rotate(0deg)',webkitTransform:'rotate(0deg)',oTransform:'rotate(0deg)'});this.css([promptBgID,promptID],{height:'30px',lineHeight:'30px',color:'#FFFFFF',fontSize:'14px',textAlign:'center',position:'absolute',borderRadius:'5px',paddingLeft:'5px',paddingRight:'5px',bottom:'0px',display:'none',zIndex:'995'});this.css(promptBgID,{backgroundColor:'#000000',filter:'alpha(opacity:0.5)',opacity:'0.5'});this.css(timeProgressBgID,{width:'100%',height:'6px',backgroundColor:'#3F3F3F',overflow:'hidden',position:'absolute',bottom:'38px',zIndex:'888'});this.css([loadProgressID,timeProgressID],{width:'1px',height:'6px',position:'absolute',bottom:'38px',top:'0px',zIndex:'991'});this.css(loadProgressID,'backgroundColor','#6F6F6F');this.css(timeProgressID,'backgroundColor',bOverColor);this.css(timeBOBGID,{width:'100%',height:'14px',overflow:'hidden',position:'absolute',bottom:'34px',cursor:'pointer',zIndex:'992'});this.css(timeBOID,{width:'14px',height:'14px',overflow:'hidden',borderRadius:'50%',backgroundColor:bBgColor,cursor:'pointer',position:'absolute',top:'0px',zIndex:'200'});this.css(timeBWID,{width:'8px',height:'8px',overflow:'hidden',borderRadius:'50%',position:'absolute',backgroundColor:bOverColor,left:'3px',top:'3px'});this.css(timeTextID,{lineHeight:bHeight+'px',color:'#FFFFFF',fontFamily:'arial',fontSize:'16px',paddingLeft:'10px',float:'left',overflow:'hidden',cursor:'default'});this.css([dlineID+'-la',dlineID+'-lb',dlineID+'-lc',dlineID+'-ra',dlineID+'-rb',dlineID+'-rc',dlineID+'-rd'],{width:'0px',height:bHeight+'px',overflow:'hidden',borderLeft:'1px solid #303030',borderRight:'1px solid #151515',filter:'alpha(opacity:0.9)',opacity:'0.9'});this.css([dlineID+'-la',dlineID+'-lb',dlineID+'-lc'],'float','left');this.css([dlineID+'-ra',dlineID+'-rb',dlineID+'-rc',dlineID+'-rd'],'float','right');this.css([dlineID+'-lb',dlineID+'-lc',dlineID+'-rb',dlineID+'-rc'],'display','none');this.css([playID,pauseID,frontID,nextID],{width:bWidth+'px',height:bHeight+'px',float:'left',overflow:'hidden',cursor:'pointer'});this.css([frontID,nextID],'display','none');this.initPlayPause();this.css([muteID,escMuteID],{width:bWidth+'px',height:bHeight+'px',float:'right',overflow:'hidden',cursor:'pointer'});if(this.vars['volume']>0){this.css(escMuteID,'display','none')}else{this.css(muteID,'display','none')}if(!this.ckplayerConfig['config']['mobileVolumeBarShow']&&this.isMobile()){this.css([muteID,escMuteID,volumeID,volumeDbgID,dlineID+'-rd'],{display:'none'})}this.css([volumeID,volumeDbgID],{width:'110px',height:bHeight+'px',overflow:'hidden',float:'right'});this.css(volumeDbgID,{position:'absolute'});this.css([volumeBgID,volumeUpID],{width:'100px',height:'6px',overflow:'hidden',borderRadius:'5px',cursor:'pointer'});this.css(volumeBgID,{position:'absolute',top:'16px'});this.css(volumeBgID,'backgroundColor','#666666');this.css(volumeUpID,'backgroundColor',bOverColor);this.buttonWidth['volume']=100;this.css(volumeBOID,{width:'12px',height:'12px',overflow:'hidden',borderRadius:'50%',position:'absolute',backgroundColor:bBgColor,top:'13px',left:'0px',cursor:'pointer'});this.css(volumeBWID,{width:'6px',height:'6px',overflow:'hidden',borderRadius:'50%',position:'absolute',backgroundColor:bOverColor,left:'3px',top:'3px'});this.css(definitionID,{lineHeight:bHeight+'px',color:'#FFFFFF',float:'right',fontSize:'14px',textAlign:'center',overflow:'hidden',display:'none',cursor:'pointer'});this.css(definitionPID,{lineHeight:(bHeight-8)+'px',color:'#FFFFFF',overflow:'hidden',position:'absolute',bottom:'4px',backgroundColor:'#000000',textAlign:'center',zIndex:'995',cursor:'pointer',display:'none'});this.css(playbackRateID,{lineHeight:bHeight+'px',color:'#FFFFFF',float:'right',fontSize:'14px',textAlign:'center',overflow:'hidden',display:'none',cursor:'pointer'});this.css(playbackRatePID,{lineHeight:(bHeight-8)+'px',color:'#FFFFFF',overflow:'hidden',position:'absolute',bottom:'4px',backgroundColor:'#000000',textAlign:'center',zIndex:'995',cursor:'pointer',display:'none'});this.css([fullID,escFullID],{width:bWidth+'px',height:bHeight+'px',float:'right',overflow:'hidden',cursor:'pointer'});this.css(escFullID,'display','none');this.css(adBackgroundID,{width:'100%',height:'100%',backgroundColor:'#000000',position:'absolute',top:'0px',zIndex:'997',display:'none'});this.css(adElementID,{position:'absolute',overflow:'hidden',top:'0px',zIndex:'998',float:'center',display:'none'});this.css(adBarID,{position:'absolute',overflow:'hidden',top:'10px',right:'10px',zIndex:'999',textAlign:'right',display:'none'});this.css(adTimeID,{backgroundColor:'#000000',color:'#FF0000',paddingLeft:'10px',paddingRight:'10px',lineHeight:(bHeight-8)+'px',marginLeft:'5px',float:'right',cursor:'pointer'});this.css([adMuteID,adEscMuteID],{backgroundColor:'#000000',width:'30px',height:'30px',marginLeft:'5px',float:'right',display:'none',cursor:'pointer'});this.css(adSkipID,{backgroundColor:'#000000',lineHeight:(bHeight-8)+'px',color:'#FFFFFF',paddingLeft:'10px',paddingRight:'10px',float:'right',display:'none',cursor:'pointer'});this.css(adLinkID,{backgroundColor:'#ea5503',lineHeight:(bHeight-8)+'px',color:'#FFFFFF',paddingLeft:'10px',paddingRight:'10px',position:'absolute',overflow:'hidden',bottom:'10px',right:'10px',zIndex:'999',display:'none'});this.css(adPauseCloseID,{backgroundColor:'#f7f7f7',widht:'20px',height:'20px',position:'absolute',overflow:'hidden',zIndex:'999',top:'60px',left:'30px',borderRadius:'20px',display:'none',cursor:'pointer'});var cPlay=this.getByElement(playID+'-canvas').getContext('2d');var cPlayFillRect=function(){thisTemp.canvasFill(cPlay,[[12,10],[29,19],[12,28]])};cPlay.fillStyle=bBgColor;cPlayFillRect();var cPlayOver=function(event){cPlay.clearRect(0,0,bWidth,bHeight);cPlay.fillStyle=bOverColor;cPlayFillRect()};var cPlayOut=function(event){cPlay.clearRect(0,0,bWidth,bHeight);cPlay.fillStyle=bBgColor;cPlayFillRect()};this.addListenerInside('mouseover',cPlayOver,this.getByElement(playID+'-canvas'));this.addListenerInside('mouseout',cPlayOut,this.getByElement(playID+'-canvas'));var cPause=this.getByElement(pauseID+'-canvas').getContext('2d');var cPauseFillRect=function(){thisTemp.canvasFillRect(cPause,[[10,10,5,18],[22,10,5,18]])};cPause.fillStyle=bBgColor;cPauseFillRect();var cPauseOver=function(event){cPause.clearRect(0,0,bWidth,bHeight);cPause.fillStyle=bOverColor;cPauseFillRect()};var cPauseOut=function(event){cPause.clearRect(0,0,bWidth,bHeight);cPause.fillStyle=bBgColor;cPauseFillRect()};this.addListenerInside('mouseover',cPauseOver,this.getByElement(pauseID+'-canvas'));this.addListenerInside('mouseout',cPauseOut,this.getByElement(pauseID+'-canvas'));var cFront=this.getByElement(frontID+'-canvas').getContext('2d');var cFrontFillRect=function(){thisTemp.canvasFill(cFront,[[16,19],[30,10],[30,28]]);thisTemp.canvasFillRect(cFront,[[8,10,5,18]])};cFront.fillStyle=bBgColor;cFrontFillRect();var cFrontOver=function(event){cFront.clearRect(0,0,bWidth,bHeight);cFront.fillStyle=bOverColor;cFrontFillRect()};var cFrontOut=function(event){cFront.clearRect(0,0,bWidth,bHeight);cFront.fillStyle=bBgColor;cFrontFillRect()};this.addListenerInside('mouseover',cFrontOver,this.getByElement(frontID+'-canvas'));this.addListenerInside('mouseout',cFrontOut,this.getByElement(frontID+'-canvas'));var cNext=this.getByElement(nextID+'-canvas').getContext('2d');var cNextFillRect=function(){thisTemp.canvasFill(cNext,[[8,10],[22,19],[8,28]]);thisTemp.canvasFillRect(cNext,[[25,10,5,18]])};cNext.fillStyle=bBgColor;cNextFillRect();var cNextOver=function(event){cNext.clearRect(0,0,bWidth,bHeight);cNext.fillStyle=bOverColor;cNextFillRect()};var cNextOut=function(event){cNext.clearRect(0,0,bWidth,bHeight);cNext.fillStyle=bBgColor;cNextFillRect()};this.addListenerInside('mouseover',cNextOver,this.getByElement(nextID+'-canvas'));this.addListenerInside('mouseout',cNextOut,this.getByElement(nextID+'-canvas'));var cFull=this.getByElement(fullID+'-canvas').getContext('2d');var cFullFillRect=function(){thisTemp.canvasFillRect(cFull,[[19,10,9,3],[25,13,3,6],[10,19,3,9],[13,25,6,3]])};cFull.fillStyle=bBgColor;cFullFillRect();var cFullOver=function(){cFull.clearRect(0,0,bWidth,bHeight);cFull.fillStyle=bOverColor;cFullFillRect()};var cFullOut=function(){cFull.clearRect(0,0,bWidth,bHeight);cFull.fillStyle=bBgColor;cFullFillRect()};this.addListenerInside('mouseover',cFullOver,this.getByElement(fullID+'-canvas'));this.addListenerInside('mouseout',cFullOut,this.getByElement(fullID+'-canvas'));var cEscFull=this.getByElement(escFullID+'-canvas').getContext('2d');var cEscFullFillRect=function(){thisTemp.canvasFillRect(cEscFull,[[20,9,3,9],[23,15,6,3],[9,20,9,3],[15,23,3,6]])};cEscFull.fillStyle=bBgColor;cEscFullFillRect();var cEscFullOver=function(){cEscFull.clearRect(0,0,bWidth,bHeight);cEscFull.fillStyle=bOverColor;cEscFullFillRect()};var cEscFullOut=function(){cEscFull.clearRect(0,0,bWidth,bHeight);cEscFull.fillStyle=bBgColor;cEscFullFillRect()};this.addListenerInside('mouseover',cEscFullOver,this.getByElement(escFullID+'-canvas'));this.addListenerInside('mouseout',cEscFullOut,this.getByElement(escFullID+'-canvas'));var cMute=this.getByElement(muteID+'-canvas').getContext('2d');var cMuteFillRect=function(){thisTemp.canvasFill(cMute,[[10,15],[15,15],[21,10],[21,28],[15,23],[10,23]]);thisTemp.canvasFillRect(cMute,[[23,15,2,8],[27,10,2,18]])};cMute.fillStyle=bBgColor;cMuteFillRect();var cMuteOver=function(){cMute.clearRect(0,0,bWidth,bHeight);cMute.fillStyle=bOverColor;cMuteFillRect()};var cMuteOut=function(){cMute.clearRect(0,0,bWidth,bHeight);cMute.fillStyle=bBgColor;cMuteFillRect()};this.addListenerInside('mouseover',cMuteOver,this.getByElement(muteID+'-canvas'));this.addListenerInside('mouseout',cMuteOut,this.getByElement(muteID+'-canvas'));var cEscMute=this.getByElement(escMuteID+'-canvas').getContext('2d');var cEscMuteFillRect=function(){thisTemp.canvasFill(cEscMute,[[10,15],[15,15],[21,10],[21,28],[15,23],[10,23]]);thisTemp.canvasFill(cEscMute,[[23,13],[24,13],[33,25],[32,25]]);thisTemp.canvasFill(cEscMute,[[32,13],[33,13],[24,25],[23,25]])};cEscMute.fillStyle=bBgColor;cEscMuteFillRect();var cEscMuteOver=function(){cEscMute.clearRect(0,0,bWidth,bHeight);cEscMute.fillStyle=bOverColor;cEscMuteFillRect()};var cEscMuteOut=function(){cEscMute.clearRect(0,0,bWidth,bHeight);cEscMute.fillStyle=bBgColor;cEscMuteFillRect()};this.addListenerInside('mouseover',cEscMuteOver,this.getByElement(escMuteID+'-canvas'));this.addListenerInside('mouseout',cEscMuteOut,this.getByElement(escMuteID+'-canvas'));var cAdMute=this.getByElement(adMuteID+'-canvas').getContext('2d');var cAdMuteFillRect=function(){thisTemp.canvasFill(cAdMute,[[8,12],[12,12],[16,8],[16,21],[12,18],[8,18]]);thisTemp.canvasFillRect(cAdMute,[[18,12,2,6],[21,8,2,14]])};cAdMute.fillStyle=bBgColor;cAdMuteFillRect();var cAdMuteOver=function(){cAdMute.clearRect(0,0,bWidth,bHeight);cAdMute.fillStyle=bOverColor;cAdMuteFillRect()};var cAdMuteOut=function(){cAdMute.clearRect(0,0,bWidth,bHeight);cAdMute.fillStyle=bBgColor;cAdMuteFillRect()};this.addListenerInside('mouseover',cAdMuteOver,this.getByElement(adMuteID+'-canvas'));this.addListenerInside('mouseout',cAdMuteOut,this.getByElement(adMuteID+'-canvas'));var cAdEscMute=this.getByElement(adEscMuteID+'-canvas').getContext('2d');var cAdEscMuteFillRect=function(){thisTemp.canvasFill(cAdEscMute,[[8,12],[12,12],[16,8],[16,21],[12,18],[8,18]]);thisTemp.canvasFill(cAdEscMute,[[18,10],[20,10],[26,20],[24,20]]);thisTemp.canvasFill(cAdEscMute,[[25,10],[27,10],[20,20],[18,20]])};cAdEscMute.fillStyle=bBgColor;cAdEscMuteFillRect();var cAdEscMuteOver=function(){cAdEscMute.clearRect(0,0,bWidth,bHeight);cAdEscMute.fillStyle=bOverColor;cAdEscMuteFillRect()};var cAdEscMuteOut=function(){cAdEscMute.clearRect(0,0,bWidth,bHeight);cAdEscMute.fillStyle=bBgColor;cAdEscMuteFillRect()};this.addListenerInside('mouseover',cAdEscMuteOver,this.getByElement(adEscMuteID+'-canvas'));this.addListenerInside('mouseout',cAdEscMuteOut,this.getByElement(adEscMuteID+'-canvas'));var adPauseClose=this.getByElement(adPauseCloseID+'-canvas').getContext('2d');var adPauseCloseFillRect=function(){thisTemp.canvasFill(adPauseClose,[[4,6],[6,6],[16,15],[14,15]]);thisTemp.canvasFill(adPauseClose,[[14,6],[16,6],[6,15],[4,15]])};adPauseClose.fillStyle='#404856';adPauseCloseFillRect();var adPauseCloseOver=function(){adPauseClose.clearRect(0,0,bWidth,bHeight);adPauseClose.fillStyle=bOverColor;adPauseCloseFillRect()};var adPauseCloseOut=function(){adPauseClose.clearRect(0,0,bWidth,bHeight);adPauseClose.fillStyle='#404856';adPauseCloseFillRect()};this.addListenerInside('mouseover',adPauseCloseOver,this.getByElement(adPauseCloseID+'-canvas'));this.addListenerInside('mouseout',adPauseCloseOut,this.getByElement(adPauseCloseID+'-canvas'));var cLoading=this.getByElement(loadingID+'-canvas').getContext('2d');var cLoadingFillRect=function(){cLoading.save();var grad=cLoading.createLinearGradient(0,0,60,60);grad.addColorStop(0,bBgColor);var grad2=cLoading.createLinearGradient(0,0,80,60);grad2.addColorStop(1,bOverColor);var grad3=cLoading.createLinearGradient(0,0,80,60);grad3.addColorStop(1,'#FF9900');var grad4=cLoading.createLinearGradient(0,0,80,60);grad4.addColorStop(1,'#CC3300');cLoading.strokeStyle=grad;cLoading.lineWidth=8;cLoading.beginPath();cLoading.arc(30,30,25,0,0.4*Math.PI,false);cLoading.stroke();cLoading.closePath();cLoading.beginPath();cLoading.strokeStyle=grad2;cLoading.arc(30,30,25,0.5*Math.PI,0.9*Math.PI,false);cLoading.stroke();cLoading.beginPath();cLoading.strokeStyle=grad3;cLoading.arc(30,30,25,Math.PI,1.4*Math.PI,false);cLoading.stroke();cLoading.beginPath();cLoading.strokeStyle=grad4;cLoading.arc(30,30,25,1.5*Math.PI,1.9*Math.PI,false);cLoading.stroke();cLoading.closePath();cLoading.restore()};cLoading.fillStyle=bBgColor;cLoadingFillRect();var cPauseCenter=this.getByElement(pauseCenterID+'-canvas').getContext('2d');var cPauseCenterFillRect=function(){thisTemp.canvasFill(cPauseCenter,[[28,22],[59,38],[28,58]]);cPauseCenter.save();cPauseCenter.lineWidth=5;cPauseCenter.beginPath();cPauseCenter.arc(40,40,35,0,2*Math.PI,false);cPauseCenter.stroke();cPauseCenter.closePath();cPauseCenter.restore()};cPauseCenter.fillStyle=bBgColor;cPauseCenter.strokeStyle=bBgColor;cPauseCenterFillRect();var cPauseCenterOver=function(){cPauseCenter.clearRect(0,0,80,80);cPauseCenter.fillStyle=bOverColor;cPauseCenter.strokeStyle=bOverColor;cPauseCenterFillRect()};var cPauseCenterOut=function(){cPauseCenter.clearRect(0,0,80,80);cPauseCenter.fillStyle=bBgColor;cPauseCenter.strokeStyle=bBgColor;cPauseCenterFillRect()};this.addListenerInside('mouseover',cPauseCenterOver,this.getByElement(pauseCenterID+'-canvas'));this.addListenerInside('mouseout',cPauseCenterOut,this.getByElement(pauseCenterID+'-canvas'));var volumeBOOver=function(){thisTemp.css(volumeBOID,'backgroundColor',bOverColor);thisTemp.css(volumeBWID,'backgroundColor',bBgColor)};var volumeBOOut=function(){thisTemp.css(volumeBOID,'backgroundColor',bBgColor);thisTemp.css(volumeBWID,'backgroundColor',bOverColor)};this.addListenerInside('mouseover',volumeBOOver,this.getByElement(volumeBOID));this.addListenerInside('mouseout',volumeBOOut,this.getByElement(volumeBOID));var timeBOOver=function(){thisTemp.css(timeBOID,'backgroundColor',bOverColor);thisTemp.css(timeBWID,'backgroundColor',bBgColor)};var timeBOOut=function(){thisTemp.css(timeBOID,'backgroundColor',bBgColor);thisTemp.css(timeBWID,'backgroundColor',bOverColor)};this.addListenerInside('mouseover',timeBOOver,this.getByElement(timeBOID));this.addListenerInside('mouseout',timeBOOut,this.getByElement(timeBOID));this.addButtonEvent();this.newMenu();this.controlBarHide();this.keypress();this.changeVolume(this.vars['volume']);this.showFrontNext();setTimeout(function(){thisTemp.elementCoordinate()},100);this.checkBarWidth();var resize=function(){thisTemp.elementCoordinate();thisTemp.timeUpdateHandler();thisTemp.changeLoad();thisTemp.checkBarWidth();thisTemp.changeElementCoor();thisTemp.changePrompt();thisTemp.adPauseCoor();thisTemp.adOtherCoor()};this.addListenerInside('resize',resize,window)},newCanvas:function(id,width,height){return' '},addButtonEvent:function(){var thisTemp=this;var playClick=function(event){thisTemp.videoPlay();thisTemp.sendJS('clickEvent','actionScript->videoPlay')};this.addListenerInside('click',playClick,this.CB['play']);this.addListenerInside('click',playClick,this.CB['pauseCenter']);var pauseClick=function(event){thisTemp.videoPause();thisTemp.sendJS('clickEvent','actionScript->videoPause')};this.addListenerInside('click',pauseClick,this.CB['pause']);var frontClick=function(event){if(thisTemp.vars['front']){eval(thisTemp.vars['front']+'()');thisTemp.sendJS('clickEvent','actionScript->'+thisTemp.vars['front'])}};this.addListenerInside('click',frontClick,this.CB['front']);var nextClick=function(event){if(thisTemp.vars['next']){eval(thisTemp.vars['next']+'()');thisTemp.sendJS('clickEvent','actionScript->'+thisTemp.vars['next'])}};this.addListenerInside('click',nextClick,this.CB['next']);var muteClick=function(event){thisTemp.videoMute();thisTemp.sendJS('clickEvent','actionScript->videoMute')};this.addListenerInside('click',muteClick,this.CB['mute']);var escMuteClick=function(event){thisTemp.videoEscMute();thisTemp.sendJS('clickEvent','actionScript->videoEscMute')};this.addListenerInside('click',escMuteClick,this.CB['escMute']);var fullClick=function(event){thisTemp.fullScreen();thisTemp.sendJS('clickEvent','actionScript->fullScreen')};this.addListenerInside('click',fullClick,this.CB['full']);var escFullClick=function(event){thisTemp.quitFullScreen();thisTemp.sendJS('clickEvent','actionScript->quitFullScreen')};this.addListenerInside('click',escFullClick,this.CB['escFull']);var adSkipClick=function(event){if(thisTemp.CB['adSkip'].innerHTML==thisTemp.language['skipAd']){thisTemp.runFunction(thisTemp.config['adSkipClick'])}};this.addListenerInside('click',adSkipClick,this.CB['adSkip']);var adMuteClick=function(event){thisTemp.adMuteFunction()};this.addListenerInside('click',adMuteClick,this.CB['adMute']);var adEscMuteClick=function(event){thisTemp.adEscMuteFunction()};this.addListenerInside('click',adEscMuteClick,this.CB['adEscMute']);var adPauseCloseClick=function(event){thisTemp.adPauseCloseFunction()};this.addListenerInside('click',adPauseCloseClick,this.CB['adPauseClose']);var promptHide=function(event){thisTemp.promptShow(false)};var playOver=function(event){thisTemp.promptShow(thisTemp.CB['play'])};this.addListenerInside('mouseover',playOver,this.CB['play']);this.addListenerInside('mouseout',promptHide,this.CB['play']);var pauseOver=function(event){thisTemp.promptShow(thisTemp.CB['pause'])};this.addListenerInside('mouseover',pauseOver,this.CB['pause']);this.addListenerInside('mouseout',promptHide,this.CB['pause']);var frontOver=function(event){thisTemp.promptShow(thisTemp.CB['front'])};this.addListenerInside('mouseover',frontOver,this.CB['front']);this.addListenerInside('mouseout',promptHide,this.CB['front']);var nextOver=function(event){thisTemp.promptShow(thisTemp.CB['next'])};this.addListenerInside('mouseover',nextOver,this.CB['next']);this.addListenerInside('mouseout',promptHide,this.CB['next']);var muteOver=function(event){thisTemp.promptShow(thisTemp.CB['mute'])};this.addListenerInside('mouseover',muteOver,this.CB['mute']);this.addListenerInside('mouseout',promptHide,this.CB['mute']);var escMuteOver=function(event){thisTemp.promptShow(thisTemp.CB['escMute'])};this.addListenerInside('mouseover',escMuteOver,this.CB['escMute']);this.addListenerInside('mouseout',promptHide,this.CB['escMute']);var fullOver=function(event){thisTemp.promptShow(thisTemp.CB['full'])};this.addListenerInside('mouseover',fullOver,this.CB['full']);this.addListenerInside('mouseout',promptHide,this.CB['full']);var escFullOver=function(event){thisTemp.promptShow(thisTemp.CB['escFull'])};this.addListenerInside('mouseover',escFullOver,this.CB['escFull']);this.addListenerInside('mouseout',promptHide,this.CB['escFull']);var definitionOver=function(event){thisTemp.promptShow(thisTemp.CB['definition'])};this.addListenerInside('mouseover',definitionOver,this.CB['definition']);this.addListenerInside('mouseout',promptHide,this.CB['definition']);var playbackrateOver=function(event){thisTemp.promptShow(thisTemp.CB['playbackrate'])};this.addListenerInside('mouseover',playbackrateOver,this.CB['playbackrate']);this.addListenerInside('mouseout',promptHide,this.CB['playbackrate']);var volumePrompt=function(vol){var volumeBOXY=thisTemp.getCoor(thisTemp.CB['volumeBO']);var promptObj={title:thisTemp.language['volume']+vol+'%',x:volumeBOXY['x']+thisTemp.CB['volumeBO'].offsetWidth*0.5,y:volumeBOXY['y']};thisTemp.promptShow(false,promptObj)};var volumeObj={slider:this.CB['volumeBO'],follow:this.CB['volumeUp'],refer:this.CB['volumeBg'],grossValue:'volume',pd:true,startFun:function(vol){},monitorFun:function(vol){thisTemp.changeVolume(vol*0.01,false,false);volumePrompt(vol)},endFun:function(vol){},overFun:function(vol){volumePrompt(vol)}};this.slider(volumeObj);var volumeClickObj={refer:this.CB['volumeBg'],grossValue:'volume',fun:function(vol){thisTemp.changeVolume(vol*0.01,true,true)}};this.progressClick(volumeClickObj);this.timeButtonMouseDown();var volumeBgMove=function(event){var volumeBgXY=thisTemp.getCoor(thisTemp.CB['volumeBg']);var eventX=thisTemp.client(event)['x'];var eventVolume=parseInt((eventX-volumeBgXY['x'])*100/thisTemp.CB['volumeBg'].offsetWidth);var buttonPromptObj={title:thisTemp.language['volume']+eventVolume+'%',x:eventX,y:volumeBgXY['y']};thisTemp.promptShow(false,buttonPromptObj)};this.addListenerInside('mousemove',volumeBgMove,this.CB['volumeBg']);this.addListenerInside('mouseout',promptHide,this.CB['volumeBg']);this.addListenerInside('mouseout',promptHide,this.CB['volumeBO']);this.addDefListener();this.addPlaybackrate()},videoClick:function(){var thisTemp=this;var clearTimerClick=function(){if(thisTemp.timerClick!=null){if(thisTemp.timerClick.runing){thisTemp.timerClick.stop()}thisTemp.timerClick=null}};var timerClickFun=function(){clearTimerClick();thisTemp.isClick=false;if(thisTemp.adPlayerPlay){var ad=thisTemp.getNowAdvertisements();try{if(ad['link']!=''){window.open(ad['link'])}thisTemp.ajaxSuccessNull(ad['clickMonitor'])}catch(event){}}else{if(thisTemp.ckplayerConfig['config']['click']){thisTemp.playOrPause()}}};clearTimerClick();if(this.isClick){this.isClick=false;if(thisTemp.ckplayerConfig['config']['doubleClick']){if(!this.full){thisTemp.fullScreen()}else{thisTemp.quitFullScreen()}}}else{this.isClick=true;this.timerClick=new this.timer(300,timerClickFun,1)}},timeButtonMouseDown:function(){var thisTemp=this;var timePrompt=function(time){if(isNaN(time)){time=0}var timeButtonXY=thisTemp.getCoor(thisTemp.CB['timeButton']);var promptObj={title:thisTemp.formatTime(time),x:timeButtonXY['x']-thisTemp.pdCoor['x']+thisTemp.CB['timeButton'].offsetWidth*0.5,y:timeButtonXY['y']-thisTemp.pdCoor['y']};thisTemp.promptShow(false,promptObj)};var timeObj={slider:this.CB['timeButton'],follow:this.CB['timeProgress'],refer:this.CB['timeBoBg'],grossValue:'time',pd:false,startFun:function(time){thisTemp.isTimeButtonMove=false},monitorFun:function(time){},endFun:function(time){if(thisTemp.V){if(thisTemp.V.duration>0){thisTemp.needSeek=0;thisTemp.videoSeek(parseInt(time))}}},overFun:function(time){timePrompt(time)}};var timeClickObj={refer:this.CB['timeBoBg'],grossValue:'time',fun:function(time){if(thisTemp.V){if(thisTemp.V.duration>0){thisTemp.needSeek=0;thisTemp.videoSeek(parseInt(time))}}}};var timeBoBgmousemove=function(event){var timeBoBgXY=thisTemp.getCoor(thisTemp.CB['timeBoBg']);var eventX=thisTemp.client(event)['x'];var eventTime=parseInt((eventX-timeBoBgXY['x'])*thisTemp.V.duration/thisTemp.CB['timeBoBg'].offsetWidth);var buttonPromptObj={title:thisTemp.formatTime(eventTime),x:eventX,y:timeBoBgXY['y']};thisTemp.promptShow(false,buttonPromptObj);var def=false;if(!thisTemp.isUndefined(thisTemp.CB['definitionP'])){if(thisTemp.css(thisTemp.CB['definitionP'],'display')!='block'){def=true}}if(thisTemp.vars['preview']!=null&&def){buttonPromptObj['time']=eventTime;thisTemp.preview(buttonPromptObj)}};var promptHide=function(event){thisTemp.promptShow(false);if(thisTemp.previewDiv!=null){thisTemp.css([thisTemp.previewDiv,thisTemp.previewTop],'display','none')}};if(!this.vars['live']){this.isTimeButtonDown=true;this.addListenerInside('mousemove',timeBoBgmousemove,this.CB['timeBoBg']);this.addListenerInside('mouseout',promptHide,this.CB['timeBoBg'])}else{this.isTimeButtonDown=false;timeObj['removeListenerInside']=true;timeClickObj['removeListenerInside']=true}this.slider(timeObj);this.progressClick(timeClickObj)},progressClick:function(obj){var thisTemp=this;var referMouseClick=function(event){var referX=thisTemp.client(event)['x']-thisTemp.getCoor(obj['refer'])['x'];var rWidth=obj['refer'].offsetWidth;var grossValue=0;if(obj['grossValue']=='volume'){grossValue=100}else{if(thisTemp.V){grossValue=thisTemp.V.duration}}var nowZ=parseInt(referX*grossValue/rWidth);if(obj['fun']){if(obj['grossValue']==='time'){var sliderXY=thisTemp.getCoor(thisTemp.CB['timeButton']);sliderLeft=sliderXY['x'];if(!thisTemp.checkSlideLeft(referX,sliderLeft,rWidth)){return}var bimeButtonWB=thisTemp.CB['timeButton'].offsetWidth*0.5;thisTemp.css(thisTemp.CB['timeButton'],'left',(referX-bimeButtonWB)+'px');thisTemp.css(thisTemp.CB['timeProgress'],'width',(referX)+'px')}obj['fun'](nowZ)}};if(this.isUndefined(obj['removeListenerInside'])){this.addListenerInside('click',referMouseClick,obj['refer'])}else{this.removeListenerInside('click',referMouseClick,obj['refer'])}},slider:function(obj){var thisTemp=this;var clientX=0,criterionWidth=0,sliderLeft=0,referLeft=0;var value=0;var calculation=function(){var sLeft=parseInt(thisTemp.css(obj['slider'],'left'));var rWidth=obj['refer'].offsetWidth-obj['slider'].offsetWidth;var grossValue=0;if(thisTemp.isUndefined(sLeft)||isNaN(sLeft)){sLeft=0}if(obj['grossValue']=='volume'){grossValue=100}else{if(thisTemp.V){grossValue=thisTemp.V.duration}}return parseInt(sLeft*grossValue/rWidth)};var mDown=function(event){thisTemp.addListenerInside('mousemove',mMove,document);thisTemp.addListenerInside('mouseup',mUp,document);var referXY=thisTemp.getCoor(obj['refer']);var sliderXY=thisTemp.getCoor(obj['slider']);clientX=thisTemp.client(event)['x'];referLeft=referXY['x'];sliderLeft=sliderXY['x'];criterionWidth=clientX-sliderLeft;if(obj['startFun']){obj['startFun'](calculation())}};var mMove=function(event){clientX=thisTemp.client(event)['x'];var newX=clientX-criterionWidth-referLeft;if(newX<0){newX=0}if(newX>obj['refer'].offsetWidth-obj['slider'].offsetWidth){newX=obj['refer'].offsetWidth-obj['slider'].offsetWidth}if(obj['slider']===thisTemp.CB['timeButton']){if(!thisTemp.checkSlideLeft(newX,sliderLeft,obj['refer'].offsetWidth)){return}}thisTemp.css(obj['slider'],'left',newX+'px');thisTemp.css(obj['follow'],'width',(newX+obj['slider'].offsetWidth*0.5)+'px');var nowZ=calculation();if(obj['monitorFun']){obj['monitorFun'](nowZ)}};var mUp=function(event){thisTemp.removeListenerInside('mousemove',mMove,document);thisTemp.removeListenerInside('mouseup',mUp,document);if(obj['endFun']){obj['endFun'](calculation())}};var mOver=function(event){if(obj['overFun']){obj['overFun'](calculation())}};if(this.isUndefined(obj['removeListenerInside'])){this.addListenerInside('mousedown',mDown,obj['slider']);this.addListenerInside('mouseover',mOver,obj['slider'])}else{this.removeListenerInside('mousedown',mDown,obj['slider']);this.removeListenerInside('mouseover',mOver,obj['slider'])}},checkSlideLeft:function(newX,sliderLeft,refer){var timeSA=this.ckplayerConfig['config']['timeScheduleAdjust'];switch(timeSA){case 0:return false;break;case 2:if(newXsliderLeft){return false}break;case 4:if(!this.timeSliderLeftTemp){this.timeSliderLeftTemp=sliderLeft/refer}if(newXthis.timeSliderLeftTemp){this.timeSliderLeftTemp=timeSliderMax}}if(newX>this.timeSliderLeftTemp*refer){return false}break;default:return true;break}return true},loadingStart:function(rot){var thisTemp=this;if(this.isUndefined(rot)){rot=true}if(this.showFace){this.css(thisTemp.CB['loading'],'display','none')}if(this.timerLoading!=null){if(this.timerLoading.runing){this.timerLoading.stop()}this.timerLoading=null}var buffer=0;var loadingFun=function(){var nowRotate='0';try{nowRotate=thisTemp.css(thisTemp.CB['loadingCanvas'],'transform')||thisTemp.css(thisTemp.CB['loadingCanvas'],'-ms-transform')||thisTemp.css(thisTemp.CB['loadingCanvas'],'-moz-transform')||thisTemp.css(thisTemp.CB['loadingCanvas'],'-webkit-transform')||thisTemp.css(thisTemp.CB['loadingCanvas'],'-o-transform')||'0'}catch(event){}nowRotate=parseInt(nowRotate.replace('rotate(','').replace('deg);',''));nowRotate+=4;if(nowRotate>360){nowRotate=0}if(thisTemp.showFace){thisTemp.css(thisTemp.CB['loadingCanvas'],{transform:'rotate('+nowRotate+'deg)',msTransform:'rotate('+nowRotate+'deg)',mozTransform:'rotate('+nowRotate+'deg)',webkitTransform:'rotate('+nowRotate+'deg)',oTransform:'rotate('+nowRotate+'deg)'})}buffer++;if(buffer>=99){buffer=99}thisTemp.sendJS('buffer',buffer)};if(rot){this.timerLoading=new this.timer(10,loadingFun);if(this.showFace){this.css(thisTemp.CB['loading'],'display','block')}}else{thisTemp.sendJS('buffer',100)}},showFrontNext:function(){if(!this.showFace){return}if(this.vars['front']){this.css([this.CB['front'],this.CB['frontLine']],'display','block')}else{this.css([this.CB['front'],this.CB['frontLine']],'display','none')}if(this.vars['next']){this.css([this.CB['next'],this.CB['nextLine']],'display','block')}else{this.css([this.CB['next'],this.CB['nextLine']],'display','none')}},promptShow:function(ele,data){if(!this.showFace){return}var obj={};if(ele||data){if(!this.isUndefined(data)){obj=data}else{var offsetCoor=this.getCoor(ele);obj={title:this.getDataset(ele,'title'),x:offsetCoor['x']+ele.offsetWidth*0.5,y:offsetCoor['y']}}this.CB['prompt'].innerHTML=obj['title'];this.css(this.CB['prompt'],'display','block');var promoptWidth=this.getStringLen(obj['title'])*10;this.css(this.CB['promptBg'],'width',promoptWidth+'px');this.css(this.CB['prompt'],'width',promoptWidth+'px');promoptWidth+=10;var x=obj['x']-(promoptWidth*0.5);var y=this.PD.offsetHeight-obj['y']+8;if(x<0){x=0}if(x>this.PD.offsetWidth-promoptWidth){x=this.PD.offsetWidth-promoptWidth}this.css([this.CB['promptBg'],this.CB['prompt']],{display:'block',left:x+'px',bottom:y+'px'})}else{this.css([this.CB['promptBg'],this.CB['prompt']],{display:'none'})}},timerErrorFun:function(){var thisTemp=this;this.errorSend=false;var clearIntervalError=function(event){if(thisTemp.timerError!=null){if(thisTemp.timerError.runing){thisTemp.timerError.stop()}thisTemp.timerError=null}};var errorFun=function(event){clearIntervalError();thisTemp.error=true;thisTemp.errorUrl=thisTemp.getVideoUrl();if(!thisTemp.errorSend){thisTemp.errorSend=true;thisTemp.sendJS('error')}if(thisTemp.showFace){thisTemp.css(thisTemp.CB['errorText'],'display','block');thisTemp.css(thisTemp.CB['pauseCenter'],'display','none');thisTemp.css(thisTemp.CB['loading'],'display','none')}thisTemp.V.removeAttribute('poster');thisTemp.resetPlayer()};var errorListenerFun=function(event){setTimeout(function(){if(isNaN(thisTemp.V.duration)){errorFun(event)}},500)};if(!this.errorAdd){this.errorAdd=true;this.addListenerInside('error',errorListenerFun,this.V)}clearIntervalError();var timerErrorFun=function(){if(thisTemp.V&&parseInt(thisTemp.V.networkState)==3){errorFun()}};this.timerError=new this.timer(this.config['errorTime'],timerErrorFun)},judgeFullScreen:function(){var thisTemp=this;if(this.timerFull!=null){if(this.timerFull.runing){this.timerFull.stop()}this.timerFull=null}var fullFun=function(){thisTemp.isFullScreen()};this.timerFull=new this.timer(20,fullFun)},isFullScreen:function(){if(!this.showFace){return}var fullState=document.fullScreen||document.mozFullScreen||document.webkitIsFullScreen||document.msFullscreenElement;if(fullState&&!this.full){this.full=true;this.sendJS('full',true);this.elementCoordinate();this.css(this.CB['full'],'display','none');this.css(this.CB['escFull'],'display','block');if(this.vars['live']==0){this.timeUpdateHandler()}this.PD.appendChild(this.CB['menu'])}if(!fullState&&this.full){this.full=false;this.sendJS('full',false);this.elementCoordinate();this.css(this.CB['full'],'display','block');this.css(this.CB['escFull'],'display','none');if(this.timerFull!=null){if(this.timerFull.runing){this.timerFull.stop()}this.timerFull=null}if(this.vars['live']==0){this.timeUpdateHandler()}this.body.appendChild(this.CB['menu'])}},newMenu:function(){var thisTemp=this;var i=0;this.css(this.CB['menu'],{backgroundColor:'#FFFFFF',padding:'5px',position:'absolute',left:'10px',top:'20px',display:'none',zIndex:'999',color:'#A1A9BE',boxShadow:'2px 2px 3px #AAAAAA'});var mArr=this.contextMenu;var cMenu=this.ckplayerConfig['menu'];if(cMenu['name']){if(cMenu['link']){mArr[0]=[cMenu['name'],'link',cMenu['link']]}else{mArr[0]=[cMenu['name'],'default']}}if(cMenu['version']){mArr[1]=[cMenu['version'],'default','line']}if(cMenu['more']){if(typeof(cMenu['more'])=='object'){if(cMenu['more'].length>0){var moreArr=cMenu['more'];for(i=0;i'+me[0]+'';break;case'link':if(me[3]){me[3]='target="'+me[3]+'"'}html+=''+me[0]+'
';break;case'javaScript':html+=''+me[0]+'
';break;case'actionScript':html+=''+me[0]+'
';break;default:break}}this.CB['menu'].innerHTML=html;var pArr=this.CB['menu'].childNodes;for(i=0;icdH-2)&&cShow&&!thisTemp.getMetaDate()['paused']){controlBarShow(false)}}else{if(!cShow){controlBarShow(true)}}oldClient={x:client['x'],y:client['y']}};this.timerCBar=new this.timer(2000,cbarFun);var cdMove=function(event){var getClient=thisTemp.client(event);client['x']=getClient['x'];client['y']=getClient['y'];if(!cShow){controlBarShow(true)}};this.addListenerInside('mousemove',cdMove,thisTemp.CD);this.addListenerInside('ended',cdMove);this.addListenerInside('resize',cdMove,window);if(hide===true){cShow=true;force=true;controlBarShow(false)}if(hide===false){cShow=false;force=true;controlBarShow(true)}},keypress:function(){var thisTemp=this;var keyDown=function(eve){var keycode=eve.keyCode||eve.which;if(this.adPlayerPlay){return}switch(keycode){case 32:thisTemp.playOrPause();break;case 37:thisTemp.fastBack();break;case 39:thisTemp.fastNext();break;case 38:now=thisTemp.volume+thisTemp.ckplayerConfig['config']['volumeJump'];thisTemp.changeVolume(now>1?1:now);break;case 40:now=thisTemp.volume-thisTemp.ckplayerConfig['config']['volumeJump'];thisTemp.changeVolume(now<0?0:now);break;default:break}};this.addListenerInside('keydown',keyDown,window||document)},playbackRate:function(){if(!this.showFace){return}var thisTemp=this;var vArr=this.playbackRateArr;var html='';var nowD='';var i=0;if(!nowD){nowD=vArr[this.playbackRateDefault][1]}if(vArr.length>1){var zlen=0;for(i=0;i'+vArr[i][1]+''+html;var dlen=this.getStringLen(vArr[i][1]);if(dlen>zlen){zlen=dlen}}if(html){html+=''+nowD+'
'}this.CB['playbackrate'].innerHTML=nowD;this.CB['playbackrateP'].innerHTML=html;this.css([this.CB['playbackrate'],this.CB['playbackrateLine']],'display','block');var pArr=this.CB['playbackrateP'].childNodes;for(var i=0;inewPlaybackrate')}};this.addListenerInside('click',defClick,pArr[i])}var pW=(zlen*10)+20;this.css(this.CB['playbackrateP'],{width:pW+'px'});this.css(this.CB['playbackrate'],{width:pW+'px'});this.buttonWidth['playbackrate']=this.CB['playbackrate'].offsetWidth}else{this.CB['playbackrate'].innerHTML='';this.CB['playbackrateP'].innerHTML='';this.css([this.CB['playbackrate'],this.CB['playbackrateLine']],'display','none')}},addPlaybackrate:function(){var thisTemp=this;var setTimeOutP=null;var defClick=function(event){thisTemp.css(thisTemp.CB['playbackrateP'],{left:thisTemp.getCoor(thisTemp.CB['playbackrate'])['x']+'px',display:'block'})};this.addListenerInside('click',defClick,this.CB['playbackrate']);var defMouseOut=function(event){if(setTimeOutP){window.clearTimeout(setTimeOutP);setTimeOutP=null}setTimeOutP=setTimeout(function(event){thisTemp.css(thisTemp.CB['playbackrateP'],'display','none')},500)};this.addListenerInside('mouseout',defMouseOut,thisTemp.CB['playbackrateP']);var defMouseOver=function(event){if(setTimeOutP){window.clearTimeout(setTimeOutP);setTimeOutP=null}};this.addListenerInside('mouseover',defMouseOver,thisTemp.CB['playbackrateP'])},newPlaybackrate:function(title){var vArr=this.playbackRateArr;var nVArr=[];var i=0;for(i=0;i1){var zlen=0;for(i=dArr.length-1;i>-1;i--){html=''+dArr[i]+'
'+html;var dlen=this.getStringLen(dArr[i]);if(dlen>zlen){zlen=dlen}}if(html){html+=''+nowD+'
'}this.CB['definition'].innerHTML=nowD;this.CB['definitionP'].innerHTML=html;this.css([this.CB['definition'],this.CB['definitionLine']],'display','block');var pArr=this.CB['definitionP'].childNodes;for(var i=0;in){var arr=this.VA[n];if(arr.length>3){var title=arr[2];if(title){this.newDefinition(title)}}}},newDefinition:function(title){var vArr=this.VA;var nVArr=[];var i=0;for(i=0;i'}this.V.removeAttribute('src');this.V.innerHTML=source;this.V.currentSrc=nVArr[0][0]}}else{this.embedHls(vArr[0][0],this.vars['autoplay'])}this.V.autoplay='autoplay';this.V.load();this.timerErrorFun()},embedHls:function(url,autoplay){var thisTemp=this;if(Hls.isSupported()){var hls=new Hls();hls.loadSource(url);hls.attachMedia(this.V);hls.on(Hls.Events.MANIFEST_PARSED,function(){thisTemp.playerLoad();if(autoplay){thisTemp.videoPlay()}})}},prompt:function(){if(!this.showFace){return}var thisTemp=this;var prompt=this.vars['promptSpot'];if(prompt==null||this.promptArr.length>0){return}var showPrompt=function(event){if(thisTemp.promptElement==null){var random2='prompte'+thisTemp.randomString(5);var ele2=document.createElement('div');ele2.className=random2;thisTemp.PD.appendChild(ele2);thisTemp.promptElement=thisTemp.getByElement(random2);thisTemp.css(thisTemp.promptElement,{overflowX:'hidden',lineHeight:'22px',fontSize:'14px',color:'#FFFFFF',position:'absolute',display:'block',zIndex:'90'})}var pcon=thisTemp.getPromptTest();var pW=pcon['pW'],pT=pcon['pT'],pL=parseInt(thisTemp.css(this,'left'))-parseInt(pW*0.5);if(pcon['pL']>10){pL=pcon['pL']}if(pL<0){pL=0}thisTemp.css(thisTemp.promptElement,{width:pW+'px',left:(-pW-10)+'px',display:'block'});thisTemp.promptElement.innerHTML=thisTemp.getDataset(this,'words');thisTemp.css(thisTemp.promptElement,{left:pL+'px',top:(pT-thisTemp.promptElement.offsetHeight-10)+'px'})};var hidePrompt=function(event){if(thisTemp.promptElement!=null){thisTemp.css(thisTemp.promptElement,{display:'none'})}};var i=0;for(i=0;ithis.PD.offsetWidth-pW){pL=this.PD.offsetWidth-pW}return{pW:pW,pT:pT,pL:pL}},deletePrompt:function(){var arr=this.promptArr;if(arr.length>0){for(var i=0;ibw-parseInt(arr[i].offsetWidth*0.5)){left=bw-parseInt(arr[i].offsetWidth*0.5)}this.css(arr[i],{left:left+'px',display:'block'})}},preview:function(obj){var thisTemp=this;var preview={file:null,scale:0};preview=this.standardization(preview,this.vars['preview']);if(preview['file']==null||preview['scale']<=0){return}var srcArr=preview['file'];if(this.previewStart==0){this.previewStart=1;if(srcArr.length>0){var i=0;var imgW=0,imgH=0;var random=thisTemp.randomString(10);var loadNum=0;var loadImg=function(i){srcArr[i]=thisTemp.getNewUrl(srcArr[i]);var n=0;var img=new Image();img.src=srcArr[i];img.className=random+i;img.onload=function(event){loadNum++;if(thisTemp.previewDiv==null){imgW=img.width;imgH=img.height;thisTemp.previewWidth=parseInt(imgW*0.1);var ele=document.createElement('div');ele.className=random;thisTemp.PD.appendChild(ele);thisTemp.previewDiv=thisTemp.getByElement(random);var eleTop=(obj['y']-parseInt(imgH*0.1)+2);thisTemp.css(thisTemp.previewDiv,{width:srcArr.length*imgW*10+'px',height:parseInt(imgH*0.1)+'px',backgroundColor:'#000000',position:'absolute',left:'0px',top:eleTop+'px',display:'none',zIndex:'80'});ele.setAttribute('data-x','0');ele.setAttribute('data-y',eleTop);var ele2=document.createElement('div');ele2.className=random+'d2';thisTemp.PD.appendChild(ele2);thisTemp.previewTop=thisTemp.getByElement(ele2.className);thisTemp.css(thisTemp.previewTop,{width:parseInt(imgW*0.1)+'px',height:parseInt(imgH*0.1)+'px',position:'absolute',border:'5px solid '+thisTemp.css(thisTemp.CB['timeProgress'],'backgroundColor'),left:'0px',top:(obj['y']-parseInt(imgH*0.1)+2)+'px',display:'none',zIndex:'81'});var html='';for(n=0;n=imgW){sx=0;sy+=h}thisTemp.css(cimg,'display','none')}if(loadNum==srcArr.length){thisTemp.previewStart=2}else{i++;loadImg(i)}}}}loadImg(i);return}if(this.previewStart==2){var isTween=true;var nowNum=parseInt(obj['time']/this.vars['preview']['scale']);var numTotal=parseInt(thisTemp.getMetaDate()['duration']/this.vars['preview']['scale']);if(thisTemp.css(thisTemp.previewDiv,'display')=='none'){isTween=false}thisTemp.css(thisTemp.previewDiv,'display','block');var imgWidth=thisTemp.previewDiv.offsetWidth*0.01/srcArr.length;var left=(imgWidth*nowNum)-obj['x']+parseInt(imgWidth*0.5),top=obj['y']-thisTemp.previewDiv.offsetHeight;thisTemp.css(thisTemp.previewDiv,'top',top+2+'px');var topLeft=obj['x']-parseInt(imgWidth*0.5);var timepieces=0;if(topLeft<0){topLeft=0;timepieces=obj['x']-topLeft-imgWidth*0.5}if(topLeft>thisTemp.PD.offsetWidth-imgWidth){topLeft=thisTemp.PD.offsetWidth-imgWidth;timepieces=obj['x']-topLeft-imgWidth*0.5}if(left<0){left=0}if(left>numTotal*imgWidth-thisTemp.PD.offsetWidth){left=numTotal*imgWidth-thisTemp.PD.offsetWidth}thisTemp.css(thisTemp.previewTop,{left:topLeft+'px',top:top+2+'px',display:'block'});if(thisTemp.previewTop.offsetHeight>thisTemp.previewDiv.offsetHeight){thisTemp.css(thisTemp.previewTop,{height:thisTemp.previewDiv.offsetHeight-(thisTemp.previewTop.offsetHeight-thisTemp.previewDiv.offsetHeight)+'px'})}if(this.previewTween!=null){this.animatePause(this.previewTween);this.previewTween=null}var nowLeft=parseInt(thisTemp.css(thisTemp.previewDiv,'left'));var leftC=nowLeft+left;if(nowLeft==-(left+timepieces)){return}if(isTween){var obj={element:thisTemp.previewDiv,start:null,end:-(left+timepieces),speed:0.3};this.previewTween=this.animate(obj)}else{thisTemp.css(thisTemp.previewDiv,'left',-(left+timepieces)+'px')}}},deletePreview:function(){if(this.previewDiv!=null){this.deleteChild(this.previewDiv);this.previewDiv=null;this.previewStart=0}},changeVideo:function(){if(!this.html5Video){this.getVarsObject();this.V.newVideo(this.vars);return}var vArr=this.VA;var v=this.vars;var i=0;if(vArr.length<1){return}if(this.V!=null&&this.needSeek==0){this.needSeek=this.V.currentTime}if(v['poster']){this.V.poster=v['poster']}else{this.V.removeAttribute('poster')}if(v['loop']){this.V.loop='loop'}else{this.V.removeAttribute('loop')}if(v['seek']>0){this.needSeek=v['seek']}else{this.needSeek=0}if(this.getFileExt(vArr[0][0])!='.m3u8'){this.isM3u8=false}if(!this.isM3u8){if(vArr.length==1){this.V.innerHTML='';this.V.src=vArr[0][0]}else{var source='';vArr=this.arrSort(vArr);for(i=0;i'}this.V.removeAttribute('src');this.V.innerHTML=source}if(v['autoplay']){this.V.autoplay='autoplay'}else{this.V.removeAttribute('autoplay')}this.V.load()}else{this.embedHls(vArr[0][0],v['autoplay'])}if(!this.isUndefined(v['volume'])){this.changeVolume(v['volume'])}this.resetPlayer();this.timerErrorFun();if(this.vars['cktrack']){this.loadTrack()}},elementCoordinate:function(){this.pdCoor=this.getXY(this.PD);try{this.css(this.CB['pauseCenter'],{left:parseInt((this.PD.offsetWidth-80)*0.5)+'px',top:parseInt((this.PD.offsetHeight-80)*0.5)+'px'})}catch(event){}try{this.css(this.CB['loading'],{left:parseInt((this.PD.offsetWidth-60)*0.5)+'px',top:parseInt((this.PD.offsetHeight-60)*0.5)+'px'})}catch(event){}try{this.css(this.CB['errorText'],{left:parseInt((this.PD.offsetWidth-120)*0.5)+'px',top:parseInt((this.PD.offsetHeight-30)*0.5)+'px'})}catch(event){}try{this.css(this.CB['logo'],{left:parseInt(this.PD.offsetWidth-this.CB['logo'].offsetWidth-20)+'px',top:'20px'})}catch(event){}this.checkBarWidth()},checkBarWidth:function(){if(!this.showFace){return}var controlBarW=this.CB['controlBar'].offsetWidth;var ele=[];ele.push([[this.CB['full'],this.CB['escFull'],this.CB['fullLine']],this.buttonWidth['full']+2,'full']);if(this.vars['front']!=''){ele.push([[this.CB['front'],this.CB['frontLine']],this.buttonWidth['front']+2])}if(this.vars['next']!=''){ele.push([[this.CB['next'],this.CB['nextLine']],this.buttonWidth['next']+2])}if(this.CB['definition'].innerHTML!=''){ele.push([[this.CB['definition'],this.CB['definitionLine']],this.buttonWidth['definition']+2])}if((this.ckplayerConfig['config']['mobileVolumeBarShow']||!this.isMobile())&&this.css(this.CB['volume'],'display')=='block'){ele.push([[this.CB['volume']],this.buttonWidth['volume']]);ele.push([[this.CB['mute'],this.CB['escMute'],this.CB['muteLine']],this.buttonWidth['mute']+2,'mute'])}ele.push([[this.CB['timeText']],this.buttonWidth['timeText']]);ele.push([[this.CB['play'],this.CB['pause'],this.CB['playLine']],this.buttonWidth['play']+2,'play']);var i=0;var len=0;var isc=true;for(var i=0;i2){len+=nlen}else{isc=false}}if(isc){this.buttonLen=len;this.buttonArr=ele}len=this.buttonLen;ele=this.buttonArr;for(var i=0;icontrolBarW){len-=ele[i][1];this.css(ele[i][0],'display','none')}else{this.css(ele[i][0],'display','block');if(ele[i].length==3){var name=ele[i][2];switch(name){case'mute':if(this.volume==0){this.css(this.CB['mute'],'display','none')}else{this.css(this.CB['escMute'],'display','none')}break;case'play':this.playShow(this.V.paused?false:true);break;case'full':if(this.full){this.css(this.CB['full'],'display','none')}else{this.css(this.CB['escFull'],'display','none')}break}}}}},initPlayPause:function(){if(!this.showFace){return}if(this.vars['autoplay']){this.css([this.CB['play'],this.CB['pauseCenter']],'display','none');this.css(this.CB['pause'],'display','block')}else{this.css(this.CB['play'],'display','block');if(this.css(this.CB['errorText'],'display')=='none'){this.css(this.CB['pauseCenter'],'display','block')}this.css(this.CB['pause'],'display','none')}},loadedHandler:function(){this.loaded=true;if(this.vars['loaded']!=''){try{eval(this.vars['loaded']+'()')}catch(event){this.log(event)}}},playingHandler:function(){this.playShow(true);if(this.isFirstTimePlay&&!this.isUndefined(this.advertisements['front'])){this.isFirstTimePlay=false;this.adI=0;this.adType='front';this.adMuteInto();this.adIsVideoTime=true;this.adPlayStart=true;this.adVideoPlay=false;this.videoPause();this.advertisementsTime();this.advertisementsPlay();this.adSkipButtonShow();return}if(this.adPlayerPlay){return}if(this.needSeek>0){this.videoSeek(this.needSeek);this.needSeek=0}if(this.animatePauseArray.length>0){this.animateResume('pause')}if(this.playerType=='html5video'&&this.V!=null&&this.config['videoDrawImage']){this.sendVCanvas()}if(!this.isUndefined(this.advertisements['pause'])&&!this.adPlayStart){this.adPauseCloseFunction()}},adPausePlayer:function(){this.adI=0;this.adType='pause';this.adPauseShow=true;this.loadAdPause()},loadAdPause:function(){var ad=this.getNowAdvertisements();var type=ad['type'];var thisTemp=this;var width=this.PD.offsetWidth,height=this.PD.offsetHeight;if(this.isStrImage(type)&&this.adPauseShow){this.css(this.CB['adElement'],'display','block');var imgClass='adimg'+this.randomString(10);var imgHtml=' ';if(ad['link']){imgHtml=''+imgHtml+' '}this.CB['adElement'].innerHTML=imgHtml;this.addListenerInside('load',function(){var imgObj=new Image();imgObj.src=this.src;var imgWH=thisTemp.adjustmentWH(imgObj.width,imgObj.height);thisTemp.css([thisTemp.getByElement(imgClass),thisTemp.CB['adElement']],{width:imgWH['width']+'px',height:imgWH['height']+'px',border:'0px'});if(thisTemp.ckplayerConfig['style']['advertisement']['closeButtonShow']&&thisTemp.adPauseShow){thisTemp.css(thisTemp.CB['adPauseClose'],{display:'block'})}thisTemp.ajaxSuccessNull(ad['exhibitionMonitor']);thisTemp.adPauseCoor()},this.getByElement(imgClass));this.addListenerInside('click',function(){thisTemp.ajaxSuccessNull(ad['clickMonitor'])},this.CB['adElement']);var newI=this.adI;if(this.adI0){setTimeout(function(){if(thisTemp.adPauseShow){thisTemp.adI=newI;thisTemp.loadAdPause()}},ad['time']*1000)}}},adPauseCoor:function(){if(this.css(this.CB['adElement'],'display')=='block'){var w=this.CB['adElement'].offsetWidth,h=this.CB['adElement'].offsetHeight;var pw=this.PD.offsetWidth,ph=this.PD.offsetHeight;this.css(this.CB['adElement'],{top:(ph-h)*0.5+'px',left:(pw-w)*0.5+'px'});if(this.css(this.CB['adPauseClose'],'display')=='block'){this.css(this.CB['adPauseClose'],{top:(ph-h)*0.5-10+'px',left:(pw-w)*0.5+w-10+'px',})}}},adPauseCloseFunction:function(){this.CB['adElement'].innerHTML='';this.css([this.CB['adElement'],this.CB['adPauseClose']],'display','none');this.adPauseShow=false},advertisementsTime:function(nt){if(this.isUndefined(nt)){nt=0}var ad=this.advertisements[this.adType];if(nt>0){ad[this.adI]['time']=Math.ceil(nt)}this.adTimeAllTotal=0;for(var i=this.adI;i0){this.CB['adTime'].innerHTML=this.language['adTime'].replace('{$second}',this.adTimeAllTotal>9?this.adTimeAllTotal:'0'+this.adTimeAllTotal)}if(this.adPauseShow){this.adPauseCloseFunction()}this.adOtherCloseAll();this.adTimeTotal=-1},adSkipButtonShow:function(){var thisTemp=this;var skipConfig=this.ckplayerConfig['style']['advertisement'];var delayTimeTemp=skipConfig[this.adType+'SkipButtonDelay'];var timeFun=function(){if(delayTimeTemp>=0){thisTemp.CB['adSkip'].innerHTML=thisTemp.language['skipAdTime'].replace('{$second}',delayTimeTemp>9?delayTimeTemp:'0'+delayTimeTemp);setTimeout(timeFun,1000)}else{thisTemp.CB['adSkip'].innerHTML=thisTemp.language['skipAd']}delayTimeTemp--};if(skipConfig['skipButtonShow']){this.css(thisTemp.CB['adSkip'],'display','block');if(skipConfig[this.adType+'SkipButtonDelay']>0&&this.isUndefined(this.adSkipButtonTime)){timeFun()}else{thisTemp.css(thisTemp.CB['adSkip'],'display','block');thisTemp.CB['adSkip'].innerHTML=this.language['skipAd']}}},advertisementsPlay:function(){this.css([this.CB['adBackground'],this.CB['adElement'],this.CB['adBar'],this.CB['adLink']],'display','none');this.adPlayerPlay=false;var ad=this.advertisements[this.adType];if(this.adI==0&&(this.adType=='front'||this.adType=='insert'||this.adType=='end')){this.sendJS('process',this.adType+' ad play')}this.trackHide();if(this.adI';if(ad['link']){imgHtml=''+imgHtml+' '}this.CB['adElement'].innerHTML=imgHtml;this.addListenerInside('load',function(){var imgObj=new Image();imgObj.src=this.src;var imgWH=thisTemp.adjustmentWH(imgObj.width,imgObj.height);thisTemp.css(thisTemp.getByElement(imgClass),{width:imgWH['width']+'px',height:imgWH['height']+'px',border:'0px'});thisTemp.css(thisTemp.CB['adElement'],{width:imgWH['width']+'px',height:imgWH['height']+'px',top:(height-imgWH['height'])*0.5+'px',left:(width-imgWH['width'])*0.5+'px',});thisTemp.ajaxSuccessNull(ad['exhibitionMonitor'])},this.getByElement(imgClass));this.addListenerInside('click',function(){thisTemp.ajaxSuccessNull(ad['clickMonitor'])},this.CB['adElement']);if(!this.isUndefined(ad['time'])){this.adCountDown()}}else{this.css(this.CB['adBar'],'display','block');if(this.adVideoMute){this.css(this.CB['adEscMute'],'display','block');this.css(this.CB['adMute'],'display','none')}else{this.css(this.CB['adEscMute'],'display','none');this.css(this.CB['adMute'],'display','block')}this.CB['adElement'].innerHTML='';if(this.videoTemp['currentSrc']==''){this.videoTemp['currentSrc']=this.getCurrentSrc()}if(this.V.loop){this.videoTemp['loop']=true;this.V.loop=false}if(this.V!=null&&this.V.currentTime>0&&this.adIsVideoTime){this.adIsVideoTime=false;this.needSeek=this.V.currentTime}this.V.src=ad['file'];this.V.currentSrc=ad['file'];this.V.innerHTML='';this.V.play();this.adVideoPlay=true;this.ajaxSuccessNull(ad['exhibitionMonitor']);if(!this.adVideoMute){this.adEscMuteFunction()}}if(ad['link']){this.css(this.CB['adLink'],'display','block');var link=''+this.language['adLink']+' ';this.CB['adLink'].innerHTML=link;this.css(this.getByElement('ckadmorelink'),{color:'#FFFFFF',textDecoration:'none'});this.addListenerInside('click',function(){thisTemp.ajaxSuccessNull(ad['clickMonitor'])},this.CB['adLink'])}else{this.css(this.CB['adLink'],'display','none')}},adCountDown:function(){var thisTemp=this;if(this.adTimeTotal>0){if(!this.adIsPause){this.adTimeTotal--;this.showAdTime();this.adCountDownObj=null;this.adCountDownObj=setTimeout(function(){thisTemp.adCountDown()},1000)}}else{this.adI++;this.advertisementsPlay()}},adPlayerTimeHandler:function(time){var ad=this.getNowAdvertisements();var type=ad['type'];if(this.isStrImage(type)){return}if(this.adTimeTotal!=parseInt(time)){this.adTimeTotal=parseInt(time);this.showAdTime()}},showAdTime:function(){this.adTimeAllTotal--;var n=this.adTimeAllTotal;if(n<0){n=0}this.CB['adTime'].innerHTML=this.language['adTime'].replace('{$second}',n<10?'0'+n:n)},checkAdOther:function(t){if(this.adPlayerPlay){return}var adTime=this.advertisements['othertime'];var adPlay=this.advertisements['otherPlay'];for(var i=0;i=adTime[i]&&!adPlay[i]){adPlay[i]=true;this.newAdOther(i)}}},newAdOther:function(i){var thisTemp=this;var ad=this.advertisements['other'][i];var randomS=this.randomString(10);var adDivID='adother'+randomS;imgClassName='adimgother'+randomS;var adDiv=document.createElement('div');adDiv.className=adDivID;this.PD.appendChild(adDiv);ad['div']=adDivID;ad['element']=imgClassName;this.getByElement(adDivID).innerHTML=' ';this.css(adDivID,{position:'absolute',overflow:'hidden',zIndex:'996',top:'60px',left:'30px',cursor:'pointer'});if(this.ckplayerConfig['style']['advertisement']['closeOtherButtonShow']){var closeAdDivID='adotherclose'+randomS;var closeAdDiv=document.createElement('div');closeAdDiv.className=closeAdDivID;this.PD.appendChild(closeAdDiv);this.getByElement(closeAdDivID).innerHTML=this.newCanvas(closeAdDivID,20,20);ad['closeDiv']=closeAdDivID;ad['close']=false;this.css(closeAdDivID,{backgroundColor:'#f7f7f7',widht:'20px',height:'20px',position:'absolute',overflow:'hidden',zIndex:'997',top:'60px',left:'30px',borderRadius:'20px',cursor:'pointer'});var adOtherClose=this.getByElement(closeAdDivID+'-canvas').getContext('2d');var adOtherCloseFillRect=function(){thisTemp.canvasFill(adOtherClose,[[4,6],[6,6],[16,15],[14,15]]);thisTemp.canvasFill(adOtherClose,[[14,6],[16,6],[6,15],[4,15]])};adOtherClose.fillStyle='#404856';adOtherCloseFillRect();var adOtherCloseOver=function(){adOtherClose.clearRect(0,0,20,20);adOtherClose.fillStyle='#0782F5';adOtherCloseFillRect()};var adOtherCloseOut=function(){adOtherClose.clearRect(0,0,20,20);adOtherClose.fillStyle='#404856';adOtherCloseFillRect()};this.addListenerInside('mouseover',adOtherCloseOver,this.getByElement(closeAdDivID+'-canvas'));this.addListenerInside('mouseout',adOtherCloseOut,this.getByElement(closeAdDivID+'-canvas'))}this.addListenerInside('load',function(){var imgObj=new Image();imgObj.src=this.src;var imgWH=thisTemp.adjustmentWH(imgObj.width,imgObj.height);thisTemp.css([thisTemp.getByElement(imgClassName),thisTemp.getByElement(adDivID)],{width:imgWH['width']+'px',height:imgWH['height']+'px',border:'0px'});thisTemp.advertisements['other'][i]=ad;thisTemp.ajaxSuccessNull(ad['exhibitionMonitor']);thisTemp.adOtherCoor()},this.getByElement(imgClassName));this.addListenerInside('click',function(){thisTemp.adOtherClose(i)},this.getByElement(closeAdDivID));this.addListenerInside('click',function(){thisTemp.ajaxSuccessNull(ad['clickMonitor'])},this.getByElement(imgClassName));if(ad['time']>0){setTimeout(function(){thisTemp.adOtherClose(i)},ad['time']*1000)}},adOtherClose:function(i){var ad=this.advertisements['other'][i];if(!this.isUndefined(ad['close'])){if(!ad['close']){ad['close']=true;this.PD.removeChild(this.getByElement(ad['div']));this.PD.removeChild(this.getByElement(ad['closeDiv']))}}},adOtherCloseAll:function(){if(!this.isUndefined(this.advertisements['other'])){var ad=this.advertisements['other'];for(var i=0;i-1;i--){if(t>=adTime[i]&&t1&&!adPlay[i]){this.adI=0;this.adType='insert';this.adMuteInto();this.adIsVideoTime=true;this.adPlayStart=true;this.adVideoPlay=false;this.videoPause();this.advertisementsTime();this.advertisementsPlay();this.adSkipButtonShow();adPlay[i]=true;for(var n=0;n=width||h>=height){if(width/w>height/h){nh=height-20;nw=w*nh/h}else{nw=width-20;nh=h*nw/w}}else{nw=w;nh=h}return{width:nw,height:nh}},ajaxSuccessNull:function(url){if(!this.isUndefined(url)){var ajaxObj={url:url,success:function(data){}};this.ajax(ajaxObj)}},runFunction:function(s){try{var arr=s.split('->');switch(arr[0]){case'javaScript':eval(arr[1]+'()');break;case'actionScript':eval('this.'+arr[1]+'()');break}}catch(event){}},sendVCanvas:function(){if(this.timerVCanvas==null){this.css(this.V,'display','none');this.css(this.MD,'display','block');var thisTemp=this;var videoCanvas=function(){if(thisTemp.MDCX.width!=thisTemp.PD.offsetWidth){thisTemp.MDC.width=thisTemp.PD.offsetWidth}if(thisTemp.MDCX.height!=thisTemp.PD.offsetHeight){thisTemp.MDC.height=thisTemp.PD.offsetHeight}thisTemp.MDCX.clearRect(0,0,thisTemp.MDCX.width,thisTemp.MDCX.height);var coor=thisTemp.getProportionCoor(thisTemp.PD.offsetWidth,thisTemp.PD.offsetHeight,thisTemp.V.videoWidth,thisTemp.V.videoHeight);thisTemp.MDCX.drawImage(thisTemp.V,0,0,thisTemp.V.videoWidth,thisTemp.V.videoHeight,coor['x'],coor['y'],coor['width'],coor['height'])};this.timerVCanvas=new this.timer(0,videoCanvas)}},pauseHandler:function(){var thisTemp=this;this.playShow(false);if(this.animatePauseArray.length>0){this.animatePause('pause')}if(this.playerType=='html5video'&&this.V!=null&&this.config['videoDrawImage']){this.stopVCanvas()}if(!this.isUndefined(this.advertisements['pause'])&&!this.adPlayStart&&!this.adPauseShow){setTimeout(function(){if(!thisTemp.isUndefined(thisTemp.advertisements['pause'])&&!thisTemp.adPlayStart&&!thisTemp.adPauseShow&&thisTemp.time>1){thisTemp.adPausePlayer()}},300)}},stopVCanvas:function(){if(this.timerVCanvas!=null){this.css(this.V,'display','block');this.css(this.MD,'display','none');if(this.timerVCanvas.runing){this.timerVCanvas.stop()}this.timerVCanvas=null}},playShow:function(b){if(!this.showFace){return}if(b){this.css(this.CB['play'],'display','none');this.css(this.CB['pauseCenter'],'display','none');this.css(this.CB['pause'],'display','block')}else{this.css(this.CB['play'],'display','block');if(this.css(this.CB['errorText'],'display')=='none'){if(!this.adPlayerPlay){this.css(this.CB['pauseCenter'],'display','block')}}else{this.css(this.CB['pauseCenter'],'display','none')}this.css(this.CB['pause'],'display','none')}},seekedHandler:function(){this.resetTrack();this.isTimeButtonMove=true;if(this.V.paused){this.videoPlay()}},endedHandler:function(){if(this.adPlayerPlay){this.adI++;this.advertisementsPlay();return}if(!this.endAdPlay&&!this.isUndefined(this.advertisements['end'])){this.endAdPlay=true;this.adI=0;this.adType='end';this.adMuteInto();this.adIsVideoTime=true;this.adPlayStart=true;this.adVideoPlay=false;this.videoPause();this.advertisementsTime();this.advertisementsPlay();this.adSkipButtonShow();this.adReset=true;return}this.sendJS('ended');this.endedAdReset();if(!this.vars['loop']){this.videoSeek(0)}},endedAdReset:function(){var arr=[];var i=0;if(!this.isUndefined(this.advertisements['insertPlay'])){arr=this.advertisements['insertPlay'];for(i=0;i0){this.css(this.CB['mute'],'display','block');this.css(this.CB['escMute'],'display','none')}else{this.css(this.CB['mute'],'display','none');this.css(this.CB['escMute'],'display','block')}}catch(event){}}},timeUpdateHandler:function(){var duration=0;if(this.playerType=='html5video'){try{duration=this.V.duration}catch(event){}}if(duration>0){this.time=this.V.currentTime;this.timeTextHandler();this.trackShowHandler();if(this.isTimeButtonMove){this.timeProgress(this.time,duration)}}},timeProgress:function(time,duration){if(!this.showFace){return}var timeProgressBgW=this.CB['timeProgressBg'].offsetWidth;var timeBOW=parseInt((time*timeProgressBgW/duration)-(this.CB['timeButton'].offsetWidth*0.5));if(timeBOW>timeProgressBgW-this.CB['timeButton'].offsetWidth){timeBOW=timeProgressBgW-this.CB['timeButton'].offsetWidth}if(timeBOW<0){timeBOW=0}this.css(this.CB['timeProgress'],'width',timeBOW+'px');this.css(this.CB['timeButton'],'left',parseInt(timeBOW)+'px')},timeTextHandler:function(){if(!this.showFace){return}var duration=this.V.duration;var time=this.V.currentTime;if(isNaN(duration)||parseInt(duration)<0.2){duration=this.vars['duration']}this.CB['timeText'].innerHTML=this.formatTime(time)+' / '+this.formatTime(duration);if(this.CB['timeText'].offsetWidth>0){this.buttonWidth['timeText']=this.CB['timeText'].offsetWidth}},bufferEdHandler:function(){if(!this.showFace||this.playerType=='flashplayer'){return}var thisTemp=this;var clearTimerBuffer=function(){if(thisTemp.timerBuffer!=null){if(thisTemp.timerBuffer.runing){thisTemp.sendJS('buffer',100);thisTemp.timerBuffer.stop()}thisTemp.timerBuffer=null}};clearTimerBuffer();var bufferFun=function(){if(thisTemp.V.buffered.length>0){var duration=thisTemp.V.duration;var len=thisTemp.V.buffered.length;var bufferStart=thisTemp.V.buffered.start(len-1);var bufferEnd=thisTemp.V.buffered.end(len-1);var loadTime=bufferStart+bufferEnd;var loadProgressBgW=thisTemp.CB['timeProgressBg'].offsetWidth;var timeButtonW=thisTemp.CB['timeButton'].offsetWidth;var loadW=parseInt((loadTime*loadProgressBgW/duration)+timeButtonW);if(loadW>=loadProgressBgW){loadW=loadProgressBgW;clearTimerBuffer()}thisTemp.changeLoad(loadTime)}};this.timerBuffer=new this.timer(200,bufferFun)},changeLoad:function(loadTime){if(this.V==null){return}if(!this.showFace){return}var loadProgressBgW=this.CB['timeProgressBg'].offsetWidth;var timeButtonW=this.CB['timeButton'].offsetWidth;var duration=this.V.duration;if(this.isUndefined(loadTime)){loadTime=this.loadTime}else{this.loadTime=loadTime}var loadW=parseInt((loadTime*loadProgressBgW/duration)+timeButtonW);this.css(this.CB['loadProgress'],'width',loadW+'px')},judgeIsLive:function(){var thisTemp=this;if(this.timerError!=null){if(this.timerError.runing){this.timerError.stop()}this.timerError=null}this.error=false;if(this.showFace){this.css(this.CB['errorText'],'display','none')}var timeupdate=function(event){thisTemp.timeUpdateHandler()};if(!this.vars['live']){if(this.V!=null&&this.playerType=='html5video'){this.addListenerInside('timeupdate',timeupdate);thisTemp.timeTextHandler();thisTemp.prompt();setTimeout(function(){thisTemp.bufferEdHandler()},200)}}else{this.removeListenerInside('timeupdate',timeupdate);if(this.timerTime!=null){window.clearInterval(this.timerTime);timerTime=null}if(this.timerTime!=null){if(this.timerTime.runing){this.timerTime.stop()}this.timerTime=null}var timeFun=function(){if(thisTemp.V!=null&&!thisTemp.V.paused&&thisTemp.showFace){thisTemp.CB['timeText'].innerHTML=thisTemp.getNowDate()}};this.timerTime=new this.timer(1000,timeFun)}this.definition()},loadTrack:function(){if(this.playerType=='flashplayer'||this.vars['flashplayer']==true){return}var thisTemp=this;var track=this.vars['cktrack'];var obj={method:'get',dataType:'text',url:track,charset:'utf-8',success:function(data){thisTemp.track=thisTemp.parseSrtSubtitles(data);thisTemp.trackIndex=0;thisTemp.nowTrackShow={sn:''}}};this.ajax(obj)},resetTrack:function(){this.trackIndex=0;this.nowTrackShow={sn:''}},trackShowHandler:function(){if(!this.showFace||this.adPlayerPlay){return}if(this.track.length<1){return}if(this.trackIndex>=this.track.length){this.trackIndex=0}var nowTrack=this.track[this.trackIndex];if(this.time>=nowTrack['startTime']&&this.time<=nowTrack['endTime']){var nowShow=this.nowTrackShow;if(nowShow['sn']!=nowTrack['sn']){this.trackHide();this.trackShow(nowTrack)}}else{this.trackHide();this.checkTrack()}},trackShow:function(track){this.nowTrackShow=track;var arr=track['content'];for(var i=0;i=arr[i]['startTime']&&this.time<=arr[i]['endTime']){this.trackIndex=i;break}}},playOrPause:function(){if(!this.loaded){return}if(this.V==null){return}if(this.playerType=='flashplayer'){this.V.playOrPause();return}if(this.V.paused){this.videoPlay()}else{this.videoPause()}},videoPlay:function(){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.videoPlay();return}if(this.adPlayerPlay){this.eliminateAd();return}try{if(this.V.currentSrc){this.V.play()}}catch(event){}},videoPause:function(){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.videoPause();return}try{this.V.pause()}catch(event){}},videoSeek:function(time){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.videoSeek(time);return}var duration=this.getMetaDate()['duration'];if(duration>0&&time>duration){time=duration}if(time>=0){this.V.currentTime=time;this.sendJS('seekTime',time)}},changeVolume:function(vol,bg,button){if(this.loaded){if(this.playerType=='flashplayer'){this.V.changeVolume(time);return}}if(isNaN(vol)||this.isUndefined(vol)){vol=0}if(!this.loaded){this.vars['volume']=vol}if(!this.html5Video){this.V.changeVolume(vol);return}try{if(this.isUndefined(bg)){bg=true}}catch(e){}try{if(this.isUndefined(button)){button=true}}catch(e){}if(!vol){vol=0}if(vol<0){vol=0}if(vol>1){vol=1}try{this.V.volume=vol}catch(error){}this.volume=vol;if(bg&&this.showFace){var bgW=vol*this.CB['volumeBg'].offsetWidth;if(bgW<0){bgW=0}if(bgW>this.CB['volumeBg'].offsetWidth){bgW=this.CB['volumeBg'].offsetWidth}this.css(this.CB['volumeUp'],'width',bgW+'px')}if(button&&this.showFace){var buLeft=parseInt(this.CB['volumeUp'].offsetWidth-(this.CB['volumeBO'].offsetWidth*0.5));if(buLeft>this.CB['volumeBg'].offsetWidth-this.CB['volumeBO'].offsetWidth){buLeft=this.CB['volumeBg'].offsetWidth-this.CB['volumeBO'].offsetWidth}if(buLeft<0){buLeft=0}this.css(this.CB['volumeBO'],'left',buLeft+'px')}},videoMute:function(){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.videoMute();return}this.volumeTemp=this.V?(this.V.volume>0?this.V.volume:this.vars['volume']):this.vars['volume'];this.changeVolume(0)},videoEscMute:function(){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.videoEscMute();return}this.changeVolume(this.volumeTemp>0?this.volumeTemp:this.vars['volume'])},adMuteFunction:function(){if(!this.loaded){return}this.changeVolume(0);this.adVideoMute=true;this.css(this.CB['adEscMute'],'display','block');this.css(this.CB['adMute'],'display','none')},adEscMuteFunction:function(){if(!this.loaded){return}var v=this.ckplayerConfig['style']['advertisement']['videoVolume'];this.changeVolume(v);this.adMuteInto()},adMuteInto:function(){this.adVideoMute=false;this.css(this.CB['adEscMute'],'display','none');this.css(this.CB['adMute'],'display','block')},fastBack:function(){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.fastBack();return}var time=this.time-this.ckplayerConfig['config']['timeJump'];if(time<0){time=0}this.videoSeek(time)},fastNext:function(){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.fastNext();return}var time=this.time+this.ckplayerConfig['config']['timeJump'];if(time>this.V.duration){time=this.V.duration}this.videoSeek(time)},getCurrentSrc:function(){if(!this.loaded){return}if(this.playerType=='flashplayer'){return this.V.getCurrentSrc()}return this.V.currentSrc},switchFull:function(){if(this.full){this.quitFullScreen()}else{this.fullScreen()}},fullScreen:function(){if(this.html5Video&&this.playerType=='html5video'){var element=this.PD;if(element.requestFullscreen){element.requestFullscreen()}else if(element.mozRequestFullScreen){element.mozRequestFullScreen()}else if(element.webkitRequestFullscreen){element.webkitRequestFullscreen()}else if(element.msRequestFullscreen){element.msRequestFullscreen()}else if(element.oRequestFullscreen){element.oRequestFullscreen()}this.judgeFullScreen()}else{}},quitFullScreen:function(){if(this.html5Video&&this.playerType=='html5video'){if(document.exitFullscreen){document.exitFullscreen()}else if(document.msExitFullscreen){document.msExitFullscreen()}else if(document.mozCancelFullScreen){document.mozCancelFullScreen()}else if(document.oRequestFullscreen){document.oCancelFullScreen()}else if(document.requestFullscreen){document.requestFullscreen()}else if(document.webkitExitFullscreen){document.webkitExitFullscreen()}else{this.css(document.documentElement,'cssText','');this.css(document.document.body,'cssText','');this.css(this.PD,'cssText','')}this.judgeFullScreen()}},videoRotation:function(n){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.videoRotation(n);return}if(this.isUndefined(n)){n=0}var tf=this.css(this.V,'transform');if(this.isUndefined(tf)&&!tf){tf='rotate(0deg)'}var reg=tf.match(/rotate\([^)]+\)/);reg=reg?reg[0].replace('rotate(','').replace('deg)',''):'';if(reg==''){reg=0}else{reg=parseInt(reg)}if(n==-1){reg-=90}else if(n==1){reg+=90}else{if(n!=90&&n!=180&&n!=270&&n!=-90&&n!=-180&&n!=-270){reg=0}else{reg=n}}n=reg;var y90=n%90,y180=n%180,y270=n%270;var ys=false;if(y90==0&&y180==90&&y270==90){ys=true}if(y90==0&&y180==90&&y270==0){ys=true}if(y90==-0&&y180==-90&&y270==-90){ys=true}if(y90==-0&&y180==-90&&y270==-0){ys=true}tf=tf.replace(/rotate\([^)]+\)/,'').replace(/scale\([^)]+\)/,'')+' rotate('+n+'deg)';var cdW=this.CD.offsetWidth,cdH=this.CD.offsetHeight,vW=this.V.videoWidth,vH=this.V.videoHeight;if(vW>0&&vH>0){if(ys){if(cdW/cdH>vH/vW){nH=cdH;nW=vH*nH/vW}else{nW=cdW;nH=vW*nW/vH}this.css(this.V,'transform','rotate(0deg)');this.css(this.V,'transform','scale('+nH/cdW+','+nW/cdH+')'+tf)}else{this.css(this.V,'transform',tf)}}else{this.css(this.V,'transform',tf)}return},videoBrightness:function(n){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.videoBrightness(n);return}},videoContrast:function(n){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.videoContrast(n);return}},videoSaturation:function(n){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.videoSaturation(n);return}},videoHue:function(n){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.videoHue(n);return}},videoZoom:function(n){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.videoZoom(n);return}if(this.isUndefined(n)){n=1}if(n<0){n=0}if(n>2){n=2}var tf=this.css(this.V,'transform');tf=tf.replace(/scale\([^)]+\)/,'')+' scale('+n+')';this.videoScale=n;this.css(this.V,'transform',tf);return},videoProportion:function(w,h){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.videoProportion(w,h);return}},adPlay:function(){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.adPlay();return}if(this.adPlayerPlay){this.adIsPause=false;if(this.adPlayerPlay){var ad=this.getNowAdvertisements();var type=ad['type'];if(this.isStrImage(type)){this.adCountDown()}else{this.V.play()}}}},adPause:function(){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.adPause();return}if(this.adPlayerPlay){this.adIsPause=true;var ad=this.getNowAdvertisements();var type=ad['type'];if(type!='jpg'&&type!='jpeg'&&type!='png'&&type!='svg'&&type!='gif'){this.videoPause()}}},videoError:function(n){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.videoError(n);return}},changeConfig:function(){if(!this.loaded){return}if(this.playerType=='flashplayer'){this.V.changeConfig(arguments);return}var obj=this.ckplayerConfig;var arg=arguments;for(var i=0;i0){this.css(this.CD,'width',w+'px')}if(h>0){this.css(this.CD,'height',h+'px')}if(this.html5Video){this.elementCoordinate()}},changePlaybackRate:function(n){if(this.html5Video){var arr=this.playbackRateArr;n=parseInt(n);if(n';html+=param['v'];html+=' ';html+=' ';html+=' ';html+=' ';html+='';this.PD.innerHTML=html;this.V=this.getObjectById(vid);this.playerType='flashplayer'},getFlashVars:function(){this.getVarsObject();var v=this.vars;var z='';for(k in v){if(k!='flashplayer'&&k!='container'&&v[k]!=''){if(z!=''){z+='&'}var vk=v[k];if(vk==true){vk=1}if(vk==false){vk=0}z+=k+'='+vk}}if(!v.hasOwnProperty('volume')||!v['volume']){if(z!=''){z+='&'}z+='volume=0'}return z},isStrImage:function(s){if(s=='jpg'||s=='jpeg'||s=='png'||s=='svg'||s=='gif'){return true}return false},getVarsObject:function(){var v=this.vars;var f='',d='',w='';var arr=this.VA;var prompt=v['promptSpot'];var i=0;var video=this.vars['video'];if(typeof(video)=='object'){if(!this.isUndefined(typeof(video.length))){var arr=video;for(i=0;i '}w=w.replace('movie=','src=');return{w:w,v:v}},getMetaDate:function(){if(!this.loaded||this.V==null){return false}if(this.playerType=='html5video'){var duration=0;try{duration=!isNaN(this.V.duration)?this.V.duration:0}catch(event){this.log(event)}var data={duration:duration,volume:this.V.volume,playbackRate:this.V.playbackRate,width:this.PD.offsetWidth||this.V.offsetWidth||this.V.width,height:this.PD.offsetHeight||this.V.offsetHeight||this.V.height,streamWidth:this.V.videoWidth,streamHeight:this.V.videoHeight,videoWidth:this.V.offsetWidth,videoHeight:this.V.offsetHeight,paused:this.V.paused};return data}else{try{return this.V.getMetaDate()}catch(event){this.log(event)}}return false},getVideoUrl:function(){if(this.playerType=='flashplayer'){return this.V.getVideoUrl()}var arr=[];if(this.V.src){arr.push(this.V.src)}else{var uArr=this.V.childNodes;for(var i=0;i');var type='',fun='',link='',target='';if(callArr.length==2){var callM=callArr[0];var callE=callArr[1];if(!callE){return{type:'none'}}var val='';var eArr=[];type=callM;switch(callM){case'actionScript':if(callE.indexOf('(')>-1){eArr=callE.split('(');callE=eArr[0];val=eArr[1].replace(')','')}if(val==''){fun='thisTemp.'+callE+'()'}else{fun='thisTemp.'+callE+'('+val+')'}break;case'javaScript':if(callE.substr(0,11)=='[flashvars]'){callE=callE.substr(11);if(this.vars.hasOwnProperty(callE)){callE=this.vars[callE]}else{break}}if(callE.indexOf('(')>-1){eArr=callE.split('(');callE=eArr[0];val=eArr[1].replace(')','')}if(val==''){fun=callE+'()'}else{fun=callE+'('+val+')'}break;case"link":var callLink=(callE+',').split(',');if(callLink[0].substr(0,11)=='[flashvars]'){var fl=callLink[0].replace('[flashvars]','');if(this.vars.hasOwnProperty(fl)){callLink[0]=this.vars[fl]}else{break}}if(!callLink[1]){callLink[1]='_blank'}link=callLink[0];target=callLink[1];break}}return{type:type,fun:fun,link:link,target:target}},getPosition:function(obj){var pw=this.PD.offsetWidth,ph=this.PD.offsetHeight;var x=0,y=0;switch(obj['align']){case'left':x=obj['offsetX'];break;case'center':x=pw*0.5+obj['offsetX'];break;case'right':x=pw+obj['offsetX'];break}switch(obj['vAlign']){case'top':y=obj['offsetY'];break;case'middle':y=ph*0.5+obj['offsetY'];break;case'bottom':y=ph+obj['offsetY'];break}return{x:x,y:y}},addElement:function(attribute){var thisTemp=this;if(this.playerType=='flashplayer'){return this.V.addElement(attribute)}var i=0;var obj={list:null,x:'100%',y:"50%",position:null,alpha:1,backgroundColor:'',backAlpha:1,backRadius:0,clickEvent:''};obj=this.standardization(obj,attribute);var list=obj['list'];if(list==null){return''}var id='element'+this.randomString(10);var ele=document.createElement('div');ele.className=id;if(obj['x']){ele.setAttribute('data-x',obj['x'])}if(obj['y']){ele.setAttribute('data-y',obj['y'])}if(obj['position']!=null){ele.setAttribute('data-position',obj['position'].join(','))}this.PD.appendChild(ele);var eid=this.getByElement(id);this.css(eid,{position:'absolute',filter:'alpha(opacity:'+obj['alpha']+')',opacity:obj['alpha'].toString(),width:'800px',zIndex:'20'});var bgid='elementbg'+this.randomString(10);var bgAlpha=obj['alpha'].toString();var bgColor=obj['backgroundColor'].replace('0x','#');var html='';var idArr=[];var clickArr=[];if(!this.isUndefined(list)&&list.length>0){var textObj,returnObj,clickEvent;for(i=0;i '}else{html+=''}break;case'text':textObj={type:'text',text:'',color:'0xFFFFFF',size:14,font:this.fontFamily,leading:0,alpha:1,paddingLeft:0,paddingRight:0,paddingTop:0,paddingBottom:0,marginLeft:0,marginRight:0,marginTop:0,marginBottom:0,backgroundColor:'',backAlpha:1,backRadius:0,clickEvent:''};list[i]=this.standardization(textObj,list[i]);clickEvent=this.clickEvent(list[i]['clickEvent']);clickArr.push(clickEvent);if(clickEvent['type']=='link'){html+=''}else{html+=''}break;default:break}idArr.push(newEleid)}}var objClickEvent=this.clickEvent(obj['clickEvent']);eid.innerHTML='
'+html+'
';if(objClickEvent['type']=='javaScript'||objClickEvent['type']=='actionScript'){var objClickHandler=function(){eval(objClickEvent['fun']);thisTemp.sendJS('clickEvent',clk['type']+'->'+clk['fun'].replace('thisTemp.','').replace('()',''))};this.addListenerInside('click',objClickHandler,this.getByElement(bgid+'_c'))}this.css(bgid+'_c',{position:'absolute',zIndex:'2'});for(i=0;i'+clk['fun'].replace('thisTemp.','').replace('()',''))};this.addListenerInside('click',clickHandler,this.getByElement(idArr[i]))}switch(list[i]['type']){case'image':case'png':case'jpg':case'jpeg':case'gif':this.css(idArr[i],{float:'left',width:list[i]['width']+'px',height:list[i]['height']+'px',filter:'alpha(opacity:'+list[i]['alpha']+')',opacity:list[i]['alpha'].toString(),marginLeft:list[i]['marginLeft']+'px',marginRight:list[i]['marginRight']+'px',marginTop:list[i]['marginTop']+'px',marginBottom:list[i]['marginBottom']+'px',borderRadius:list[i]['radius']+'px',cursor:'pointer'});this.css(idArr[i]+'_image',{width:list[i]['width']+'px',height:list[i]['height']+'px',borderRadius:list[i]['radius']+'px'});break;case'text':this.css(idArr[i]+'_text',{filter:'alpha(opacity:'+list[i]['alpha']+')',opacity:list[i]['alpha'].toString(),borderRadius:list[i]['radius']+'px',fontFamily:list[i]['font'],fontSize:list[i]['size']+'px',color:list[i]['color'].replace('0x','#'),lineHeight:list[i]['leading']>0?list[i]['leading']+'px':'',paddingLeft:list[i]['paddingLeft']+'px',paddingRight:list[i]['paddingRight']+'px',paddingTop:list[i]['paddingTop']+'px',paddingBottom:list[i]['paddingBottom']+'px',whiteSpace:'nowrap',position:'absolute',zIndex:'3',cursor:'pointer'});this.css(idArr[i],{float:'left',width:this.getByElement(idArr[i]+'_text').offsetWidth+'px',height:this.getByElement(idArr[i]+'_text').offsetHeight+'px',marginLeft:list[i]['marginLeft']+'px',marginRight:list[i]['marginRight']+'px',marginTop:list[i]['marginTop']+'px',marginBottom:list[i]['marginBottom']+'px'});this.css(idArr[i]+'_bg',{width:this.getByElement(idArr[i]+'_text').offsetWidth+'px',height:this.getByElement(idArr[i]+'_text').offsetHeight+'px',filter:'alpha(opacity:'+list[i]['backAlpha']+')',opacity:list[i]['backAlpha'].toString(),borderRadius:list[i]['backRadius']+'px',backgroundColor:list[i]['backgroundColor'].replace('0x','#'),position:'absolute',zIndex:'2'});break;default:break}}this.css(bgid,{width:this.getByElement(bgid+'_c').offsetWidth+'px',height:this.getByElement(bgid+'_c').offsetHeight+'px',position:'absolute',filter:'alpha(opacity:'+bgAlpha+')',opacity:bgAlpha,backgroundColor:bgColor.replace('0x','#'),borderRadius:obj['backRadius']+'px',zIndex:'1'});this.css(eid,{width:this.getByElement(bgid).offsetWidth+'px',height:this.getByElement(bgid).offsetHeight+'px'});var eidCoor=this.calculationCoor(eid);this.css(eid,{left:eidCoor['x']+'px',top:eidCoor['y']+'px'});this.elementArr.push(eid.className);return eid},getElement:function(element){if(this.playerType=='flashplayer'){return this.V.getElement(element)}var ele=element;if(typeof(element)=='string'){ele=this.getByElement(element)}var coor=this.getCoor(ele);return{x:coor['x'],y:coor['y'],width:ele.offsetWidth,height:ele.offsetHeight,alpha:!this.isUndefined(this.css(ele,'opacity'))?parseFloat(this.css(ele,'opacity')):1,show:this.css(ele,'display')=='none'?false:true}},elementShow:function(element,show){if(this.playerType=='flashplayer'){this.V.elementShow(element,show);return}if(typeof(element)=='string'){if(element){this.css(ele,'display',show==true?'block':'none')}else{var arr=this.elementTempArr;for(var i=0;i0){position.push(null,null,null,null);var i=0;for(i=0;i-1){this.elementTempArr.push(obj['element'].className);this.elementArr.splice(def,1)}var css={};var pm=this.getElement(obj['element']);var t=0;var b=0;var c=0;var d=obj['speed']*1000;var timerTween=null;var tweenObj=null;var start=obj['start']==null?'':obj['start'].toString();var end=obj['end']==null?'':obj['end'].toString();switch(obj['parameter']){case'x':if(obj['start']==null){b=pm['x']}else{if(start.substring(start.length-1,start.length)=='%'){b=parseInt(start)*w*0.01}else{b=parseInt(start)}}if(obj['end']==null){c=pm['x']-b}else{if(end.substring(end.length-1,end.length)=='%'){c=parseInt(end)*w*0.01-b}else if(end.substring(0,1)=='-'||end.substring(0,1)=='+'){if(typeof(obj['end'])=='number'){c=parseInt(obj['end'])-b}else{c=parseInt(end)}}else{c=parseInt(end)-b}}break;case'y':if(obj['start']==null){b=pm['y']}else{if(start.substring(start.length-1,start.length)=='%'){b=parseInt(start)*h*0.01}else{b=parseInt(start)}}if(obj['end']==null){c=pm['y']-b}else{if(end.substring(end.length-1,end.length)=='%'){c=parseInt(end)*h*0.01-b}else if(end.substring(0,1)=='-'||end.substring(0,1)=='+'){if(typeof(obj['end'])=='number'){c=parseInt(obj['end'])-b}else{c=parseInt(end)}}else{c=parseInt(end)-b}}break;case'alpha':if(obj['start']==null){b=pm['alpha']*100}else{if(start.substring(start.length-1,start.length)=='%'){b=parseInt(obj['start'])}else{b=parseInt(obj['start']*100)}}if(obj['end']==null){c=pm['alpha']*100-b}else{if(end.substring(end.length-1,end.length)=='%'){c=parseInt(end)-b}else if(end.substring(0,1)=='-'||end.substring(0,1)=='+'){if(typeof(obj['end'])=='number'){c=parseInt(obj['end'])*100-b}else{c=parseInt(obj['end'])*100}}else{c=parseInt(obj['end'])*100-b}}break}var callBack=function(){var index=thisTemp.arrIndexOf(thisTemp.animateElementArray,animateId);if(index>-1){thisTemp.animateArray.splice(index,1);thisTemp.animateElementArray.splice(index,1)}index=thisTemp.arrIndexOf(thisTemp.animatePauseArray,animateId);if(index>-1){thisTemp.animatePauseArray.splice(index,1)}if(obj['callBack']!=null&&obj['element']&&obj['callBack']!='callBack'&&obj['callBack']!='tweenX'&&obj['tweenY']!='callBack'&&obj['callBack']!='tweenAlpha'){var cb=eval(obj['callBack']);cb(obj['element']);obj['callBack']=null}};var stopTween=function(){if(timerTween!=null){if(timerTween.runing){timerTween.stop()}timerTween=null}};var tweenX=function(){if(t-1){this.elementTempArr.splice(defX,1)}}catch(event){}thisTemp.elementArr.push(obj['element'].className);callBack()}};var tweenY=function(){if(t-1){this.elementTempArr.splice(defY,1)}}catch(event){}thisTemp.elementArr.push(obj['element'].className);callBack()}};var tweenAlpha=function(){if(t-1){this.elementTempArr.splice(defA,1)}}catch(event){}thisTemp.elementArr.push(obj['element'].className);callBack()}};switch(obj['parameter']){case'x':tweenObj=tweenX;break;case'y':tweenObj=tweenY;break;case'alpha':tweenObj=tweenAlpha;break;default:break}timerTween=new thisTemp.timer(10,tweenObj);timerTween.callBackFunction=callBack;if(obj['overStop']){var mouseOver=function(){if(timerTween!=null&&timerTween.runing){timerTween.stop()}};this.addListenerInside('mouseover',mouseOver,obj['element']);var mouseOut=function(){var start=true;if(obj['pauseStop']&&thisTemp.getMetaDate()['paused']){start=false}if(timerTween!=null&&!timerTween.runing&&start){timerTween.start()}};this.addListenerInside('mouseout',mouseOut,obj['element'])}this.animateArray.push(timerTween);this.animateElementArray.push(animateId);if(obj['pauseStop']){this.animatePauseArray.push(animateId)}return animateId},animateResume:function(id){if(this.playerType=='flashplayer'){this.V.animateResume(this.isUndefined(id)?'':id);return}var arr=[];if(id!=''&&!this.isUndefined(id)&&id!='pause'){arr.push(id)}else{if(id==='pause'){arr=this.animatePauseArray}else{arr=this.animateElementArray}}for(var i=0;i-1){this.animateArray[index].start()}}},animatePause:function(id){if(this.playerType=='flashplayer'){this.V.animatePause(this.isUndefined(id)?'':id);return}var arr=[];if(id!=''&&!this.isUndefined(id)&&id!='pause'){arr.push(id)}else{if(id==='pause'){arr=this.animatePauseArray}else{arr=this.animateElementArray}}for(var i=0;i-1){this.animateArray[index].stop()}}},deleteAnimate:function(id){if(this.playerType=='flashplayer'&&this.V){try{this.V.deleteAnimate(id)}catch(event){this.log(event)}return}var index=this.arrIndexOf(this.animateElementArray,id);if(index>-1){this.animateArray[index].callBackFunction();this.animateArray.splice(index,1);this.animateElementArray.splice(index,1)}},deleteElement:function(ele){if(this.playerType=='flashplayer'&&this.V){try{this.V.deleteElement(ele)}catch(event){}return}var def=this.arrIndexOf(this.elementArr,ele.className);if(def>-1){this.elementArr.splice(def,1)}try{def=this.arrIndexOf(this.elementTempArr,ele.className);if(def>-1){this.elementTempArr.splice(def,1)}}catch(event){}this.deleteAnimate(ele);this.deleteChild(ele)},getByElement:function(obj,parent){if(this.isUndefined(parent)){parent=document}var num=obj.substr(0,1);var res=[];if(num!='#'){if(num=='.'){obj=obj.substr(1,obj.length)}if(parent.getElementsByClassName){res=parent.getElementsByClassName(obj)}else{var reg=new RegExp(' '+obj+' ','i');var ele=parent.getElementsByTagName('*');for(var i=0;i0){return res[0]}else{return res}}else{if(num=='#'){obj=obj.substr(1,obj.length)}return document.getElementById(obj)}},css:function(elem,attribute,value){var i=0;var k='';if(typeof(elem)=='object'){if(!this.isUndefined(typeof(elem.length))){for(i=0;i0)?((m<10)?'0'+m+':':m+':'):'00:';tHours=(h>0)?((h<10)?'0'+h+':':h+':'):'';if(ishours){return tHours+tMinutes+tSeconds}else{return tMinutes+tSeconds}},randomString:function(len){len=len||16;var chars='abcdefghijklmnopqrstuvwxyz';var maxPos=chars.length;var val='';for(i=0;i127||str.charCodeAt(i)==94){len+=2}else{len++}}return len},createXHR:function(){if(window.XMLHttpRequest){return new XMLHttpRequest()}else if(window.ActiveXObject){try{return new ActiveXObject('Microsoft.XMLHTTP')}catch(event){try{return new ActiveXObject('Msxml2.XMLHTTP')}catch(event){this.eject(this.errorList[7])}}}else{this.eject(this.errorList[8])}},ajax:function(cObj){var thisTemp=this;var callback=null;var obj={method:'get',dataType:'json',charset:'utf-8',async:false,url:'',data:null,success:null};if(typeof(cObj)!='object'){this.eject(this.errorList[9]);return}obj=this.standardization(obj,cObj);if(obj.dataType==='json'||obj.dataType==='text'||obj.dataType==='html'){var xhr=this.createXHR();callback=function(){if(xhr.status==200){if(thisTemp.isUndefined(obj.success)){return}if(obj.dataType==='json'){try{obj.success(eval('('+xhr.responseText+')'))}catch(event){obj.success(null)}}else{obj.success(xhr.responseText)}}else{thisTemp.eject(thisTemp.errorList[10],'Ajax.status:'+xhr.status)}};obj.url=obj.url.indexOf('?')==-1?obj.url+'?rand='+this.randomString(6):obj.url;obj.data=this.formatParams(obj.data);if(obj.method==='get'&&!this.isUndefined(obj.data)){if(obj.data!=''){if(obj.url.indexOf('?')==-1){obj.url+='?'+obj.data}else{obj.url+='&'+obj.data}}}if(obj.async===true){xhr.onreadystatechange=function(){if(xhr.readyState==4&&callback!=null){callback()}}}xhr.open(obj.method,obj.url,obj.async);if(obj.method==='post'){xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');xhr.setRequestHeader('charset',obj['charset']);xhr.send(obj.data)}else{xhr.send(null)}if(obj.async===false){callback()}}else if(obj.dataType==='jsonp'){var oHead=document.getElementsByTagName('head')[0];var oScript=document.createElement('script');var callbackName='callback'+new Date().getTime();var params=this.formatParams(obj.data)+'&callback='+callbackName;callback=obj.success;oScript.src=obj.url.split('?')+'?'+params;oHead.insertBefore(oScript,oHead.firstChild);window[callbackName]=function(json){callback(json);oHead.removeChild(oScript)}}},loadJs:function(path,success){var oHead=document.getElementsByTagName('HEAD').item(0);var oScript=document.createElement('script');oScript.type='text/javascript';oScript.src=this.getNewUrl(path);oHead.appendChild(oScript);oScript.onload=function(){success()}},isMsie:function(){var browser=navigator.appName;var b_version=navigator.appVersion;var version=b_version.split(';');var trim_Version='';if(version.length>1){trim_Version=version[1].replace(/[ ]/g,'')}if(browser=='Microsoft Internet Explorer'&&(trim_Version=='MSIE6.0'||trim_Version=='MSIE7.0'||trim_Version=='MSIE8.0'||trim_Version=='MSIE9.0'||trim_Version=='MSIE10.0')){return false}return true},uploadFlash:function(){var swf;if(navigator.userAgent.indexOf('MSIE')>0){try{var swf=new ActiveXObject('ShockwaveFlash.ShockwaveFlash');return true}catch(e){return false}}if(navigator.userAgent.indexOf('Firefox')>0){swf=navigator.plugins['Shockwave Flash'];if(swf){return true}else{return false}}return true},supportVideo:function(){if(!this.isMsie()){return false}if(!!document.createElement('video').canPlayType){var vidTest=document.createElement('video');var oggTest;try{oggTest=vidTest.canPlayType('video/ogg; codecs="theora, vorbis"')}catch(error){oggTest=false}if(!oggTest){var h264Test;try{h264Test=vidTest.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"')}catch(error){h264Test=false}if(!h264Test){return false}else{if(h264Test=="probably"){return true}else{return false}}}else{if(oggTest=="probably"){return true}else{return false}}}else{return false}},getDataset:function(ele,z){try{return ele.dataset[z]}catch(error){try{return ele.getAttribute('data-'+z)}catch(error){return false}}},getObjectById:function(id){var x=null;var y=this.getByElement('#'+id);var r='embed';if(y&&y.nodeName=='OBJECT'){if(typeof(y.SetVariable)!='undefined'){x=y}else{var z=y.getElementsByTagName(r)[0];if(z){x=z}}}return x},formatParams:function(data){var arr=[];for(var i in data){arr.push(encodeURIComponent(i)+'='+encodeURIComponent(data[i]))}return arr.join('&')},arrSort:function(arr){var temp=[];for(var i=0;i-1){filepath=filepath.split('?')[0]}var pos='.'+filepath.replace(/.+\./,'');return pos.toLowerCase()}return''},isMobile:function(){if(navigator.userAgent.match(/(iPhone|iPad|iPod|Android|ios)/i)){return true}return false},isContains:function(str,key){return str.indexOf(key)>-1},getNewUrl:function(url){if(this.isContains(url,'?')){return url+='&'+this.randomString(8)+'='+this.randomString(8)}else{return url+='?'+this.randomString(8)+'='+this.randomString(8)}},client:function(event){var eve=event||window.event;if(this.isUndefined(eve)){eve={clientX:0,clientY:0}}return{x:eve.clientX+(document.documentElement.scrollLeft||this.body.scrollLeft)-this.pdCoor['x'],y:eve.clientY+(document.documentElement.scrollTop||this.body.scrollTop)-this.pdCoor['y']}},getCoor:function(obj){var coor=this.getXY(obj);return{x:coor['x']-this.pdCoor['x'],y:coor['y']-this.pdCoor['y']}},getXY:function(obj){var parObj=obj;var left=obj.offsetLeft;var top=obj.offsetTop;while(parObj=parObj.offsetParent){left+=parObj.offsetLeft;top+=parObj.offsetTop}return{x:left,y:top}},removeChild:function(){if(this.playerType=='html5video'){var i=0;var timerArr=[this.timerError,this.timerFull,this.timerTime,this.timerBuffer,this.timerClick,this.timerLoading,this.timerCBar,this.timerVCanvas];for(i=0;i0){name.lineTo(d[0],d[1])}else{name.moveTo(d[0],d[1])}}name.closePath();name.fill()},canvasFillRect:function(name,path){for(var i=0;i-1){this.elementArr.splice(def,1)}var childs=f.childNodes;for(var i=childs.length-1;i>=0;i--){f.removeChild(childs[i])}if(f&&f!=null&&f.parentNode){try{if(f.parentNode){f.parentNode.removeChild(f)}}catch(event){}}},getProportionCoor:function(stageW,stageH,vw,vh){var w=0,h=0,x=0,y=0;if(stageW/stageH]+>/g,'')};for(i=0;i0){arr.push(arrs[i])}else{if(arr.length>0){textSubtitles.push(arr)}arr=[]}}for(i=0;i=2){var sn=textSubtitle[0];var startTime=this.toSeconds(this.trim(textSubtitle[1].split(' --> ')[0]));var endTime=this.toSeconds(this.trim(textSubtitle[1].split(' --> ')[1]));var content=[delHtmlTag(textSubtitle[2])];if(textSubtitle.length>2){for(var j=3;j=thisTemp.numberTotal){thisTemp.stop()}};this.start=function(){if(!thisTemp.runing){thisTemp.runing=true;thisTemp.timeObj=window.setInterval(thisTemp.startFun,time)}};this.stop=function(){if(thisTemp.runing){thisTemp.runing=false;window.clearInterval(thisTemp.timeObj);thisTemp.timeObj=null}};if(time){this.time=time}if(fun){this.fun=fun}if(number){this.numberTotal=number}this.start()},toSeconds:function(t){var s=0.0;if(t){var p=t.split(':');for(i=0;i
+
+
+
+ true
+ 30
+ 100
+ true
+ 0
+ true
+ true
+ 200
+ true
+ true
+ 200
+
+ true
+ true
+ true
+ true
+ true
+
+ 10
+ 0.1
+ 1
+ true
+ false
+
+ false
+ false
+ true
+ true
+
+
+ false
+ 2
+ start
+
+ 1
+ false
+ true
+
+
+
+ 30
+ ,
+
+ adPlay,adPause,playOrPause,videoPlay,videoPause,videoMute,videoEscMute,videoClear,changeVolume,fastBack,fastNext,videoSeek,newVideo,getMetaDate,videoRotation,videoBrightness,videoContrast,videoSaturation,videoHue,videoZoom,videoProportion,videoError,addListener,removeListener,addElement,getElement,deleteElement,animate,animateResume,animatePause,deleteAnimate,changeConfig,getConfig,openUrl,fullScreen,quitFullScreen,switchFull,screenshot,custom,changeControlBarShow,getCurrentSrc
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/video/ckplayer/hls/LICENSE b/video/ckplayer/hls/LICENSE
new file mode 100644
index 0000000..8f263a0
--- /dev/null
+++ b/video/ckplayer/hls/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2017 Dailymotion (http://www.dailymotion.com)
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+src/remux/mp4-generator.js and src/demux/exp-golomb.js implementation in this project
+are derived from the HLS library for video.js (https://github.com/videojs/videojs-contrib-hls)
+
+That work is also covered by the Apache 2 License, following copyright:
+Copyright (c) 2013-2015 Brightcove
+
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/video/ckplayer/hls/hls.js b/video/ckplayer/hls/hls.js
new file mode 100644
index 0000000..205ae2d
--- /dev/null
+++ b/video/ckplayer/hls/hls.js
@@ -0,0 +1,15403 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Hls = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0 && this._events[type].length > m) {
+ this._events[type].warned = true;
+ console.error('(node) warning: possible EventEmitter memory ' +
+ 'leak detected. %d listeners added. ' +
+ 'Use emitter.setMaxListeners() to increase limit.',
+ this._events[type].length);
+ if (typeof console.trace === 'function') {
+ // not supported in IE 10
+ console.trace();
+ }
+ }
+ }
+
+ return this;
+};
+
+EventEmitter.prototype.on = EventEmitter.prototype.addListener;
+
+EventEmitter.prototype.once = function(type, listener) {
+ if (!isFunction(listener))
+ throw TypeError('listener must be a function');
+
+ var fired = false;
+
+ function g() {
+ this.removeListener(type, g);
+
+ if (!fired) {
+ fired = true;
+ listener.apply(this, arguments);
+ }
+ }
+
+ g.listener = listener;
+ this.on(type, g);
+
+ return this;
+};
+
+// emits a 'removeListener' event iff the listener was removed
+EventEmitter.prototype.removeListener = function(type, listener) {
+ var list, position, length, i;
+
+ if (!isFunction(listener))
+ throw TypeError('listener must be a function');
+
+ if (!this._events || !this._events[type])
+ return this;
+
+ list = this._events[type];
+ length = list.length;
+ position = -1;
+
+ if (list === listener ||
+ (isFunction(list.listener) && list.listener === listener)) {
+ delete this._events[type];
+ if (this._events.removeListener)
+ this.emit('removeListener', type, listener);
+
+ } else if (isObject(list)) {
+ for (i = length; i-- > 0;) {
+ if (list[i] === listener ||
+ (list[i].listener && list[i].listener === listener)) {
+ position = i;
+ break;
+ }
+ }
+
+ if (position < 0)
+ return this;
+
+ if (list.length === 1) {
+ list.length = 0;
+ delete this._events[type];
+ } else {
+ list.splice(position, 1);
+ }
+
+ if (this._events.removeListener)
+ this.emit('removeListener', type, listener);
+ }
+
+ return this;
+};
+
+EventEmitter.prototype.removeAllListeners = function(type) {
+ var key, listeners;
+
+ if (!this._events)
+ return this;
+
+ // not listening for removeListener, no need to emit
+ if (!this._events.removeListener) {
+ if (arguments.length === 0)
+ this._events = {};
+ else if (this._events[type])
+ delete this._events[type];
+ return this;
+ }
+
+ // emit removeListener for all listeners on all events
+ if (arguments.length === 0) {
+ for (key in this._events) {
+ if (key === 'removeListener') continue;
+ this.removeAllListeners(key);
+ }
+ this.removeAllListeners('removeListener');
+ this._events = {};
+ return this;
+ }
+
+ listeners = this._events[type];
+
+ if (isFunction(listeners)) {
+ this.removeListener(type, listeners);
+ } else if (listeners) {
+ // LIFO order
+ while (listeners.length)
+ this.removeListener(type, listeners[listeners.length - 1]);
+ }
+ delete this._events[type];
+
+ return this;
+};
+
+EventEmitter.prototype.listeners = function(type) {
+ var ret;
+ if (!this._events || !this._events[type])
+ ret = [];
+ else if (isFunction(this._events[type]))
+ ret = [this._events[type]];
+ else
+ ret = this._events[type].slice();
+ return ret;
+};
+
+EventEmitter.prototype.listenerCount = function(type) {
+ if (this._events) {
+ var evlistener = this._events[type];
+
+ if (isFunction(evlistener))
+ return 1;
+ else if (evlistener)
+ return evlistener.length;
+ }
+ return 0;
+};
+
+EventEmitter.listenerCount = function(emitter, type) {
+ return emitter.listenerCount(type);
+};
+
+function isFunction(arg) {
+ return typeof arg === 'function';
+}
+
+function isNumber(arg) {
+ return typeof arg === 'number';
+}
+
+function isObject(arg) {
+ return typeof arg === 'object' && arg !== null;
+}
+
+function isUndefined(arg) {
+ return arg === void 0;
+}
+
+},{}],2:[function(_dereq_,module,exports){
+// see https://tools.ietf.org/html/rfc1808
+
+/* jshint ignore:start */
+(function(root) {
+/* jshint ignore:end */
+
+ var URL_REGEX = /^((?:[^\/;?#]+:)?)(\/\/[^\/\;?#]*)?(.*?)??(;.*?)?(\?.*?)?(#.*?)?$/;
+ var FIRST_SEGMENT_REGEX = /^([^\/;?#]*)(.*)$/;
+ var SLASH_DOT_REGEX = /(?:\/|^)\.(?=\/)/g;
+ var SLASH_DOT_DOT_REGEX = /(?:\/|^)\.\.\/(?!\.\.\/).*?(?=\/)/g;
+
+ var URLToolkit = { // jshint ignore:line
+ // If opts.alwaysNormalize is true then the path will always be normalized even when it starts with / or //
+ // E.g
+ // With opts.alwaysNormalize = false (default, spec compliant)
+ // http://a.com/b/cd + /e/f/../g => http://a.com/e/f/../g
+ // With opts.alwaysNormalize = true (default, not spec compliant)
+ // http://a.com/b/cd + /e/f/../g => http://a.com/e/g
+ buildAbsoluteURL: function(baseURL, relativeURL, opts) {
+ opts = opts || {};
+ // remove any remaining space and CRLF
+ baseURL = baseURL.trim();
+ relativeURL = relativeURL.trim();
+ if (!relativeURL) {
+ // 2a) If the embedded URL is entirely empty, it inherits the
+ // entire base URL (i.e., is set equal to the base URL)
+ // and we are done.
+ if (!opts.alwaysNormalize) {
+ return baseURL;
+ }
+ var basePartsForNormalise = this.parseURL(baseURL);
+ if (!baseParts) {
+ throw new Error('Error trying to parse base URL.');
+ }
+ basePartsForNormalise.path = URLToolkit.normalizePath(basePartsForNormalise.path);
+ return URLToolkit.buildURLFromParts(basePartsForNormalise);
+ }
+ var relativeParts = this.parseURL(relativeURL);
+ if (!relativeParts) {
+ throw new Error('Error trying to parse relative URL.');
+ }
+ if (relativeParts.scheme) {
+ // 2b) If the embedded URL starts with a scheme name, it is
+ // interpreted as an absolute URL and we are done.
+ if (!opts.alwaysNormalize) {
+ return relativeURL;
+ }
+ relativeParts.path = URLToolkit.normalizePath(relativeParts.path);
+ return URLToolkit.buildURLFromParts(relativeParts);
+ }
+ var baseParts = this.parseURL(baseURL);
+ if (!baseParts) {
+ throw new Error('Error trying to parse base URL.');
+ }
+ if (!baseParts.netLoc && baseParts.path && baseParts.path[0] !== '/') {
+ // If netLoc missing and path doesn't start with '/', assume everthing before the first '/' is the netLoc
+ // This causes 'example.com/a' to be handled as '//example.com/a' instead of '/example.com/a'
+ var pathParts = FIRST_SEGMENT_REGEX.exec(baseParts.path);
+ baseParts.netLoc = pathParts[1];
+ baseParts.path = pathParts[2];
+ }
+ if (baseParts.netLoc && !baseParts.path) {
+ baseParts.path = '/';
+ }
+ var builtParts = {
+ // 2c) Otherwise, the embedded URL inherits the scheme of
+ // the base URL.
+ scheme: baseParts.scheme,
+ netLoc: relativeParts.netLoc,
+ path: null,
+ params: relativeParts.params,
+ query: relativeParts.query,
+ fragment: relativeParts.fragment
+ };
+ if (!relativeParts.netLoc) {
+ // 3) If the embedded URL's is non-empty, we skip to
+ // Step 7. Otherwise, the embedded URL inherits the
+ // (if any) of the base URL.
+ builtParts.netLoc = baseParts.netLoc;
+ // 4) If the embedded URL path is preceded by a slash "/", the
+ // path is not relative and we skip to Step 7.
+ if (relativeParts.path[0] !== '/') {
+ if (!relativeParts.path) {
+ // 5) If the embedded URL path is empty (and not preceded by a
+ // slash), then the embedded URL inherits the base URL path
+ builtParts.path = baseParts.path;
+ // 5a) if the embedded URL's is non-empty, we skip to
+ // step 7; otherwise, it inherits the of the base
+ // URL (if any) and
+ if (!relativeParts.params) {
+ builtParts.params = baseParts.params;
+ // 5b) if the embedded URL's is non-empty, we skip to
+ // step 7; otherwise, it inherits the of the base
+ // URL (if any) and we skip to step 7.
+ if (!relativeParts.query) {
+ builtParts.query = baseParts.query;
+ }
+ }
+ } else {
+ // 6) The last segment of the base URL's path (anything
+ // following the rightmost slash "/", or the entire path if no
+ // slash is present) is removed and the embedded URL's path is
+ // appended in its place.
+ var baseURLPath = baseParts.path;
+ var newPath = baseURLPath.substring(0, baseURLPath.lastIndexOf('/') + 1) + relativeParts.path;
+ builtParts.path = URLToolkit.normalizePath(newPath);
+ }
+ }
+ }
+ if (builtParts.path === null) {
+ builtParts.path = opts.alwaysNormalize ? URLToolkit.normalizePath(relativeParts.path) : relativeParts.path;
+ }
+ return URLToolkit.buildURLFromParts(builtParts);
+ },
+ parseURL: function(url) {
+ var parts = URL_REGEX.exec(url);
+ if (!parts) {
+ return null;
+ }
+ return {
+ scheme: parts[1] || '',
+ netLoc: parts[2] || '',
+ path: parts[3] || '',
+ params: parts[4] || '',
+ query: parts[5] || '',
+ fragment: parts[6] || ''
+ };
+ },
+ normalizePath: function(path) {
+ // The following operations are
+ // then applied, in order, to the new path:
+ // 6a) All occurrences of "./", where "." is a complete path
+ // segment, are removed.
+ // 6b) If the path ends with "." as a complete path segment,
+ // that "." is removed.
+ path = path.split('').reverse().join('').replace(SLASH_DOT_REGEX, '');
+ // 6c) All occurrences of "/../", where is a
+ // complete path segment not equal to "..", are removed.
+ // Removal of these path segments is performed iteratively,
+ // removing the leftmost matching pattern on each iteration,
+ // until no matching pattern remains.
+ // 6d) If the path ends with "/..", where is a
+ // complete path segment not equal to "..", that
+ // "/.." is removed.
+ while (path.length !== (path = path.replace(SLASH_DOT_DOT_REGEX, '')).length) {} // jshint ignore:line
+ return path.split('').reverse().join('');
+ },
+ buildURLFromParts: function(parts) {
+ return parts.scheme + parts.netLoc + parts.path + parts.params + parts.query + parts.fragment;
+ }
+ };
+
+/* jshint ignore:start */
+ if(typeof exports === 'object' && typeof module === 'object')
+ module.exports = URLToolkit;
+ else if(typeof define === 'function' && define.amd)
+ define([], function() { return URLToolkit; });
+ else if(typeof exports === 'object')
+ exports["URLToolkit"] = URLToolkit;
+ else
+ root["URLToolkit"] = URLToolkit;
+})(this);
+/* jshint ignore:end */
+
+},{}],3:[function(_dereq_,module,exports){
+var bundleFn = arguments[3];
+var sources = arguments[4];
+var cache = arguments[5];
+
+var stringify = JSON.stringify;
+
+module.exports = function (fn, options) {
+ var wkey;
+ var cacheKeys = Object.keys(cache);
+
+ for (var i = 0, l = cacheKeys.length; i < l; i++) {
+ var key = cacheKeys[i];
+ var exp = cache[key].exports;
+ // Using babel as a transpiler to use esmodule, the export will always
+ // be an object with the default export as a property of it. To ensure
+ // the existing api and babel esmodule exports are both supported we
+ // check for both
+ if (exp === fn || exp && exp.default === fn) {
+ wkey = key;
+ break;
+ }
+ }
+
+ if (!wkey) {
+ wkey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);
+ var wcache = {};
+ for (var i = 0, l = cacheKeys.length; i < l; i++) {
+ var key = cacheKeys[i];
+ wcache[key] = key;
+ }
+ sources[wkey] = [
+ Function(['require','module','exports'], '(' + fn + ')(self)'),
+ wcache
+ ];
+ }
+ var skey = Math.floor(Math.pow(16, 8) * Math.random()).toString(16);
+
+ var scache = {}; scache[wkey] = wkey;
+ sources[skey] = [
+ Function(['require'], (
+ // try to call default if defined to also support babel esmodule
+ // exports
+ 'var f = require(' + stringify(wkey) + ');' +
+ '(f.default ? f.default : f)(self);'
+ )),
+ scache
+ ];
+
+ var workerSources = {};
+ resolveSources(skey);
+
+ function resolveSources(key) {
+ workerSources[key] = true;
+
+ for (var depPath in sources[key][1]) {
+ var depKey = sources[key][1][depPath];
+ if (!workerSources[depKey]) {
+ resolveSources(depKey);
+ }
+ }
+ }
+
+ var src = '(' + bundleFn + ')({'
+ + Object.keys(workerSources).map(function (key) {
+ return stringify(key) + ':['
+ + sources[key][0]
+ + ',' + stringify(sources[key][1]) + ']'
+ ;
+ }).join(',')
+ + '},{},[' + stringify(skey) + '])'
+ ;
+
+ var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
+
+ var blob = new Blob([src], { type: 'text/javascript' });
+ if (options && options.bare) { return blob; }
+ var workerUrl = URL.createObjectURL(blob);
+ var worker = new Worker(workerUrl);
+ worker.objectURL = workerUrl;
+ return worker;
+};
+
+},{}],4:[function(_dereq_,module,exports){
+/**
+ * HLS config
+ */
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.hlsDefaultConfig = undefined;
+
+var _abrController = _dereq_(5);
+
+var _abrController2 = _interopRequireDefault(_abrController);
+
+var _bufferController = _dereq_(8);
+
+var _bufferController2 = _interopRequireDefault(_bufferController);
+
+var _capLevelController = _dereq_(9);
+
+var _capLevelController2 = _interopRequireDefault(_capLevelController);
+
+var _fpsController = _dereq_(10);
+
+var _fpsController2 = _interopRequireDefault(_fpsController);
+
+var _xhrLoader = _dereq_(55);
+
+var _xhrLoader2 = _interopRequireDefault(_xhrLoader);
+
+var _audioTrackController = _dereq_(7);
+
+var _audioTrackController2 = _interopRequireDefault(_audioTrackController);
+
+var _audioStreamController = _dereq_(6);
+
+var _audioStreamController2 = _interopRequireDefault(_audioStreamController);
+
+var _cues = _dereq_(47);
+
+var _cues2 = _interopRequireDefault(_cues);
+
+var _timelineController = _dereq_(15);
+
+var _timelineController2 = _interopRequireDefault(_timelineController);
+
+var _subtitleTrackController = _dereq_(14);
+
+var _subtitleTrackController2 = _interopRequireDefault(_subtitleTrackController);
+
+var _subtitleStreamController = _dereq_(13);
+
+var _subtitleStreamController2 = _interopRequireDefault(_subtitleStreamController);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+//#endif
+
+//#endif
+
+//#if subtitle
+
+//import FetchLoader from './utils/fetch-loader';
+//#if altaudio
+var hlsDefaultConfig = exports.hlsDefaultConfig = {
+ autoStartLoad: true, // used by stream-controller
+ startPosition: -1, // used by stream-controller
+ defaultAudioCodec: undefined, // used by stream-controller
+ debug: false, // used by logger
+ capLevelOnFPSDrop: false, // used by fps-controller
+ capLevelToPlayerSize: false, // used by cap-level-controller
+ initialLiveManifestSize: 1, // used by stream-controller
+ maxBufferLength: 30, // used by stream-controller
+ maxBufferSize: 60 * 1000 * 1000, // used by stream-controller
+ maxBufferHole: 0.5, // used by stream-controller
+ maxSeekHole: 2, // used by stream-controller
+ lowBufferWatchdogPeriod: 0.5, // used by stream-controller
+ highBufferWatchdogPeriod: 3, // used by stream-controller
+ nudgeOffset: 0.1, // used by stream-controller
+ nudgeMaxRetry: 3, // used by stream-controller
+ maxFragLookUpTolerance: 0.2, // used by stream-controller
+ liveSyncDurationCount: 3, // used by stream-controller
+ liveMaxLatencyDurationCount: Infinity, // used by stream-controller
+ liveSyncDuration: undefined, // used by stream-controller
+ liveMaxLatencyDuration: undefined, // used by stream-controller
+ maxMaxBufferLength: 600, // used by stream-controller
+ enableWorker: true, // used by demuxer
+ enableSoftwareAES: true, // used by decrypter
+ manifestLoadingTimeOut: 10000, // used by playlist-loader
+ manifestLoadingMaxRetry: 1, // used by playlist-loader
+ manifestLoadingRetryDelay: 1000, // used by playlist-loader
+ manifestLoadingMaxRetryTimeout: 64000, // used by playlist-loader
+ startLevel: undefined, // used by level-controller
+ levelLoadingTimeOut: 10000, // used by playlist-loader
+ levelLoadingMaxRetry: 4, // used by playlist-loader
+ levelLoadingRetryDelay: 1000, // used by playlist-loader
+ levelLoadingMaxRetryTimeout: 64000, // used by playlist-loader
+ fragLoadingTimeOut: 20000, // used by fragment-loader
+ fragLoadingMaxRetry: 6, // used by fragment-loader
+ fragLoadingRetryDelay: 1000, // used by fragment-loader
+ fragLoadingMaxRetryTimeout: 64000, // used by fragment-loader
+ fragLoadingLoopThreshold: 3, // used by stream-controller
+ startFragPrefetch: false, // used by stream-controller
+ fpsDroppedMonitoringPeriod: 5000, // used by fps-controller
+ fpsDroppedMonitoringThreshold: 0.2, // used by fps-controller
+ appendErrorMaxRetry: 3, // used by buffer-controller
+ loader: _xhrLoader2.default,
+ //loader: FetchLoader,
+ fLoader: undefined,
+ pLoader: undefined,
+ xhrSetup: undefined,
+ fetchSetup: undefined,
+ abrController: _abrController2.default,
+ bufferController: _bufferController2.default,
+ capLevelController: _capLevelController2.default,
+ fpsController: _fpsController2.default,
+ //#if altaudio
+ audioStreamController: _audioStreamController2.default,
+ audioTrackController: _audioTrackController2.default,
+ //#endif
+ //#if subtitle
+ subtitleStreamController: _subtitleStreamController2.default,
+ subtitleTrackController: _subtitleTrackController2.default,
+ timelineController: _timelineController2.default,
+ cueHandler: _cues2.default,
+ enableCEA708Captions: true, // used by timeline-controller
+ enableWebVTT: true, // used by timeline-controller
+ captionsTextTrack1Label: 'English', // used by timeline-controller
+ captionsTextTrack1LanguageCode: 'en', // used by timeline-controller
+ captionsTextTrack2Label: 'Spanish', // used by timeline-controller
+ captionsTextTrack2LanguageCode: 'es', // used by timeline-controller
+ //#endif
+ stretchShortVideoTrack: false, // used by mp4-remuxer
+ forceKeyFrameOnDiscontinuity: true, // used by ts-demuxer
+ abrEwmaFastLive: 3, // used by abr-controller
+ abrEwmaSlowLive: 9, // used by abr-controller
+ abrEwmaFastVoD: 3, // used by abr-controller
+ abrEwmaSlowVoD: 9, // used by abr-controller
+ abrEwmaDefaultEstimate: 5e5, // 500 kbps // used by abr-controller
+ abrBandWidthFactor: 0.95, // used by abr-controller
+ abrBandWidthUpFactor: 0.7, // used by abr-controller
+ abrMaxWithRealBitrate: false, // used by abr-controller
+ maxStarvationDelay: 4, // used by abr-controller
+ maxLoadingDelay: 4, // used by abr-controller
+ minAutoBitrate: 0 // used by hls
+};
+
+},{"10":10,"13":13,"14":14,"15":15,"47":47,"5":5,"55":55,"6":6,"7":7,"8":8,"9":9}],5:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = _dereq_(31);
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+var _bufferHelper = _dereq_(34);
+
+var _bufferHelper2 = _interopRequireDefault(_bufferHelper);
+
+var _errors = _dereq_(30);
+
+var _logger = _dereq_(50);
+
+var _ewmaBandwidthEstimator = _dereq_(48);
+
+var _ewmaBandwidthEstimator2 = _interopRequireDefault(_ewmaBandwidthEstimator);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+ * simple ABR Controller
+ * - compute next level based on last fragment bw heuristics
+ * - implement an abandon rules triggered if we have less than 2 frag buffered and if computed bw shows that we risk buffer stalling
+ */
+
+var AbrController = function (_EventHandler) {
+ _inherits(AbrController, _EventHandler);
+
+ function AbrController(hls) {
+ _classCallCheck(this, AbrController);
+
+ var _this = _possibleConstructorReturn(this, (AbrController.__proto__ || Object.getPrototypeOf(AbrController)).call(this, hls, _events2.default.FRAG_LOADING, _events2.default.FRAG_LOADED, _events2.default.FRAG_BUFFERED, _events2.default.ERROR));
+
+ _this.lastLoadedFragLevel = 0;
+ _this._nextAutoLevel = -1;
+ _this.hls = hls;
+ _this.onCheck = _this._abandonRulesCheck.bind(_this);
+ return _this;
+ }
+
+ _createClass(AbrController, [{
+ key: 'destroy',
+ value: function destroy() {
+ this.clearTimer();
+ _eventHandler2.default.prototype.destroy.call(this);
+ }
+ }, {
+ key: 'onFragLoading',
+ value: function onFragLoading(data) {
+ var frag = data.frag;
+ if (frag.type === 'main') {
+ if (!this.timer) {
+ this.timer = setInterval(this.onCheck, 100);
+ }
+ // lazy init of bw Estimator, rationale is that we use different params for Live/VoD
+ // so we need to wait for stream manifest / playlist type to instantiate it.
+ if (!this._bwEstimator) {
+ var hls = this.hls,
+ level = data.frag.level,
+ isLive = hls.levels[level].details.live,
+ config = hls.config,
+ ewmaFast = void 0,
+ ewmaSlow = void 0;
+
+ if (isLive) {
+ ewmaFast = config.abrEwmaFastLive;
+ ewmaSlow = config.abrEwmaSlowLive;
+ } else {
+ ewmaFast = config.abrEwmaFastVoD;
+ ewmaSlow = config.abrEwmaSlowVoD;
+ }
+ this._bwEstimator = new _ewmaBandwidthEstimator2.default(hls, ewmaSlow, ewmaFast, config.abrEwmaDefaultEstimate);
+ }
+ this.fragCurrent = frag;
+ }
+ }
+ }, {
+ key: '_abandonRulesCheck',
+ value: function _abandonRulesCheck() {
+ /*
+ monitor fragment retrieval time...
+ we compute expected time of arrival of the complete fragment.
+ we compare it to expected time of buffer starvation
+ */
+ var hls = this.hls,
+ v = hls.media,
+ frag = this.fragCurrent,
+ loader = frag.loader,
+ minAutoLevel = hls.minAutoLevel;
+
+ // if loader has been destroyed or loading has been aborted, stop timer and return
+ if (!loader || loader.stats && loader.stats.aborted) {
+ _logger.logger.warn('frag loader destroy or aborted, disarm abandonRules');
+ this.clearTimer();
+ return;
+ }
+ var stats = loader.stats;
+ /* only monitor frag retrieval time if
+ (video not paused OR first fragment being loaded(ready state === HAVE_NOTHING = 0)) AND autoswitching enabled AND not lowest level (=> means that we have several levels) */
+ if (v && (!v.paused && v.playbackRate !== 0 || !v.readyState) && frag.autoLevel && frag.level) {
+ var requestDelay = performance.now() - stats.trequest,
+ playbackRate = Math.abs(v.playbackRate);
+ // monitor fragment load progress after half of expected fragment duration,to stabilize bitrate
+ if (requestDelay > 500 * frag.duration / playbackRate) {
+ var levels = hls.levels,
+ loadRate = Math.max(1, stats.bw ? stats.bw / 8 : stats.loaded * 1000 / requestDelay),
+ // byte/s; at least 1 byte/s to avoid division by zero
+ // compute expected fragment length using frag duration and level bitrate. also ensure that expected len is gte than already loaded size
+ level = levels[frag.level],
+ levelBitrate = level.realBitrate ? Math.max(level.realBitrate, level.bitrate) : level.bitrate,
+ expectedLen = stats.total ? stats.total : Math.max(stats.loaded, Math.round(frag.duration * levelBitrate / 8)),
+ pos = v.currentTime,
+ fragLoadedDelay = (expectedLen - stats.loaded) / loadRate,
+ bufferStarvationDelay = (_bufferHelper2.default.bufferInfo(v, pos, hls.config.maxBufferHole).end - pos) / playbackRate;
+ // consider emergency switch down only if we have less than 2 frag buffered AND
+ // time to finish loading current fragment is bigger than buffer starvation delay
+ // ie if we risk buffer starvation if bw does not increase quickly
+ if (bufferStarvationDelay < 2 * frag.duration / playbackRate && fragLoadedDelay > bufferStarvationDelay) {
+ var fragLevelNextLoadedDelay = void 0,
+ nextLoadLevel = void 0;
+ // lets iterate through lower level and try to find the biggest one that could avoid rebuffering
+ // we start from current level - 1 and we step down , until we find a matching level
+ for (nextLoadLevel = frag.level - 1; nextLoadLevel > minAutoLevel; nextLoadLevel--) {
+ // compute time to load next fragment at lower level
+ // 0.8 : consider only 80% of current bw to be conservative
+ // 8 = bits per byte (bps/Bps)
+ var levelNextBitrate = levels[nextLoadLevel].realBitrate ? Math.max(levels[nextLoadLevel].realBitrate, levels[nextLoadLevel].bitrate) : levels[nextLoadLevel].bitrate;
+ fragLevelNextLoadedDelay = frag.duration * levelNextBitrate / (8 * 0.8 * loadRate);
+ if (fragLevelNextLoadedDelay < bufferStarvationDelay) {
+ // we found a lower level that be rebuffering free with current estimated bw !
+ break;
+ }
+ }
+ // only emergency switch down if it takes less time to load new fragment at lowest level instead
+ // of finishing loading current one ...
+ if (fragLevelNextLoadedDelay < fragLoadedDelay) {
+ _logger.logger.warn('loading too slow, abort fragment loading and switch to level ' + nextLoadLevel + ':fragLoadedDelay[' + nextLoadLevel + ']= minAutoLevel; i--) {
+ var levelInfo = levels[i],
+ levelDetails = levelInfo.details,
+ avgDuration = levelDetails ? levelDetails.totalduration / levelDetails.fragments.length : currentFragDuration,
+ live = levelDetails ? levelDetails.live : false,
+ adjustedbw = void 0;
+ // follow algorithm captured from stagefright :
+ // https://android.googlesource.com/platform/frameworks/av/+/master/media/libstagefright/httplive/LiveSession.cpp
+ // Pick the highest bandwidth stream below or equal to estimated bandwidth.
+ // consider only 80% of the available bandwidth, but if we are switching up,
+ // be even more conservative (70%) to avoid overestimating and immediately
+ // switching back.
+ if (i <= currentLevel) {
+ adjustedbw = bwFactor * currentBw;
+ } else {
+ adjustedbw = bwUpFactor * currentBw;
+ }
+ var bitrate = levels[i].realBitrate ? Math.max(levels[i].realBitrate, levels[i].bitrate) : levels[i].bitrate,
+ fetchDuration = bitrate * avgDuration / adjustedbw;
+
+ _logger.logger.trace('level/adjustedbw/bitrate/avgDuration/maxFetchDuration/fetchDuration: ' + i + '/' + Math.round(adjustedbw) + '/' + bitrate + '/' + avgDuration + '/' + maxFetchDuration + '/' + fetchDuration);
+ // if adjusted bw is greater than level bitrate AND
+ if (adjustedbw > bitrate && (
+ // fragment fetchDuration unknown OR live stream OR fragment fetchDuration less than max allowed fetch duration, then this level matches
+ // we don't account for max Fetch Duration for live streams, this is to avoid switching down when near the edge of live sliding window ...
+ !fetchDuration || live || fetchDuration < maxFetchDuration)) {
+ // as we are looping from highest to lowest, this will return the best achievable quality level
+
+ return i;
+ }
+ }
+ // not enough time budget even with quality level 0 ... rebuffering might happen
+ return -1;
+ }
+ }, {
+ key: 'nextAutoLevel',
+ get: function get() {
+ var forcedAutoLevel = this._nextAutoLevel;
+ var bwEstimator = this._bwEstimator;
+ // in case next auto level has been forced, and bw not available or not reliable, return forced value
+ if (forcedAutoLevel !== -1 && (!bwEstimator || !bwEstimator.canEstimate())) {
+ return forcedAutoLevel;
+ }
+ // compute next level using ABR logic
+ var nextABRAutoLevel = this._nextABRAutoLevel;
+ // if forced auto level has been defined, use it to cap ABR computed quality level
+ if (forcedAutoLevel !== -1) {
+ nextABRAutoLevel = Math.min(forcedAutoLevel, nextABRAutoLevel);
+ }
+ return nextABRAutoLevel;
+ },
+ set: function set(nextLevel) {
+ this._nextAutoLevel = nextLevel;
+ }
+ }, {
+ key: '_nextABRAutoLevel',
+ get: function get() {
+ var hls = this.hls,
+ maxAutoLevel = hls.maxAutoLevel,
+ levels = hls.levels,
+ config = hls.config,
+ minAutoLevel = hls.minAutoLevel;
+ var v = hls.media,
+ currentLevel = this.lastLoadedFragLevel,
+ currentFragDuration = this.fragCurrent ? this.fragCurrent.duration : 0,
+ pos = v ? v.currentTime : 0,
+
+ // playbackRate is the absolute value of the playback rate; if v.playbackRate is 0, we use 1 to load as
+ // if we're playing back at the normal rate.
+ playbackRate = v && v.playbackRate !== 0 ? Math.abs(v.playbackRate) : 1.0,
+ avgbw = this._bwEstimator ? this._bwEstimator.getEstimate() : config.abrEwmaDefaultEstimate,
+
+ // bufferStarvationDelay is the wall-clock time left until the playback buffer is exhausted.
+ bufferStarvationDelay = (_bufferHelper2.default.bufferInfo(v, pos, config.maxBufferHole).end - pos) / playbackRate;
+
+ // First, look to see if we can find a level matching with our avg bandwidth AND that could also guarantee no rebuffering at all
+ var bestLevel = this._findBestLevel(currentLevel, currentFragDuration, avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, config.abrBandWidthFactor, config.abrBandWidthUpFactor, levels);
+ if (bestLevel >= 0) {
+ return bestLevel;
+ } else {
+ _logger.logger.trace('rebuffering expected to happen, lets try to find a quality level minimizing the rebuffering');
+ // not possible to get rid of rebuffering ... let's try to find level that will guarantee less than maxStarvationDelay of rebuffering
+ // if no matching level found, logic will return 0
+ var maxStarvationDelay = currentFragDuration ? Math.min(currentFragDuration, config.maxStarvationDelay) : config.maxStarvationDelay,
+ bwFactor = config.abrBandWidthFactor,
+ bwUpFactor = config.abrBandWidthUpFactor;
+ if (bufferStarvationDelay === 0) {
+ // in case buffer is empty, let's check if previous fragment was loaded to perform a bitrate test
+ var bitrateTestDelay = this.bitrateTestDelay;
+ if (bitrateTestDelay) {
+ // if it is the case, then we need to adjust our max starvation delay using maxLoadingDelay config value
+ // max video loading delay used in automatic start level selection :
+ // in that mode ABR controller will ensure that video loading time (ie the time to fetch the first fragment at lowest quality level +
+ // the time to fetch the fragment at the appropriate quality level is less than ```maxLoadingDelay``` )
+ // cap maxLoadingDelay and ensure it is not bigger 'than bitrate test' frag duration
+ var maxLoadingDelay = currentFragDuration ? Math.min(currentFragDuration, config.maxLoadingDelay) : config.maxLoadingDelay;
+ maxStarvationDelay = maxLoadingDelay - bitrateTestDelay;
+ _logger.logger.trace('bitrate test took ' + Math.round(1000 * bitrateTestDelay) + 'ms, set first fragment max fetchDuration to ' + Math.round(1000 * maxStarvationDelay) + ' ms');
+ // don't use conservative factor on bitrate test
+ bwFactor = bwUpFactor = 1;
+ }
+ }
+ bestLevel = this._findBestLevel(currentLevel, currentFragDuration, avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay + maxStarvationDelay, bwFactor, bwUpFactor, levels);
+ return Math.max(bestLevel, 0);
+ }
+ }
+ }]);
+
+ return AbrController;
+}(_eventHandler2.default);
+
+exports.default = AbrController;
+
+},{"30":30,"31":31,"32":32,"34":34,"48":48,"50":50}],6:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _binarySearch = _dereq_(45);
+
+var _binarySearch2 = _interopRequireDefault(_binarySearch);
+
+var _bufferHelper = _dereq_(34);
+
+var _bufferHelper2 = _interopRequireDefault(_bufferHelper);
+
+var _demuxer = _dereq_(24);
+
+var _demuxer2 = _interopRequireDefault(_demuxer);
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = _dereq_(31);
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+var _levelHelper = _dereq_(35);
+
+var _levelHelper2 = _interopRequireDefault(_levelHelper);
+
+var _timeRanges = _dereq_(51);
+
+var _timeRanges2 = _interopRequireDefault(_timeRanges);
+
+var _errors = _dereq_(30);
+
+var _logger = _dereq_(50);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+ * Audio Stream Controller
+ */
+
+var State = {
+ STOPPED: 'STOPPED',
+ STARTING: 'STARTING',
+ IDLE: 'IDLE',
+ PAUSED: 'PAUSED',
+ KEY_LOADING: 'KEY_LOADING',
+ FRAG_LOADING: 'FRAG_LOADING',
+ FRAG_LOADING_WAITING_RETRY: 'FRAG_LOADING_WAITING_RETRY',
+ WAITING_TRACK: 'WAITING_TRACK',
+ PARSING: 'PARSING',
+ PARSED: 'PARSED',
+ BUFFER_FLUSHING: 'BUFFER_FLUSHING',
+ ENDED: 'ENDED',
+ ERROR: 'ERROR',
+ WAITING_INIT_PTS: 'WAITING_INIT_PTS'
+};
+
+var AudioStreamController = function (_EventHandler) {
+ _inherits(AudioStreamController, _EventHandler);
+
+ function AudioStreamController(hls) {
+ _classCallCheck(this, AudioStreamController);
+
+ var _this = _possibleConstructorReturn(this, (AudioStreamController.__proto__ || Object.getPrototypeOf(AudioStreamController)).call(this, hls, _events2.default.MEDIA_ATTACHED, _events2.default.MEDIA_DETACHING, _events2.default.AUDIO_TRACKS_UPDATED, _events2.default.AUDIO_TRACK_SWITCHING, _events2.default.AUDIO_TRACK_LOADED, _events2.default.KEY_LOADED, _events2.default.FRAG_LOADED, _events2.default.FRAG_PARSING_INIT_SEGMENT, _events2.default.FRAG_PARSING_DATA, _events2.default.FRAG_PARSED, _events2.default.ERROR, _events2.default.BUFFER_CREATED, _events2.default.BUFFER_APPENDED, _events2.default.BUFFER_FLUSHED, _events2.default.INIT_PTS_FOUND));
+
+ _this.config = hls.config;
+ _this.audioCodecSwap = false;
+ _this.ticks = 0;
+ _this._state = State.STOPPED;
+ _this.ontick = _this.tick.bind(_this);
+ _this.initPTS = [];
+ _this.waitingFragment = null;
+ return _this;
+ }
+
+ _createClass(AudioStreamController, [{
+ key: 'destroy',
+ value: function destroy() {
+ this.stopLoad();
+ if (this.timer) {
+ clearInterval(this.timer);
+ this.timer = null;
+ }
+ _eventHandler2.default.prototype.destroy.call(this);
+ this.state = State.STOPPED;
+ }
+
+ //Signal that video PTS was found
+
+ }, {
+ key: 'onInitPtsFound',
+ value: function onInitPtsFound(data) {
+ var demuxerId = data.id,
+ cc = data.frag.cc,
+ initPTS = data.initPTS;
+ if (demuxerId === 'main') {
+ //Always update the new INIT PTS
+ //Can change due level switch
+ this.initPTS[cc] = initPTS;
+ _logger.logger.log('InitPTS for cc:' + cc + ' found from video track:' + initPTS);
+
+ //If we are waiting we need to demux/remux the waiting frag
+ //With the new initPTS
+ if (this.state === State.WAITING_INIT_PTS) {
+ _logger.logger.log('sending pending audio frag to demuxer');
+ this.state = State.FRAG_LOADING;
+ //We have audio frag waiting or video pts
+ //Let process it
+ this.onFragLoaded(this.waitingFragment);
+ //Lets clean the waiting frag
+ this.waitingFragment = null;
+ }
+ }
+ }
+ }, {
+ key: 'startLoad',
+ value: function startLoad(startPosition) {
+ if (this.tracks) {
+ var lastCurrentTime = this.lastCurrentTime;
+ this.stopLoad();
+ if (!this.timer) {
+ this.timer = setInterval(this.ontick, 100);
+ }
+ this.fragLoadError = 0;
+ if (lastCurrentTime > 0 && startPosition === -1) {
+ _logger.logger.log('audio:override startPosition with lastCurrentTime @' + lastCurrentTime.toFixed(3));
+ this.state = State.IDLE;
+ } else {
+ this.lastCurrentTime = this.startPosition ? this.startPosition : startPosition;
+ this.state = State.STARTING;
+ }
+ this.nextLoadPosition = this.startPosition = this.lastCurrentTime;
+ this.tick();
+ } else {
+ this.startPosition = startPosition;
+ this.state = State.STOPPED;
+ }
+ }
+ }, {
+ key: 'stopLoad',
+ value: function stopLoad() {
+ var frag = this.fragCurrent;
+ if (frag) {
+ if (frag.loader) {
+ frag.loader.abort();
+ }
+ this.fragCurrent = null;
+ }
+ this.fragPrevious = null;
+ if (this.demuxer) {
+ this.demuxer.destroy();
+ this.demuxer = null;
+ }
+ this.state = State.STOPPED;
+ }
+ }, {
+ key: 'tick',
+ value: function tick() {
+ this.ticks++;
+ if (this.ticks === 1) {
+ this.doTick();
+ if (this.ticks > 1) {
+ setTimeout(this.tick, 1);
+ }
+ this.ticks = 0;
+ }
+ }
+ }, {
+ key: 'doTick',
+ value: function doTick() {
+ var pos,
+ track,
+ trackDetails,
+ hls = this.hls,
+ config = hls.config;
+ //logger.log('audioStream:' + this.state);
+ switch (this.state) {
+ case State.ERROR:
+ //don't do anything in error state to avoid breaking further ...
+ case State.PAUSED:
+ //don't do anything in paused state either ...
+ case State.BUFFER_FLUSHING:
+ break;
+ case State.STARTING:
+ this.state = State.WAITING_TRACK;
+ this.loadedmetadata = false;
+ break;
+ case State.IDLE:
+ var tracks = this.tracks;
+ // audio tracks not received => exit loop
+ if (!tracks) {
+ break;
+ }
+ // if video not attached AND
+ // start fragment already requested OR start frag prefetch disable
+ // exit loop
+ // => if media not attached but start frag prefetch is enabled and start frag not requested yet, we will not exit loop
+ if (!this.media && (this.startFragRequested || !config.startFragPrefetch)) {
+ break;
+ }
+ // determine next candidate fragment to be loaded, based on current position and
+ // end of buffer position
+ // if we have not yet loaded any fragment, start loading from start position
+ if (this.loadedmetadata) {
+ pos = this.media.currentTime;
+ } else {
+ pos = this.nextLoadPosition;
+ }
+ var media = this.mediaBuffer ? this.mediaBuffer : this.media,
+ bufferInfo = _bufferHelper2.default.bufferInfo(media, pos, config.maxBufferHole),
+ bufferLen = bufferInfo.len,
+ bufferEnd = bufferInfo.end,
+ fragPrevious = this.fragPrevious,
+ maxBufLen = config.maxMaxBufferLength,
+ audioSwitch = this.audioSwitch,
+ trackId = this.trackId;
+
+ // if buffer length is less than maxBufLen try to load a new fragment
+ if ((bufferLen < maxBufLen || audioSwitch) && trackId < tracks.length) {
+ trackDetails = tracks[trackId].details;
+ // if track info not retrieved yet, switch state and wait for track retrieval
+ if (typeof trackDetails === 'undefined') {
+ this.state = State.WAITING_TRACK;
+ break;
+ }
+
+ // we just got done loading the final fragment, check if we need to finalize media stream
+ if (!audioSwitch && !trackDetails.live && fragPrevious && fragPrevious.sn === trackDetails.endSN) {
+ // if we are not seeking or if we are seeking but everything (almost) til the end is buffered, let's signal eos
+ // we don't compare exactly media.duration === bufferInfo.end as there could be some subtle media duration difference when switching
+ // between different renditions. using half frag duration should help cope with these cases.
+ if (!this.media.seeking || this.media.duration - bufferEnd < fragPrevious.duration / 2) {
+ // Finalize the media stream
+ this.hls.trigger(_events2.default.BUFFER_EOS, { type: 'audio' });
+ this.state = State.ENDED;
+ break;
+ }
+ }
+
+ // find fragment index, contiguous with end of buffer position
+ var fragments = trackDetails.fragments,
+ fragLen = fragments.length,
+ start = fragments[0].start,
+ end = fragments[fragLen - 1].start + fragments[fragLen - 1].duration,
+ frag = void 0;
+
+ // When switching audio track, reload audio as close as possible to currentTime
+ if (audioSwitch) {
+ if (trackDetails.live && !trackDetails.PTSKnown) {
+ _logger.logger.log('switching audiotrack, live stream, unknown PTS,load first fragment');
+ bufferEnd = 0;
+ } else {
+ bufferEnd = pos;
+ // if currentTime (pos) is less than alt audio playlist start time, it means that alt audio is ahead of currentTime
+ if (trackDetails.PTSKnown && pos < start) {
+ // if everything is buffered from pos to start or if audio buffer upfront, let's seek to start
+ if (bufferInfo.end > start || bufferInfo.nextStart) {
+ _logger.logger.log('alt audio track ahead of main track, seek to start of alt audio track');
+ this.media.currentTime = start + 0.05;
+ } else {
+ return;
+ }
+ }
+ }
+ }
+ if (trackDetails.initSegment && !trackDetails.initSegment.data) {
+ frag = trackDetails.initSegment;
+ }
+ // if bufferEnd before start of playlist, load first fragment
+ else if (bufferEnd <= start) {
+ frag = fragments[0];
+ if (trackDetails.live && frag.loadIdx && frag.loadIdx === this.fragLoadIdx) {
+ // we just loaded this first fragment, and we are still lagging behind the start of the live playlist
+ // let's force seek to start
+ var nextBuffered = bufferInfo.nextStart ? bufferInfo.nextStart : start;
+ _logger.logger.log('no alt audio available @currentTime:' + this.media.currentTime + ', seeking @' + (nextBuffered + 0.05));
+ this.media.currentTime = nextBuffered + 0.05;
+ return;
+ }
+ } else {
+ var foundFrag = void 0;
+ var maxFragLookUpTolerance = config.maxFragLookUpTolerance;
+ var fragNext = fragPrevious ? fragments[fragPrevious.sn - fragments[0].sn + 1] : undefined;
+ var fragmentWithinToleranceTest = function fragmentWithinToleranceTest(candidate) {
+ // offset should be within fragment boundary - config.maxFragLookUpTolerance
+ // this is to cope with situations like
+ // bufferEnd = 9.991
+ // frag[Ø] : [0,10]
+ // frag[1] : [10,20]
+ // bufferEnd is within frag[0] range ... although what we are expecting is to return frag[1] here
+ // frag start frag start+duration
+ // |-----------------------------|
+ // <---> <--->
+ // ...--------><-----------------------------><---------....
+ // previous frag matching fragment next frag
+ // return -1 return 0 return 1
+ //logger.log(`level/sn/start/end/bufEnd:${level}/${candidate.sn}/${candidate.start}/${(candidate.start+candidate.duration)}/${bufferEnd}`);
+ // Set the lookup tolerance to be small enough to detect the current segment - ensures we don't skip over very small segments
+ var candidateLookupTolerance = Math.min(maxFragLookUpTolerance, candidate.duration);
+ if (candidate.start + candidate.duration - candidateLookupTolerance <= bufferEnd) {
+ return 1;
+ } // if maxFragLookUpTolerance will have negative value then don't return -1 for first element
+ else if (candidate.start - candidateLookupTolerance > bufferEnd && candidate.start) {
+ return -1;
+ }
+ return 0;
+ };
+
+ if (bufferEnd < end) {
+ if (bufferEnd > end - maxFragLookUpTolerance) {
+ maxFragLookUpTolerance = 0;
+ }
+ // Prefer the next fragment if it's within tolerance
+ if (fragNext && !fragmentWithinToleranceTest(fragNext)) {
+ foundFrag = fragNext;
+ } else {
+ foundFrag = _binarySearch2.default.search(fragments, fragmentWithinToleranceTest);
+ }
+ } else {
+ // reach end of playlist
+ foundFrag = fragments[fragLen - 1];
+ }
+ if (foundFrag) {
+ frag = foundFrag;
+ start = foundFrag.start;
+ //logger.log('find SN matching with pos:' + bufferEnd + ':' + frag.sn);
+ if (fragPrevious && frag.level === fragPrevious.level && frag.sn === fragPrevious.sn) {
+ if (frag.sn < trackDetails.endSN) {
+ frag = fragments[frag.sn + 1 - trackDetails.startSN];
+ _logger.logger.log('SN just loaded, load next one: ' + frag.sn);
+ } else {
+ frag = null;
+ }
+ }
+ }
+ }
+ if (frag) {
+ //logger.log(' loading frag ' + i +',pos/bufEnd:' + pos.toFixed(3) + '/' + bufferEnd.toFixed(3));
+ if (frag.decryptdata && frag.decryptdata.uri != null && frag.decryptdata.key == null) {
+ _logger.logger.log('Loading key for ' + frag.sn + ' of [' + trackDetails.startSN + ' ,' + trackDetails.endSN + '],track ' + trackId);
+ this.state = State.KEY_LOADING;
+ hls.trigger(_events2.default.KEY_LOADING, { frag: frag });
+ } else {
+ _logger.logger.log('Loading ' + frag.sn + ' of [' + trackDetails.startSN + ' ,' + trackDetails.endSN + '],track ' + trackId + ', currentTime:' + pos + ',bufferEnd:' + bufferEnd.toFixed(3));
+ // ensure that we are not reloading the same fragments in loop ...
+ if (this.fragLoadIdx !== undefined) {
+ this.fragLoadIdx++;
+ } else {
+ this.fragLoadIdx = 0;
+ }
+ if (frag.loadCounter) {
+ frag.loadCounter++;
+ var maxThreshold = config.fragLoadingLoopThreshold;
+ // if this frag has already been loaded 3 times, and if it has been reloaded recently
+ if (frag.loadCounter > maxThreshold && Math.abs(this.fragLoadIdx - frag.loadIdx) < maxThreshold) {
+ hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.FRAG_LOOP_LOADING_ERROR, fatal: false, frag: frag });
+ return;
+ }
+ } else {
+ frag.loadCounter = 1;
+ }
+ frag.loadIdx = this.fragLoadIdx;
+ this.fragCurrent = frag;
+ this.startFragRequested = true;
+ if (!isNaN(frag.sn)) {
+ this.nextLoadPosition = frag.start + frag.duration;
+ }
+ hls.trigger(_events2.default.FRAG_LOADING, { frag: frag });
+ this.state = State.FRAG_LOADING;
+ }
+ }
+ }
+ break;
+ case State.WAITING_TRACK:
+ track = this.tracks[this.trackId];
+ // check if playlist is already loaded
+ if (track && track.details) {
+ this.state = State.IDLE;
+ }
+ break;
+ case State.FRAG_LOADING_WAITING_RETRY:
+ var now = performance.now();
+ var retryDate = this.retryDate;
+ media = this.media;
+ var isSeeking = media && media.seeking;
+ // if current time is gt than retryDate, or if media seeking let's switch to IDLE state to retry loading
+ if (!retryDate || now >= retryDate || isSeeking) {
+ _logger.logger.log('audioStreamController: retryDate reached, switch back to IDLE state');
+ this.state = State.IDLE;
+ }
+ break;
+ case State.WAITING_INIT_PTS:
+ case State.STOPPED:
+ case State.FRAG_LOADING:
+ case State.PARSING:
+ case State.PARSED:
+ case State.ENDED:
+ break;
+ default:
+ break;
+ }
+ }
+ }, {
+ key: 'onMediaAttached',
+ value: function onMediaAttached(data) {
+ var media = this.media = this.mediaBuffer = data.media;
+ this.onvseeking = this.onMediaSeeking.bind(this);
+ this.onvended = this.onMediaEnded.bind(this);
+ media.addEventListener('seeking', this.onvseeking);
+ media.addEventListener('ended', this.onvended);
+ var config = this.config;
+ if (this.tracks && config.autoStartLoad) {
+ this.startLoad(config.startPosition);
+ }
+ }
+ }, {
+ key: 'onMediaDetaching',
+ value: function onMediaDetaching() {
+ var media = this.media;
+ if (media && media.ended) {
+ _logger.logger.log('MSE detaching and video ended, reset startPosition');
+ this.startPosition = this.lastCurrentTime = 0;
+ }
+
+ // reset fragment loading counter on MSE detaching to avoid reporting FRAG_LOOP_LOADING_ERROR after error recovery
+ var tracks = this.tracks;
+ if (tracks) {
+ // reset fragment load counter
+ tracks.forEach(function (track) {
+ if (track.details) {
+ track.details.fragments.forEach(function (fragment) {
+ fragment.loadCounter = undefined;
+ });
+ }
+ });
+ }
+ // remove video listeners
+ if (media) {
+ media.removeEventListener('seeking', this.onvseeking);
+ media.removeEventListener('ended', this.onvended);
+ this.onvseeking = this.onvseeked = this.onvended = null;
+ }
+ this.media = this.mediaBuffer = null;
+ this.loadedmetadata = false;
+ this.stopLoad();
+ }
+ }, {
+ key: 'onMediaSeeking',
+ value: function onMediaSeeking() {
+ if (this.state === State.ENDED) {
+ // switch to IDLE state to check for potential new fragment
+ this.state = State.IDLE;
+ }
+ if (this.media) {
+ this.lastCurrentTime = this.media.currentTime;
+ }
+ // avoid reporting fragment loop loading error in case user is seeking several times on same position
+ if (this.fragLoadIdx !== undefined) {
+ this.fragLoadIdx += 2 * this.config.fragLoadingLoopThreshold;
+ }
+ // tick to speed up processing
+ this.tick();
+ }
+ }, {
+ key: 'onMediaEnded',
+ value: function onMediaEnded() {
+ // reset startPosition and lastCurrentTime to restart playback @ stream beginning
+ this.startPosition = this.lastCurrentTime = 0;
+ }
+ }, {
+ key: 'onAudioTracksUpdated',
+ value: function onAudioTracksUpdated(data) {
+ _logger.logger.log('audio tracks updated');
+ this.tracks = data.audioTracks;
+ }
+ }, {
+ key: 'onAudioTrackSwitching',
+ value: function onAudioTrackSwitching(data) {
+ // if any URL found on new audio track, it is an alternate audio track
+ var altAudio = !!data.url;
+ this.trackId = data.id;
+ this.state = State.IDLE;
+
+ this.fragCurrent = null;
+ this.state = State.PAUSED;
+ this.waitingFragment = null;
+ // destroy useless demuxer when switching audio to main
+ if (!altAudio) {
+ if (this.demuxer) {
+ this.demuxer.destroy();
+ this.demuxer = null;
+ }
+ } else {
+ // switching to audio track, start timer if not already started
+ if (!this.timer) {
+ this.timer = setInterval(this.ontick, 100);
+ }
+ }
+
+ //should we switch tracks ?
+ if (altAudio) {
+ this.audioSwitch = true;
+ //main audio track are handled by stream-controller, just do something if switching to alt audio track
+ this.state = State.IDLE;
+ // increase fragment load Index to avoid frag loop loading error after buffer flush
+ if (this.fragLoadIdx !== undefined) {
+ this.fragLoadIdx += 2 * this.config.fragLoadingLoopThreshold;
+ }
+ }
+ this.tick();
+ }
+ }, {
+ key: 'onAudioTrackLoaded',
+ value: function onAudioTrackLoaded(data) {
+ var newDetails = data.details,
+ trackId = data.id,
+ track = this.tracks[trackId],
+ duration = newDetails.totalduration,
+ sliding = 0;
+
+ _logger.logger.log('track ' + trackId + ' loaded [' + newDetails.startSN + ',' + newDetails.endSN + '],duration:' + duration);
+
+ if (newDetails.live) {
+ var curDetails = track.details;
+ if (curDetails && newDetails.fragments.length > 0) {
+ // we already have details for that level, merge them
+ _levelHelper2.default.mergeDetails(curDetails, newDetails);
+ sliding = newDetails.fragments[0].start;
+ // TODO
+ //this.liveSyncPosition = this.computeLivePosition(sliding, curDetails);
+ if (newDetails.PTSKnown) {
+ _logger.logger.log('live audio playlist sliding:' + sliding.toFixed(3));
+ } else {
+ _logger.logger.log('live audio playlist - outdated PTS, unknown sliding');
+ }
+ } else {
+ newDetails.PTSKnown = false;
+ _logger.logger.log('live audio playlist - first load, unknown sliding');
+ }
+ } else {
+ newDetails.PTSKnown = false;
+ }
+ track.details = newDetails;
+
+ // compute start position
+ if (!this.startFragRequested) {
+ // compute start position if set to -1. use it straight away if value is defined
+ if (this.startPosition === -1) {
+ // first, check if start time offset has been set in playlist, if yes, use this value
+ var startTimeOffset = newDetails.startTimeOffset;
+ if (!isNaN(startTimeOffset)) {
+ _logger.logger.log('start time offset found in playlist, adjust startPosition to ' + startTimeOffset);
+ this.startPosition = startTimeOffset;
+ } else {
+ this.startPosition = 0;
+ }
+ }
+ this.nextLoadPosition = this.startPosition;
+ }
+ // only switch batck to IDLE state if we were waiting for track to start downloading a new fragment
+ if (this.state === State.WAITING_TRACK) {
+ this.state = State.IDLE;
+ }
+ //trigger handler right now
+ this.tick();
+ }
+ }, {
+ key: 'onKeyLoaded',
+ value: function onKeyLoaded() {
+ if (this.state === State.KEY_LOADING) {
+ this.state = State.IDLE;
+ this.tick();
+ }
+ }
+ }, {
+ key: 'onFragLoaded',
+ value: function onFragLoaded(data) {
+ var fragCurrent = this.fragCurrent,
+ fragLoaded = data.frag;
+ if (this.state === State.FRAG_LOADING && fragCurrent && fragLoaded.type === 'audio' && fragLoaded.level === fragCurrent.level && fragLoaded.sn === fragCurrent.sn) {
+ var track = this.tracks[this.trackId],
+ details = track.details,
+ duration = details.totalduration,
+ trackId = fragCurrent.level,
+ sn = fragCurrent.sn,
+ cc = fragCurrent.cc,
+ audioCodec = this.config.defaultAudioCodec || track.audioCodec || 'mp4a.40.2',
+ stats = this.stats = data.stats;
+ if (sn === 'initSegment') {
+ this.state = State.IDLE;
+
+ stats.tparsed = stats.tbuffered = performance.now();
+ details.initSegment.data = data.payload;
+ this.hls.trigger(_events2.default.FRAG_BUFFERED, { stats: stats, frag: fragCurrent, id: 'audio' });
+ this.tick();
+ } else {
+ this.state = State.PARSING;
+ // transmux the MPEG-TS data to ISO-BMFF segments
+ this.appended = false;
+ if (!this.demuxer) {
+ this.demuxer = new _demuxer2.default(this.hls, 'audio');
+ }
+ //Check if we have video initPTS
+ // If not we need to wait for it
+ var initPTS = this.initPTS[cc];
+ var initSegmentData = details.initSegment ? details.initSegment.data : [];
+ if (initSegmentData || initPTS !== undefined) {
+ this.pendingBuffering = true;
+ _logger.logger.log('Demuxing ' + sn + ' of [' + details.startSN + ' ,' + details.endSN + '],track ' + trackId);
+ // time Offset is accurate if level PTS is known, or if playlist is not sliding (not live)
+ var accurateTimeOffset = false; //details.PTSKnown || !details.live;
+ this.demuxer.push(data.payload, initSegmentData, audioCodec, null, fragCurrent, duration, accurateTimeOffset, initPTS);
+ } else {
+ _logger.logger.log('unknown video PTS for continuity counter ' + cc + ', waiting for video PTS before demuxing audio frag ' + sn + ' of [' + details.startSN + ' ,' + details.endSN + '],track ' + trackId);
+ this.waitingFragment = data;
+ this.state = State.WAITING_INIT_PTS;
+ }
+ }
+ }
+ this.fragLoadError = 0;
+ }
+ }, {
+ key: 'onFragParsingInitSegment',
+ value: function onFragParsingInitSegment(data) {
+ var fragCurrent = this.fragCurrent;
+ var fragNew = data.frag;
+ if (fragCurrent && data.id === 'audio' && fragNew.sn === fragCurrent.sn && fragNew.level === fragCurrent.level && this.state === State.PARSING) {
+ var tracks = data.tracks,
+ track = void 0;
+
+ // delete any video track found on audio demuxer
+ if (tracks.video) {
+ delete tracks.video;
+ }
+
+ // include levelCodec in audio and video tracks
+ track = tracks.audio;
+ if (track) {
+ track.levelCodec = 'mp4a.40.2';
+ track.id = data.id;
+ this.hls.trigger(_events2.default.BUFFER_CODECS, tracks);
+ _logger.logger.log('audio track:audio,container:' + track.container + ',codecs[level/parsed]=[' + track.levelCodec + '/' + track.codec + ']');
+ var initSegment = track.initSegment;
+ if (initSegment) {
+ var appendObj = { type: 'audio', data: initSegment, parent: 'audio', content: 'initSegment' };
+ if (this.audioSwitch) {
+ this.pendingData = [appendObj];
+ } else {
+ this.appended = true;
+ // arm pending Buffering flag before appending a segment
+ this.pendingBuffering = true;
+ this.hls.trigger(_events2.default.BUFFER_APPENDING, appendObj);
+ }
+ }
+ //trigger handler right now
+ this.tick();
+ }
+ }
+ }
+ }, {
+ key: 'onFragParsingData',
+ value: function onFragParsingData(data) {
+ var _this2 = this;
+
+ var fragCurrent = this.fragCurrent;
+ var fragNew = data.frag;
+ if (fragCurrent && data.id === 'audio' && data.type === 'audio' && fragNew.sn === fragCurrent.sn && fragNew.level === fragCurrent.level && this.state === State.PARSING) {
+ var trackId = this.trackId,
+ track = this.tracks[trackId],
+ hls = this.hls;
+
+ if (isNaN(data.endPTS)) {
+ data.endPTS = data.startPTS + fragCurrent.duration;
+ data.endDTS = data.startDTS + fragCurrent.duration;
+ }
+
+ _logger.logger.log('parsed ' + data.type + ',PTS:[' + data.startPTS.toFixed(3) + ',' + data.endPTS.toFixed(3) + '],DTS:[' + data.startDTS.toFixed(3) + '/' + data.endDTS.toFixed(3) + '],nb:' + data.nb);
+ _levelHelper2.default.updateFragPTSDTS(track.details, fragCurrent.sn, data.startPTS, data.endPTS);
+
+ var audioSwitch = this.audioSwitch,
+ media = this.media,
+ appendOnBufferFlush = false;
+ //Only flush audio from old audio tracks when PTS is known on new audio track
+ if (audioSwitch && media) {
+ if (media.readyState) {
+ var currentTime = media.currentTime;
+ _logger.logger.log('switching audio track : currentTime:' + currentTime);
+ if (currentTime >= data.startPTS) {
+ _logger.logger.log('switching audio track : flushing all audio');
+ this.state = State.BUFFER_FLUSHING;
+ hls.trigger(_events2.default.BUFFER_FLUSHING, { startOffset: 0, endOffset: Number.POSITIVE_INFINITY, type: 'audio' });
+ appendOnBufferFlush = true;
+ //Lets announce that the initial audio track switch flush occur
+ this.audioSwitch = false;
+ hls.trigger(_events2.default.AUDIO_TRACK_SWITCHED, { id: trackId });
+ }
+ } else {
+ //Lets announce that the initial audio track switch flush occur
+ this.audioSwitch = false;
+ hls.trigger(_events2.default.AUDIO_TRACK_SWITCHED, { id: trackId });
+ }
+ }
+
+ var pendingData = this.pendingData;
+ if (!this.audioSwitch) {
+ [data.data1, data.data2].forEach(function (buffer) {
+ if (buffer && buffer.length) {
+ pendingData.push({ type: data.type, data: buffer, parent: 'audio', content: 'data' });
+ }
+ });
+ if (!appendOnBufferFlush && pendingData.length) {
+ pendingData.forEach(function (appendObj) {
+ // only append in PARSING state (rationale is that an appending error could happen synchronously on first segment appending)
+ // in that case it is useless to append following segments
+ if (_this2.state === State.PARSING) {
+ // arm pending Buffering flag before appending a segment
+ _this2.pendingBuffering = true;
+ _this2.hls.trigger(_events2.default.BUFFER_APPENDING, appendObj);
+ }
+ });
+ this.pendingData = [];
+ this.appended = true;
+ }
+ }
+ //trigger handler right now
+ this.tick();
+ }
+ }
+ }, {
+ key: 'onFragParsed',
+ value: function onFragParsed(data) {
+ var fragCurrent = this.fragCurrent;
+ var fragNew = data.frag;
+ if (fragCurrent && data.id === 'audio' && fragNew.sn === fragCurrent.sn && fragNew.level === fragCurrent.level && this.state === State.PARSING) {
+ this.stats.tparsed = performance.now();
+ this.state = State.PARSED;
+ this._checkAppendedParsed();
+ }
+ }
+ }, {
+ key: 'onBufferCreated',
+ value: function onBufferCreated(data) {
+ var audioTrack = data.tracks.audio;
+ if (audioTrack) {
+ this.mediaBuffer = audioTrack.buffer;
+ this.loadedmetadata = true;
+ }
+ }
+ }, {
+ key: 'onBufferAppended',
+ value: function onBufferAppended(data) {
+ if (data.parent === 'audio') {
+ var state = this.state;
+ if (state === State.PARSING || state === State.PARSED) {
+ // check if all buffers have been appended
+ this.pendingBuffering = data.pending > 0;
+ this._checkAppendedParsed();
+ }
+ }
+ }
+ }, {
+ key: '_checkAppendedParsed',
+ value: function _checkAppendedParsed() {
+ //trigger handler right now
+ if (this.state === State.PARSED && (!this.appended || !this.pendingBuffering)) {
+ var frag = this.fragCurrent,
+ stats = this.stats,
+ hls = this.hls;
+ if (frag) {
+ this.fragPrevious = frag;
+ stats.tbuffered = performance.now();
+ hls.trigger(_events2.default.FRAG_BUFFERED, { stats: stats, frag: frag, id: 'audio' });
+ var media = this.mediaBuffer ? this.mediaBuffer : this.media;
+ _logger.logger.log('audio buffered : ' + _timeRanges2.default.toString(media.buffered));
+ if (this.audioSwitch && this.appended) {
+ this.audioSwitch = false;
+ hls.trigger(_events2.default.AUDIO_TRACK_SWITCHED, { id: this.trackId });
+ }
+ this.state = State.IDLE;
+ }
+ this.tick();
+ }
+ }
+ }, {
+ key: 'onError',
+ value: function onError(data) {
+ var frag = data.frag;
+ // don't handle frag error not related to audio fragment
+ if (frag && frag.type !== 'audio') {
+ return;
+ }
+ switch (data.details) {
+ case _errors.ErrorDetails.FRAG_LOAD_ERROR:
+ case _errors.ErrorDetails.FRAG_LOAD_TIMEOUT:
+ if (!data.fatal) {
+ var loadError = this.fragLoadError;
+ if (loadError) {
+ loadError++;
+ } else {
+ loadError = 1;
+ }
+ var config = this.config;
+ if (loadError <= config.fragLoadingMaxRetry) {
+ this.fragLoadError = loadError;
+ // reset load counter to avoid frag loop loading error
+ frag.loadCounter = 0;
+ // exponential backoff capped to config.fragLoadingMaxRetryTimeout
+ var delay = Math.min(Math.pow(2, loadError - 1) * config.fragLoadingRetryDelay, config.fragLoadingMaxRetryTimeout);
+ _logger.logger.warn('audioStreamController: frag loading failed, retry in ' + delay + ' ms');
+ this.retryDate = performance.now() + delay;
+ // retry loading state
+ this.state = State.FRAG_LOADING_WAITING_RETRY;
+ } else {
+ _logger.logger.error('audioStreamController: ' + data.details + ' reaches max retry, redispatch as fatal ...');
+ // switch error to fatal
+ data.fatal = true;
+ this.state = State.ERROR;
+ }
+ }
+ break;
+ case _errors.ErrorDetails.FRAG_LOOP_LOADING_ERROR:
+ case _errors.ErrorDetails.AUDIO_TRACK_LOAD_ERROR:
+ case _errors.ErrorDetails.AUDIO_TRACK_LOAD_TIMEOUT:
+ case _errors.ErrorDetails.KEY_LOAD_ERROR:
+ case _errors.ErrorDetails.KEY_LOAD_TIMEOUT:
+ // when in ERROR state, don't switch back to IDLE state in case a non-fatal error is received
+ if (this.state !== State.ERROR) {
+ // if fatal error, stop processing, otherwise move to IDLE to retry loading
+ this.state = data.fatal ? State.ERROR : State.IDLE;
+ _logger.logger.warn('audioStreamController: ' + data.details + ' while loading frag,switch to ' + this.state + ' state ...');
+ }
+ break;
+ case _errors.ErrorDetails.BUFFER_FULL_ERROR:
+ // if in appending state
+ if (data.parent === 'audio' && (this.state === State.PARSING || this.state === State.PARSED)) {
+ var media = this.mediaBuffer,
+ currentTime = this.media.currentTime,
+ mediaBuffered = media && _bufferHelper2.default.isBuffered(media, currentTime) && _bufferHelper2.default.isBuffered(media, currentTime + 0.5);
+ // reduce max buf len if current position is buffered
+ if (mediaBuffered) {
+ var _config = this.config;
+ if (_config.maxMaxBufferLength >= _config.maxBufferLength) {
+ // reduce max buffer length as it might be too high. we do this to avoid loop flushing ...
+ _config.maxMaxBufferLength /= 2;
+ _logger.logger.warn('audio:reduce max buffer length to ' + _config.maxMaxBufferLength + 's');
+ // increase fragment load Index to avoid frag loop loading error after buffer flush
+ this.fragLoadIdx += 2 * _config.fragLoadingLoopThreshold;
+ }
+ this.state = State.IDLE;
+ } else {
+ // current position is not buffered, but browser is still complaining about buffer full error
+ // this happens on IE/Edge, refer to https://github.com/video-dev/hls.js/pull/708
+ // in that case flush the whole audio buffer to recover
+ _logger.logger.warn('buffer full error also media.currentTime is not buffered, flush audio buffer');
+ this.fragCurrent = null;
+ // flush everything
+ this.state = State.BUFFER_FLUSHING;
+ this.hls.trigger(_events2.default.BUFFER_FLUSHING, { startOffset: 0, endOffset: Number.POSITIVE_INFINITY, type: 'audio' });
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }, {
+ key: 'onBufferFlushed',
+ value: function onBufferFlushed() {
+ var _this3 = this;
+
+ var pendingData = this.pendingData;
+ if (pendingData && pendingData.length) {
+ _logger.logger.log('appending pending audio data on Buffer Flushed');
+ pendingData.forEach(function (appendObj) {
+ _this3.hls.trigger(_events2.default.BUFFER_APPENDING, appendObj);
+ });
+ this.appended = true;
+ this.pendingData = [];
+ this.state = State.PARSED;
+ } else {
+ // move to IDLE once flush complete. this should trigger new fragment loading
+ this.state = State.IDLE;
+ // reset reference to frag
+ this.fragPrevious = null;
+ this.tick();
+ }
+ }
+ }, {
+ key: 'state',
+ set: function set(nextState) {
+ if (this.state !== nextState) {
+ var previousState = this.state;
+ this._state = nextState;
+ _logger.logger.log('audio stream:' + previousState + '->' + nextState);
+ }
+ },
+ get: function get() {
+ return this._state;
+ }
+ }]);
+
+ return AudioStreamController;
+}(_eventHandler2.default);
+
+exports.default = AudioStreamController;
+
+},{"24":24,"30":30,"31":31,"32":32,"34":34,"35":35,"45":45,"50":50,"51":51}],7:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = _dereq_(31);
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+var _logger = _dereq_(50);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+ * audio track controller
+ */
+
+var AudioTrackController = function (_EventHandler) {
+ _inherits(AudioTrackController, _EventHandler);
+
+ function AudioTrackController(hls) {
+ _classCallCheck(this, AudioTrackController);
+
+ var _this = _possibleConstructorReturn(this, (AudioTrackController.__proto__ || Object.getPrototypeOf(AudioTrackController)).call(this, hls, _events2.default.MANIFEST_LOADING, _events2.default.MANIFEST_LOADED, _events2.default.AUDIO_TRACK_LOADED));
+
+ _this.ticks = 0;
+ _this.ontick = _this.tick.bind(_this);
+ return _this;
+ }
+
+ _createClass(AudioTrackController, [{
+ key: 'destroy',
+ value: function destroy() {
+ _eventHandler2.default.prototype.destroy.call(this);
+ }
+ }, {
+ key: 'tick',
+ value: function tick() {
+ this.ticks++;
+ if (this.ticks === 1) {
+ this.doTick();
+ if (this.ticks > 1) {
+ setTimeout(this.tick, 1);
+ }
+ this.ticks = 0;
+ }
+ }
+ }, {
+ key: 'doTick',
+ value: function doTick() {
+ this.updateTrack(this.trackId);
+ }
+ }, {
+ key: 'onManifestLoading',
+ value: function onManifestLoading() {
+ // reset audio tracks on manifest loading
+ this.tracks = [];
+ this.trackId = -1;
+ }
+ }, {
+ key: 'onManifestLoaded',
+ value: function onManifestLoaded(data) {
+ var _this2 = this;
+
+ var tracks = data.audioTracks || [];
+ var defaultFound = false;
+ this.tracks = tracks;
+ this.hls.trigger(_events2.default.AUDIO_TRACKS_UPDATED, { audioTracks: tracks });
+ // loop through available audio tracks and autoselect default if needed
+ var id = 0;
+ tracks.forEach(function (track) {
+ if (track.default) {
+ _this2.audioTrack = id;
+ defaultFound = true;
+ return;
+ }
+ id++;
+ });
+ if (defaultFound === false && tracks.length) {
+ _logger.logger.log('no default audio track defined, use first audio track as default');
+ this.audioTrack = 0;
+ }
+ }
+ }, {
+ key: 'onAudioTrackLoaded',
+ value: function onAudioTrackLoaded(data) {
+ if (data.id < this.tracks.length) {
+ _logger.logger.log('audioTrack ' + data.id + ' loaded');
+ this.tracks[data.id].details = data.details;
+ // check if current playlist is a live playlist
+ if (data.details.live && !this.timer) {
+ // if live playlist we will have to reload it periodically
+ // set reload period to playlist target duration
+ this.timer = setInterval(this.ontick, 1000 * data.details.targetduration);
+ }
+ if (!data.details.live && this.timer) {
+ // playlist is not live and timer is armed : stopping it
+ clearInterval(this.timer);
+ this.timer = null;
+ }
+ }
+ }
+
+ /** get alternate audio tracks list from playlist **/
+
+ }, {
+ key: 'setAudioTrackInternal',
+ value: function setAudioTrackInternal(newId) {
+ // check if level idx is valid
+ if (newId >= 0 && newId < this.tracks.length) {
+ // stopping live reloading timer if any
+ if (this.timer) {
+ clearInterval(this.timer);
+ this.timer = null;
+ }
+ this.trackId = newId;
+ _logger.logger.log('switching to audioTrack ' + newId);
+ var audioTrack = this.tracks[newId],
+ hls = this.hls,
+ type = audioTrack.type,
+ url = audioTrack.url,
+ eventObj = { id: newId, type: type, url: url };
+ // keep AUDIO_TRACK_SWITCH for legacy reason
+ hls.trigger(_events2.default.AUDIO_TRACK_SWITCH, eventObj);
+ hls.trigger(_events2.default.AUDIO_TRACK_SWITCHING, eventObj);
+ // check if we need to load playlist for this audio Track
+ var details = audioTrack.details;
+ if (url && (details === undefined || details.live === true)) {
+ // track not retrieved yet, or live playlist we need to (re)load it
+ _logger.logger.log('(re)loading playlist for audioTrack ' + newId);
+ hls.trigger(_events2.default.AUDIO_TRACK_LOADING, { url: url, id: newId });
+ }
+ }
+ }
+ }, {
+ key: 'updateTrack',
+ value: function updateTrack(newId) {
+ // check if level idx is valid
+ if (newId >= 0 && newId < this.tracks.length) {
+ // stopping live reloading timer if any
+ if (this.timer) {
+ clearInterval(this.timer);
+ this.timer = null;
+ }
+ this.trackId = newId;
+ _logger.logger.log('updating audioTrack ' + newId);
+ var audioTrack = this.tracks[newId],
+ url = audioTrack.url;
+ // check if we need to load playlist for this audio Track
+ var details = audioTrack.details;
+ if (url && (details === undefined || details.live === true)) {
+ // track not retrieved yet, or live playlist we need to (re)load it
+ _logger.logger.log('(re)loading playlist for audioTrack ' + newId);
+ this.hls.trigger(_events2.default.AUDIO_TRACK_LOADING, { url: url, id: newId });
+ }
+ }
+ }
+ }, {
+ key: 'audioTracks',
+ get: function get() {
+ return this.tracks;
+ }
+
+ /** get index of the selected audio track (index in audio track lists) **/
+
+ }, {
+ key: 'audioTrack',
+ get: function get() {
+ return this.trackId;
+ }
+
+ /** select an audio track, based on its index in audio track lists**/
+ ,
+ set: function set(audioTrackId) {
+ if (this.trackId !== audioTrackId || this.tracks[audioTrackId].details === undefined) {
+ this.setAudioTrackInternal(audioTrackId);
+ }
+ }
+ }]);
+
+ return AudioTrackController;
+}(_eventHandler2.default);
+
+exports.default = AudioTrackController;
+
+},{"31":31,"32":32,"50":50}],8:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = _dereq_(31);
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+var _logger = _dereq_(50);
+
+var _errors = _dereq_(30);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+ * Buffer Controller
+ */
+
+var BufferController = function (_EventHandler) {
+ _inherits(BufferController, _EventHandler);
+
+ function BufferController(hls) {
+ _classCallCheck(this, BufferController);
+
+ // the value that we have set mediasource.duration to
+ // (the actual duration may be tweaked slighly by the browser)
+ var _this = _possibleConstructorReturn(this, (BufferController.__proto__ || Object.getPrototypeOf(BufferController)).call(this, hls, _events2.default.MEDIA_ATTACHING, _events2.default.MEDIA_DETACHING, _events2.default.MANIFEST_PARSED, _events2.default.BUFFER_RESET, _events2.default.BUFFER_APPENDING, _events2.default.BUFFER_CODECS, _events2.default.BUFFER_EOS, _events2.default.BUFFER_FLUSHING, _events2.default.LEVEL_PTS_UPDATED, _events2.default.LEVEL_UPDATED));
+
+ _this._msDuration = null;
+ // the value that we want to set mediaSource.duration to
+ _this._levelDuration = null;
+
+ // Source Buffer listeners
+ _this.onsbue = _this.onSBUpdateEnd.bind(_this);
+ _this.onsbe = _this.onSBUpdateError.bind(_this);
+ _this.pendingTracks = {};
+ _this.tracks = {};
+ return _this;
+ }
+
+ _createClass(BufferController, [{
+ key: 'destroy',
+ value: function destroy() {
+ _eventHandler2.default.prototype.destroy.call(this);
+ }
+ }, {
+ key: 'onLevelPtsUpdated',
+ value: function onLevelPtsUpdated(data) {
+ var type = data.type;
+ var audioTrack = this.tracks.audio;
+
+ // Adjusting `SourceBuffer.timestampOffset` (desired point in the timeline where the next frames should be appended)
+ // in Chrome browser when we detect MPEG audio container and time delta between level PTS and `SourceBuffer.timestampOffset`
+ // is greater than 100ms (this is enough to handle seek for VOD or level change for LIVE videos). At the time of change we issue
+ // `SourceBuffer.abort()` and adjusting `SourceBuffer.timestampOffset` if `SourceBuffer.updating` is false or awaiting `updateend`
+ // event if SB is in updating state.
+ // More info here: https://github.com/video-dev/hls.js/issues/332#issuecomment-257986486
+
+ if (type === 'audio' && audioTrack && audioTrack.container === 'audio/mpeg') {
+ // Chrome audio mp3 track
+ var audioBuffer = this.sourceBuffer.audio;
+ var delta = Math.abs(audioBuffer.timestampOffset - data.start);
+
+ // adjust timestamp offset if time delta is greater than 100ms
+ if (delta > 0.1) {
+ var updating = audioBuffer.updating;
+
+ try {
+ audioBuffer.abort();
+ } catch (err) {
+ updating = true;
+ _logger.logger.warn('can not abort audio buffer: ' + err);
+ }
+
+ if (!updating) {
+ _logger.logger.warn('change mpeg audio timestamp offset from ' + audioBuffer.timestampOffset + ' to ' + data.start);
+ audioBuffer.timestampOffset = data.start;
+ } else {
+ this.audioTimestampOffset = data.start;
+ }
+ }
+ }
+ }
+ }, {
+ key: 'onManifestParsed',
+ value: function onManifestParsed(data) {
+ var audioExpected = data.audio,
+ videoExpected = data.video,
+ sourceBufferNb = 0;
+ // in case of alt audio 2 BUFFER_CODECS events will be triggered, one per stream controller
+ // sourcebuffers will be created all at once when the expected nb of tracks will be reached
+ // in case alt audio is not used, only one BUFFER_CODEC event will be fired from main stream controller
+ // it will contain the expected nb of source buffers, no need to compute it
+ if (data.altAudio && (audioExpected || videoExpected)) {
+ sourceBufferNb = (audioExpected ? 1 : 0) + (videoExpected ? 1 : 0);
+ _logger.logger.log(sourceBufferNb + ' sourceBuffer(s) expected');
+ }
+ this.sourceBufferNb = sourceBufferNb;
+ }
+ }, {
+ key: 'onMediaAttaching',
+ value: function onMediaAttaching(data) {
+ var media = this.media = data.media;
+ if (media) {
+ // setup the media source
+ var ms = this.mediaSource = new MediaSource();
+ //Media Source listeners
+ this.onmso = this.onMediaSourceOpen.bind(this);
+ this.onmse = this.onMediaSourceEnded.bind(this);
+ this.onmsc = this.onMediaSourceClose.bind(this);
+ ms.addEventListener('sourceopen', this.onmso);
+ ms.addEventListener('sourceended', this.onmse);
+ ms.addEventListener('sourceclose', this.onmsc);
+ // link video and media Source
+ media.src = URL.createObjectURL(ms);
+ }
+ }
+ }, {
+ key: 'onMediaDetaching',
+ value: function onMediaDetaching() {
+ _logger.logger.log('media source detaching');
+ var ms = this.mediaSource;
+ if (ms) {
+ if (ms.readyState === 'open') {
+ try {
+ // endOfStream could trigger exception if any sourcebuffer is in updating state
+ // we don't really care about checking sourcebuffer state here,
+ // as we are anyway detaching the MediaSource
+ // let's just avoid this exception to propagate
+ ms.endOfStream();
+ } catch (err) {
+ _logger.logger.warn('onMediaDetaching:' + err.message + ' while calling endOfStream');
+ }
+ }
+ ms.removeEventListener('sourceopen', this.onmso);
+ ms.removeEventListener('sourceended', this.onmse);
+ ms.removeEventListener('sourceclose', this.onmsc);
+
+ // Detach properly the MediaSource from the HTMLMediaElement as
+ // suggested in https://github.com/w3c/media-source/issues/53.
+ if (this.media) {
+ URL.revokeObjectURL(this.media.src);
+ this.media.removeAttribute('src');
+ this.media.load();
+ }
+
+ this.mediaSource = null;
+ this.media = null;
+ this.pendingTracks = {};
+ this.tracks = {};
+ this.sourceBuffer = {};
+ this.flushRange = [];
+ this.segments = [];
+ this.appended = 0;
+ }
+ this.onmso = this.onmse = this.onmsc = null;
+ this.hls.trigger(_events2.default.MEDIA_DETACHED);
+ }
+ }, {
+ key: 'onMediaSourceOpen',
+ value: function onMediaSourceOpen() {
+ _logger.logger.log('media source opened');
+ this.hls.trigger(_events2.default.MEDIA_ATTACHED, { media: this.media });
+ var mediaSource = this.mediaSource;
+ if (mediaSource) {
+ // once received, don't listen anymore to sourceopen event
+ mediaSource.removeEventListener('sourceopen', this.onmso);
+ }
+ this.checkPendingTracks();
+ }
+ }, {
+ key: 'checkPendingTracks',
+ value: function checkPendingTracks() {
+ // if any buffer codecs pending, check if we have enough to create sourceBuffers
+ var pendingTracks = this.pendingTracks,
+ pendingTracksNb = Object.keys(pendingTracks).length;
+ // if any pending tracks and (if nb of pending tracks gt or equal than expected nb or if unknown expected nb)
+ if (pendingTracksNb && (this.sourceBufferNb <= pendingTracksNb || this.sourceBufferNb === 0)) {
+ // ok, let's create them now !
+ this.createSourceBuffers(pendingTracks);
+ this.pendingTracks = {};
+ // append any pending segments now !
+ this.doAppending();
+ }
+ }
+ }, {
+ key: 'onMediaSourceClose',
+ value: function onMediaSourceClose() {
+ _logger.logger.log('media source closed');
+ }
+ }, {
+ key: 'onMediaSourceEnded',
+ value: function onMediaSourceEnded() {
+ _logger.logger.log('media source ended');
+ }
+ }, {
+ key: 'onSBUpdateEnd',
+ value: function onSBUpdateEnd() {
+ // update timestampOffset
+ if (this.audioTimestampOffset) {
+ var audioBuffer = this.sourceBuffer.audio;
+ _logger.logger.warn('change mpeg audio timestamp offset from ' + audioBuffer.timestampOffset + ' to ' + this.audioTimestampOffset);
+ audioBuffer.timestampOffset = this.audioTimestampOffset;
+ delete this.audioTimestampOffset;
+ }
+
+ if (this._needsFlush) {
+ this.doFlush();
+ }
+
+ if (this._needsEos) {
+ this.checkEos();
+ }
+ this.appending = false;
+ var parent = this.parent;
+ // count nb of pending segments waiting for appending on this sourcebuffer
+ var pending = this.segments.reduce(function (counter, segment) {
+ return segment.parent === parent ? counter + 1 : counter;
+ }, 0);
+ this.hls.trigger(_events2.default.BUFFER_APPENDED, { parent: parent, pending: pending });
+
+ // don't append in flushing mode
+ if (!this._needsFlush) {
+ this.doAppending();
+ }
+
+ this.updateMediaElementDuration();
+ }
+ }, {
+ key: 'onSBUpdateError',
+ value: function onSBUpdateError(event) {
+ _logger.logger.error('sourceBuffer error:', event);
+ // according to http://www.w3.org/TR/media-source/#sourcebuffer-append-error
+ // this error might not always be fatal (it is fatal if decode error is set, in that case
+ // it will be followed by a mediaElement error ...)
+ this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.BUFFER_APPENDING_ERROR, fatal: false });
+ // we don't need to do more than that, as accordin to the spec, updateend will be fired just after
+ }
+ }, {
+ key: 'onBufferReset',
+ value: function onBufferReset() {
+ var sourceBuffer = this.sourceBuffer;
+ for (var type in sourceBuffer) {
+ var sb = sourceBuffer[type];
+ try {
+ this.mediaSource.removeSourceBuffer(sb);
+ sb.removeEventListener('updateend', this.onsbue);
+ sb.removeEventListener('error', this.onsbe);
+ } catch (err) {}
+ }
+ this.sourceBuffer = {};
+ this.flushRange = [];
+ this.segments = [];
+ this.appended = 0;
+ }
+ }, {
+ key: 'onBufferCodecs',
+ value: function onBufferCodecs(tracks) {
+ // if source buffer(s) not created yet, appended buffer tracks in this.pendingTracks
+ // if sourcebuffers already created, do nothing ...
+ if (Object.keys(this.sourceBuffer).length === 0) {
+ for (var trackName in tracks) {
+ this.pendingTracks[trackName] = tracks[trackName];
+ }
+ var mediaSource = this.mediaSource;
+ if (mediaSource && mediaSource.readyState === 'open') {
+ // try to create sourcebuffers if mediasource opened
+ this.checkPendingTracks();
+ }
+ }
+ }
+ }, {
+ key: 'createSourceBuffers',
+ value: function createSourceBuffers(tracks) {
+ var sourceBuffer = this.sourceBuffer,
+ mediaSource = this.mediaSource;
+
+ for (var trackName in tracks) {
+ if (!sourceBuffer[trackName]) {
+ var track = tracks[trackName];
+ // use levelCodec as first priority
+ var codec = track.levelCodec || track.codec;
+ var mimeType = track.container + ';codecs=' + codec;
+ _logger.logger.log('creating sourceBuffer(' + mimeType + ')');
+ try {
+ var sb = sourceBuffer[trackName] = mediaSource.addSourceBuffer(mimeType);
+ sb.addEventListener('updateend', this.onsbue);
+ sb.addEventListener('error', this.onsbe);
+ this.tracks[trackName] = { codec: codec, container: track.container };
+ track.buffer = sb;
+ } catch (err) {
+ _logger.logger.error('error while trying to add sourceBuffer:' + err.message);
+ this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.BUFFER_ADD_CODEC_ERROR, fatal: false, err: err, mimeType: mimeType });
+ }
+ }
+ }
+ this.hls.trigger(_events2.default.BUFFER_CREATED, { tracks: tracks });
+ }
+ }, {
+ key: 'onBufferAppending',
+ value: function onBufferAppending(data) {
+ if (!this._needsFlush) {
+ if (!this.segments) {
+ this.segments = [data];
+ } else {
+ this.segments.push(data);
+ }
+ this.doAppending();
+ }
+ }
+ }, {
+ key: 'onBufferAppendFail',
+ value: function onBufferAppendFail(data) {
+ _logger.logger.error('sourceBuffer error:', data.event);
+ // according to http://www.w3.org/TR/media-source/#sourcebuffer-append-error
+ // this error might not always be fatal (it is fatal if decode error is set, in that case
+ // it will be followed by a mediaElement error ...)
+ this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.BUFFER_APPENDING_ERROR, fatal: false });
+ }
+
+ // on BUFFER_EOS mark matching sourcebuffer(s) as ended and trigger checkEos()
+
+ }, {
+ key: 'onBufferEos',
+ value: function onBufferEos(data) {
+ var sb = this.sourceBuffer;
+ var dataType = data.type;
+ for (var type in sb) {
+ if (!dataType || type === dataType) {
+ if (!sb[type].ended) {
+ sb[type].ended = true;
+ _logger.logger.log(type + ' sourceBuffer now EOS');
+ }
+ }
+ }
+ this.checkEos();
+ }
+
+ // if all source buffers are marked as ended, signal endOfStream() to MediaSource.
+
+ }, {
+ key: 'checkEos',
+ value: function checkEos() {
+ var sb = this.sourceBuffer,
+ mediaSource = this.mediaSource;
+ if (!mediaSource || mediaSource.readyState !== 'open') {
+ this._needsEos = false;
+ return;
+ }
+ for (var type in sb) {
+ var sbobj = sb[type];
+ if (!sbobj.ended) {
+ return;
+ }
+ if (sbobj.updating) {
+ this._needsEos = true;
+ return;
+ }
+ }
+ _logger.logger.log('all media data available, signal endOfStream() to MediaSource and stop loading fragment');
+ //Notify the media element that it now has all of the media data
+ try {
+ mediaSource.endOfStream();
+ } catch (e) {
+ _logger.logger.warn('exception while calling mediaSource.endOfStream()');
+ }
+ this._needsEos = false;
+ }
+ }, {
+ key: 'onBufferFlushing',
+ value: function onBufferFlushing(data) {
+ this.flushRange.push({ start: data.startOffset, end: data.endOffset, type: data.type });
+ // attempt flush immediatly
+ this.flushBufferCounter = 0;
+ this.doFlush();
+ }
+ }, {
+ key: 'onLevelUpdated',
+ value: function onLevelUpdated(event) {
+ var details = event.details;
+ if (details.fragments.length === 0) {
+ return;
+ }
+ this._levelDuration = details.totalduration + details.fragments[0].start;
+ this.updateMediaElementDuration();
+ }
+
+ // https://github.com/video-dev/hls.js/issues/355
+
+ }, {
+ key: 'updateMediaElementDuration',
+ value: function updateMediaElementDuration() {
+ var media = this.media,
+ mediaSource = this.mediaSource,
+ sourceBuffer = this.sourceBuffer,
+ levelDuration = this._levelDuration;
+ if (levelDuration === null || !media || !mediaSource || !sourceBuffer || media.readyState === 0 || mediaSource.readyState !== 'open') {
+ return;
+ }
+ for (var type in sourceBuffer) {
+ if (sourceBuffer[type].updating) {
+ // can't set duration whilst a buffer is updating
+ return;
+ }
+ }
+ if (this._msDuration === null) {
+ // initialise to the value that the media source is reporting
+ this._msDuration = mediaSource.duration;
+ }
+ var duration = media.duration;
+ // levelDuration was the last value we set.
+ // not using mediaSource.duration as the browser may tweak this value
+ // only update mediasource duration if its value increase, this is to avoid
+ // flushing already buffered portion when switching between quality level
+ if (levelDuration > this._msDuration && levelDuration > duration || duration === Infinity || isNaN(duration)) {
+ _logger.logger.log('Updating mediasource duration to ' + levelDuration.toFixed(3));
+ this._msDuration = mediaSource.duration = levelDuration;
+ }
+ }
+ }, {
+ key: 'doFlush',
+ value: function doFlush() {
+ // loop through all buffer ranges to flush
+ while (this.flushRange.length) {
+ var range = this.flushRange[0];
+ // flushBuffer will abort any buffer append in progress and flush Audio/Video Buffer
+ if (this.flushBuffer(range.start, range.end, range.type)) {
+ // range flushed, remove from flush array
+ this.flushRange.shift();
+ this.flushBufferCounter = 0;
+ } else {
+ this._needsFlush = true;
+ // avoid looping, wait for SB update end to retrigger a flush
+ return;
+ }
+ }
+ if (this.flushRange.length === 0) {
+ // everything flushed
+ this._needsFlush = false;
+
+ // let's recompute this.appended, which is used to avoid flush looping
+ var appended = 0;
+ var sourceBuffer = this.sourceBuffer;
+ try {
+ for (var type in sourceBuffer) {
+ appended += sourceBuffer[type].buffered.length;
+ }
+ } catch (error) {
+ // error could be thrown while accessing buffered, in case sourcebuffer has already been removed from MediaSource
+ // this is harmess at this stage, catch this to avoid reporting an internal exception
+ _logger.logger.error('error while accessing sourceBuffer.buffered');
+ }
+ this.appended = appended;
+ this.hls.trigger(_events2.default.BUFFER_FLUSHED);
+ }
+ }
+ }, {
+ key: 'doAppending',
+ value: function doAppending() {
+ var hls = this.hls,
+ sourceBuffer = this.sourceBuffer,
+ segments = this.segments;
+ if (Object.keys(sourceBuffer).length) {
+ if (this.media.error) {
+ this.segments = [];
+ _logger.logger.error('trying to append although a media error occured, flush segment and abort');
+ return;
+ }
+ if (this.appending) {
+ //logger.log(`sb appending in progress`);
+ return;
+ }
+ if (segments && segments.length) {
+ var segment = segments.shift();
+ try {
+ var type = segment.type,
+ sb = sourceBuffer[type];
+ if (sb) {
+ if (!sb.updating) {
+ // reset sourceBuffer ended flag before appending segment
+ sb.ended = false;
+ //logger.log(`appending ${segment.content} ${type} SB, size:${segment.data.length}, ${segment.parent}`);
+ this.parent = segment.parent;
+ sb.appendBuffer(segment.data);
+ this.appendError = 0;
+ this.appended++;
+ this.appending = true;
+ } else {
+ segments.unshift(segment);
+ }
+ } else {
+ // in case we don't have any source buffer matching with this segment type,
+ // it means that Mediasource fails to create sourcebuffer
+ // discard this segment, and trigger update end
+ this.onSBUpdateEnd();
+ }
+ } catch (err) {
+ // in case any error occured while appending, put back segment in segments table
+ _logger.logger.error('error while trying to append buffer:' + err.message);
+ segments.unshift(segment);
+ var event = { type: _errors.ErrorTypes.MEDIA_ERROR, parent: segment.parent };
+ if (err.code !== 22) {
+ if (this.appendError) {
+ this.appendError++;
+ } else {
+ this.appendError = 1;
+ }
+ event.details = _errors.ErrorDetails.BUFFER_APPEND_ERROR;
+ /* with UHD content, we could get loop of quota exceeded error until
+ browser is able to evict some data from sourcebuffer. retrying help recovering this
+ */
+ if (this.appendError > hls.config.appendErrorMaxRetry) {
+ _logger.logger.log('fail ' + hls.config.appendErrorMaxRetry + ' times to append segment in sourceBuffer');
+ segments = [];
+ event.fatal = true;
+ hls.trigger(_events2.default.ERROR, event);
+ return;
+ } else {
+ event.fatal = false;
+ hls.trigger(_events2.default.ERROR, event);
+ }
+ } else {
+ // QuotaExceededError: http://www.w3.org/TR/html5/infrastructure.html#quotaexceedederror
+ // let's stop appending any segments, and report BUFFER_FULL_ERROR error
+ this.segments = [];
+ event.details = _errors.ErrorDetails.BUFFER_FULL_ERROR;
+ event.fatal = false;
+ hls.trigger(_events2.default.ERROR, event);
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ flush specified buffered range,
+ return true once range has been flushed.
+ as sourceBuffer.remove() is asynchronous, flushBuffer will be retriggered on sourceBuffer update end
+ */
+
+ }, {
+ key: 'flushBuffer',
+ value: function flushBuffer(startOffset, endOffset, typeIn) {
+ var sb,
+ i,
+ bufStart,
+ bufEnd,
+ flushStart,
+ flushEnd,
+ sourceBuffer = this.sourceBuffer;
+ if (Object.keys(sourceBuffer).length) {
+ _logger.logger.log('flushBuffer,pos/start/end: ' + this.media.currentTime.toFixed(3) + '/' + startOffset + '/' + endOffset);
+ // safeguard to avoid infinite looping : don't try to flush more than the nb of appended segments
+ if (this.flushBufferCounter < this.appended) {
+ for (var type in sourceBuffer) {
+ // check if sourcebuffer type is defined (typeIn): if yes, let's only flush this one
+ // if no, let's flush all sourcebuffers
+ if (typeIn && type !== typeIn) {
+ continue;
+ }
+ sb = sourceBuffer[type];
+ // we are going to flush buffer, mark source buffer as 'not ended'
+ sb.ended = false;
+ if (!sb.updating) {
+ try {
+ for (i = 0; i < sb.buffered.length; i++) {
+ bufStart = sb.buffered.start(i);
+ bufEnd = sb.buffered.end(i);
+ // workaround firefox not able to properly flush multiple buffered range.
+ if (navigator.userAgent.toLowerCase().indexOf('firefox') !== -1 && endOffset === Number.POSITIVE_INFINITY) {
+ flushStart = startOffset;
+ flushEnd = endOffset;
+ } else {
+ flushStart = Math.max(bufStart, startOffset);
+ flushEnd = Math.min(bufEnd, endOffset);
+ }
+ /* sometimes sourcebuffer.remove() does not flush
+ the exact expected time range.
+ to avoid rounding issues/infinite loop,
+ only flush buffer range of length greater than 500ms.
+ */
+ if (Math.min(flushEnd, bufEnd) - flushStart > 0.5) {
+ this.flushBufferCounter++;
+ _logger.logger.log('flush ' + type + ' [' + flushStart + ',' + flushEnd + '], of [' + bufStart + ',' + bufEnd + '], pos:' + this.media.currentTime);
+ sb.remove(flushStart, flushEnd);
+ return false;
+ }
+ }
+ } catch (e) {
+ _logger.logger.warn('exception while accessing sourcebuffer, it might have been removed from MediaSource');
+ }
+ } else {
+ //logger.log('abort ' + type + ' append in progress');
+ // this will abort any appending in progress
+ //sb.abort();
+ _logger.logger.warn('cannot flush, sb updating in progress');
+ return false;
+ }
+ }
+ } else {
+ _logger.logger.warn('abort flushing too many retries');
+ }
+ _logger.logger.log('buffer flushed');
+ }
+ // everything flushed !
+ return true;
+ }
+ }]);
+
+ return BufferController;
+}(_eventHandler2.default);
+
+exports.default = BufferController;
+
+},{"30":30,"31":31,"32":32,"50":50}],9:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = _dereq_(31);
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+ * cap stream level to media size dimension controller
+ */
+
+var CapLevelController = function (_EventHandler) {
+ _inherits(CapLevelController, _EventHandler);
+
+ function CapLevelController(hls) {
+ _classCallCheck(this, CapLevelController);
+
+ return _possibleConstructorReturn(this, (CapLevelController.__proto__ || Object.getPrototypeOf(CapLevelController)).call(this, hls, _events2.default.FPS_DROP_LEVEL_CAPPING, _events2.default.MEDIA_ATTACHING, _events2.default.MANIFEST_PARSED));
+ }
+
+ _createClass(CapLevelController, [{
+ key: 'destroy',
+ value: function destroy() {
+ if (this.hls.config.capLevelToPlayerSize) {
+ this.media = this.restrictedLevels = null;
+ this.autoLevelCapping = Number.POSITIVE_INFINITY;
+ if (this.timer) {
+ this.timer = clearInterval(this.timer);
+ }
+ }
+ }
+ }, {
+ key: 'onFpsDropLevelCapping',
+ value: function onFpsDropLevelCapping(data) {
+ if (!this.restrictedLevels) {
+ this.restrictedLevels = [];
+ }
+ if (!this.isLevelRestricted(data.droppedLevel)) {
+ this.restrictedLevels.push(data.droppedLevel);
+ }
+ }
+ }, {
+ key: 'onMediaAttaching',
+ value: function onMediaAttaching(data) {
+ this.media = data.media instanceof HTMLVideoElement ? data.media : null;
+ }
+ }, {
+ key: 'onManifestParsed',
+ value: function onManifestParsed(data) {
+ var hls = this.hls;
+ if (hls.config.capLevelToPlayerSize) {
+ this.autoLevelCapping = Number.POSITIVE_INFINITY;
+ this.levels = data.levels;
+ hls.firstLevel = this.getMaxLevel(data.firstLevel);
+ clearInterval(this.timer);
+ this.timer = setInterval(this.detectPlayerSize.bind(this), 1000);
+ this.detectPlayerSize();
+ }
+ }
+ }, {
+ key: 'detectPlayerSize',
+ value: function detectPlayerSize() {
+ if (this.media) {
+ var levelsLength = this.levels ? this.levels.length : 0;
+ if (levelsLength) {
+ var hls = this.hls;
+ hls.autoLevelCapping = this.getMaxLevel(levelsLength - 1);
+ if (hls.autoLevelCapping > this.autoLevelCapping) {
+ // if auto level capping has a higher value for the previous one, flush the buffer using nextLevelSwitch
+ // usually happen when the user go to the fullscreen mode.
+ hls.streamController.nextLevelSwitch();
+ }
+ this.autoLevelCapping = hls.autoLevelCapping;
+ }
+ }
+ }
+
+ /*
+ * returns level should be the one with the dimensions equal or greater than the media (player) dimensions (so the video will be downscaled)
+ */
+
+ }, {
+ key: 'getMaxLevel',
+ value: function getMaxLevel(capLevelIndex) {
+ var result = 0,
+ i = void 0,
+ level = void 0,
+ mWidth = this.mediaWidth,
+ mHeight = this.mediaHeight,
+ lWidth = 0,
+ lHeight = 0;
+
+ for (i = 0; i <= capLevelIndex; i++) {
+ level = this.levels[i];
+ if (this.isLevelRestricted(i)) {
+ break;
+ }
+ result = i;
+ lWidth = level.width;
+ lHeight = level.height;
+ if (mWidth <= lWidth || mHeight <= lHeight) {
+ break;
+ }
+ }
+ return result;
+ }
+ }, {
+ key: 'isLevelRestricted',
+ value: function isLevelRestricted(level) {
+ return this.restrictedLevels && this.restrictedLevels.indexOf(level) !== -1 ? true : false;
+ }
+ }, {
+ key: 'contentScaleFactor',
+ get: function get() {
+ var pixelRatio = 1;
+ try {
+ pixelRatio = window.devicePixelRatio;
+ } catch (e) {}
+ return pixelRatio;
+ }
+ }, {
+ key: 'mediaWidth',
+ get: function get() {
+ var width = void 0;
+ var media = this.media;
+ if (media) {
+ width = media.width || media.clientWidth || media.offsetWidth;
+ width *= this.contentScaleFactor;
+ }
+ return width;
+ }
+ }, {
+ key: 'mediaHeight',
+ get: function get() {
+ var height = void 0;
+ var media = this.media;
+ if (media) {
+ height = media.height || media.clientHeight || media.offsetHeight;
+ height *= this.contentScaleFactor;
+ }
+ return height;
+ }
+ }]);
+
+ return CapLevelController;
+}(_eventHandler2.default);
+
+exports.default = CapLevelController;
+
+},{"31":31,"32":32}],10:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = _dereq_(31);
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+var _logger = _dereq_(50);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+ * FPS Controller
+ */
+
+var FPSController = function (_EventHandler) {
+ _inherits(FPSController, _EventHandler);
+
+ function FPSController(hls) {
+ _classCallCheck(this, FPSController);
+
+ return _possibleConstructorReturn(this, (FPSController.__proto__ || Object.getPrototypeOf(FPSController)).call(this, hls, _events2.default.MEDIA_ATTACHING));
+ }
+
+ _createClass(FPSController, [{
+ key: 'destroy',
+ value: function destroy() {
+ if (this.timer) {
+ clearInterval(this.timer);
+ }
+ this.isVideoPlaybackQualityAvailable = false;
+ }
+ }, {
+ key: 'onMediaAttaching',
+ value: function onMediaAttaching(data) {
+ var config = this.hls.config;
+ if (config.capLevelOnFPSDrop) {
+ var video = this.video = data.media instanceof HTMLVideoElement ? data.media : null;
+ if (typeof video.getVideoPlaybackQuality === 'function') {
+ this.isVideoPlaybackQualityAvailable = true;
+ }
+ clearInterval(this.timer);
+ this.timer = setInterval(this.checkFPSInterval.bind(this), config.fpsDroppedMonitoringPeriod);
+ }
+ }
+ }, {
+ key: 'checkFPS',
+ value: function checkFPS(video, decodedFrames, droppedFrames) {
+ var currentTime = performance.now();
+ if (decodedFrames) {
+ if (this.lastTime) {
+ var currentPeriod = currentTime - this.lastTime,
+ currentDropped = droppedFrames - this.lastDroppedFrames,
+ currentDecoded = decodedFrames - this.lastDecodedFrames,
+ droppedFPS = 1000 * currentDropped / currentPeriod,
+ hls = this.hls;
+ hls.trigger(_events2.default.FPS_DROP, { currentDropped: currentDropped, currentDecoded: currentDecoded, totalDroppedFrames: droppedFrames });
+ if (droppedFPS > 0) {
+ //logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod));
+ if (currentDropped > hls.config.fpsDroppedMonitoringThreshold * currentDecoded) {
+ var currentLevel = hls.currentLevel;
+ _logger.logger.warn('drop FPS ratio greater than max allowed value for currentLevel: ' + currentLevel);
+ if (currentLevel > 0 && (hls.autoLevelCapping === -1 || hls.autoLevelCapping >= currentLevel)) {
+ currentLevel = currentLevel - 1;
+ hls.trigger(_events2.default.FPS_DROP_LEVEL_CAPPING, { level: currentLevel, droppedLevel: hls.currentLevel });
+ hls.autoLevelCapping = currentLevel;
+ hls.streamController.nextLevelSwitch();
+ }
+ }
+ }
+ }
+ this.lastTime = currentTime;
+ this.lastDroppedFrames = droppedFrames;
+ this.lastDecodedFrames = decodedFrames;
+ }
+ }
+ }, {
+ key: 'checkFPSInterval',
+ value: function checkFPSInterval() {
+ var video = this.video;
+ if (video) {
+ if (this.isVideoPlaybackQualityAvailable) {
+ var videoPlaybackQuality = video.getVideoPlaybackQuality();
+ this.checkFPS(video, videoPlaybackQuality.totalVideoFrames, videoPlaybackQuality.droppedVideoFrames);
+ } else {
+ this.checkFPS(video, video.webkitDecodedFrameCount, video.webkitDroppedFrameCount);
+ }
+ }
+ }
+ }]);
+
+ return FPSController;
+}(_eventHandler2.default);
+
+exports.default = FPSController;
+
+},{"31":31,"32":32,"50":50}],11:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = _dereq_(31);
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+var _logger = _dereq_(50);
+
+var _errors = _dereq_(30);
+
+var _bufferHelper = _dereq_(34);
+
+var _bufferHelper2 = _interopRequireDefault(_bufferHelper);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+ * Level Controller
+ */
+
+var LevelController = function (_EventHandler) {
+ _inherits(LevelController, _EventHandler);
+
+ function LevelController(hls) {
+ _classCallCheck(this, LevelController);
+
+ var _this = _possibleConstructorReturn(this, (LevelController.__proto__ || Object.getPrototypeOf(LevelController)).call(this, hls, _events2.default.MANIFEST_LOADED, _events2.default.LEVEL_LOADED, _events2.default.FRAG_LOADED, _events2.default.ERROR));
+
+ _this.ontick = _this.tick.bind(_this);
+ _this._manualLevel = -1;
+ return _this;
+ }
+
+ _createClass(LevelController, [{
+ key: 'destroy',
+ value: function destroy() {
+ if (this.timer) {
+ clearTimeout(this.timer);
+ this.timer = null;
+ }
+ this._manualLevel = -1;
+ }
+ }, {
+ key: 'startLoad',
+ value: function startLoad() {
+ this.canload = true;
+ var levels = this._levels;
+ // clean up live level details to force reload them, and reset load errors
+ if (levels) {
+ levels.forEach(function (level) {
+ level.loadError = 0;
+ var levelDetails = level.details;
+ if (levelDetails && levelDetails.live) {
+ level.details = undefined;
+ }
+ });
+ }
+ // speed up live playlist refresh if timer exists
+ if (this.timer) {
+ this.tick();
+ }
+ }
+ }, {
+ key: 'stopLoad',
+ value: function stopLoad() {
+ this.canload = false;
+ }
+ }, {
+ key: 'onManifestLoaded',
+ value: function onManifestLoaded(data) {
+ var levels0 = [],
+ levels = [],
+ bitrateStart,
+ bitrateSet = {},
+ videoCodecFound = false,
+ audioCodecFound = false,
+ hls = this.hls,
+ brokenmp4inmp3 = /chrome|firefox/.test(navigator.userAgent.toLowerCase()),
+ checkSupported = function checkSupported(type, codec) {
+ return MediaSource.isTypeSupported(type + '/mp4;codecs=' + codec);
+ };
+
+ // regroup redundant level together
+ data.levels.forEach(function (level) {
+ if (level.videoCodec) {
+ videoCodecFound = true;
+ }
+ // erase audio codec info if browser does not support mp4a.40.34. demuxer will autodetect codec and fallback to mpeg/audio
+ if (brokenmp4inmp3 && level.audioCodec && level.audioCodec.indexOf('mp4a.40.34') !== -1) {
+ level.audioCodec = undefined;
+ }
+ if (level.audioCodec || level.attrs && level.attrs.AUDIO) {
+ audioCodecFound = true;
+ }
+ var redundantLevelId = bitrateSet[level.bitrate];
+ if (redundantLevelId === undefined) {
+ bitrateSet[level.bitrate] = levels0.length;
+ level.url = [level.url];
+ level.urlId = 0;
+ levels0.push(level);
+ } else {
+ levels0[redundantLevelId].url.push(level.url);
+ }
+ });
+
+ // remove audio-only level if we also have levels with audio+video codecs signalled
+ if (videoCodecFound && audioCodecFound) {
+ levels0.forEach(function (level) {
+ if (level.videoCodec) {
+ levels.push(level);
+ }
+ });
+ } else {
+ levels = levels0;
+ }
+ // only keep level with supported audio/video codecs
+ levels = levels.filter(function (level) {
+ var audioCodec = level.audioCodec,
+ videoCodec = level.videoCodec;
+ return (!audioCodec || checkSupported('audio', audioCodec)) && (!videoCodec || checkSupported('video', videoCodec));
+ });
+
+ if (levels.length) {
+ // start bitrate is the first bitrate of the manifest
+ bitrateStart = levels[0].bitrate;
+ // sort level on bitrate
+ levels.sort(function (a, b) {
+ return a.bitrate - b.bitrate;
+ });
+ this._levels = levels;
+ // find index of first level in sorted levels
+ for (var i = 0; i < levels.length; i++) {
+ if (levels[i].bitrate === bitrateStart) {
+ this._firstLevel = i;
+ _logger.logger.log('manifest loaded,' + levels.length + ' level(s) found, first bitrate:' + bitrateStart);
+ break;
+ }
+ }
+ hls.trigger(_events2.default.MANIFEST_PARSED, { levels: levels, firstLevel: this._firstLevel, stats: data.stats, audio: audioCodecFound, video: videoCodecFound, altAudio: data.audioTracks.length > 0 });
+ } else {
+ hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.MANIFEST_INCOMPATIBLE_CODECS_ERROR, fatal: true, url: hls.url, reason: 'no level with compatible codecs found in manifest' });
+ }
+ return;
+ }
+ }, {
+ key: 'setLevelInternal',
+ value: function setLevelInternal(newLevel) {
+ var levels = this._levels;
+ var hls = this.hls;
+ // check if level idx is valid
+ if (newLevel >= 0 && newLevel < levels.length) {
+ // stopping live reloading timer if any
+ if (this.timer) {
+ clearTimeout(this.timer);
+ this.timer = null;
+ }
+ if (this._level !== newLevel) {
+ _logger.logger.log('switching to level ' + newLevel);
+ this._level = newLevel;
+ var levelProperties = levels[newLevel];
+ levelProperties.level = newLevel;
+ // LEVEL_SWITCH to be deprecated in next major release
+ hls.trigger(_events2.default.LEVEL_SWITCH, levelProperties);
+ hls.trigger(_events2.default.LEVEL_SWITCHING, levelProperties);
+ }
+ var level = levels[newLevel],
+ levelDetails = level.details;
+ // check if we need to load playlist for this level
+ if (!levelDetails || levelDetails.live === true) {
+ // level not retrieved yet, or live playlist we need to (re)load it
+ var urlId = level.urlId;
+ hls.trigger(_events2.default.LEVEL_LOADING, { url: level.url[urlId], level: newLevel, id: urlId });
+ }
+ } else {
+ // invalid level id given, trigger error
+ hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.OTHER_ERROR, details: _errors.ErrorDetails.LEVEL_SWITCH_ERROR, level: newLevel, fatal: false, reason: 'invalid level idx' });
+ }
+ }
+ }, {
+ key: 'onError',
+ value: function onError(data) {
+ if (data.fatal) {
+ return;
+ }
+
+ var details = data.details,
+ hls = this.hls,
+ levelId = void 0,
+ level = void 0,
+ levelError = false;
+ // try to recover not fatal errors
+ switch (details) {
+ case _errors.ErrorDetails.FRAG_LOAD_ERROR:
+ case _errors.ErrorDetails.FRAG_LOAD_TIMEOUT:
+ case _errors.ErrorDetails.FRAG_LOOP_LOADING_ERROR:
+ case _errors.ErrorDetails.KEY_LOAD_ERROR:
+ case _errors.ErrorDetails.KEY_LOAD_TIMEOUT:
+ levelId = data.frag.level;
+ break;
+ case _errors.ErrorDetails.LEVEL_LOAD_ERROR:
+ case _errors.ErrorDetails.LEVEL_LOAD_TIMEOUT:
+ levelId = data.context.level;
+ levelError = true;
+ break;
+ case _errors.ErrorDetails.REMUX_ALLOC_ERROR:
+ levelId = data.level;
+ break;
+ default:
+ break;
+ }
+ /* try to switch to a redundant stream if any available.
+ * if no redundant stream available, emergency switch down (if in auto mode and current level not 0)
+ * otherwise, we cannot recover this network error ...
+ */
+ if (levelId !== undefined) {
+ level = this._levels[levelId];
+ if (!level.loadError) {
+ level.loadError = 1;
+ } else {
+ level.loadError++;
+ }
+ // if any redundant streams available and if we haven't try them all (level.loadError is reseted on successful frag/level load.
+ // if level.loadError reaches nbRedundantLevel it means that we tried them all, no hope => let's switch down
+ var nbRedundantLevel = level.url.length;
+ if (nbRedundantLevel > 1 && level.loadError < nbRedundantLevel) {
+ level.urlId = (level.urlId + 1) % nbRedundantLevel;
+ level.details = undefined;
+ _logger.logger.warn('level controller,' + details + ' for level ' + levelId + ': switching to redundant stream id ' + level.urlId);
+ } else {
+ // we could try to recover if in auto mode and current level not lowest level (0)
+ var recoverable = this._manualLevel === -1 && levelId;
+ if (recoverable) {
+ _logger.logger.warn('level controller,' + details + ': switch-down for next fragment');
+ hls.nextAutoLevel = Math.max(0, levelId - 1);
+ } else if (level && level.details && level.details.live) {
+ _logger.logger.warn('level controller,' + details + ' on live stream, discard');
+ if (levelError) {
+ // reset this._level so that another call to set level() will retrigger a frag load
+ this._level = undefined;
+ }
+ // other errors are handled by stream controller
+ } else if (details === _errors.ErrorDetails.LEVEL_LOAD_ERROR || details === _errors.ErrorDetails.LEVEL_LOAD_TIMEOUT) {
+ var media = hls.media,
+
+ // 0.5 : tolerance needed as some browsers stalls playback before reaching buffered end
+ mediaBuffered = media && _bufferHelper2.default.isBuffered(media, media.currentTime) && _bufferHelper2.default.isBuffered(media, media.currentTime + 0.5);
+ if (mediaBuffered) {
+ var retryDelay = hls.config.levelLoadingRetryDelay;
+ _logger.logger.warn('level controller,' + details + ', but media buffered, retry in ' + retryDelay + 'ms');
+ this.timer = setTimeout(this.ontick, retryDelay);
+ } else {
+ _logger.logger.error('cannot recover ' + details + ' error');
+ this._level = undefined;
+ // stopping live reloading timer if any
+ if (this.timer) {
+ clearTimeout(this.timer);
+ this.timer = null;
+ }
+ // switch error to fatal
+ data.fatal = true;
+ }
+ }
+ }
+ }
+ }
+
+ // reset level load error counter on successful frag loaded
+
+ }, {
+ key: 'onFragLoaded',
+ value: function onFragLoaded(data) {
+ var fragLoaded = data.frag;
+ if (fragLoaded && fragLoaded.type === 'main') {
+ var level = this._levels[fragLoaded.level];
+ if (level) {
+ level.loadError = 0;
+ }
+ }
+ }
+ }, {
+ key: 'onLevelLoaded',
+ value: function onLevelLoaded(data) {
+ var levelId = data.level;
+ // only process level loaded events matching with expected level
+ if (levelId === this._level) {
+ var curLevel = this._levels[levelId];
+ // reset level load error counter on successful level loaded
+ curLevel.loadError = 0;
+ var newDetails = data.details;
+ // if current playlist is a live playlist, arm a timer to reload it
+ if (newDetails.live) {
+ var reloadInterval = 1000 * (newDetails.averagetargetduration ? newDetails.averagetargetduration : newDetails.targetduration),
+ curDetails = curLevel.details;
+ if (curDetails && newDetails.endSN === curDetails.endSN) {
+ // follow HLS Spec, If the client reloads a Playlist file and finds that it has not
+ // changed then it MUST wait for a period of one-half the target
+ // duration before retrying.
+ reloadInterval /= 2;
+ _logger.logger.log('same live playlist, reload twice faster');
+ }
+ // decrement reloadInterval with level loading delay
+ reloadInterval -= performance.now() - data.stats.trequest;
+ // in any case, don't reload more than every second
+ reloadInterval = Math.max(1000, Math.round(reloadInterval));
+ _logger.logger.log('live playlist, reload in ' + reloadInterval + ' ms');
+ this.timer = setTimeout(this.ontick, reloadInterval);
+ } else {
+ this.timer = null;
+ }
+ }
+ }
+ }, {
+ key: 'tick',
+ value: function tick() {
+ var levelId = this._level;
+ if (levelId !== undefined && this.canload) {
+ var level = this._levels[levelId];
+ if (level && level.url) {
+ var urlId = level.urlId;
+ this.hls.trigger(_events2.default.LEVEL_LOADING, { url: level.url[urlId], level: levelId, id: urlId });
+ }
+ }
+ }
+ }, {
+ key: 'levels',
+ get: function get() {
+ return this._levels;
+ }
+ }, {
+ key: 'level',
+ get: function get() {
+ return this._level;
+ },
+ set: function set(newLevel) {
+ var levels = this._levels;
+ if (levels && levels.length > newLevel) {
+ if (this._level !== newLevel || levels[newLevel].details === undefined) {
+ this.setLevelInternal(newLevel);
+ }
+ }
+ }
+ }, {
+ key: 'manualLevel',
+ get: function get() {
+ return this._manualLevel;
+ },
+ set: function set(newLevel) {
+ this._manualLevel = newLevel;
+ if (this._startLevel === undefined) {
+ this._startLevel = newLevel;
+ }
+ if (newLevel !== -1) {
+ this.level = newLevel;
+ }
+ }
+ }, {
+ key: 'firstLevel',
+ get: function get() {
+ return this._firstLevel;
+ },
+ set: function set(newLevel) {
+ this._firstLevel = newLevel;
+ }
+ }, {
+ key: 'startLevel',
+ get: function get() {
+ // hls.startLevel takes precedence over config.startLevel
+ // if none of these values are defined, fallback on this._firstLevel (first quality level appearing in variant manifest)
+ if (this._startLevel === undefined) {
+ var configStartLevel = this.hls.config.startLevel;
+ if (configStartLevel !== undefined) {
+ return configStartLevel;
+ } else {
+ return this._firstLevel;
+ }
+ } else {
+ return this._startLevel;
+ }
+ },
+ set: function set(newLevel) {
+ this._startLevel = newLevel;
+ }
+ }, {
+ key: 'nextLoadLevel',
+ get: function get() {
+ if (this._manualLevel !== -1) {
+ return this._manualLevel;
+ } else {
+ return this.hls.nextAutoLevel;
+ }
+ },
+ set: function set(nextLevel) {
+ this.level = nextLevel;
+ if (this._manualLevel === -1) {
+ this.hls.nextAutoLevel = nextLevel;
+ }
+ }
+ }]);
+
+ return LevelController;
+}(_eventHandler2.default);
+
+exports.default = LevelController;
+
+},{"30":30,"31":31,"32":32,"34":34,"50":50}],12:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _binarySearch = _dereq_(45);
+
+var _binarySearch2 = _interopRequireDefault(_binarySearch);
+
+var _bufferHelper = _dereq_(34);
+
+var _bufferHelper2 = _interopRequireDefault(_bufferHelper);
+
+var _demuxer = _dereq_(24);
+
+var _demuxer2 = _interopRequireDefault(_demuxer);
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = _dereq_(31);
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+var _levelHelper = _dereq_(35);
+
+var _levelHelper2 = _interopRequireDefault(_levelHelper);
+
+var _timeRanges = _dereq_(51);
+
+var _timeRanges2 = _interopRequireDefault(_timeRanges);
+
+var _errors = _dereq_(30);
+
+var _logger = _dereq_(50);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+ * Stream Controller
+ */
+
+var State = {
+ STOPPED: 'STOPPED',
+ IDLE: 'IDLE',
+ KEY_LOADING: 'KEY_LOADING',
+ FRAG_LOADING: 'FRAG_LOADING',
+ FRAG_LOADING_WAITING_RETRY: 'FRAG_LOADING_WAITING_RETRY',
+ WAITING_LEVEL: 'WAITING_LEVEL',
+ PARSING: 'PARSING',
+ PARSED: 'PARSED',
+ BUFFER_FLUSHING: 'BUFFER_FLUSHING',
+ ENDED: 'ENDED',
+ ERROR: 'ERROR'
+};
+
+var StreamController = function (_EventHandler) {
+ _inherits(StreamController, _EventHandler);
+
+ function StreamController(hls) {
+ _classCallCheck(this, StreamController);
+
+ var _this = _possibleConstructorReturn(this, (StreamController.__proto__ || Object.getPrototypeOf(StreamController)).call(this, hls, _events2.default.MEDIA_ATTACHED, _events2.default.MEDIA_DETACHING, _events2.default.MANIFEST_LOADING, _events2.default.MANIFEST_PARSED, _events2.default.LEVEL_LOADED, _events2.default.KEY_LOADED, _events2.default.FRAG_LOADED, _events2.default.FRAG_LOAD_EMERGENCY_ABORTED, _events2.default.FRAG_PARSING_INIT_SEGMENT, _events2.default.FRAG_PARSING_DATA, _events2.default.FRAG_PARSED, _events2.default.ERROR, _events2.default.AUDIO_TRACK_SWITCHING, _events2.default.AUDIO_TRACK_SWITCHED, _events2.default.BUFFER_CREATED, _events2.default.BUFFER_APPENDED, _events2.default.BUFFER_FLUSHED));
+
+ _this.config = hls.config;
+ _this.audioCodecSwap = false;
+ _this.ticks = 0;
+ _this._state = State.STOPPED;
+ _this.ontick = _this.tick.bind(_this);
+ return _this;
+ }
+
+ _createClass(StreamController, [{
+ key: 'destroy',
+ value: function destroy() {
+ this.stopLoad();
+ if (this.timer) {
+ clearInterval(this.timer);
+ this.timer = null;
+ }
+ _eventHandler2.default.prototype.destroy.call(this);
+ this.state = State.STOPPED;
+ }
+ }, {
+ key: 'startLoad',
+ value: function startLoad(startPosition) {
+ if (this.levels) {
+ var lastCurrentTime = this.lastCurrentTime,
+ hls = this.hls;
+ this.stopLoad();
+ if (!this.timer) {
+ this.timer = setInterval(this.ontick, 100);
+ }
+ this.level = -1;
+ this.fragLoadError = 0;
+ if (!this.startFragRequested) {
+ // determine load level
+ var startLevel = hls.startLevel;
+ if (startLevel === -1) {
+ // -1 : guess start Level by doing a bitrate test by loading first fragment of lowest quality level
+ startLevel = 0;
+ this.bitrateTest = true;
+ }
+ // set new level to playlist loader : this will trigger start level load
+ // hls.nextLoadLevel remains until it is set to a new value or until a new frag is successfully loaded
+ this.level = hls.nextLoadLevel = startLevel;
+ this.loadedmetadata = false;
+ }
+ // if startPosition undefined but lastCurrentTime set, set startPosition to last currentTime
+ if (lastCurrentTime > 0 && startPosition === -1) {
+ _logger.logger.log('override startPosition with lastCurrentTime @' + lastCurrentTime.toFixed(3));
+ startPosition = lastCurrentTime;
+ }
+ this.state = State.IDLE;
+ this.nextLoadPosition = this.startPosition = this.lastCurrentTime = startPosition;
+ this.tick();
+ } else {
+ this.forceStartLoad = true;
+ this.state = State.STOPPED;
+ }
+ }
+ }, {
+ key: 'stopLoad',
+ value: function stopLoad() {
+ var frag = this.fragCurrent;
+ if (frag) {
+ if (frag.loader) {
+ frag.loader.abort();
+ }
+ this.fragCurrent = null;
+ }
+ this.fragPrevious = null;
+ if (this.demuxer) {
+ this.demuxer.destroy();
+ this.demuxer = null;
+ }
+ this.state = State.STOPPED;
+ this.forceStartLoad = false;
+ }
+ }, {
+ key: 'tick',
+ value: function tick() {
+ this.ticks++;
+ if (this.ticks === 1) {
+ this.doTick();
+ if (this.ticks > 1) {
+ setTimeout(this.tick, 1);
+ }
+ this.ticks = 0;
+ }
+ }
+ }, {
+ key: 'doTick',
+ value: function doTick() {
+ switch (this.state) {
+ case State.ERROR:
+ //don't do anything in error state to avoid breaking further ...
+ break;
+ case State.BUFFER_FLUSHING:
+ // in buffer flushing state, reset fragLoadError counter
+ this.fragLoadError = 0;
+ break;
+ case State.IDLE:
+ // when this returns false there was an error and we shall return immediatly
+ // from current tick
+ if (!this._doTickIdle()) {
+ return;
+ }
+ break;
+ case State.WAITING_LEVEL:
+ var level = this.levels[this.level];
+ // check if playlist is already loaded
+ if (level && level.details) {
+ this.state = State.IDLE;
+ }
+ break;
+ case State.FRAG_LOADING_WAITING_RETRY:
+ var now = performance.now();
+ var retryDate = this.retryDate;
+ // if current time is gt than retryDate, or if media seeking let's switch to IDLE state to retry loading
+ if (!retryDate || now >= retryDate || this.media && this.media.seeking) {
+ _logger.logger.log('mediaController: retryDate reached, switch back to IDLE state');
+ this.state = State.IDLE;
+ }
+ break;
+ case State.ERROR:
+ case State.STOPPED:
+ case State.FRAG_LOADING:
+ case State.PARSING:
+ case State.PARSED:
+ case State.ENDED:
+ break;
+ default:
+ break;
+ }
+ // check buffer
+ this._checkBuffer();
+ // check/update current fragment
+ this._checkFragmentChanged();
+ }
+
+ // Ironically the "idle" state is the on we do the most logic in it seems ....
+ // NOTE: Maybe we could rather schedule a check for buffer length after half of the currently
+ // played segment, or on pause/play/seek instead of naively checking every 100ms?
+
+ }, {
+ key: '_doTickIdle',
+ value: function _doTickIdle() {
+ var hls = this.hls,
+ config = hls.config,
+ media = this.media;
+
+ // if video not attached AND
+ // start fragment already requested OR start frag prefetch disable
+ // exit loop
+ // => if start level loaded and media not attached but start frag prefetch is enabled and start frag not requested yet, we will not exit loop
+ if (this.levelLastLoaded !== undefined && !media && (this.startFragRequested || !config.startFragPrefetch)) {
+ return true;
+ }
+
+ // if we have not yet loaded any fragment, start loading from start position
+ var pos = void 0;
+ if (this.loadedmetadata) {
+ pos = media.currentTime;
+ } else {
+ pos = this.nextLoadPosition;
+ }
+ // determine next load level
+ var level = hls.nextLoadLevel,
+ levelInfo = this.levels[level],
+ levelBitrate = levelInfo.bitrate,
+ maxBufLen = void 0;
+
+ // compute max Buffer Length that we could get from this load level, based on level bitrate. don't buffer more than 60 MB and more than 30s
+ if (levelBitrate) {
+ maxBufLen = Math.max(8 * config.maxBufferSize / levelBitrate, config.maxBufferLength);
+ } else {
+ maxBufLen = config.maxBufferLength;
+ }
+ maxBufLen = Math.min(maxBufLen, config.maxMaxBufferLength);
+
+ // determine next candidate fragment to be loaded, based on current position and end of buffer position
+ // ensure up to `config.maxMaxBufferLength` of buffer upfront
+
+ var bufferInfo = _bufferHelper2.default.bufferInfo(this.mediaBuffer ? this.mediaBuffer : media, pos, config.maxBufferHole),
+ bufferLen = bufferInfo.len;
+ // Stay idle if we are still with buffer margins
+ if (bufferLen >= maxBufLen) {
+ return true;
+ }
+
+ // if buffer length is less than maxBufLen try to load a new fragment ...
+ _logger.logger.trace('buffer length of ' + bufferLen.toFixed(3) + ' is below max of ' + maxBufLen.toFixed(3) + '. checking for more payload ...');
+
+ // set next load level : this will trigger a playlist load if needed
+ this.level = hls.nextLoadLevel = level;
+
+ var levelDetails = levelInfo.details;
+ // if level info not retrieved yet, switch state and wait for level retrieval
+ // if live playlist, ensure that new playlist has been refreshed to avoid loading/try to load
+ // a useless and outdated fragment (that might even introduce load error if it is already out of the live playlist)
+ if (typeof levelDetails === 'undefined' || levelDetails.live && this.levelLastLoaded !== level) {
+ this.state = State.WAITING_LEVEL;
+ return true;
+ }
+
+ // we just got done loading the final fragment, check if we need to finalize media stream
+ var fragPrevious = this.fragPrevious;
+ if (!levelDetails.live && fragPrevious && fragPrevious.sn === levelDetails.endSN) {
+ // fragPrevious is last fragment. retrieve level duration using last frag start offset + duration
+ // real duration might be lower than initial duration if there are drifts between real frag duration and playlist signaling
+ var duration = Math.min(media.duration, fragPrevious.start + fragPrevious.duration);
+ // if everything (almost) til the end is buffered, let's signal eos
+ // we don't compare exactly media.duration === bufferInfo.end as there could be some subtle media duration difference
+ // using half frag duration should help cope with these cases.
+ // also cope with almost zero last frag duration (max last frag duration with 200ms) refer to https://github.com/video-dev/hls.js/pull/657
+ if (duration - Math.max(bufferInfo.end, fragPrevious.start) <= Math.max(0.2, fragPrevious.duration / 2)) {
+ // Finalize the media stream
+ var data = {};
+ if (this.altAudio) {
+ data.type = 'video';
+ }
+ this.hls.trigger(_events2.default.BUFFER_EOS, data);
+ this.state = State.ENDED;
+ return true;
+ }
+ }
+
+ // if we have the levelDetails for the selected variant, lets continue enrichen our stream (load keys/fragments or trigger EOS, etc..)
+ return this._fetchPayloadOrEos(pos, bufferInfo, levelDetails);
+ }
+ }, {
+ key: '_fetchPayloadOrEos',
+ value: function _fetchPayloadOrEos(pos, bufferInfo, levelDetails) {
+ var fragPrevious = this.fragPrevious,
+ level = this.level,
+ fragments = levelDetails.fragments,
+ fragLen = fragments.length;
+
+ // empty playlist
+ if (fragLen === 0) {
+ return false;
+ }
+
+ // find fragment index, contiguous with end of buffer position
+ var start = fragments[0].start,
+ end = fragments[fragLen - 1].start + fragments[fragLen - 1].duration,
+ bufferEnd = bufferInfo.end,
+ frag = void 0;
+
+ if (levelDetails.initSegment && !levelDetails.initSegment.data) {
+ frag = levelDetails.initSegment;
+ } else {
+ // in case of live playlist we need to ensure that requested position is not located before playlist start
+ if (levelDetails.live) {
+ var initialLiveManifestSize = this.config.initialLiveManifestSize;
+ if (fragLen < initialLiveManifestSize) {
+ _logger.logger.warn('Can not start playback of a level, reason: not enough fragments ' + fragLen + ' < ' + initialLiveManifestSize);
+ return false;
+ }
+
+ frag = this._ensureFragmentAtLivePoint(levelDetails, bufferEnd, start, end, fragPrevious, fragments, fragLen);
+ // if it explicitely returns null don't load any fragment and exit function now
+ if (frag === null) {
+ return false;
+ }
+ } else {
+ // VoD playlist: if bufferEnd before start of playlist, load first fragment
+ if (bufferEnd < start) {
+ frag = fragments[0];
+ }
+ }
+ }
+ if (!frag) {
+ frag = this._findFragment(start, fragPrevious, fragLen, fragments, bufferEnd, end, levelDetails);
+ }
+ if (frag) {
+ return this._loadFragmentOrKey(frag, level, levelDetails, pos, bufferEnd);
+ }
+ return true;
+ }
+ }, {
+ key: '_ensureFragmentAtLivePoint',
+ value: function _ensureFragmentAtLivePoint(levelDetails, bufferEnd, start, end, fragPrevious, fragments, fragLen) {
+ var config = this.hls.config,
+ media = this.media;
+
+ var frag = void 0;
+
+ // check if requested position is within seekable boundaries :
+ //logger.log(`start/pos/bufEnd/seeking:${start.toFixed(3)}/${pos.toFixed(3)}/${bufferEnd.toFixed(3)}/${this.media.seeking}`);
+ var maxLatency = config.liveMaxLatencyDuration !== undefined ? config.liveMaxLatencyDuration : config.liveMaxLatencyDurationCount * levelDetails.targetduration;
+
+ if (bufferEnd < Math.max(start - config.maxFragLookUpTolerance, end - maxLatency)) {
+ var liveSyncPosition = this.liveSyncPosition = this.computeLivePosition(start, levelDetails);
+ _logger.logger.log('buffer end: ' + bufferEnd.toFixed(3) + ' is located too far from the end of live sliding playlist, reset currentTime to : ' + liveSyncPosition.toFixed(3));
+ bufferEnd = liveSyncPosition;
+ if (media && media.readyState && media.duration > liveSyncPosition) {
+ media.currentTime = liveSyncPosition;
+ }
+ }
+
+ // if end of buffer greater than live edge, don't load any fragment
+ // this could happen if live playlist intermittently slides in the past.
+ // level 1 loaded [182580161,182580167]
+ // level 1 loaded [182580162,182580169]
+ // Loading 182580168 of [182580162 ,182580169],level 1 ..
+ // Loading 182580169 of [182580162 ,182580169],level 1 ..
+ // level 1 loaded [182580162,182580168] <============= here we should have bufferEnd > end. in that case break to avoid reloading 182580168
+ // level 1 loaded [182580164,182580171]
+ //
+ // don't return null in case media not loaded yet (readystate === 0)
+ if (levelDetails.PTSKnown && bufferEnd > end && media && media.readyState) {
+ return null;
+ }
+
+ if (this.startFragRequested && !levelDetails.PTSKnown) {
+ /* we are switching level on live playlist, but we don't have any PTS info for that quality level ...
+ try to load frag matching with next SN.
+ even if SN are not synchronized between playlists, loading this frag will help us
+ compute playlist sliding and find the right one after in case it was not the right consecutive one */
+ if (fragPrevious) {
+ var targetSN = fragPrevious.sn + 1;
+ if (targetSN >= levelDetails.startSN && targetSN <= levelDetails.endSN) {
+ frag = fragments[targetSN - levelDetails.startSN];
+ _logger.logger.log('live playlist, switching playlist, load frag with next SN: ' + frag.sn);
+ }
+ }
+ if (!frag) {
+ /* we have no idea about which fragment should be loaded.
+ so let's load mid fragment. it will help computing playlist sliding and find the right one
+ */
+ frag = fragments[Math.min(fragLen - 1, Math.round(fragLen / 2))];
+ _logger.logger.log('live playlist, switching playlist, unknown, load middle frag : ' + frag.sn);
+ }
+ }
+ return frag;
+ }
+ }, {
+ key: '_findFragment',
+ value: function _findFragment(start, fragPrevious, fragLen, fragments, bufferEnd, end, levelDetails) {
+ var config = this.hls.config;
+ var frag = void 0;
+ var foundFrag = void 0;
+ var maxFragLookUpTolerance = config.maxFragLookUpTolerance;
+ var fragNext = fragPrevious ? fragments[fragPrevious.sn - fragments[0].sn + 1] : undefined;
+ var fragmentWithinToleranceTest = function fragmentWithinToleranceTest(candidate) {
+ // offset should be within fragment boundary - config.maxFragLookUpTolerance
+ // this is to cope with situations like
+ // bufferEnd = 9.991
+ // frag[Ø] : [0,10]
+ // frag[1] : [10,20]
+ // bufferEnd is within frag[0] range ... although what we are expecting is to return frag[1] here
+ // frag start frag start+duration
+ // |-----------------------------|
+ // <---> <--->
+ // ...--------><-----------------------------><---------....
+ // previous frag matching fragment next frag
+ // return -1 return 0 return 1
+ //logger.log(`level/sn/start/end/bufEnd:${level}/${candidate.sn}/${candidate.start}/${(candidate.start+candidate.duration)}/${bufferEnd}`);
+ // Set the lookup tolerance to be small enough to detect the current segment - ensures we don't skip over very small segments
+ var candidateLookupTolerance = Math.min(maxFragLookUpTolerance, candidate.duration);
+ if (candidate.start + candidate.duration - candidateLookupTolerance <= bufferEnd) {
+ return 1;
+ } // if maxFragLookUpTolerance will have negative value then don't return -1 for first element
+ else if (candidate.start - candidateLookupTolerance > bufferEnd && candidate.start) {
+ return -1;
+ }
+ return 0;
+ };
+
+ if (bufferEnd < end) {
+ if (bufferEnd > end - maxFragLookUpTolerance) {
+ maxFragLookUpTolerance = 0;
+ }
+ // Prefer the next fragment if it's within tolerance
+ if (fragNext && !fragmentWithinToleranceTest(fragNext)) {
+ foundFrag = fragNext;
+ } else {
+ foundFrag = _binarySearch2.default.search(fragments, fragmentWithinToleranceTest);
+ }
+ } else {
+ // reach end of playlist
+ foundFrag = fragments[fragLen - 1];
+ }
+ if (foundFrag) {
+ frag = foundFrag;
+ var curSNIdx = frag.sn - levelDetails.startSN;
+ var sameLevel = fragPrevious && frag.level === fragPrevious.level;
+ var prevFrag = fragments[curSNIdx - 1];
+ var nextFrag = fragments[curSNIdx + 1];
+ //logger.log('find SN matching with pos:' + bufferEnd + ':' + frag.sn);
+ if (sameLevel && frag.sn === fragPrevious.sn) {
+ if (frag.sn < levelDetails.endSN) {
+ var deltaPTS = fragPrevious.deltaPTS;
+ // if there is a significant delta between audio and video, larger than max allowed hole,
+ // and if previous remuxed fragment did not start with a keyframe. (fragPrevious.dropped)
+ // let's try to load previous fragment again to get last keyframe
+ // then we will reload again current fragment (that way we should be able to fill the buffer hole ...)
+ if (deltaPTS && deltaPTS > config.maxBufferHole && fragPrevious.dropped && curSNIdx) {
+ frag = prevFrag;
+ _logger.logger.warn('SN just loaded, with large PTS gap between audio and video, maybe frag is not starting with a keyframe ? load previous one to try to overcome this');
+ // decrement previous frag load counter to avoid frag loop loading error when next fragment will get reloaded
+ fragPrevious.loadCounter--;
+ } else {
+ frag = nextFrag;
+ _logger.logger.log('SN just loaded, load next one: ' + frag.sn);
+ }
+ } else {
+ frag = null;
+ }
+ } else if (frag.dropped && !sameLevel) {
+ // Only backtrack a max of 1 consecutive fragment to prevent sliding back too far when little or no frags start with keyframes
+ if (nextFrag && nextFrag.backtracked) {
+ _logger.logger.warn('Already backtracked from fragment ' + (curSNIdx + 1) + ', will not backtrack to fragment ' + curSNIdx + '. Loading fragment ' + (curSNIdx + 1));
+ frag = nextFrag;
+ } else {
+ // If a fragment has dropped frames and it's in a different level/sequence, load the previous fragment to try and find the keyframe
+ // Reset the dropped count now since it won't be reset until we parse the fragment again, which prevents infinite backtracking on the same segment
+ _logger.logger.warn('Loaded fragment with dropped frames, backtracking 1 segment to find a keyframe');
+ frag.dropped = 0;
+ if (prevFrag) {
+ if (prevFrag.loadCounter) {
+ prevFrag.loadCounter--;
+ }
+ frag = prevFrag;
+ } else {
+ frag = null;
+ }
+ }
+ }
+ }
+ return frag;
+ }
+ }, {
+ key: '_loadFragmentOrKey',
+ value: function _loadFragmentOrKey(frag, level, levelDetails, pos, bufferEnd) {
+ var hls = this.hls,
+ config = hls.config;
+
+ //logger.log('loading frag ' + i +',pos/bufEnd:' + pos.toFixed(3) + '/' + bufferEnd.toFixed(3));
+ if (frag.decryptdata && frag.decryptdata.uri != null && frag.decryptdata.key == null) {
+ _logger.logger.log('Loading key for ' + frag.sn + ' of [' + levelDetails.startSN + ' ,' + levelDetails.endSN + '],level ' + level);
+ this.state = State.KEY_LOADING;
+ hls.trigger(_events2.default.KEY_LOADING, { frag: frag });
+ } else {
+ _logger.logger.log('Loading ' + frag.sn + ' of [' + levelDetails.startSN + ' ,' + levelDetails.endSN + '],level ' + level + ', currentTime:' + pos.toFixed(3) + ',bufferEnd:' + bufferEnd.toFixed(3));
+ // ensure that we are not reloading the same fragments in loop ...
+ if (this.fragLoadIdx !== undefined) {
+ this.fragLoadIdx++;
+ } else {
+ this.fragLoadIdx = 0;
+ }
+ if (frag.loadCounter) {
+ frag.loadCounter++;
+ var maxThreshold = config.fragLoadingLoopThreshold;
+ // if this frag has already been loaded 3 times, and if it has been reloaded recently
+ if (frag.loadCounter > maxThreshold && Math.abs(this.fragLoadIdx - frag.loadIdx) < maxThreshold) {
+ hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.FRAG_LOOP_LOADING_ERROR, fatal: false, frag: frag });
+ return false;
+ }
+ } else {
+ frag.loadCounter = 1;
+ }
+ frag.loadIdx = this.fragLoadIdx;
+ this.fragCurrent = frag;
+ this.startFragRequested = true;
+ if (!isNaN(frag.sn)) {
+ this.nextLoadPosition = frag.start + frag.duration;
+ }
+ frag.autoLevel = hls.autoLevelEnabled;
+ frag.bitrateTest = this.bitrateTest;
+ hls.trigger(_events2.default.FRAG_LOADING, { frag: frag });
+ // lazy demuxer init, as this could take some time ... do it during frag loading
+ if (!this.demuxer) {
+ this.demuxer = new _demuxer2.default(hls, 'main');
+ }
+ this.state = State.FRAG_LOADING;
+ return true;
+ }
+ }
+ }, {
+ key: 'getBufferedFrag',
+ value: function getBufferedFrag(position) {
+ return _binarySearch2.default.search(this._bufferedFrags, function (frag) {
+ if (position < frag.startPTS) {
+ return -1;
+ } else if (position > frag.endPTS) {
+ return 1;
+ }
+ return 0;
+ });
+ }
+ }, {
+ key: 'followingBufferedFrag',
+ value: function followingBufferedFrag(frag) {
+ if (frag) {
+ // try to get range of next fragment (500ms after this range)
+ return this.getBufferedFrag(frag.endPTS + 0.5);
+ }
+ return null;
+ }
+ }, {
+ key: '_checkFragmentChanged',
+ value: function _checkFragmentChanged() {
+ var fragPlayingCurrent,
+ currentTime,
+ video = this.media;
+ if (video && video.readyState && video.seeking === false) {
+ currentTime = video.currentTime;
+ /* if video element is in seeked state, currentTime can only increase.
+ (assuming that playback rate is positive ...)
+ As sometimes currentTime jumps back to zero after a
+ media decode error, check this, to avoid seeking back to
+ wrong position after a media decode error
+ */
+ if (currentTime > video.playbackRate * this.lastCurrentTime) {
+ this.lastCurrentTime = currentTime;
+ }
+ if (_bufferHelper2.default.isBuffered(video, currentTime)) {
+ fragPlayingCurrent = this.getBufferedFrag(currentTime);
+ } else if (_bufferHelper2.default.isBuffered(video, currentTime + 0.1)) {
+ /* ensure that FRAG_CHANGED event is triggered at startup,
+ when first video frame is displayed and playback is paused.
+ add a tolerance of 100ms, in case current position is not buffered,
+ check if current pos+100ms is buffered and use that buffer range
+ for FRAG_CHANGED event reporting */
+ fragPlayingCurrent = this.getBufferedFrag(currentTime + 0.1);
+ }
+ if (fragPlayingCurrent) {
+ var fragPlaying = fragPlayingCurrent;
+ if (fragPlaying !== this.fragPlaying) {
+ this.hls.trigger(_events2.default.FRAG_CHANGED, { frag: fragPlaying });
+ var fragPlayingLevel = fragPlaying.level;
+ if (!this.fragPlaying || this.fragPlaying.level !== fragPlayingLevel) {
+ this.hls.trigger(_events2.default.LEVEL_SWITCHED, { level: fragPlayingLevel });
+ }
+ this.fragPlaying = fragPlaying;
+ }
+ }
+ }
+ }
+
+ /*
+ on immediate level switch :
+ - pause playback if playing
+ - cancel any pending load request
+ - and trigger a buffer flush
+ */
+
+ }, {
+ key: 'immediateLevelSwitch',
+ value: function immediateLevelSwitch() {
+ _logger.logger.log('immediateLevelSwitch');
+ if (!this.immediateSwitch) {
+ this.immediateSwitch = true;
+ var media = this.media,
+ previouslyPaused = void 0;
+ if (media) {
+ previouslyPaused = media.paused;
+ media.pause();
+ } else {
+ // don't restart playback after instant level switch in case media not attached
+ previouslyPaused = true;
+ }
+ this.previouslyPaused = previouslyPaused;
+ }
+ var fragCurrent = this.fragCurrent;
+ if (fragCurrent && fragCurrent.loader) {
+ fragCurrent.loader.abort();
+ }
+ this.fragCurrent = null;
+ // increase fragment load Index to avoid frag loop loading error after buffer flush
+ this.fragLoadIdx += 2 * this.config.fragLoadingLoopThreshold;
+ // flush everything
+ this.flushMainBuffer(0, Number.POSITIVE_INFINITY);
+ }
+
+ /*
+ on immediate level switch end, after new fragment has been buffered :
+ - nudge video decoder by slightly adjusting video currentTime (if currentTime buffered)
+ - resume the playback if needed
+ */
+
+ }, {
+ key: 'immediateLevelSwitchEnd',
+ value: function immediateLevelSwitchEnd() {
+ var media = this.media;
+ if (media && media.buffered.length) {
+ this.immediateSwitch = false;
+ if (_bufferHelper2.default.isBuffered(media, media.currentTime)) {
+ // only nudge if currentTime is buffered
+ media.currentTime -= 0.0001;
+ }
+ if (!this.previouslyPaused) {
+ media.play();
+ }
+ }
+ }
+ }, {
+ key: 'nextLevelSwitch',
+ value: function nextLevelSwitch() {
+ /* try to switch ASAP without breaking video playback :
+ in order to ensure smooth but quick level switching,
+ we need to find the next flushable buffer range
+ we should take into account new segment fetch time
+ */
+ var media = this.media;
+ // ensure that media is defined and that metadata are available (to retrieve currentTime)
+ if (media && media.readyState) {
+ var fetchdelay = void 0,
+ fragPlayingCurrent = void 0,
+ nextBufferedFrag = void 0;
+ // increase fragment load Index to avoid frag loop loading error after buffer flush
+ this.fragLoadIdx += 2 * this.config.fragLoadingLoopThreshold;
+ fragPlayingCurrent = this.getBufferedFrag(media.currentTime);
+ if (fragPlayingCurrent && fragPlayingCurrent.startPTS > 1) {
+ // flush buffer preceding current fragment (flush until current fragment start offset)
+ // minus 1s to avoid video freezing, that could happen if we flush keyframe of current video ...
+ this.flushMainBuffer(0, fragPlayingCurrent.startPTS - 1);
+ }
+ if (!media.paused) {
+ // add a safety delay of 1s
+ var nextLevelId = this.hls.nextLoadLevel,
+ nextLevel = this.levels[nextLevelId],
+ fragLastKbps = this.fragLastKbps;
+ if (fragLastKbps && this.fragCurrent) {
+ fetchdelay = this.fragCurrent.duration * nextLevel.bitrate / (1000 * fragLastKbps) + 1;
+ } else {
+ fetchdelay = 0;
+ }
+ } else {
+ fetchdelay = 0;
+ }
+ //logger.log('fetchdelay:'+fetchdelay);
+ // find buffer range that will be reached once new fragment will be fetched
+ nextBufferedFrag = this.getBufferedFrag(media.currentTime + fetchdelay);
+ if (nextBufferedFrag) {
+ // we can flush buffer range following this one without stalling playback
+ nextBufferedFrag = this.followingBufferedFrag(nextBufferedFrag);
+ if (nextBufferedFrag) {
+ // if we are here, we can also cancel any loading/demuxing in progress, as they are useless
+ var fragCurrent = this.fragCurrent;
+ if (fragCurrent && fragCurrent.loader) {
+ fragCurrent.loader.abort();
+ }
+ this.fragCurrent = null;
+ // flush position is the start position of this new buffer
+ this.flushMainBuffer(nextBufferedFrag.startPTS, Number.POSITIVE_INFINITY);
+ }
+ }
+ }
+ }
+ }, {
+ key: 'flushMainBuffer',
+ value: function flushMainBuffer(startOffset, endOffset) {
+ this.state = State.BUFFER_FLUSHING;
+ var flushScope = { startOffset: startOffset, endOffset: endOffset };
+ // if alternate audio tracks are used, only flush video, otherwise flush everything
+ if (this.altAudio) {
+ flushScope.type = 'video';
+ }
+ this.hls.trigger(_events2.default.BUFFER_FLUSHING, flushScope);
+ }
+ }, {
+ key: 'onMediaAttached',
+ value: function onMediaAttached(data) {
+ var media = this.media = this.mediaBuffer = data.media;
+ this.onvseeking = this.onMediaSeeking.bind(this);
+ this.onvseeked = this.onMediaSeeked.bind(this);
+ this.onvended = this.onMediaEnded.bind(this);
+ media.addEventListener('seeking', this.onvseeking);
+ media.addEventListener('seeked', this.onvseeked);
+ media.addEventListener('ended', this.onvended);
+ var config = this.config;
+ if (this.levels && config.autoStartLoad) {
+ this.hls.startLoad(config.startPosition);
+ }
+ }
+ }, {
+ key: 'onMediaDetaching',
+ value: function onMediaDetaching() {
+ var media = this.media;
+ if (media && media.ended) {
+ _logger.logger.log('MSE detaching and video ended, reset startPosition');
+ this.startPosition = this.lastCurrentTime = 0;
+ }
+
+ // reset fragment loading counter on MSE detaching to avoid reporting FRAG_LOOP_LOADING_ERROR after error recovery
+ var levels = this.levels;
+ if (levels) {
+ // reset fragment load counter
+ levels.forEach(function (level) {
+ if (level.details) {
+ level.details.fragments.forEach(function (fragment) {
+ fragment.loadCounter = undefined;
+ fragment.backtracked = undefined;
+ });
+ }
+ });
+ }
+ // remove video listeners
+ if (media) {
+ media.removeEventListener('seeking', this.onvseeking);
+ media.removeEventListener('seeked', this.onvseeked);
+ media.removeEventListener('ended', this.onvended);
+ this.onvseeking = this.onvseeked = this.onvended = null;
+ }
+ this.media = this.mediaBuffer = null;
+ this.loadedmetadata = false;
+ this.stopLoad();
+ }
+ }, {
+ key: 'onMediaSeeking',
+ value: function onMediaSeeking() {
+ var media = this.media,
+ currentTime = media ? media.currentTime : undefined,
+ config = this.config;
+ _logger.logger.log('media seeking to ' + currentTime.toFixed(3));
+ if (this.state === State.FRAG_LOADING) {
+ var mediaBuffer = this.mediaBuffer ? this.mediaBuffer : media;
+ var bufferInfo = _bufferHelper2.default.bufferInfo(mediaBuffer, currentTime, this.config.maxBufferHole),
+ fragCurrent = this.fragCurrent;
+ // check if we are seeking to a unbuffered area AND if frag loading is in progress
+ if (bufferInfo.len === 0 && fragCurrent) {
+ var tolerance = config.maxFragLookUpTolerance,
+ fragStartOffset = fragCurrent.start - tolerance,
+ fragEndOffset = fragCurrent.start + fragCurrent.duration + tolerance;
+ // check if we seek position will be out of currently loaded frag range : if out cancel frag load, if in, don't do anything
+ if (currentTime < fragStartOffset || currentTime > fragEndOffset) {
+ if (fragCurrent.loader) {
+ _logger.logger.log('seeking outside of buffer while fragment load in progress, cancel fragment load');
+ fragCurrent.loader.abort();
+ }
+ this.fragCurrent = null;
+ this.fragPrevious = null;
+ // switch to IDLE state to load new fragment
+ this.state = State.IDLE;
+ } else {
+ _logger.logger.log('seeking outside of buffer but within currently loaded fragment range');
+ }
+ }
+ } else if (this.state === State.ENDED) {
+ // switch to IDLE state to check for potential new fragment
+ this.state = State.IDLE;
+ }
+ if (media) {
+ this.lastCurrentTime = currentTime;
+ }
+ // avoid reporting fragment loop loading error in case user is seeking several times on same position
+ if (this.state !== State.FRAG_LOADING && this.fragLoadIdx !== undefined) {
+ this.fragLoadIdx += 2 * config.fragLoadingLoopThreshold;
+ }
+ // in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target
+ if (!this.loadedmetadata) {
+ this.nextLoadPosition = this.startPosition = currentTime;
+ }
+ // tick to speed up processing
+ this.tick();
+ }
+ }, {
+ key: 'onMediaSeeked',
+ value: function onMediaSeeked() {
+ _logger.logger.log('media seeked to ' + this.media.currentTime.toFixed(3));
+ // tick to speed up FRAGMENT_PLAYING triggering
+ this.tick();
+ }
+ }, {
+ key: 'onMediaEnded',
+ value: function onMediaEnded() {
+ _logger.logger.log('media ended');
+ // reset startPosition and lastCurrentTime to restart playback @ stream beginning
+ this.startPosition = this.lastCurrentTime = 0;
+ }
+ }, {
+ key: 'onManifestLoading',
+ value: function onManifestLoading() {
+ // reset buffer on manifest loading
+ _logger.logger.log('trigger BUFFER_RESET');
+ this.hls.trigger(_events2.default.BUFFER_RESET);
+ this._bufferedFrags = [];
+ this.stalled = false;
+ this.startPosition = this.lastCurrentTime = 0;
+ }
+ }, {
+ key: 'onManifestParsed',
+ value: function onManifestParsed(data) {
+ var aac = false,
+ heaac = false,
+ codec;
+ data.levels.forEach(function (level) {
+ // detect if we have different kind of audio codecs used amongst playlists
+ codec = level.audioCodec;
+ if (codec) {
+ if (codec.indexOf('mp4a.40.2') !== -1) {
+ aac = true;
+ }
+ if (codec.indexOf('mp4a.40.5') !== -1) {
+ heaac = true;
+ }
+ }
+ });
+ this.audioCodecSwitch = aac && heaac;
+ if (this.audioCodecSwitch) {
+ _logger.logger.log('both AAC/HE-AAC audio found in levels; declaring level codec as HE-AAC');
+ }
+ this.levels = data.levels;
+ this.startLevelLoaded = false;
+ this.startFragRequested = false;
+ var config = this.config;
+ if (config.autoStartLoad || this.forceStartLoad) {
+ this.hls.startLoad(config.startPosition);
+ }
+ }
+ }, {
+ key: 'onLevelLoaded',
+ value: function onLevelLoaded(data) {
+ var newDetails = data.details,
+ newLevelId = data.level,
+ curLevel = this.levels[newLevelId],
+ duration = newDetails.totalduration,
+ sliding = 0;
+
+ _logger.logger.log('level ' + newLevelId + ' loaded [' + newDetails.startSN + ',' + newDetails.endSN + '],duration:' + duration);
+ this.levelLastLoaded = newLevelId;
+
+ if (newDetails.live) {
+ var curDetails = curLevel.details;
+ if (curDetails && newDetails.fragments.length > 0) {
+ // we already have details for that level, merge them
+ _levelHelper2.default.mergeDetails(curDetails, newDetails);
+ sliding = newDetails.fragments[0].start;
+ this.liveSyncPosition = this.computeLivePosition(sliding, curDetails);
+ if (newDetails.PTSKnown) {
+ _logger.logger.log('live playlist sliding:' + sliding.toFixed(3));
+ } else {
+ _logger.logger.log('live playlist - outdated PTS, unknown sliding');
+ }
+ } else {
+ newDetails.PTSKnown = false;
+ _logger.logger.log('live playlist - first load, unknown sliding');
+ }
+ } else {
+ newDetails.PTSKnown = false;
+ }
+ // override level info
+ curLevel.details = newDetails;
+ this.hls.trigger(_events2.default.LEVEL_UPDATED, { details: newDetails, level: newLevelId });
+
+ if (this.startFragRequested === false) {
+ // compute start position if set to -1. use it straight away if value is defined
+ if (this.startPosition === -1 || this.lastCurrentTime === -1) {
+ // first, check if start time offset has been set in playlist, if yes, use this value
+ var startTimeOffset = newDetails.startTimeOffset;
+ if (!isNaN(startTimeOffset)) {
+ if (startTimeOffset < 0) {
+ _logger.logger.log('negative start time offset ' + startTimeOffset + ', count from end of last fragment');
+ startTimeOffset = sliding + duration + startTimeOffset;
+ }
+ _logger.logger.log('start time offset found in playlist, adjust startPosition to ' + startTimeOffset);
+ this.startPosition = startTimeOffset;
+ } else {
+ // if live playlist, set start position to be fragment N-this.config.liveSyncDurationCount (usually 3)
+ if (newDetails.live) {
+ this.startPosition = this.computeLivePosition(sliding, newDetails);
+ _logger.logger.log('configure startPosition to ' + this.startPosition);
+ } else {
+ this.startPosition = 0;
+ }
+ }
+ this.lastCurrentTime = this.startPosition;
+ }
+ this.nextLoadPosition = this.startPosition;
+ }
+ // only switch batck to IDLE state if we were waiting for level to start downloading a new fragment
+ if (this.state === State.WAITING_LEVEL) {
+ this.state = State.IDLE;
+ }
+ //trigger handler right now
+ this.tick();
+ }
+ }, {
+ key: 'onKeyLoaded',
+ value: function onKeyLoaded() {
+ if (this.state === State.KEY_LOADING) {
+ this.state = State.IDLE;
+ this.tick();
+ }
+ }
+ }, {
+ key: 'onFragLoaded',
+ value: function onFragLoaded(data) {
+ var fragCurrent = this.fragCurrent,
+ fragLoaded = data.frag;
+ if (this.state === State.FRAG_LOADING && fragCurrent && fragLoaded.type === 'main' && fragLoaded.level === fragCurrent.level && fragLoaded.sn === fragCurrent.sn) {
+ var stats = data.stats,
+ currentLevel = this.levels[fragCurrent.level],
+ details = currentLevel.details;
+ _logger.logger.log('Loaded ' + fragCurrent.sn + ' of [' + details.startSN + ' ,' + details.endSN + '],level ' + fragCurrent.level);
+ // reset frag bitrate test in any case after frag loaded event
+ this.bitrateTest = false;
+ this.stats = stats;
+ // if this frag was loaded to perform a bitrate test AND if hls.nextLoadLevel is greater than 0
+ // then this means that we should be able to load a fragment at a higher quality level
+ if (fragLoaded.bitrateTest === true && this.hls.nextLoadLevel) {
+ // switch back to IDLE state ... we just loaded a fragment to determine adequate start bitrate and initialize autoswitch algo
+ this.state = State.IDLE;
+ this.startFragRequested = false;
+ stats.tparsed = stats.tbuffered = performance.now();
+ this.hls.trigger(_events2.default.FRAG_BUFFERED, { stats: stats, frag: fragCurrent, id: 'main' });
+ this.tick();
+ } else if (fragLoaded.sn === 'initSegment') {
+ this.state = State.IDLE;
+ stats.tparsed = stats.tbuffered = performance.now();
+ details.initSegment.data = data.payload;
+ this.hls.trigger(_events2.default.FRAG_BUFFERED, { stats: stats, frag: fragCurrent, id: 'main' });
+ this.tick();
+ } else {
+ this.state = State.PARSING;
+ // transmux the MPEG-TS data to ISO-BMFF segments
+ var duration = details.totalduration,
+ level = fragCurrent.level,
+ sn = fragCurrent.sn,
+ audioCodec = this.config.defaultAudioCodec || currentLevel.audioCodec;
+ if (this.audioCodecSwap) {
+ _logger.logger.log('swapping playlist audio codec');
+ if (audioCodec === undefined) {
+ audioCodec = this.lastAudioCodec;
+ }
+ if (audioCodec) {
+ if (audioCodec.indexOf('mp4a.40.5') !== -1) {
+ audioCodec = 'mp4a.40.2';
+ } else {
+ audioCodec = 'mp4a.40.5';
+ }
+ }
+ }
+ this.pendingBuffering = true;
+ this.appended = false;
+ _logger.logger.log('Parsing ' + sn + ' of [' + details.startSN + ' ,' + details.endSN + '],level ' + level + ', cc ' + fragCurrent.cc);
+ var demuxer = this.demuxer;
+ if (!demuxer) {
+ demuxer = this.demuxer = new _demuxer2.default(this.hls, 'main');
+ }
+ // time Offset is accurate if level PTS is known, or if playlist is not sliding (not live) and if media is not seeking (this is to overcome potential timestamp drifts between playlists and fragments)
+ var media = this.media;
+ var mediaSeeking = media && media.seeking;
+ var accurateTimeOffset = !mediaSeeking && (details.PTSKnown || !details.live);
+ var initSegmentData = details.initSegment ? details.initSegment.data : [];
+ demuxer.push(data.payload, initSegmentData, audioCodec, currentLevel.videoCodec, fragCurrent, duration, accurateTimeOffset, undefined);
+ }
+ }
+ this.fragLoadError = 0;
+ }
+ }, {
+ key: 'onFragParsingInitSegment',
+ value: function onFragParsingInitSegment(data) {
+ var fragCurrent = this.fragCurrent;
+ var fragNew = data.frag;
+ if (fragCurrent && data.id === 'main' && fragNew.sn === fragCurrent.sn && fragNew.level === fragCurrent.level && this.state === State.PARSING) {
+ var tracks = data.tracks,
+ trackName,
+ track;
+
+ // if audio track is expected to come from audio stream controller, discard any coming from main
+ if (tracks.audio && this.altAudio) {
+ delete tracks.audio;
+ }
+ // include levelCodec in audio and video tracks
+ track = tracks.audio;
+ if (track) {
+ var audioCodec = this.levels[this.level].audioCodec,
+ ua = navigator.userAgent.toLowerCase();
+ if (audioCodec && this.audioCodecSwap) {
+ _logger.logger.log('swapping playlist audio codec');
+ if (audioCodec.indexOf('mp4a.40.5') !== -1) {
+ audioCodec = 'mp4a.40.2';
+ } else {
+ audioCodec = 'mp4a.40.5';
+ }
+ }
+ // in case AAC and HE-AAC audio codecs are signalled in manifest
+ // force HE-AAC , as it seems that most browsers prefers that way,
+ // except for mono streams OR on FF
+ // these conditions might need to be reviewed ...
+ if (this.audioCodecSwitch) {
+ // don't force HE-AAC if mono stream
+ if (track.metadata.channelCount !== 1 &&
+ // don't force HE-AAC if firefox
+ ua.indexOf('firefox') === -1) {
+ audioCodec = 'mp4a.40.5';
+ }
+ }
+ // HE-AAC is broken on Android, always signal audio codec as AAC even if variant manifest states otherwise
+ if (ua.indexOf('android') !== -1 && track.container !== 'audio/mpeg') {
+ // Exclude mpeg audio
+ audioCodec = 'mp4a.40.2';
+ _logger.logger.log('Android: force audio codec to ' + audioCodec);
+ }
+ track.levelCodec = audioCodec;
+ track.id = data.id;
+ }
+ track = tracks.video;
+ if (track) {
+ track.levelCodec = this.levels[this.level].videoCodec;
+ track.id = data.id;
+ }
+ this.hls.trigger(_events2.default.BUFFER_CODECS, tracks);
+ // loop through tracks that are going to be provided to bufferController
+ for (trackName in tracks) {
+ track = tracks[trackName];
+ _logger.logger.log('main track:' + trackName + ',container:' + track.container + ',codecs[level/parsed]=[' + track.levelCodec + '/' + track.codec + ']');
+ var initSegment = track.initSegment;
+ if (initSegment) {
+ this.appended = true;
+ // arm pending Buffering flag before appending a segment
+ this.pendingBuffering = true;
+ this.hls.trigger(_events2.default.BUFFER_APPENDING, { type: trackName, data: initSegment, parent: 'main', content: 'initSegment' });
+ }
+ }
+ //trigger handler right now
+ this.tick();
+ }
+ }
+ }, {
+ key: 'onFragParsingData',
+ value: function onFragParsingData(data) {
+ var _this2 = this;
+
+ var fragCurrent = this.fragCurrent;
+ var fragNew = data.frag;
+ if (fragCurrent && data.id === 'main' && fragNew.sn === fragCurrent.sn && fragNew.level === fragCurrent.level && !(data.type === 'audio' && this.altAudio) && // filter out main audio if audio track is loaded through audio stream controller
+ this.state === State.PARSING) {
+ var level = this.levels[this.level],
+ frag = fragCurrent;
+ if (isNaN(data.endPTS)) {
+ data.endPTS = data.startPTS + fragCurrent.duration;
+ data.endDTS = data.startDTS + fragCurrent.duration;
+ }
+
+ _logger.logger.log('Parsed ' + data.type + ',PTS:[' + data.startPTS.toFixed(3) + ',' + data.endPTS.toFixed(3) + '],DTS:[' + data.startDTS.toFixed(3) + '/' + data.endDTS.toFixed(3) + '],nb:' + data.nb + ',dropped:' + (data.dropped || 0));
+
+ // Detect gaps in a fragment and try to fix it by finding a keyframe in the previous fragment (see _findFragments)
+ if (data.type === 'video') {
+ frag.dropped = data.dropped;
+ if (frag.dropped) {
+ if (!frag.backtracked) {
+ // Return back to the IDLE state without appending to buffer
+ // Causes findFragments to backtrack a segment and find the keyframe
+ // Audio fragments arriving before video sets the nextLoadPosition, causing _findFragments to skip the backtracked fragment
+ frag.backtracked = true;
+ this.nextLoadPosition = data.startPTS;
+ this.state = State.IDLE;
+ this.tick();
+ return;
+ } else {
+ _logger.logger.warn('Already backtracked on this fragment, appending with the gap');
+ }
+ } else {
+ // Only reset the backtracked flag if we've loaded the frag without any dropped frames
+ frag.backtracked = false;
+ }
+ }
+
+ var drift = _levelHelper2.default.updateFragPTSDTS(level.details, frag.sn, data.startPTS, data.endPTS, data.startDTS, data.endDTS),
+ hls = this.hls;
+ hls.trigger(_events2.default.LEVEL_PTS_UPDATED, { details: level.details, level: this.level, drift: drift, type: data.type, start: data.startPTS, end: data.endPTS });
+
+ // has remuxer dropped video frames located before first keyframe ?
+ [data.data1, data.data2].forEach(function (buffer) {
+ // only append in PARSING state (rationale is that an appending error could happen synchronously on first segment appending)
+ // in that case it is useless to append following segments
+ if (buffer && buffer.length && _this2.state === State.PARSING) {
+ _this2.appended = true;
+ // arm pending Buffering flag before appending a segment
+ _this2.pendingBuffering = true;
+ hls.trigger(_events2.default.BUFFER_APPENDING, { type: data.type, data: buffer, parent: 'main', content: 'data' });
+ }
+ });
+ //trigger handler right now
+ this.tick();
+ }
+ }
+ }, {
+ key: 'onFragParsed',
+ value: function onFragParsed(data) {
+ var fragCurrent = this.fragCurrent;
+ var fragNew = data.frag;
+ if (fragCurrent && data.id === 'main' && fragNew.sn === fragCurrent.sn && fragNew.level === fragCurrent.level && this.state === State.PARSING) {
+ this.stats.tparsed = performance.now();
+ this.state = State.PARSED;
+ this._checkAppendedParsed();
+ }
+ }
+ }, {
+ key: 'onAudioTrackSwitching',
+ value: function onAudioTrackSwitching(data) {
+ // if any URL found on new audio track, it is an alternate audio track
+ var altAudio = !!data.url,
+ trackId = data.id;
+ // if we switch on main audio, ensure that main fragment scheduling is synced with media.buffered
+ // don't do anything if we switch to alt audio: audio stream controller is handling it.
+ // we will just have to change buffer scheduling on audioTrackSwitched
+ if (!altAudio) {
+ if (this.mediaBuffer !== this.media) {
+ _logger.logger.log('switching on main audio, use media.buffered to schedule main fragment loading');
+ this.mediaBuffer = this.media;
+ var fragCurrent = this.fragCurrent;
+ // we need to refill audio buffer from main: cancel any frag loading to speed up audio switch
+ if (fragCurrent.loader) {
+ _logger.logger.log('switching to main audio track, cancel main fragment load');
+ fragCurrent.loader.abort();
+ }
+ this.fragCurrent = null;
+ this.fragPrevious = null;
+ // destroy demuxer to force init segment generation (following audio switch)
+ if (this.demuxer) {
+ this.demuxer.destroy();
+ this.demuxer = null;
+ }
+ // switch to IDLE state to load new fragment
+ this.state = State.IDLE;
+ }
+ var hls = this.hls;
+ // switching to main audio, flush all audio and trigger track switched
+ hls.trigger(_events2.default.BUFFER_FLUSHING, { startOffset: 0, endOffset: Number.POSITIVE_INFINITY, type: 'audio' });
+ hls.trigger(_events2.default.AUDIO_TRACK_SWITCHED, { id: trackId });
+ this.altAudio = false;
+ }
+ }
+ }, {
+ key: 'onAudioTrackSwitched',
+ value: function onAudioTrackSwitched(data) {
+ var trackId = data.id,
+ altAudio = !!this.hls.audioTracks[trackId].url;
+ if (altAudio) {
+ var videoBuffer = this.videoBuffer;
+ // if we switched on alternate audio, ensure that main fragment scheduling is synced with video sourcebuffer buffered
+ if (videoBuffer && this.mediaBuffer !== videoBuffer) {
+ _logger.logger.log('switching on alternate audio, use video.buffered to schedule main fragment loading');
+ this.mediaBuffer = videoBuffer;
+ }
+ }
+ this.altAudio = altAudio;
+ this.tick();
+ }
+ }, {
+ key: 'onBufferCreated',
+ value: function onBufferCreated(data) {
+ var tracks = data.tracks,
+ mediaTrack = void 0,
+ name = void 0,
+ alternate = false;
+ for (var type in tracks) {
+ var track = tracks[type];
+ if (track.id === 'main') {
+ name = type;
+ mediaTrack = track;
+ // keep video source buffer reference
+ if (type === 'video') {
+ this.videoBuffer = tracks[type].buffer;
+ }
+ } else {
+ alternate = true;
+ }
+ }
+ if (alternate && mediaTrack) {
+ _logger.logger.log('alternate track found, use ' + name + '.buffered to schedule main fragment loading');
+ this.mediaBuffer = mediaTrack.buffer;
+ } else {
+ this.mediaBuffer = this.media;
+ }
+ }
+ }, {
+ key: 'onBufferAppended',
+ value: function onBufferAppended(data) {
+ if (data.parent === 'main') {
+ var state = this.state;
+ if (state === State.PARSING || state === State.PARSED) {
+ // check if all buffers have been appended
+ this.pendingBuffering = data.pending > 0;
+ this._checkAppendedParsed();
+ }
+ }
+ }
+ }, {
+ key: '_checkAppendedParsed',
+ value: function _checkAppendedParsed() {
+ //trigger handler right now
+ if (this.state === State.PARSED && (!this.appended || !this.pendingBuffering)) {
+ var frag = this.fragCurrent;
+ if (frag) {
+ var media = this.mediaBuffer ? this.mediaBuffer : this.media;
+ _logger.logger.log('main buffered : ' + _timeRanges2.default.toString(media.buffered));
+ // filter fragments potentially evicted from buffer. this is to avoid memleak on live streams
+ var bufferedFrags = this._bufferedFrags.filter(function (frag) {
+ return _bufferHelper2.default.isBuffered(media, (frag.startPTS + frag.endPTS) / 2);
+ });
+ // push new range
+ bufferedFrags.push(frag);
+ // sort frags, as we use BinarySearch for lookup in getBufferedFrag ...
+ this._bufferedFrags = bufferedFrags.sort(function (a, b) {
+ return a.startPTS - b.startPTS;
+ });
+ this.fragPrevious = frag;
+ var stats = this.stats;
+ stats.tbuffered = performance.now();
+ // we should get rid of this.fragLastKbps
+ this.fragLastKbps = Math.round(8 * stats.total / (stats.tbuffered - stats.tfirst));
+ this.hls.trigger(_events2.default.FRAG_BUFFERED, { stats: stats, frag: frag, id: 'main' });
+ this.state = State.IDLE;
+ }
+ this.tick();
+ }
+ }
+ }, {
+ key: 'onError',
+ value: function onError(data) {
+ var frag = data.frag || this.fragCurrent;
+ // don't handle frag error not related to main fragment
+ if (frag && frag.type !== 'main') {
+ return;
+ }
+ var media = this.media,
+
+ // 0.5 : tolerance needed as some browsers stalls playback before reaching buffered end
+ mediaBuffered = media && _bufferHelper2.default.isBuffered(media, media.currentTime) && _bufferHelper2.default.isBuffered(media, media.currentTime + 0.5);
+ switch (data.details) {
+ case _errors.ErrorDetails.FRAG_LOAD_ERROR:
+ case _errors.ErrorDetails.FRAG_LOAD_TIMEOUT:
+ case _errors.ErrorDetails.KEY_LOAD_ERROR:
+ case _errors.ErrorDetails.KEY_LOAD_TIMEOUT:
+ if (!data.fatal) {
+ var loadError = this.fragLoadError;
+ if (loadError) {
+ loadError++;
+ } else {
+ loadError = 1;
+ }
+ var config = this.config;
+ // keep retrying / don't raise fatal network error if current position is buffered or if in automode with current level not 0
+ if (loadError <= config.fragLoadingMaxRetry || mediaBuffered || frag.autoLevel && frag.level) {
+ this.fragLoadError = loadError;
+ // reset load counter to avoid frag loop loading error
+ frag.loadCounter = 0;
+ // exponential backoff capped to config.fragLoadingMaxRetryTimeout
+ var delay = Math.min(Math.pow(2, loadError - 1) * config.fragLoadingRetryDelay, config.fragLoadingMaxRetryTimeout);
+ _logger.logger.warn('mediaController: frag loading failed, retry in ' + delay + ' ms');
+ this.retryDate = performance.now() + delay;
+ // retry loading state
+ // if loadedmetadata is not set, it means that we are emergency switch down on first frag
+ // in that case, reset startFragRequested flag
+ if (!this.loadedmetadata) {
+ this.startFragRequested = false;
+ this.nextLoadPosition = this.startPosition;
+ }
+ this.state = State.FRAG_LOADING_WAITING_RETRY;
+ } else {
+ _logger.logger.error('mediaController: ' + data.details + ' reaches max retry, redispatch as fatal ...');
+ // switch error to fatal
+ data.fatal = true;
+ this.state = State.ERROR;
+ }
+ }
+ break;
+ case _errors.ErrorDetails.FRAG_LOOP_LOADING_ERROR:
+ if (!data.fatal) {
+ // if buffer is not empty
+ if (mediaBuffered) {
+ // try to reduce max buffer length : rationale is that we could get
+ // frag loop loading error because of buffer eviction
+ this._reduceMaxBufferLength(frag.duration);
+ this.state = State.IDLE;
+ } else {
+ // buffer empty. report as fatal if in manual mode or if lowest level.
+ // level controller takes care of emergency switch down logic
+ if (!frag.autoLevel || frag.level === 0) {
+ // switch error to fatal
+ data.fatal = true;
+ this.state = State.ERROR;
+ }
+ }
+ }
+ break;
+ case _errors.ErrorDetails.LEVEL_LOAD_ERROR:
+ case _errors.ErrorDetails.LEVEL_LOAD_TIMEOUT:
+ if (this.state !== State.ERROR) {
+ if (data.fatal) {
+ // if fatal error, stop processing
+ this.state = State.ERROR;
+ _logger.logger.warn('streamController: ' + data.details + ',switch to ' + this.state + ' state ...');
+ } else {
+ // in cas of non fatal error while waiting level load to be completed, switch back to IDLE
+ if (this.state === State.WAITING_LEVEL) {
+ this.state = State.IDLE;
+ }
+ }
+ }
+ break;
+ case _errors.ErrorDetails.BUFFER_FULL_ERROR:
+ // if in appending state
+ if (data.parent === 'main' && (this.state === State.PARSING || this.state === State.PARSED)) {
+ // reduce max buf len if current position is buffered
+ if (mediaBuffered) {
+ this._reduceMaxBufferLength(this.config.maxBufferLength);
+ this.state = State.IDLE;
+ } else {
+ // current position is not buffered, but browser is still complaining about buffer full error
+ // this happens on IE/Edge, refer to https://github.com/video-dev/hls.js/pull/708
+ // in that case flush the whole buffer to recover
+ _logger.logger.warn('buffer full error also media.currentTime is not buffered, flush everything');
+ this.fragCurrent = null;
+ // flush everything
+ this.flushMainBuffer(0, Number.POSITIVE_INFINITY);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }, {
+ key: '_reduceMaxBufferLength',
+ value: function _reduceMaxBufferLength(minLength) {
+ var config = this.config;
+ if (config.maxMaxBufferLength >= minLength) {
+ // reduce max buffer length as it might be too high. we do this to avoid loop flushing ...
+ config.maxMaxBufferLength /= 2;
+ _logger.logger.warn('main:reduce max buffer length to ' + config.maxMaxBufferLength + 's');
+ // increase fragment load Index to avoid frag loop loading error after buffer flush
+ this.fragLoadIdx += 2 * config.fragLoadingLoopThreshold;
+ }
+ }
+ }, {
+ key: '_checkBuffer',
+ value: function _checkBuffer() {
+ var media = this.media;
+ // if ready state different from HAVE_NOTHING (numeric value 0), we are allowed to seek
+ if (media && media.readyState) {
+ var currentTime = media.currentTime,
+ mediaBuffer = this.mediaBuffer ? this.mediaBuffer : media,
+ buffered = mediaBuffer.buffered;
+ // adjust currentTime to start position on loaded metadata
+ if (!this.loadedmetadata && buffered.length) {
+ this.loadedmetadata = true;
+ // only adjust currentTime if different from startPosition or if startPosition not buffered
+ // at that stage, there should be only one buffered range, as we reach that code after first fragment has been buffered
+ var startPosition = media.seeking ? currentTime : this.startPosition,
+ startPositionBuffered = _bufferHelper2.default.isBuffered(mediaBuffer, startPosition);
+ // if currentTime not matching with expected startPosition or startPosition not buffered
+ if (currentTime !== startPosition || !startPositionBuffered) {
+ _logger.logger.log('target start position:' + startPosition);
+ // if startPosition not buffered, let's seek to buffered.start(0)
+ if (!startPositionBuffered) {
+ startPosition = buffered.start(0);
+ _logger.logger.log('target start position not buffered, seek to buffered.start(0) ' + startPosition);
+ }
+ _logger.logger.log('adjust currentTime from ' + currentTime + ' to ' + startPosition);
+ media.currentTime = startPosition;
+ }
+ } else if (this.immediateSwitch) {
+ this.immediateLevelSwitchEnd();
+ } else {
+ var bufferInfo = _bufferHelper2.default.bufferInfo(media, currentTime, 0),
+ expectedPlaying = !(media.paused || // not playing when media is paused
+ media.ended || // not playing when media is ended
+ media.buffered.length === 0),
+ // not playing if nothing buffered
+ jumpThreshold = 0.5,
+ // tolerance needed as some browsers stalls playback before reaching buffered range end
+ playheadMoving = currentTime !== this.lastCurrentTime,
+ config = this.config;
+
+ if (playheadMoving) {
+ // played moving, but was previously stalled => now not stuck anymore
+ if (this.stallReported) {
+ _logger.logger.warn('playback not stuck anymore @' + currentTime + ', after ' + Math.round(performance.now() - this.stalled) + 'ms');
+ this.stallReported = false;
+ }
+ this.stalled = undefined;
+ this.nudgeRetry = 0;
+ } else {
+ // playhead not moving
+ if (expectedPlaying) {
+ // playhead not moving BUT media expected to play
+ var tnow = performance.now();
+ var hls = this.hls;
+ if (!this.stalled) {
+ // stall just detected, store current time
+ this.stalled = tnow;
+ this.stallReported = false;
+ } else {
+ // playback already stalled, check stalling duration
+ // if stalling for more than a given threshold, let's try to recover
+ var stalledDuration = tnow - this.stalled;
+ var bufferLen = bufferInfo.len;
+ var nudgeRetry = this.nudgeRetry || 0;
+ // have we reached stall deadline ?
+ if (bufferLen <= jumpThreshold && stalledDuration > config.lowBufferWatchdogPeriod * 1000) {
+ // report stalled error once
+ if (!this.stallReported) {
+ this.stallReported = true;
+ _logger.logger.warn('playback stalling in low buffer @' + currentTime);
+ hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.BUFFER_STALLED_ERROR, fatal: false, buffer: bufferLen });
+ }
+ // if buffer len is below threshold, try to jump to start of next buffer range if close
+ // no buffer available @ currentTime, check if next buffer is close (within a config.maxSeekHole second range)
+ var nextBufferStart = bufferInfo.nextStart,
+ delta = nextBufferStart - currentTime;
+ if (nextBufferStart && delta < config.maxSeekHole && delta > 0) {
+ this.nudgeRetry = ++nudgeRetry;
+ var nudgeOffset = nudgeRetry * config.nudgeOffset;
+ // next buffer is close ! adjust currentTime to nextBufferStart
+ // this will ensure effective video decoding
+ _logger.logger.log('adjust currentTime from ' + media.currentTime + ' to next buffered @ ' + nextBufferStart + ' + nudge ' + nudgeOffset);
+ media.currentTime = nextBufferStart + nudgeOffset;
+ // reset stalled so to rearm watchdog timer
+ this.stalled = undefined;
+ hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.BUFFER_SEEK_OVER_HOLE, fatal: false, hole: nextBufferStart + nudgeOffset - currentTime });
+ }
+ } else if (bufferLen > jumpThreshold && stalledDuration > config.highBufferWatchdogPeriod * 1000) {
+ // report stalled error once
+ if (!this.stallReported) {
+ this.stallReported = true;
+ _logger.logger.warn('playback stalling in high buffer @' + currentTime);
+ hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.BUFFER_STALLED_ERROR, fatal: false, buffer: bufferLen });
+ }
+ // reset stalled so to rearm watchdog timer
+ this.stalled = undefined;
+ this.nudgeRetry = ++nudgeRetry;
+ if (nudgeRetry < config.nudgeMaxRetry) {
+ var _currentTime = media.currentTime;
+ var targetTime = _currentTime + nudgeRetry * config.nudgeOffset;
+ _logger.logger.log('adjust currentTime from ' + _currentTime + ' to ' + targetTime);
+ // playback stalled in buffered area ... let's nudge currentTime to try to overcome this
+ media.currentTime = targetTime;
+ hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.BUFFER_NUDGE_ON_STALL, fatal: false });
+ } else {
+ _logger.logger.error('still stuck in high buffer @' + currentTime + ' after ' + config.nudgeMaxRetry + ', raise fatal error');
+ hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.BUFFER_STALLED_ERROR, fatal: true });
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }, {
+ key: 'onFragLoadEmergencyAborted',
+ value: function onFragLoadEmergencyAborted() {
+ this.state = State.IDLE;
+ // if loadedmetadata is not set, it means that we are emergency switch down on first frag
+ // in that case, reset startFragRequested flag
+ if (!this.loadedmetadata) {
+ this.startFragRequested = false;
+ this.nextLoadPosition = this.startPosition;
+ }
+ this.tick();
+ }
+ }, {
+ key: 'onBufferFlushed',
+ value: function onBufferFlushed() {
+ /* after successful buffer flushing, filter flushed fragments from bufferedFrags
+ use mediaBuffered instead of media (so that we will check against video.buffered ranges in case of alt audio track)
+ */
+ var media = this.mediaBuffer ? this.mediaBuffer : this.media;
+ this._bufferedFrags = this._bufferedFrags.filter(function (frag) {
+ return _bufferHelper2.default.isBuffered(media, (frag.startPTS + frag.endPTS) / 2);
+ });
+
+ // increase fragment load Index to avoid frag loop loading error after buffer flush
+ this.fragLoadIdx += 2 * this.config.fragLoadingLoopThreshold;
+ // move to IDLE once flush complete. this should trigger new fragment loading
+ this.state = State.IDLE;
+ // reset reference to frag
+ this.fragPrevious = null;
+ }
+ }, {
+ key: 'swapAudioCodec',
+ value: function swapAudioCodec() {
+ this.audioCodecSwap = !this.audioCodecSwap;
+ }
+ }, {
+ key: 'computeLivePosition',
+ value: function computeLivePosition(sliding, levelDetails) {
+ var targetLatency = this.config.liveSyncDuration !== undefined ? this.config.liveSyncDuration : this.config.liveSyncDurationCount * levelDetails.targetduration;
+ return sliding + Math.max(0, levelDetails.totalduration - targetLatency);
+ }
+ }, {
+ key: 'state',
+ set: function set(nextState) {
+ if (this.state !== nextState) {
+ var previousState = this.state;
+ this._state = nextState;
+ _logger.logger.log('main stream:' + previousState + '->' + nextState);
+ this.hls.trigger(_events2.default.STREAM_STATE_TRANSITION, { previousState: previousState, nextState: nextState });
+ }
+ },
+ get: function get() {
+ return this._state;
+ }
+ }, {
+ key: 'currentLevel',
+ get: function get() {
+ var media = this.media;
+ if (media) {
+ var frag = this.getBufferedFrag(media.currentTime);
+ if (frag) {
+ return frag.level;
+ }
+ }
+ return -1;
+ }
+ }, {
+ key: 'nextBufferedFrag',
+ get: function get() {
+ var media = this.media;
+ if (media) {
+ // first get end range of current fragment
+ return this.followingBufferedFrag(this.getBufferedFrag(media.currentTime));
+ } else {
+ return null;
+ }
+ }
+ }, {
+ key: 'nextLevel',
+ get: function get() {
+ var frag = this.nextBufferedFrag;
+ if (frag) {
+ return frag.level;
+ } else {
+ return -1;
+ }
+ }
+ }, {
+ key: 'liveSyncPosition',
+ get: function get() {
+ return this._liveSyncPosition;
+ },
+ set: function set(value) {
+ this._liveSyncPosition = value;
+ }
+ }]);
+
+ return StreamController;
+}(_eventHandler2.default);
+
+exports.default = StreamController;
+
+},{"24":24,"30":30,"31":31,"32":32,"34":34,"35":35,"45":45,"50":50,"51":51}],13:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = _dereq_(31);
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+var _logger = _dereq_(50);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+ * Subtitle Stream Controller
+ */
+
+var SubtitleStreamController = function (_EventHandler) {
+ _inherits(SubtitleStreamController, _EventHandler);
+
+ function SubtitleStreamController(hls) {
+ _classCallCheck(this, SubtitleStreamController);
+
+ var _this = _possibleConstructorReturn(this, (SubtitleStreamController.__proto__ || Object.getPrototypeOf(SubtitleStreamController)).call(this, hls, _events2.default.ERROR, _events2.default.SUBTITLE_TRACKS_UPDATED, _events2.default.SUBTITLE_TRACK_SWITCH, _events2.default.SUBTITLE_TRACK_LOADED, _events2.default.SUBTITLE_FRAG_PROCESSED));
+
+ _this.config = hls.config;
+ _this.vttFragSNsProcessed = {};
+ _this.vttFragQueues = undefined;
+ _this.currentlyProcessing = null;
+ _this.currentTrackId = -1;
+ return _this;
+ }
+
+ _createClass(SubtitleStreamController, [{
+ key: 'destroy',
+ value: function destroy() {
+ _eventHandler2.default.prototype.destroy.call(this);
+ }
+
+ // Remove all queued items and create a new, empty queue for each track.
+
+ }, {
+ key: 'clearVttFragQueues',
+ value: function clearVttFragQueues() {
+ var _this2 = this;
+
+ this.vttFragQueues = {};
+ this.tracks.forEach(function (track) {
+ _this2.vttFragQueues[track.id] = [];
+ });
+ }
+
+ // If no frag is being processed and queue isn't empty, initiate processing of next frag in line.
+
+ }, {
+ key: 'nextFrag',
+ value: function nextFrag() {
+ if (this.currentlyProcessing === null && this.currentTrackId > -1 && this.vttFragQueues[this.currentTrackId].length) {
+ var frag = this.currentlyProcessing = this.vttFragQueues[this.currentTrackId].shift();
+ this.hls.trigger(_events2.default.FRAG_LOADING, { frag: frag });
+ }
+ }
+
+ // When fragment has finished processing, add sn to list of completed if successful.
+
+ }, {
+ key: 'onSubtitleFragProcessed',
+ value: function onSubtitleFragProcessed(data) {
+ if (data.success) {
+ this.vttFragSNsProcessed[data.frag.trackId].push(data.frag.sn);
+ }
+ this.currentlyProcessing = null;
+ this.nextFrag();
+ }
+
+ // If something goes wrong, procede to next frag, if we were processing one.
+
+ }, {
+ key: 'onError',
+ value: function onError(data) {
+ var frag = data.frag;
+ // don't handle frag error not related to subtitle fragment
+ if (frag && frag.type !== 'subtitle') {
+ return;
+ }
+ if (this.currentlyProcessing) {
+ this.currentlyProcessing = null;
+ this.nextFrag();
+ }
+ }
+
+ // Got all new subtitle tracks.
+
+ }, {
+ key: 'onSubtitleTracksUpdated',
+ value: function onSubtitleTracksUpdated(data) {
+ var _this3 = this;
+
+ _logger.logger.log('subtitle tracks updated');
+ this.tracks = data.subtitleTracks;
+ this.clearVttFragQueues();
+ this.vttFragSNsProcessed = {};
+ this.tracks.forEach(function (track) {
+ _this3.vttFragSNsProcessed[track.id] = [];
+ });
+ }
+ }, {
+ key: 'onSubtitleTrackSwitch',
+ value: function onSubtitleTrackSwitch(data) {
+ this.currentTrackId = data.id;
+ this.clearVttFragQueues();
+ }
+
+ // Got a new set of subtitle fragments.
+
+ }, {
+ key: 'onSubtitleTrackLoaded',
+ value: function onSubtitleTrackLoaded(data) {
+ var processedFragSNs = this.vttFragSNsProcessed[data.id],
+ fragQueue = this.vttFragQueues[data.id],
+ currentFragSN = !!this.currentlyProcessing ? this.currentlyProcessing.sn : -1;
+
+ var alreadyProcessed = function alreadyProcessed(frag) {
+ return processedFragSNs.indexOf(frag.sn) > -1;
+ };
+
+ var alreadyInQueue = function alreadyInQueue(frag) {
+ return fragQueue.some(function (fragInQueue) {
+ return fragInQueue.sn === frag.sn;
+ });
+ };
+
+ // Add all fragments that haven't been, aren't currently being and aren't waiting to be processed, to queue.
+ data.details.fragments.forEach(function (frag) {
+ if (!(alreadyProcessed(frag) || frag.sn === currentFragSN || alreadyInQueue(frag))) {
+ // Frags don't know their subtitle track ID, so let's just add that...
+ frag.trackId = data.id;
+ fragQueue.push(frag);
+ }
+ });
+
+ this.nextFrag();
+ }
+ }]);
+
+ return SubtitleStreamController;
+}(_eventHandler2.default);
+
+exports.default = SubtitleStreamController;
+
+},{"31":31,"32":32,"50":50}],14:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = _dereq_(31);
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+var _logger = _dereq_(50);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+ * audio track controller
+ */
+
+var SubtitleTrackController = function (_EventHandler) {
+ _inherits(SubtitleTrackController, _EventHandler);
+
+ function SubtitleTrackController(hls) {
+ _classCallCheck(this, SubtitleTrackController);
+
+ var _this = _possibleConstructorReturn(this, (SubtitleTrackController.__proto__ || Object.getPrototypeOf(SubtitleTrackController)).call(this, hls, _events2.default.MEDIA_ATTACHED, _events2.default.MEDIA_DETACHING, _events2.default.MANIFEST_LOADING, _events2.default.MANIFEST_LOADED, _events2.default.SUBTITLE_TRACK_LOADED));
+
+ _this.tracks = [];
+ _this.trackId = -1;
+ _this.media = undefined;
+ return _this;
+ }
+
+ _createClass(SubtitleTrackController, [{
+ key: 'destroy',
+ value: function destroy() {
+ _eventHandler2.default.prototype.destroy.call(this);
+ }
+
+ // Listen for subtitle track change, then extract the current track ID.
+
+ }, {
+ key: 'onMediaAttached',
+ value: function onMediaAttached(data) {
+ var _this2 = this;
+
+ this.media = data.media;
+ if (!this.media) {
+ return;
+ }
+
+ this.media.textTracks.addEventListener('change', function () {
+ // Media is undefined when switching streams via loadSource()
+ if (!_this2.media) {
+ return;
+ }
+
+ var trackId = -1;
+ var tracks = _this2.media.textTracks;
+ for (var id = 0; id < tracks.length; id++) {
+ if (tracks[id].mode === 'showing') {
+ trackId = id;
+ }
+ }
+ // Setting current subtitleTrack will invoke code.
+ _this2.subtitleTrack = trackId;
+ });
+ }
+ }, {
+ key: 'onMediaDetaching',
+ value: function onMediaDetaching() {
+ // TODO: Remove event listeners.
+ this.media = undefined;
+ }
+
+ // Reset subtitle tracks on manifest loading
+
+ }, {
+ key: 'onManifestLoading',
+ value: function onManifestLoading() {
+ this.tracks = [];
+ this.trackId = -1;
+ }
+
+ // Fired whenever a new manifest is loaded.
+
+ }, {
+ key: 'onManifestLoaded',
+ value: function onManifestLoaded(data) {
+ var _this3 = this;
+
+ var tracks = data.subtitles || [];
+ var defaultFound = false;
+ this.tracks = tracks;
+ this.trackId = -1;
+ this.hls.trigger(_events2.default.SUBTITLE_TRACKS_UPDATED, { subtitleTracks: tracks });
+
+ // loop through available subtitle tracks and autoselect default if needed
+ // TODO: improve selection logic to handle forced, etc
+ tracks.forEach(function (track) {
+ if (track.default) {
+ _this3.subtitleTrack = track.id;
+ defaultFound = true;
+ }
+ });
+ }
+
+ // Trigger subtitle track playlist reload.
+
+ }, {
+ key: 'onTick',
+ value: function onTick() {
+ var trackId = this.trackId;
+ var subtitleTrack = this.tracks[trackId];
+ if (!subtitleTrack) {
+ return;
+ }
+
+ var details = subtitleTrack.details;
+ // check if we need to load playlist for this subtitle Track
+ if (details === undefined || details.live === true) {
+ // track not retrieved yet, or live playlist we need to (re)load it
+ _logger.logger.log('(re)loading playlist for subtitle track ' + trackId);
+ this.hls.trigger(_events2.default.SUBTITLE_TRACK_LOADING, { url: subtitleTrack.url, id: trackId });
+ }
+ }
+ }, {
+ key: 'onSubtitleTrackLoaded',
+ value: function onSubtitleTrackLoaded(data) {
+ var _this4 = this;
+
+ if (data.id < this.tracks.length) {
+ _logger.logger.log('subtitle track ' + data.id + ' loaded');
+ this.tracks[data.id].details = data.details;
+ // check if current playlist is a live playlist
+ if (data.details.live && !this.timer) {
+ // if live playlist we will have to reload it periodically
+ // set reload period to playlist target duration
+ this.timer = setInterval(function () {
+ _this4.onTick();
+ }, 1000 * data.details.targetduration, this);
+ }
+ if (!data.details.live && this.timer) {
+ // playlist is not live and timer is armed : stopping it
+ clearInterval(this.timer);
+ this.timer = null;
+ }
+ }
+ }
+
+ /** get alternate subtitle tracks list from playlist **/
+
+ }, {
+ key: 'setSubtitleTrackInternal',
+ value: function setSubtitleTrackInternal(newId) {
+ // check if level idx is valid
+ if (newId >= 0 && newId < this.tracks.length) {
+ // stopping live reloading timer if any
+ if (this.timer) {
+ clearInterval(this.timer);
+ this.timer = null;
+ }
+ this.trackId = newId;
+ _logger.logger.log('switching to subtitle track ' + newId);
+ var subtitleTrack = this.tracks[newId];
+ this.hls.trigger(_events2.default.SUBTITLE_TRACK_SWITCH, { id: newId });
+ // check if we need to load playlist for this subtitle Track
+ var details = subtitleTrack.details;
+ if (details === undefined || details.live === true) {
+ // track not retrieved yet, or live playlist we need to (re)load it
+ _logger.logger.log('(re)loading playlist for subtitle track ' + newId);
+ this.hls.trigger(_events2.default.SUBTITLE_TRACK_LOADING, { url: subtitleTrack.url, id: newId });
+ }
+ }
+ }
+ }, {
+ key: 'subtitleTracks',
+ get: function get() {
+ return this.tracks;
+ }
+
+ /** get index of the selected subtitle track (index in subtitle track lists) **/
+
+ }, {
+ key: 'subtitleTrack',
+ get: function get() {
+ return this.trackId;
+ }
+
+ /** select a subtitle track, based on its index in subtitle track lists**/
+ ,
+ set: function set(subtitleTrackId) {
+ if (this.trackId !== subtitleTrackId) {
+ // || this.tracks[subtitleTrackId].details === undefined) {
+ this.setSubtitleTrackInternal(subtitleTrackId);
+ }
+ }
+ }]);
+
+ return SubtitleTrackController;
+}(_eventHandler2.default);
+
+exports.default = SubtitleTrackController;
+
+},{"31":31,"32":32,"50":50}],15:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = _dereq_(31);
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+var _cea608Parser = _dereq_(46);
+
+var _cea608Parser2 = _interopRequireDefault(_cea608Parser);
+
+var _webvttParser = _dereq_(54);
+
+var _webvttParser2 = _interopRequireDefault(_webvttParser);
+
+var _logger = _dereq_(50);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+ * Timeline Controller
+ */
+
+function clearCurrentCues(track) {
+ if (track && track.cues) {
+ while (track.cues.length > 0) {
+ track.removeCue(track.cues[0]);
+ }
+ }
+}
+
+function reuseVttTextTrack(inUseTrack, manifestTrack) {
+ return inUseTrack && inUseTrack.label === manifestTrack.name && !(inUseTrack.textTrack1 || inUseTrack.textTrack2);
+}
+
+function intersection(x1, x2, y1, y2) {
+ return Math.min(x2, y2) - Math.max(x1, y1);
+}
+
+var TimelineController = function (_EventHandler) {
+ _inherits(TimelineController, _EventHandler);
+
+ function TimelineController(hls) {
+ _classCallCheck(this, TimelineController);
+
+ var _this = _possibleConstructorReturn(this, (TimelineController.__proto__ || Object.getPrototypeOf(TimelineController)).call(this, hls, _events2.default.MEDIA_ATTACHING, _events2.default.MEDIA_DETACHING, _events2.default.FRAG_PARSING_USERDATA, _events2.default.MANIFEST_LOADING, _events2.default.MANIFEST_LOADED, _events2.default.FRAG_LOADED, _events2.default.LEVEL_SWITCHING, _events2.default.INIT_PTS_FOUND));
+
+ _this.hls = hls;
+ _this.config = hls.config;
+ _this.enabled = true;
+ _this.Cues = hls.config.cueHandler;
+ _this.textTracks = [];
+ _this.tracks = [];
+ _this.unparsedVttFrags = [];
+ _this.initPTS = undefined;
+ _this.cueRanges = [];
+
+ if (_this.config.enableCEA708Captions) {
+ var self = _this;
+ var sendAddTrackEvent = function sendAddTrackEvent(track, media) {
+ var e = null;
+ try {
+ e = new window.Event('addtrack');
+ } catch (err) {
+ //for IE11
+ e = document.createEvent('Event');
+ e.initEvent('addtrack', false, false);
+ }
+ e.track = track;
+ media.dispatchEvent(e);
+ };
+
+ var channel1 = {
+ 'newCue': function newCue(startTime, endTime, screen) {
+ if (!self.textTrack1) {
+ //Enable reuse of existing text track.
+ var existingTrack1 = self.getExistingTrack('1');
+ if (!existingTrack1) {
+ var textTrack1 = self.createTextTrack('captions', self.config.captionsTextTrack1Label, self.config.captionsTextTrack1LanguageCode);
+ if (textTrack1) {
+ textTrack1.textTrack1 = true;
+ self.textTrack1 = textTrack1;
+ }
+ } else {
+ self.textTrack1 = existingTrack1;
+ clearCurrentCues(self.textTrack1);
+
+ sendAddTrackEvent(self.textTrack1, self.media);
+ }
+ }
+ self.addCues('textTrack1', startTime, endTime, screen);
+ }
+ };
+
+ var channel2 = {
+ 'newCue': function newCue(startTime, endTime, screen) {
+ if (!self.textTrack2) {
+ //Enable reuse of existing text track.
+ var existingTrack2 = self.getExistingTrack('2');
+ if (!existingTrack2) {
+ var textTrack2 = self.createTextTrack('captions', self.config.captionsTextTrack2Label, self.config.captionsTextTrack1LanguageCode);
+ if (textTrack2) {
+ textTrack2.textTrack2 = true;
+ self.textTrack2 = textTrack2;
+ }
+ } else {
+ self.textTrack2 = existingTrack2;
+ clearCurrentCues(self.textTrack2);
+
+ sendAddTrackEvent(self.textTrack2, self.media);
+ }
+ }
+ self.addCues('textTrack2', startTime, endTime, screen);
+ }
+ };
+
+ _this.cea608Parser = new _cea608Parser2.default(0, channel1, channel2);
+ }
+ return _this;
+ }
+
+ _createClass(TimelineController, [{
+ key: 'addCues',
+ value: function addCues(channel, startTime, endTime, screen) {
+ // skip cues which overlap more than 50% with previously parsed time ranges
+ var ranges = this.cueRanges;
+ var merged = false;
+ for (var i = ranges.length; i--;) {
+ var cueRange = ranges[i];
+ var overlap = intersection(cueRange[0], cueRange[1], startTime, endTime);
+ if (overlap >= 0) {
+ cueRange[0] = Math.min(cueRange[0], startTime);
+ cueRange[1] = Math.max(cueRange[1], endTime);
+ merged = true;
+ if (overlap / (endTime - startTime) > 0.5) {
+ return;
+ }
+ }
+ }
+ if (!merged) {
+ ranges.push([startTime, endTime]);
+ }
+ this.Cues.newCue(this[channel], startTime, endTime, screen);
+ }
+
+ // Triggered when an initial PTS is found; used for synchronisation of WebVTT.
+
+ }, {
+ key: 'onInitPtsFound',
+ value: function onInitPtsFound(data) {
+ var _this2 = this;
+
+ if (typeof this.initPTS === 'undefined') {
+ this.initPTS = data.initPTS;
+ }
+
+ // Due to asynchrony, initial PTS may arrive later than the first VTT fragments are loaded.
+ // Parse any unparsed fragments upon receiving the initial PTS.
+ if (this.unparsedVttFrags.length) {
+ this.unparsedVttFrags.forEach(function (frag) {
+ _this2.onFragLoaded(frag);
+ });
+ this.unparsedVttFrags = [];
+ }
+ }
+ }, {
+ key: 'getExistingTrack',
+ value: function getExistingTrack(channelNumber) {
+ var media = this.media;
+ if (media) {
+ for (var i = 0; i < media.textTracks.length; i++) {
+ var textTrack = media.textTracks[i];
+ var propName = 'textTrack' + channelNumber;
+ if (textTrack[propName] === true) {
+ return textTrack;
+ }
+ }
+ }
+ return null;
+ }
+ }, {
+ key: 'createTextTrack',
+ value: function createTextTrack(kind, label, lang) {
+ var media = this.media;
+ if (media) {
+ return media.addTextTrack(kind, label, lang);
+ }
+ }
+ }, {
+ key: 'destroy',
+ value: function destroy() {
+ _eventHandler2.default.prototype.destroy.call(this);
+ }
+ }, {
+ key: 'onMediaAttaching',
+ value: function onMediaAttaching(data) {
+ this.media = data.media;
+ }
+ }, {
+ key: 'onMediaDetaching',
+ value: function onMediaDetaching() {
+ clearCurrentCues(this.textTrack1);
+ clearCurrentCues(this.textTrack2);
+ }
+ }, {
+ key: 'onManifestLoading',
+ value: function onManifestLoading() {
+ this.lastSn = -1; // Detect discontiguity in fragment parsing
+ this.prevCC = -1;
+ this.vttCCs = { ccOffset: 0, presentationOffset: 0 }; // Detect discontinuity in subtitle manifests
+
+ // clear outdated subtitles
+ var media = this.media;
+ if (media) {
+ var textTracks = media.textTracks;
+ if (textTracks) {
+ for (var i = 0; i < textTracks.length; i++) {
+ clearCurrentCues(textTracks[i]);
+ }
+ }
+ }
+ }
+ }, {
+ key: 'onManifestLoaded',
+ value: function onManifestLoaded(data) {
+ var _this3 = this;
+
+ this.textTracks = [];
+ this.unparsedVttFrags = this.unparsedVttFrags || [];
+ this.initPTS = undefined;
+ this.cueRanges = [];
+
+ if (this.config.enableWebVTT) {
+ this.tracks = data.subtitles || [];
+ var inUseTracks = this.media ? this.media.textTracks : [];
+
+ this.tracks.forEach(function (track, index) {
+ var textTrack = void 0;
+ if (index < inUseTracks.length) {
+ var inUseTrack = inUseTracks[index];
+ // Reuse tracks with the same label, but do not reuse 608/708 tracks
+ if (reuseVttTextTrack(inUseTrack, track)) {
+ textTrack = inUseTrack;
+ }
+ }
+ if (!textTrack) {
+ textTrack = _this3.createTextTrack('subtitles', track.name, track.lang);
+ }
+ textTrack.mode = track.default ? 'showing' : 'hidden';
+ _this3.textTracks.push(textTrack);
+ });
+ }
+ }
+ }, {
+ key: 'onLevelSwitching',
+ value: function onLevelSwitching() {
+ this.enabled = this.hls.currentLevel.closedCaptions !== 'NONE';
+ }
+ }, {
+ key: 'onFragLoaded',
+ value: function onFragLoaded(data) {
+ var frag = data.frag,
+ payload = data.payload;
+ if (frag.type === 'main') {
+ var sn = frag.sn;
+ // if this frag isn't contiguous, clear the parser so cues with bad start/end times aren't added to the textTrack
+ if (sn !== this.lastSn + 1) {
+ this.cea608Parser.reset();
+ }
+ this.lastSn = sn;
+ }
+ // If fragment is subtitle type, parse as WebVTT.
+ else if (frag.type === 'subtitle') {
+ if (payload.byteLength) {
+ // We need an initial synchronisation PTS. Store fragments as long as none has arrived.
+ if (typeof this.initPTS === 'undefined') {
+ this.unparsedVttFrags.push(data);
+ return;
+ }
+ var vttCCs = this.vttCCs;
+ if (!vttCCs[frag.cc]) {
+ vttCCs[frag.cc] = { start: frag.start, prevCC: this.prevCC, new: true };
+ this.prevCC = frag.cc;
+ }
+ var textTracks = this.textTracks,
+ hls = this.hls;
+
+ // Parse the WebVTT file contents.
+ _webvttParser2.default.parse(payload, this.initPTS, vttCCs, frag.cc, function (cues) {
+ // Add cues and trigger event with success true.
+ cues.forEach(function (cue) {
+ textTracks[frag.trackId].addCue(cue);
+ });
+ hls.trigger(_events2.default.SUBTITLE_FRAG_PROCESSED, { success: true, frag: frag });
+ }, function (e) {
+ // Something went wrong while parsing. Trigger event with success false.
+ _logger.logger.log('Failed to parse VTT cue: ' + e);
+ hls.trigger(_events2.default.SUBTITLE_FRAG_PROCESSED, { success: false, frag: frag });
+ });
+ } else {
+ // In case there is no payload, finish unsuccessfully.
+ this.hls.trigger(_events2.default.SUBTITLE_FRAG_PROCESSED, { success: false, frag: frag });
+ }
+ }
+ }
+ }, {
+ key: 'onFragParsingUserdata',
+ value: function onFragParsingUserdata(data) {
+ // push all of the CEA-708 messages into the interpreter
+ // immediately. It will create the proper timestamps based on our PTS value
+ if (this.enabled && this.config.enableCEA708Captions) {
+ for (var i = 0; i < data.samples.length; i++) {
+ var ccdatas = this.extractCea608Data(data.samples[i].bytes);
+ this.cea608Parser.addData(data.samples[i].pts, ccdatas);
+ }
+ }
+ }
+ }, {
+ key: 'extractCea608Data',
+ value: function extractCea608Data(byteArray) {
+ var count = byteArray[0] & 31;
+ var position = 2;
+ var tmpByte, ccbyte1, ccbyte2, ccValid, ccType;
+ var actualCCBytes = [];
+
+ for (var j = 0; j < count; j++) {
+ tmpByte = byteArray[position++];
+ ccbyte1 = 0x7F & byteArray[position++];
+ ccbyte2 = 0x7F & byteArray[position++];
+ ccValid = (4 & tmpByte) !== 0;
+ ccType = 3 & tmpByte;
+
+ if (ccbyte1 === 0 && ccbyte2 === 0) {
+ continue;
+ }
+
+ if (ccValid) {
+ if (ccType === 0) // || ccType === 1
+ {
+ actualCCBytes.push(ccbyte1);
+ actualCCBytes.push(ccbyte2);
+ }
+ }
+ }
+ return actualCCBytes;
+ }
+ }]);
+
+ return TimelineController;
+}(_eventHandler2.default);
+
+exports.default = TimelineController;
+
+},{"31":31,"32":32,"46":46,"50":50,"54":54}],16:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var AESCrypto = function () {
+ function AESCrypto(subtle, iv) {
+ _classCallCheck(this, AESCrypto);
+
+ this.subtle = subtle;
+ this.aesIV = iv;
+ }
+
+ _createClass(AESCrypto, [{
+ key: 'decrypt',
+ value: function decrypt(data, key) {
+ return this.subtle.decrypt({ name: 'AES-CBC', iv: this.aesIV }, key, data);
+ }
+ }]);
+
+ return AESCrypto;
+}();
+
+exports.default = AESCrypto;
+
+},{}],17:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var AESDecryptor = function () {
+ function AESDecryptor() {
+ _classCallCheck(this, AESDecryptor);
+
+ // Static after running initTable
+ this.rcon = [0x0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
+ this.subMix = [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)];
+ this.invSubMix = [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)];
+ this.sBox = new Uint32Array(256);
+ this.invSBox = new Uint32Array(256);
+
+ // Changes during runtime
+ this.key = new Uint32Array(0);
+
+ this.initTable();
+ }
+
+ // Using view.getUint32() also swaps the byte order.
+
+
+ _createClass(AESDecryptor, [{
+ key: 'uint8ArrayToUint32Array_',
+ value: function uint8ArrayToUint32Array_(arrayBuffer) {
+ var view = new DataView(arrayBuffer);
+ var newArray = new Uint32Array(4);
+ for (var i = 0; i < 4; i++) {
+ newArray[i] = view.getUint32(i * 4);
+ }
+ return newArray;
+ }
+ }, {
+ key: 'initTable',
+ value: function initTable() {
+ var sBox = this.sBox;
+ var invSBox = this.invSBox;
+ var subMix = this.subMix;
+ var subMix0 = subMix[0];
+ var subMix1 = subMix[1];
+ var subMix2 = subMix[2];
+ var subMix3 = subMix[3];
+ var invSubMix = this.invSubMix;
+ var invSubMix0 = invSubMix[0];
+ var invSubMix1 = invSubMix[1];
+ var invSubMix2 = invSubMix[2];
+ var invSubMix3 = invSubMix[3];
+
+ var d = new Uint32Array(256);
+ var x = 0;
+ var xi = 0;
+ var i = 0;
+ for (i = 0; i < 256; i++) {
+ if (i < 128) {
+ d[i] = i << 1;
+ } else {
+ d[i] = i << 1 ^ 0x11b;
+ }
+ }
+
+ for (i = 0; i < 256; i++) {
+ var sx = xi ^ xi << 1 ^ xi << 2 ^ xi << 3 ^ xi << 4;
+ sx = sx >>> 8 ^ sx & 0xff ^ 0x63;
+ sBox[x] = sx;
+ invSBox[sx] = x;
+
+ // Compute multiplication
+ var x2 = d[x];
+ var x4 = d[x2];
+ var x8 = d[x4];
+
+ // Compute sub/invSub bytes, mix columns tables
+ var t = d[sx] * 0x101 ^ sx * 0x1010100;
+ subMix0[x] = t << 24 | t >>> 8;
+ subMix1[x] = t << 16 | t >>> 16;
+ subMix2[x] = t << 8 | t >>> 24;
+ subMix3[x] = t;
+
+ // Compute inv sub bytes, inv mix columns tables
+ t = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100;
+ invSubMix0[sx] = t << 24 | t >>> 8;
+ invSubMix1[sx] = t << 16 | t >>> 16;
+ invSubMix2[sx] = t << 8 | t >>> 24;
+ invSubMix3[sx] = t;
+
+ // Compute next counter
+ if (!x) {
+ x = xi = 1;
+ } else {
+ x = x2 ^ d[d[d[x8 ^ x2]]];
+ xi ^= d[d[xi]];
+ }
+ }
+ }
+ }, {
+ key: 'expandKey',
+ value: function expandKey(keyBuffer) {
+ // convert keyBuffer to Uint32Array
+ var key = this.uint8ArrayToUint32Array_(keyBuffer);
+ var sameKey = true;
+ var offset = 0;
+
+ while (offset < key.length && sameKey) {
+ sameKey = key[offset] === this.key[offset];
+ offset++;
+ }
+
+ if (sameKey) {
+ return;
+ }
+
+ this.key = key;
+ var keySize = this.keySize = key.length;
+
+ if (keySize !== 4 && keySize !== 6 && keySize !== 8) {
+ throw new Error('Invalid aes key size=' + keySize);
+ }
+
+ var ksRows = this.ksRows = (keySize + 6 + 1) * 4;
+ var ksRow = void 0;
+ var invKsRow = void 0;
+
+ var keySchedule = this.keySchedule = new Uint32Array(ksRows);
+ var invKeySchedule = this.invKeySchedule = new Uint32Array(ksRows);
+ var sbox = this.sBox;
+ var rcon = this.rcon;
+
+ var invSubMix = this.invSubMix;
+ var invSubMix0 = invSubMix[0];
+ var invSubMix1 = invSubMix[1];
+ var invSubMix2 = invSubMix[2];
+ var invSubMix3 = invSubMix[3];
+
+ var prev = void 0;
+ var t = void 0;
+
+ for (ksRow = 0; ksRow < ksRows; ksRow++) {
+ if (ksRow < keySize) {
+ prev = keySchedule[ksRow] = key[ksRow];
+ continue;
+ }
+ t = prev;
+
+ if (ksRow % keySize === 0) {
+ // Rot word
+ t = t << 8 | t >>> 24;
+
+ // Sub word
+ t = sbox[t >>> 24] << 24 | sbox[t >>> 16 & 0xff] << 16 | sbox[t >>> 8 & 0xff] << 8 | sbox[t & 0xff];
+
+ // Mix Rcon
+ t ^= rcon[ksRow / keySize | 0] << 24;
+ } else if (keySize > 6 && ksRow % keySize === 4) {
+ // Sub word
+ t = sbox[t >>> 24] << 24 | sbox[t >>> 16 & 0xff] << 16 | sbox[t >>> 8 & 0xff] << 8 | sbox[t & 0xff];
+ }
+
+ keySchedule[ksRow] = prev = (keySchedule[ksRow - keySize] ^ t) >>> 0;
+ }
+
+ for (invKsRow = 0; invKsRow < ksRows; invKsRow++) {
+ ksRow = ksRows - invKsRow;
+ if (invKsRow & 3) {
+ t = keySchedule[ksRow];
+ } else {
+ t = keySchedule[ksRow - 4];
+ }
+
+ if (invKsRow < 4 || ksRow <= 4) {
+ invKeySchedule[invKsRow] = t;
+ } else {
+ invKeySchedule[invKsRow] = invSubMix0[sbox[t >>> 24]] ^ invSubMix1[sbox[t >>> 16 & 0xff]] ^ invSubMix2[sbox[t >>> 8 & 0xff]] ^ invSubMix3[sbox[t & 0xff]];
+ }
+
+ invKeySchedule[invKsRow] = invKeySchedule[invKsRow] >>> 0;
+ }
+ }
+
+ // Adding this as a method greatly improves performance.
+
+ }, {
+ key: 'networkToHostOrderSwap',
+ value: function networkToHostOrderSwap(word) {
+ return word << 24 | (word & 0xff00) << 8 | (word & 0xff0000) >> 8 | word >>> 24;
+ }
+ }, {
+ key: 'decrypt',
+ value: function decrypt(inputArrayBuffer, offset, aesIV) {
+ var nRounds = this.keySize + 6;
+ var invKeySchedule = this.invKeySchedule;
+ var invSBOX = this.invSBox;
+
+ var invSubMix = this.invSubMix;
+ var invSubMix0 = invSubMix[0];
+ var invSubMix1 = invSubMix[1];
+ var invSubMix2 = invSubMix[2];
+ var invSubMix3 = invSubMix[3];
+
+ var initVector = this.uint8ArrayToUint32Array_(aesIV);
+ var initVector0 = initVector[0];
+ var initVector1 = initVector[1];
+ var initVector2 = initVector[2];
+ var initVector3 = initVector[3];
+
+ var inputInt32 = new Int32Array(inputArrayBuffer);
+ var outputInt32 = new Int32Array(inputInt32.length);
+
+ var t0 = void 0,
+ t1 = void 0,
+ t2 = void 0,
+ t3 = void 0;
+ var s0 = void 0,
+ s1 = void 0,
+ s2 = void 0,
+ s3 = void 0;
+ var inputWords0 = void 0,
+ inputWords1 = void 0,
+ inputWords2 = void 0,
+ inputWords3 = void 0;
+
+ var ksRow, i;
+ var swapWord = this.networkToHostOrderSwap;
+
+ while (offset < inputInt32.length) {
+ inputWords0 = swapWord(inputInt32[offset]);
+ inputWords1 = swapWord(inputInt32[offset + 1]);
+ inputWords2 = swapWord(inputInt32[offset + 2]);
+ inputWords3 = swapWord(inputInt32[offset + 3]);
+
+ s0 = inputWords0 ^ invKeySchedule[0];
+ s1 = inputWords3 ^ invKeySchedule[1];
+ s2 = inputWords2 ^ invKeySchedule[2];
+ s3 = inputWords1 ^ invKeySchedule[3];
+
+ ksRow = 4;
+
+ // Iterate through the rounds of decryption
+ for (i = 1; i < nRounds; i++) {
+ t0 = invSubMix0[s0 >>> 24] ^ invSubMix1[s1 >> 16 & 0xff] ^ invSubMix2[s2 >> 8 & 0xff] ^ invSubMix3[s3 & 0xff] ^ invKeySchedule[ksRow];
+ t1 = invSubMix0[s1 >>> 24] ^ invSubMix1[s2 >> 16 & 0xff] ^ invSubMix2[s3 >> 8 & 0xff] ^ invSubMix3[s0 & 0xff] ^ invKeySchedule[ksRow + 1];
+ t2 = invSubMix0[s2 >>> 24] ^ invSubMix1[s3 >> 16 & 0xff] ^ invSubMix2[s0 >> 8 & 0xff] ^ invSubMix3[s1 & 0xff] ^ invKeySchedule[ksRow + 2];
+ t3 = invSubMix0[s3 >>> 24] ^ invSubMix1[s0 >> 16 & 0xff] ^ invSubMix2[s1 >> 8 & 0xff] ^ invSubMix3[s2 & 0xff] ^ invKeySchedule[ksRow + 3];
+ // Update state
+ s0 = t0;
+ s1 = t1;
+ s2 = t2;
+ s3 = t3;
+
+ ksRow = ksRow + 4;
+ }
+
+ // Shift rows, sub bytes, add round key
+ t0 = invSBOX[s0 >>> 24] << 24 ^ invSBOX[s1 >> 16 & 0xff] << 16 ^ invSBOX[s2 >> 8 & 0xff] << 8 ^ invSBOX[s3 & 0xff] ^ invKeySchedule[ksRow];
+ t1 = invSBOX[s1 >>> 24] << 24 ^ invSBOX[s2 >> 16 & 0xff] << 16 ^ invSBOX[s3 >> 8 & 0xff] << 8 ^ invSBOX[s0 & 0xff] ^ invKeySchedule[ksRow + 1];
+ t2 = invSBOX[s2 >>> 24] << 24 ^ invSBOX[s3 >> 16 & 0xff] << 16 ^ invSBOX[s0 >> 8 & 0xff] << 8 ^ invSBOX[s1 & 0xff] ^ invKeySchedule[ksRow + 2];
+ t3 = invSBOX[s3 >>> 24] << 24 ^ invSBOX[s0 >> 16 & 0xff] << 16 ^ invSBOX[s1 >> 8 & 0xff] << 8 ^ invSBOX[s2 & 0xff] ^ invKeySchedule[ksRow + 3];
+ ksRow = ksRow + 3;
+
+ // Write
+ outputInt32[offset] = swapWord(t0 ^ initVector0);
+ outputInt32[offset + 1] = swapWord(t3 ^ initVector1);
+ outputInt32[offset + 2] = swapWord(t2 ^ initVector2);
+ outputInt32[offset + 3] = swapWord(t1 ^ initVector3);
+
+ // reset initVector to last 4 unsigned int
+ initVector0 = inputWords0;
+ initVector1 = inputWords1;
+ initVector2 = inputWords2;
+ initVector3 = inputWords3;
+
+ offset = offset + 4;
+ }
+
+ return outputInt32.buffer;
+ }
+ }, {
+ key: 'destroy',
+ value: function destroy() {
+ this.key = undefined;
+ this.keySize = undefined;
+ this.ksRows = undefined;
+
+ this.sBox = undefined;
+ this.invSBox = undefined;
+ this.subMix = undefined;
+ this.invSubMix = undefined;
+ this.keySchedule = undefined;
+ this.invKeySchedule = undefined;
+
+ this.rcon = undefined;
+ }
+ }]);
+
+ return AESDecryptor;
+}();
+
+exports.default = AESDecryptor;
+
+},{}],18:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _aesCrypto = _dereq_(16);
+
+var _aesCrypto2 = _interopRequireDefault(_aesCrypto);
+
+var _fastAesKey = _dereq_(19);
+
+var _fastAesKey2 = _interopRequireDefault(_fastAesKey);
+
+var _aesDecryptor = _dereq_(17);
+
+var _aesDecryptor2 = _interopRequireDefault(_aesDecryptor);
+
+var _errors = _dereq_(30);
+
+var _logger = _dereq_(50);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+/*globals self: false */
+
+var Decrypter = function () {
+ function Decrypter(observer, config) {
+ _classCallCheck(this, Decrypter);
+
+ this.observer = observer;
+ this.config = config;
+ this.logEnabled = true;
+ try {
+ var browserCrypto = crypto ? crypto : self.crypto;
+ this.subtle = browserCrypto.subtle || browserCrypto.webkitSubtle;
+ } catch (e) {}
+ this.disableWebCrypto = !this.subtle;
+ }
+
+ _createClass(Decrypter, [{
+ key: 'isSync',
+ value: function isSync() {
+ return this.disableWebCrypto && this.config.enableSoftwareAES;
+ }
+ }, {
+ key: 'decrypt',
+ value: function decrypt(data, key, iv, callback) {
+ var _this = this;
+
+ if (this.disableWebCrypto && this.config.enableSoftwareAES) {
+ if (this.logEnabled) {
+ _logger.logger.log('JS AES decrypt');
+ this.logEnabled = false;
+ }
+ var decryptor = this.decryptor;
+ if (!decryptor) {
+ this.decryptor = decryptor = new _aesDecryptor2.default();
+ }
+ decryptor.expandKey(key);
+ callback(decryptor.decrypt(data, 0, iv));
+ } else {
+ if (this.logEnabled) {
+ _logger.logger.log('WebCrypto AES decrypt');
+ this.logEnabled = false;
+ }
+ var subtle = this.subtle;
+ if (this.key !== key) {
+ this.key = key;
+ this.fastAesKey = new _fastAesKey2.default(subtle, key);
+ }
+
+ this.fastAesKey.expandKey().then(function (aesKey) {
+ // decrypt using web crypto
+ var crypto = new _aesCrypto2.default(subtle, iv);
+ crypto.decrypt(data, aesKey).catch(function (err) {
+ _this.onWebCryptoError(err, data, key, iv, callback);
+ }).then(function (result) {
+ callback(result);
+ });
+ }).catch(function (err) {
+ _this.onWebCryptoError(err, data, key, iv, callback);
+ });
+ }
+ }
+ }, {
+ key: 'onWebCryptoError',
+ value: function onWebCryptoError(err, data, key, iv, callback) {
+ if (this.config.enableSoftwareAES) {
+ _logger.logger.log('WebCrypto Error, disable WebCrypto API');
+ this.disableWebCrypto = true;
+ this.logEnabled = true;
+ this.decrypt(data, key, iv, callback);
+ } else {
+ _logger.logger.error('decrypting error : ' + err.message);
+ this.observer.trigger(Event.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.FRAG_DECRYPT_ERROR, fatal: true, reason: err.message });
+ }
+ }
+ }, {
+ key: 'destroy',
+ value: function destroy() {
+ var decryptor = this.decryptor;
+ if (decryptor) {
+ decryptor.destroy();
+ this.decryptor = undefined;
+ }
+ }
+ }]);
+
+ return Decrypter;
+}();
+
+exports.default = Decrypter;
+
+},{"16":16,"17":17,"19":19,"30":30,"50":50}],19:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var FastAESKey = function () {
+ function FastAESKey(subtle, key) {
+ _classCallCheck(this, FastAESKey);
+
+ this.subtle = subtle;
+ this.key = key;
+ }
+
+ _createClass(FastAESKey, [{
+ key: 'expandKey',
+ value: function expandKey() {
+ return this.subtle.importKey('raw', this.key, { name: 'AES-CBC' }, false, ['encrypt', 'decrypt']);
+ }
+ }]);
+
+ return FastAESKey;
+}();
+
+exports.default = FastAESKey;
+
+},{}],20:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
+ * AAC demuxer
+ */
+
+
+var _adts = _dereq_(21);
+
+var _adts2 = _interopRequireDefault(_adts);
+
+var _logger = _dereq_(50);
+
+var _id = _dereq_(26);
+
+var _id2 = _interopRequireDefault(_id);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var AACDemuxer = function () {
+ function AACDemuxer(observer, remuxer, config) {
+ _classCallCheck(this, AACDemuxer);
+
+ this.observer = observer;
+ this.config = config;
+ this.remuxer = remuxer;
+ }
+
+ _createClass(AACDemuxer, [{
+ key: 'resetInitSegment',
+ value: function resetInitSegment(initSegment, audioCodec, videoCodec, duration) {
+ this._aacTrack = { container: 'audio/adts', type: 'audio', id: -1, sequenceNumber: 0, isAAC: true, samples: [], len: 0, manifestCodec: audioCodec, duration: duration, inputTimeScale: 90000 };
+ }
+ }, {
+ key: 'resetTimeStamp',
+ value: function resetTimeStamp() {}
+ }, {
+ key: 'append',
+
+
+ // feed incoming data to the front of the parsing pipeline
+ value: function append(data, timeOffset, contiguous, accurateTimeOffset) {
+ var track,
+ id3 = new _id2.default(data),
+ pts = 90 * id3.timeStamp,
+ config,
+ frameLength,
+ frameDuration,
+ frameIndex,
+ offset,
+ headerLength,
+ stamp,
+ len,
+ aacSample;
+
+ track = this._aacTrack;
+
+ // look for ADTS header (0xFFFx)
+ for (offset = id3.length, len = data.length; offset < len - 1; offset++) {
+ if (data[offset] === 0xff && (data[offset + 1] & 0xf0) === 0xf0) {
+ break;
+ }
+ }
+
+ if (!track.samplerate) {
+ config = _adts2.default.getAudioConfig(this.observer, data, offset, track.manifestCodec);
+ track.config = config.config;
+ track.samplerate = config.samplerate;
+ track.channelCount = config.channelCount;
+ track.codec = config.codec;
+ _logger.logger.log('parsed codec:' + track.codec + ',rate:' + config.samplerate + ',nb channel:' + config.channelCount);
+ }
+ frameIndex = 0;
+ frameDuration = 1024 * 90000 / track.samplerate;
+ while (offset + 5 < len) {
+ // The protection skip bit tells us if we have 2 bytes of CRC data at the end of the ADTS header
+ headerLength = !!(data[offset + 1] & 0x01) ? 7 : 9;
+ // retrieve frame size
+ frameLength = (data[offset + 3] & 0x03) << 11 | data[offset + 4] << 3 | (data[offset + 5] & 0xE0) >>> 5;
+ frameLength -= headerLength;
+ //stamp = pes.pts;
+
+ if (frameLength > 0 && offset + headerLength + frameLength <= len) {
+ stamp = pts + frameIndex * frameDuration;
+ //logger.log(`AAC frame, offset/length/total/pts:${offset+headerLength}/${frameLength}/${data.byteLength}/${(stamp/90).toFixed(0)}`);
+ aacSample = { unit: data.subarray(offset + headerLength, offset + headerLength + frameLength), pts: stamp, dts: stamp };
+ track.samples.push(aacSample);
+ track.len += frameLength;
+ offset += frameLength + headerLength;
+ frameIndex++;
+ // look for ADTS header (0xFFFx)
+ for (; offset < len - 1; offset++) {
+ if (data[offset] === 0xff && (data[offset + 1] & 0xf0) === 0xf0) {
+ break;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ this.remuxer.remux(track, { samples: [] }, { samples: [{ pts: pts, dts: pts, unit: id3.payload }] }, { samples: [] }, timeOffset, contiguous, accurateTimeOffset);
+ }
+ }, {
+ key: 'destroy',
+ value: function destroy() {}
+ }], [{
+ key: 'probe',
+ value: function probe(data) {
+ // check if data contains ID3 timestamp and ADTS sync worc
+ var id3 = new _id2.default(data),
+ offset,
+ len;
+ if (id3.hasTimeStamp) {
+ // look for ADTS header (0xFFFx)
+ for (offset = id3.length, len = data.length; offset < len - 1; offset++) {
+ if (data[offset] === 0xff && (data[offset + 1] & 0xf0) === 0xf0) {
+ //logger.log('ADTS sync word found !');
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }]);
+
+ return AACDemuxer;
+}();
+
+exports.default = AACDemuxer;
+
+},{"21":21,"26":26,"50":50}],21:[function(_dereq_,module,exports){
+'use strict';
+
+var _logger = _dereq_(50);
+
+var _errors = _dereq_(30);
+
+/**
+ * ADTS parser helper
+ */
+var ADTS = {
+ getAudioConfig: function getAudioConfig(observer, data, offset, audioCodec) {
+ var adtsObjectType,
+ // :int
+ adtsSampleingIndex,
+ // :int
+ adtsExtensionSampleingIndex,
+ // :int
+ adtsChanelConfig,
+ // :int
+ config,
+ userAgent = navigator.userAgent.toLowerCase(),
+ manifestCodec = audioCodec,
+ adtsSampleingRates = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350];
+ // byte 2
+ adtsObjectType = ((data[offset + 2] & 0xC0) >>> 6) + 1;
+ adtsSampleingIndex = (data[offset + 2] & 0x3C) >>> 2;
+ if (adtsSampleingIndex > adtsSampleingRates.length - 1) {
+ observer.trigger(Event.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.FRAG_PARSING_ERROR, fatal: true, reason: 'invalid ADTS sampling index:' + adtsSampleingIndex });
+ return;
+ }
+ adtsChanelConfig = (data[offset + 2] & 0x01) << 2;
+ // byte 3
+ adtsChanelConfig |= (data[offset + 3] & 0xC0) >>> 6;
+ _logger.logger.log('manifest codec:' + audioCodec + ',ADTS data:type:' + adtsObjectType + ',sampleingIndex:' + adtsSampleingIndex + '[' + adtsSampleingRates[adtsSampleingIndex] + 'Hz],channelConfig:' + adtsChanelConfig);
+ // firefox: freq less than 24kHz = AAC SBR (HE-AAC)
+ if (/firefox/i.test(userAgent)) {
+ if (adtsSampleingIndex >= 6) {
+ adtsObjectType = 5;
+ config = new Array(4);
+ // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies
+ // there is a factor 2 between frame sample rate and output sample rate
+ // multiply frequency by 2 (see table below, equivalent to substract 3)
+ adtsExtensionSampleingIndex = adtsSampleingIndex - 3;
+ } else {
+ adtsObjectType = 2;
+ config = new Array(2);
+ adtsExtensionSampleingIndex = adtsSampleingIndex;
+ }
+ // Android : always use AAC
+ } else if (userAgent.indexOf('android') !== -1) {
+ adtsObjectType = 2;
+ config = new Array(2);
+ adtsExtensionSampleingIndex = adtsSampleingIndex;
+ } else {
+ /* for other browsers (Chrome/Vivaldi/Opera ...)
+ always force audio type to be HE-AAC SBR, as some browsers do not support audio codec switch properly (like Chrome ...)
+ */
+ adtsObjectType = 5;
+ config = new Array(4);
+ // if (manifest codec is HE-AAC or HE-AACv2) OR (manifest codec not specified AND frequency less than 24kHz)
+ if (audioCodec && (audioCodec.indexOf('mp4a.40.29') !== -1 || audioCodec.indexOf('mp4a.40.5') !== -1) || !audioCodec && adtsSampleingIndex >= 6) {
+ // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies
+ // there is a factor 2 between frame sample rate and output sample rate
+ // multiply frequency by 2 (see table below, equivalent to substract 3)
+ adtsExtensionSampleingIndex = adtsSampleingIndex - 3;
+ } else {
+ // if (manifest codec is AAC) AND (frequency less than 24kHz AND nb channel is 1) OR (manifest codec not specified and mono audio)
+ // Chrome fails to play back with low frequency AAC LC mono when initialized with HE-AAC. This is not a problem with stereo.
+ if (audioCodec && audioCodec.indexOf('mp4a.40.2') !== -1 && adtsSampleingIndex >= 6 && adtsChanelConfig === 1 || !audioCodec && adtsChanelConfig === 1) {
+ adtsObjectType = 2;
+ config = new Array(2);
+ }
+ adtsExtensionSampleingIndex = adtsSampleingIndex;
+ }
+ }
+ /* refer to http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio#Audio_Specific_Config
+ ISO 14496-3 (AAC).pdf - Table 1.13 — Syntax of AudioSpecificConfig()
+ Audio Profile / Audio Object Type
+ 0: Null
+ 1: AAC Main
+ 2: AAC LC (Low Complexity)
+ 3: AAC SSR (Scalable Sample Rate)
+ 4: AAC LTP (Long Term Prediction)
+ 5: SBR (Spectral Band Replication)
+ 6: AAC Scalable
+ sampling freq
+ 0: 96000 Hz
+ 1: 88200 Hz
+ 2: 64000 Hz
+ 3: 48000 Hz
+ 4: 44100 Hz
+ 5: 32000 Hz
+ 6: 24000 Hz
+ 7: 22050 Hz
+ 8: 16000 Hz
+ 9: 12000 Hz
+ 10: 11025 Hz
+ 11: 8000 Hz
+ 12: 7350 Hz
+ 13: Reserved
+ 14: Reserved
+ 15: frequency is written explictly
+ Channel Configurations
+ These are the channel configurations:
+ 0: Defined in AOT Specifc Config
+ 1: 1 channel: front-center
+ 2: 2 channels: front-left, front-right
+ */
+ // audioObjectType = profile => profile, the MPEG-4 Audio Object Type minus 1
+ config[0] = adtsObjectType << 3;
+ // samplingFrequencyIndex
+ config[0] |= (adtsSampleingIndex & 0x0E) >> 1;
+ config[1] |= (adtsSampleingIndex & 0x01) << 7;
+ // channelConfiguration
+ config[1] |= adtsChanelConfig << 3;
+ if (adtsObjectType === 5) {
+ // adtsExtensionSampleingIndex
+ config[1] |= (adtsExtensionSampleingIndex & 0x0E) >> 1;
+ config[2] = (adtsExtensionSampleingIndex & 0x01) << 7;
+ // adtsObjectType (force to 2, chrome is checking that object type is less than 5 ???
+ // https://chromium.googlesource.com/chromium/src.git/+/master/media/formats/mp4/aac.cc
+ config[2] |= 2 << 2;
+ config[3] = 0;
+ }
+ return { config: config, samplerate: adtsSampleingRates[adtsSampleingIndex], channelCount: adtsChanelConfig, codec: 'mp4a.40.' + adtsObjectType, manifestCodec: manifestCodec };
+ }
+};
+
+module.exports = ADTS;
+
+},{"30":30,"50":50}],22:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /* inline demuxer.
+ * probe fragments and instantiate appropriate demuxer depending on content type (TSDemuxer, AACDemuxer, ...)
+ */
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _errors = _dereq_(30);
+
+var _decrypter = _dereq_(18);
+
+var _decrypter2 = _interopRequireDefault(_decrypter);
+
+var _aacdemuxer = _dereq_(20);
+
+var _aacdemuxer2 = _interopRequireDefault(_aacdemuxer);
+
+var _mp4demuxer = _dereq_(27);
+
+var _mp4demuxer2 = _interopRequireDefault(_mp4demuxer);
+
+var _tsdemuxer = _dereq_(29);
+
+var _tsdemuxer2 = _interopRequireDefault(_tsdemuxer);
+
+var _mp4Remuxer = _dereq_(42);
+
+var _mp4Remuxer2 = _interopRequireDefault(_mp4Remuxer);
+
+var _passthroughRemuxer = _dereq_(43);
+
+var _passthroughRemuxer2 = _interopRequireDefault(_passthroughRemuxer);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var DemuxerInline = function () {
+ function DemuxerInline(observer, typeSupported, config, vendor) {
+ _classCallCheck(this, DemuxerInline);
+
+ this.observer = observer;
+ this.typeSupported = typeSupported;
+ this.config = config;
+ this.vendor = vendor;
+ }
+
+ _createClass(DemuxerInline, [{
+ key: 'destroy',
+ value: function destroy() {
+ var demuxer = this.demuxer;
+ if (demuxer) {
+ demuxer.destroy();
+ }
+ }
+ }, {
+ key: 'push',
+ value: function push(data, decryptdata, initSegment, audioCodec, videoCodec, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS) {
+ if (data.byteLength > 0 && decryptdata != null && decryptdata.key != null && decryptdata.method === 'AES-128') {
+ var decrypter = this.decrypter;
+ if (decrypter == null) {
+ decrypter = this.decrypter = new _decrypter2.default(this.observer, this.config);
+ }
+ var localthis = this;
+ // performance.now() not available on WebWorker, at least on Safari Desktop
+ var startTime;
+ try {
+ startTime = performance.now();
+ } catch (error) {
+ startTime = Date.now();
+ }
+ decrypter.decrypt(data, decryptdata.key.buffer, decryptdata.iv.buffer, function (decryptedData) {
+ var endTime;
+ try {
+ endTime = performance.now();
+ } catch (error) {
+ endTime = Date.now();
+ }
+ localthis.observer.trigger(_events2.default.FRAG_DECRYPTED, { stats: { tstart: startTime, tdecrypt: endTime } });
+ localthis.pushDecrypted(new Uint8Array(decryptedData), decryptdata, new Uint8Array(initSegment), audioCodec, videoCodec, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS);
+ });
+ } else {
+ this.pushDecrypted(new Uint8Array(data), decryptdata, new Uint8Array(initSegment), audioCodec, videoCodec, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS);
+ }
+ }
+ }, {
+ key: 'pushDecrypted',
+ value: function pushDecrypted(data, decryptdata, initSegment, audioCodec, videoCodec, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS) {
+ var demuxer = this.demuxer;
+ if (!demuxer ||
+ // in case of continuity change, we might switch from content type (AAC container to TS container for example)
+ // so let's check that current demuxer is still valid
+ discontinuity && !this.probe(data)) {
+ var observer = this.observer;
+ var typeSupported = this.typeSupported;
+ var config = this.config;
+ var muxConfig = [{ demux: _tsdemuxer2.default, remux: _mp4Remuxer2.default }, { demux: _aacdemuxer2.default, remux: _mp4Remuxer2.default }, { demux: _mp4demuxer2.default, remux: _passthroughRemuxer2.default }];
+
+ // probe for content type
+ for (var i in muxConfig) {
+ var mux = muxConfig[i];
+ var probe = mux.demux.probe;
+ if (probe(data)) {
+ var _remuxer = this.remuxer = new mux.remux(observer, config, typeSupported, this.vendor);
+ demuxer = new mux.demux(observer, _remuxer, config, typeSupported);
+ this.probe = probe;
+ break;
+ }
+ }
+ if (!demuxer) {
+ observer.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.FRAG_PARSING_ERROR, fatal: true, reason: 'no demux matching with content found' });
+ return;
+ }
+ this.demuxer = demuxer;
+ }
+ var remuxer = this.remuxer;
+
+ if (discontinuity || trackSwitch) {
+ demuxer.resetInitSegment(initSegment, audioCodec, videoCodec, duration);
+ remuxer.resetInitSegment();
+ }
+ if (discontinuity) {
+ demuxer.resetTimeStamp();
+ remuxer.resetTimeStamp(defaultInitPTS);
+ }
+ if (typeof demuxer.setDecryptData === 'function') {
+ demuxer.setDecryptData(decryptdata);
+ }
+ demuxer.append(data, timeOffset, contiguous, accurateTimeOffset);
+ }
+ }]);
+
+ return DemuxerInline;
+}();
+
+exports.default = DemuxerInline;
+
+},{"18":18,"20":20,"27":27,"29":29,"30":30,"32":32,"42":42,"43":43}],23:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _demuxerInline = _dereq_(22);
+
+var _demuxerInline2 = _interopRequireDefault(_demuxerInline);
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _logger = _dereq_(50);
+
+var _events3 = _dereq_(1);
+
+var _events4 = _interopRequireDefault(_events3);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/* demuxer web worker.
+ * - listen to worker message, and trigger DemuxerInline upon reception of Fragments.
+ * - provides MP4 Boxes back to main thread using [transferable objects](https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast) in order to minimize message passing overhead.
+ */
+
+var DemuxerWorker = function DemuxerWorker(self) {
+ // observer setup
+ var observer = new _events4.default();
+ observer.trigger = function trigger(event) {
+ for (var _len = arguments.length, data = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ data[_key - 1] = arguments[_key];
+ }
+
+ observer.emit.apply(observer, [event, event].concat(data));
+ };
+
+ observer.off = function off(event) {
+ for (var _len2 = arguments.length, data = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
+ data[_key2 - 1] = arguments[_key2];
+ }
+
+ observer.removeListener.apply(observer, [event].concat(data));
+ };
+
+ var forwardMessage = function forwardMessage(ev, data) {
+ self.postMessage({ event: ev, data: data });
+ };
+
+ self.addEventListener('message', function (ev) {
+ var data = ev.data;
+ //console.log('demuxer cmd:' + data.cmd);
+ switch (data.cmd) {
+ case 'init':
+ var config = JSON.parse(data.config);
+ self.demuxer = new _demuxerInline2.default(observer, data.typeSupported, config, data.vendor);
+ try {
+ (0, _logger.enableLogs)(config.debug === true);
+ } catch (err) {
+ console.warn('demuxerWorker: unable to enable logs');
+ }
+ // signal end of worker init
+ forwardMessage('init', null);
+ break;
+ case 'demux':
+ self.demuxer.push(data.data, data.decryptdata, data.initSegment, data.audioCodec, data.videoCodec, data.timeOffset, data.discontinuity, data.trackSwitch, data.contiguous, data.duration, data.accurateTimeOffset, data.defaultInitPTS);
+ break;
+ default:
+ break;
+ }
+ });
+
+ // forward events to main thread
+ observer.on(_events2.default.FRAG_DECRYPTED, forwardMessage);
+ observer.on(_events2.default.FRAG_PARSING_INIT_SEGMENT, forwardMessage);
+ observer.on(_events2.default.FRAG_PARSED, forwardMessage);
+ observer.on(_events2.default.ERROR, forwardMessage);
+ observer.on(_events2.default.FRAG_PARSING_METADATA, forwardMessage);
+ observer.on(_events2.default.FRAG_PARSING_USERDATA, forwardMessage);
+ observer.on(_events2.default.INIT_PTS_FOUND, forwardMessage);
+
+ // special case for FRAG_PARSING_DATA: pass data1/data2 as transferable object (no copy)
+ observer.on(_events2.default.FRAG_PARSING_DATA, function (ev, data) {
+ var transferable = [];
+ var message = { event: ev, data: data };
+ if (data.data1) {
+ message.data1 = data.data1.buffer;
+ transferable.push(data.data1.buffer);
+ delete data.data1;
+ }
+ if (data.data2) {
+ message.data2 = data.data2.buffer;
+ transferable.push(data.data2.buffer);
+ delete data.data2;
+ }
+ self.postMessage(message, transferable);
+ });
+};
+
+exports.default = DemuxerWorker;
+
+},{"1":1,"22":22,"32":32,"50":50}],24:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _demuxerInline = _dereq_(22);
+
+var _demuxerInline2 = _interopRequireDefault(_demuxerInline);
+
+var _demuxerWorker = _dereq_(23);
+
+var _demuxerWorker2 = _interopRequireDefault(_demuxerWorker);
+
+var _logger = _dereq_(50);
+
+var _errors = _dereq_(30);
+
+var _events3 = _dereq_(1);
+
+var _events4 = _interopRequireDefault(_events3);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Demuxer = function () {
+ function Demuxer(hls, id) {
+ _classCallCheck(this, Demuxer);
+
+ this.hls = hls;
+ this.id = id;
+ // observer setup
+ var observer = this.observer = new _events4.default();
+ var config = hls.config;
+ observer.trigger = function trigger(event) {
+ for (var _len = arguments.length, data = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ data[_key - 1] = arguments[_key];
+ }
+
+ observer.emit.apply(observer, [event, event].concat(data));
+ };
+
+ observer.off = function off(event) {
+ for (var _len2 = arguments.length, data = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
+ data[_key2 - 1] = arguments[_key2];
+ }
+
+ observer.removeListener.apply(observer, [event].concat(data));
+ };
+
+ var forwardMessage = function (ev, data) {
+ data = data || {};
+ data.frag = this.frag;
+ data.id = this.id;
+ hls.trigger(ev, data);
+ }.bind(this);
+
+ // forward events to main thread
+ observer.on(_events2.default.FRAG_DECRYPTED, forwardMessage);
+ observer.on(_events2.default.FRAG_PARSING_INIT_SEGMENT, forwardMessage);
+ observer.on(_events2.default.FRAG_PARSING_DATA, forwardMessage);
+ observer.on(_events2.default.FRAG_PARSED, forwardMessage);
+ observer.on(_events2.default.ERROR, forwardMessage);
+ observer.on(_events2.default.FRAG_PARSING_METADATA, forwardMessage);
+ observer.on(_events2.default.FRAG_PARSING_USERDATA, forwardMessage);
+ observer.on(_events2.default.INIT_PTS_FOUND, forwardMessage);
+
+ var typeSupported = {
+ mp4: MediaSource.isTypeSupported('video/mp4'),
+ mpeg: MediaSource.isTypeSupported('audio/mpeg'),
+ mp3: MediaSource.isTypeSupported('audio/mp4; codecs="mp3"')
+ };
+ // navigator.vendor is not always available in Web Worker
+ // refer to https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/navigator
+ var vendor = navigator.vendor;
+ if (config.enableWorker && typeof Worker !== 'undefined') {
+ _logger.logger.log('demuxing in webworker');
+ var w = void 0;
+ try {
+ var work = _dereq_(3);
+ w = this.w = work(_demuxerWorker2.default);
+ this.onwmsg = this.onWorkerMessage.bind(this);
+ w.addEventListener('message', this.onwmsg);
+ w.onerror = function (event) {
+ hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.OTHER_ERROR, details: _errors.ErrorDetails.INTERNAL_EXCEPTION, fatal: true, event: 'demuxerWorker', err: { message: event.message + ' (' + event.filename + ':' + event.lineno + ')' } });
+ };
+ w.postMessage({ cmd: 'init', typeSupported: typeSupported, vendor: vendor, id: id, config: JSON.stringify(config) });
+ } catch (err) {
+ _logger.logger.error('error while initializing DemuxerWorker, fallback on DemuxerInline');
+ if (w) {
+ // revoke the Object URL that was used to create demuxer worker, so as not to leak it
+ URL.revokeObjectURL(w.objectURL);
+ }
+ this.demuxer = new _demuxerInline2.default(observer, typeSupported, config, vendor);
+ this.w = undefined;
+ }
+ } else {
+ this.demuxer = new _demuxerInline2.default(observer, typeSupported, config, vendor);
+ }
+ }
+
+ _createClass(Demuxer, [{
+ key: 'destroy',
+ value: function destroy() {
+ var w = this.w;
+ if (w) {
+ w.removeEventListener('message', this.onwmsg);
+ w.terminate();
+ this.w = null;
+ } else {
+ var demuxer = this.demuxer;
+ if (demuxer) {
+ demuxer.destroy();
+ this.demuxer = null;
+ }
+ }
+ var observer = this.observer;
+ if (observer) {
+ observer.removeAllListeners();
+ this.observer = null;
+ }
+ }
+ }, {
+ key: 'push',
+ value: function push(data, initSegment, audioCodec, videoCodec, frag, duration, accurateTimeOffset, defaultInitPTS) {
+ var w = this.w;
+ var timeOffset = !isNaN(frag.startDTS) ? frag.startDTS : frag.start;
+ var decryptdata = frag.decryptdata;
+ var lastFrag = this.frag;
+ var discontinuity = !(lastFrag && frag.cc === lastFrag.cc);
+ var trackSwitch = !(lastFrag && frag.level === lastFrag.level);
+ var nextSN = lastFrag && frag.sn === lastFrag.sn + 1;
+ var contiguous = !trackSwitch && nextSN;
+ if (discontinuity) {
+ _logger.logger.log(this.id + ':discontinuity detected');
+ }
+ if (trackSwitch) {
+ _logger.logger.log(this.id + ':switch detected');
+ }
+ this.frag = frag;
+ if (w) {
+ // post fragment payload as transferable objects (no copy)
+ w.postMessage({ cmd: 'demux', data: data, decryptdata: decryptdata, initSegment: initSegment, audioCodec: audioCodec, videoCodec: videoCodec, timeOffset: timeOffset, discontinuity: discontinuity, trackSwitch: trackSwitch, contiguous: contiguous, duration: duration, accurateTimeOffset: accurateTimeOffset, defaultInitPTS: defaultInitPTS }, [data]);
+ } else {
+ var demuxer = this.demuxer;
+ if (demuxer) {
+ demuxer.push(data, decryptdata, initSegment, audioCodec, videoCodec, timeOffset, discontinuity, trackSwitch, contiguous, duration, accurateTimeOffset, defaultInitPTS);
+ }
+ }
+ }
+ }, {
+ key: 'onWorkerMessage',
+ value: function onWorkerMessage(ev) {
+ var data = ev.data,
+ hls = this.hls;
+ //console.log('onWorkerMessage:' + data.event);
+ switch (data.event) {
+ case 'init':
+ // revoke the Object URL that was used to create demuxer worker, so as not to leak it
+ URL.revokeObjectURL(this.w.objectURL);
+ break;
+ // special case for FRAG_PARSING_DATA: data1 and data2 are transferable objects
+ case _events2.default.FRAG_PARSING_DATA:
+ data.data.data1 = new Uint8Array(data.data1);
+ if (data.data2) {
+ data.data.data2 = new Uint8Array(data.data2);
+ }
+ /* falls through */
+ default:
+ data.data = data.data || {};
+ data.data.frag = this.frag;
+ data.data.id = this.id;
+ hls.trigger(data.event, data.data);
+ break;
+ }
+ }
+ }]);
+
+ return Demuxer;
+}();
+
+exports.default = Demuxer;
+
+},{"1":1,"22":22,"23":23,"3":3,"30":30,"32":32,"50":50}],25:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
+ * Parser for exponential Golomb codes, a variable-bitwidth number encoding scheme used by h264.
+ */
+
+var _logger = _dereq_(50);
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var ExpGolomb = function () {
+ function ExpGolomb(data) {
+ _classCallCheck(this, ExpGolomb);
+
+ this.data = data;
+ // the number of bytes left to examine in this.data
+ this.bytesAvailable = data.byteLength;
+ // the current word being examined
+ this.word = 0; // :uint
+ // the number of bits left to examine in the current word
+ this.bitsAvailable = 0; // :uint
+ }
+
+ // ():void
+
+
+ _createClass(ExpGolomb, [{
+ key: 'loadWord',
+ value: function loadWord() {
+ var data = this.data,
+ bytesAvailable = this.bytesAvailable,
+ position = data.byteLength - bytesAvailable,
+ workingBytes = new Uint8Array(4),
+ availableBytes = Math.min(4, bytesAvailable);
+ if (availableBytes === 0) {
+ throw new Error('no bytes available');
+ }
+ workingBytes.set(data.subarray(position, position + availableBytes));
+ this.word = new DataView(workingBytes.buffer).getUint32(0);
+ // track the amount of this.data that has been processed
+ this.bitsAvailable = availableBytes * 8;
+ this.bytesAvailable -= availableBytes;
+ }
+
+ // (count:int):void
+
+ }, {
+ key: 'skipBits',
+ value: function skipBits(count) {
+ var skipBytes; // :int
+ if (this.bitsAvailable > count) {
+ this.word <<= count;
+ this.bitsAvailable -= count;
+ } else {
+ count -= this.bitsAvailable;
+ skipBytes = count >> 3;
+ count -= skipBytes >> 3;
+ this.bytesAvailable -= skipBytes;
+ this.loadWord();
+ this.word <<= count;
+ this.bitsAvailable -= count;
+ }
+ }
+
+ // (size:int):uint
+
+ }, {
+ key: 'readBits',
+ value: function readBits(size) {
+ var bits = Math.min(this.bitsAvailable, size),
+ // :uint
+ valu = this.word >>> 32 - bits; // :uint
+ if (size > 32) {
+ _logger.logger.error('Cannot read more than 32 bits at a time');
+ }
+ this.bitsAvailable -= bits;
+ if (this.bitsAvailable > 0) {
+ this.word <<= bits;
+ } else if (this.bytesAvailable > 0) {
+ this.loadWord();
+ }
+ bits = size - bits;
+ if (bits > 0 && this.bitsAvailable) {
+ return valu << bits | this.readBits(bits);
+ } else {
+ return valu;
+ }
+ }
+
+ // ():uint
+
+ }, {
+ key: 'skipLZ',
+ value: function skipLZ() {
+ var leadingZeroCount; // :uint
+ for (leadingZeroCount = 0; leadingZeroCount < this.bitsAvailable; ++leadingZeroCount) {
+ if (0 !== (this.word & 0x80000000 >>> leadingZeroCount)) {
+ // the first bit of working word is 1
+ this.word <<= leadingZeroCount;
+ this.bitsAvailable -= leadingZeroCount;
+ return leadingZeroCount;
+ }
+ }
+ // we exhausted word and still have not found a 1
+ this.loadWord();
+ return leadingZeroCount + this.skipLZ();
+ }
+
+ // ():void
+
+ }, {
+ key: 'skipUEG',
+ value: function skipUEG() {
+ this.skipBits(1 + this.skipLZ());
+ }
+
+ // ():void
+
+ }, {
+ key: 'skipEG',
+ value: function skipEG() {
+ this.skipBits(1 + this.skipLZ());
+ }
+
+ // ():uint
+
+ }, {
+ key: 'readUEG',
+ value: function readUEG() {
+ var clz = this.skipLZ(); // :uint
+ return this.readBits(clz + 1) - 1;
+ }
+
+ // ():int
+
+ }, {
+ key: 'readEG',
+ value: function readEG() {
+ var valu = this.readUEG(); // :int
+ if (0x01 & valu) {
+ // the number is odd if the low order bit is set
+ return 1 + valu >>> 1; // add 1 to make it even, and divide by 2
+ } else {
+ return -1 * (valu >>> 1); // divide by two then make it negative
+ }
+ }
+
+ // Some convenience functions
+ // :Boolean
+
+ }, {
+ key: 'readBoolean',
+ value: function readBoolean() {
+ return 1 === this.readBits(1);
+ }
+
+ // ():int
+
+ }, {
+ key: 'readUByte',
+ value: function readUByte() {
+ return this.readBits(8);
+ }
+
+ // ():int
+
+ }, {
+ key: 'readUShort',
+ value: function readUShort() {
+ return this.readBits(16);
+ }
+ // ():int
+
+ }, {
+ key: 'readUInt',
+ value: function readUInt() {
+ return this.readBits(32);
+ }
+
+ /**
+ * Advance the ExpGolomb decoder past a scaling list. The scaling
+ * list is optionally transmitted as part of a sequence parameter
+ * set and is not relevant to transmuxing.
+ * @param count {number} the number of entries in this scaling list
+ * @see Recommendation ITU-T H.264, Section 7.3.2.1.1.1
+ */
+
+ }, {
+ key: 'skipScalingList',
+ value: function skipScalingList(count) {
+ var lastScale = 8,
+ nextScale = 8,
+ j,
+ deltaScale;
+ for (j = 0; j < count; j++) {
+ if (nextScale !== 0) {
+ deltaScale = this.readEG();
+ nextScale = (lastScale + deltaScale + 256) % 256;
+ }
+ lastScale = nextScale === 0 ? lastScale : nextScale;
+ }
+ }
+
+ /**
+ * Read a sequence parameter set and return some interesting video
+ * properties. A sequence parameter set is the H264 metadata that
+ * describes the properties of upcoming video frames.
+ * @param data {Uint8Array} the bytes of a sequence parameter set
+ * @return {object} an object with configuration parsed from the
+ * sequence parameter set, including the dimensions of the
+ * associated video frames.
+ */
+
+ }, {
+ key: 'readSPS',
+ value: function readSPS() {
+ var frameCropLeftOffset = 0,
+ frameCropRightOffset = 0,
+ frameCropTopOffset = 0,
+ frameCropBottomOffset = 0,
+ profileIdc,
+ profileCompat,
+ levelIdc,
+ numRefFramesInPicOrderCntCycle,
+ picWidthInMbsMinus1,
+ picHeightInMapUnitsMinus1,
+ frameMbsOnlyFlag,
+ scalingListCount,
+ i,
+ readUByte = this.readUByte.bind(this),
+ readBits = this.readBits.bind(this),
+ readUEG = this.readUEG.bind(this),
+ readBoolean = this.readBoolean.bind(this),
+ skipBits = this.skipBits.bind(this),
+ skipEG = this.skipEG.bind(this),
+ skipUEG = this.skipUEG.bind(this),
+ skipScalingList = this.skipScalingList.bind(this);
+
+ readUByte();
+ profileIdc = readUByte(); // profile_idc
+ profileCompat = readBits(5); // constraint_set[0-4]_flag, u(5)
+ skipBits(3); // reserved_zero_3bits u(3),
+ levelIdc = readUByte(); //level_idc u(8)
+ skipUEG(); // seq_parameter_set_id
+ // some profiles have more optional data we don't need
+ if (profileIdc === 100 || profileIdc === 110 || profileIdc === 122 || profileIdc === 244 || profileIdc === 44 || profileIdc === 83 || profileIdc === 86 || profileIdc === 118 || profileIdc === 128) {
+ var chromaFormatIdc = readUEG();
+ if (chromaFormatIdc === 3) {
+ skipBits(1); // separate_colour_plane_flag
+ }
+ skipUEG(); // bit_depth_luma_minus8
+ skipUEG(); // bit_depth_chroma_minus8
+ skipBits(1); // qpprime_y_zero_transform_bypass_flag
+ if (readBoolean()) {
+ // seq_scaling_matrix_present_flag
+ scalingListCount = chromaFormatIdc !== 3 ? 8 : 12;
+ for (i = 0; i < scalingListCount; i++) {
+ if (readBoolean()) {
+ // seq_scaling_list_present_flag[ i ]
+ if (i < 6) {
+ skipScalingList(16);
+ } else {
+ skipScalingList(64);
+ }
+ }
+ }
+ }
+ }
+ skipUEG(); // log2_max_frame_num_minus4
+ var picOrderCntType = readUEG();
+ if (picOrderCntType === 0) {
+ readUEG(); //log2_max_pic_order_cnt_lsb_minus4
+ } else if (picOrderCntType === 1) {
+ skipBits(1); // delta_pic_order_always_zero_flag
+ skipEG(); // offset_for_non_ref_pic
+ skipEG(); // offset_for_top_to_bottom_field
+ numRefFramesInPicOrderCntCycle = readUEG();
+ for (i = 0; i < numRefFramesInPicOrderCntCycle; i++) {
+ skipEG(); // offset_for_ref_frame[ i ]
+ }
+ }
+ skipUEG(); // max_num_ref_frames
+ skipBits(1); // gaps_in_frame_num_value_allowed_flag
+ picWidthInMbsMinus1 = readUEG();
+ picHeightInMapUnitsMinus1 = readUEG();
+ frameMbsOnlyFlag = readBits(1);
+ if (frameMbsOnlyFlag === 0) {
+ skipBits(1); // mb_adaptive_frame_field_flag
+ }
+ skipBits(1); // direct_8x8_inference_flag
+ if (readBoolean()) {
+ // frame_cropping_flag
+ frameCropLeftOffset = readUEG();
+ frameCropRightOffset = readUEG();
+ frameCropTopOffset = readUEG();
+ frameCropBottomOffset = readUEG();
+ }
+ var pixelRatio = [1, 1];
+ if (readBoolean()) {
+ // vui_parameters_present_flag
+ if (readBoolean()) {
+ // aspect_ratio_info_present_flag
+ var aspectRatioIdc = readUByte();
+ switch (aspectRatioIdc) {
+ case 1:
+ pixelRatio = [1, 1];break;
+ case 2:
+ pixelRatio = [12, 11];break;
+ case 3:
+ pixelRatio = [10, 11];break;
+ case 4:
+ pixelRatio = [16, 11];break;
+ case 5:
+ pixelRatio = [40, 33];break;
+ case 6:
+ pixelRatio = [24, 11];break;
+ case 7:
+ pixelRatio = [20, 11];break;
+ case 8:
+ pixelRatio = [32, 11];break;
+ case 9:
+ pixelRatio = [80, 33];break;
+ case 10:
+ pixelRatio = [18, 11];break;
+ case 11:
+ pixelRatio = [15, 11];break;
+ case 12:
+ pixelRatio = [64, 33];break;
+ case 13:
+ pixelRatio = [160, 99];break;
+ case 14:
+ pixelRatio = [4, 3];break;
+ case 15:
+ pixelRatio = [3, 2];break;
+ case 16:
+ pixelRatio = [2, 1];break;
+ case 255:
+ {
+ pixelRatio = [readUByte() << 8 | readUByte(), readUByte() << 8 | readUByte()];
+ break;
+ }
+ }
+ }
+ }
+ return {
+ width: Math.ceil((picWidthInMbsMinus1 + 1) * 16 - frameCropLeftOffset * 2 - frameCropRightOffset * 2),
+ height: (2 - frameMbsOnlyFlag) * (picHeightInMapUnitsMinus1 + 1) * 16 - (frameMbsOnlyFlag ? 2 : 4) * (frameCropTopOffset + frameCropBottomOffset),
+ pixelRatio: pixelRatio
+ };
+ }
+ }, {
+ key: 'readSliceType',
+ value: function readSliceType() {
+ // skip NALu type
+ this.readUByte();
+ // discard first_mb_in_slice
+ this.readUEG();
+ // return slice_type
+ return this.readUEG();
+ }
+ }]);
+
+ return ExpGolomb;
+}();
+
+exports.default = ExpGolomb;
+
+},{"50":50}],26:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
+ * ID3 parser
+ */
+
+
+var _logger = _dereq_(50);
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+//import Hex from '../utils/hex';
+
+var ID3 = function () {
+ function ID3(data) {
+ _classCallCheck(this, ID3);
+
+ this._hasTimeStamp = false;
+ var offset = 0,
+ byte1,
+ byte2,
+ byte3,
+ byte4,
+ tagSize,
+ endPos,
+ header,
+ len;
+ do {
+ header = this.readUTF(data, offset, 3);
+ offset += 3;
+ // first check for ID3 header
+ if (header === 'ID3') {
+ // skip 24 bits
+ offset += 3;
+ // retrieve tag(s) length
+ byte1 = data[offset++] & 0x7f;
+ byte2 = data[offset++] & 0x7f;
+ byte3 = data[offset++] & 0x7f;
+ byte4 = data[offset++] & 0x7f;
+ tagSize = (byte1 << 21) + (byte2 << 14) + (byte3 << 7) + byte4;
+ endPos = offset + tagSize;
+ //logger.log(`ID3 tag found, size/end: ${tagSize}/${endPos}`);
+
+ // read ID3 tags
+ this._parseID3Frames(data, offset, endPos);
+ offset = endPos;
+ } else if (header === '3DI') {
+ // http://id3.org/id3v2.4.0-structure chapter 3.4. ID3v2 footer
+ offset += 7;
+ _logger.logger.log('3DI footer found, end: ' + offset);
+ } else {
+ offset -= 3;
+ len = offset;
+ if (len) {
+ //logger.log(`ID3 len: ${len}`);
+ if (!this.hasTimeStamp) {
+ _logger.logger.warn('ID3 tag found, but no timestamp');
+ }
+ this._length = len;
+ this._payload = data.subarray(0, len);
+ }
+ return;
+ }
+ } while (true);
+ }
+
+ _createClass(ID3, [{
+ key: 'readUTF',
+ value: function readUTF(data, start, len) {
+
+ var result = '',
+ offset = start,
+ end = start + len;
+ do {
+ result += String.fromCharCode(data[offset++]);
+ } while (offset < end);
+ return result;
+ }
+ }, {
+ key: '_parseID3Frames',
+ value: function _parseID3Frames(data, offset, endPos) {
+ var tagId, tagLen, tagStart, tagFlags, timestamp;
+ while (offset + 8 <= endPos) {
+ tagId = this.readUTF(data, offset, 4);
+ offset += 4;
+
+ tagLen = data[offset++] << 24 + data[offset++] << 16 + data[offset++] << 8 + data[offset++];
+
+ tagFlags = data[offset++] << 8 + data[offset++];
+
+ tagStart = offset;
+ //logger.log("ID3 tag id:" + tagId);
+ switch (tagId) {
+ case 'PRIV':
+ //logger.log('parse frame:' + Hex.hexDump(data.subarray(offset,endPos)));
+ // owner should be "com.apple.streaming.transportStreamTimestamp"
+ if (this.readUTF(data, offset, 44) === 'com.apple.streaming.transportStreamTimestamp') {
+ offset += 44;
+ // smelling even better ! we found the right descriptor
+ // skip null character (string end) + 3 first bytes
+ offset += 4;
+
+ // timestamp is 33 bit expressed as a big-endian eight-octet number, with the upper 31 bits set to zero.
+ var pts33Bit = data[offset++] & 0x1;
+ this._hasTimeStamp = true;
+
+ timestamp = ((data[offset++] << 23) + (data[offset++] << 15) + (data[offset++] << 7) + data[offset++]) / 45;
+
+ if (pts33Bit) {
+ timestamp += 47721858.84; // 2^32 / 90
+ }
+ timestamp = Math.round(timestamp);
+ _logger.logger.trace('ID3 timestamp found: ' + timestamp);
+ this._timeStamp = timestamp;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }, {
+ key: 'hasTimeStamp',
+ get: function get() {
+ return this._hasTimeStamp;
+ }
+ }, {
+ key: 'timeStamp',
+ get: function get() {
+ return this._timeStamp;
+ }
+ }, {
+ key: 'length',
+ get: function get() {
+ return this._length;
+ }
+ }, {
+ key: 'payload',
+ get: function get() {
+ return this._payload;
+ }
+ }]);
+
+ return ID3;
+}();
+
+exports.default = ID3;
+
+},{"50":50}],27:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
+ * MP4 demuxer
+ */
+//import {logger} from '../utils/logger';
+
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var MP4Demuxer = function () {
+ function MP4Demuxer(observer, remuxer) {
+ _classCallCheck(this, MP4Demuxer);
+
+ this.observer = observer;
+ this.remuxer = remuxer;
+ }
+
+ _createClass(MP4Demuxer, [{
+ key: 'resetTimeStamp',
+ value: function resetTimeStamp() {}
+ }, {
+ key: 'resetInitSegment',
+ value: function resetInitSegment(initSegment, audioCodec, videoCodec, duration) {
+ //jshint unused:false
+ var initData = this.initData = MP4Demuxer.parseInitSegment(initSegment);
+ var tracks = {};
+ if (initData.audio) {
+ tracks.audio = { container: 'audio/mp4', codec: audioCodec, initSegment: initSegment };
+ }
+ if (initData.video) {
+ tracks.video = { container: 'video/mp4', codec: videoCodec, initSegment: initSegment };
+ }
+ this.observer.trigger(_events2.default.FRAG_PARSING_INIT_SEGMENT, { tracks: tracks });
+ }
+ }, {
+ key: 'append',
+
+
+ // feed incoming data to the front of the parsing pipeline
+ value: function append(data, timeOffset, contiguous, accurateTimeOffset) {
+ var initData = this.initData;
+ var startDTS = MP4Demuxer.startDTS(initData, data);
+ this.remuxer.remux(initData.audio, initData.video, null, null, startDTS, contiguous, accurateTimeOffset, data);
+ }
+ }, {
+ key: 'destroy',
+ value: function destroy() {}
+ }], [{
+ key: 'probe',
+ value: function probe(data) {
+ if (data.length >= 8) {
+ var dataType = MP4Demuxer.bin2str(data.subarray(4, 8));
+ return ['moof', 'ftyp', 'styp'].indexOf(dataType) >= 0;
+ }
+ return false;
+ }
+ }, {
+ key: 'bin2str',
+ value: function bin2str(buffer) {
+ return String.fromCharCode.apply(null, buffer);
+ }
+
+ // Find the data for a box specified by its path
+
+ }, {
+ key: 'findBox',
+ value: function findBox(data, path) {
+ var results = [],
+ i,
+ size,
+ type,
+ end,
+ subresults;
+
+ if (!path.length) {
+ // short-circuit the search for empty paths
+ return null;
+ }
+
+ for (i = 0; i < data.byteLength;) {
+ size = data[i] << 24;
+ size |= data[i + 1] << 16;
+ size |= data[i + 2] << 8;
+ size |= data[i + 3];
+
+ type = MP4Demuxer.bin2str(data.subarray(i + 4, i + 8));
+
+ end = size > 1 ? i + size : data.byteLength;
+
+ if (type === path[0]) {
+ if (path.length === 1) {
+ // this is the end of the path and we've found the box we were
+ // looking for
+ results.push(data.subarray(i + 8, end));
+ } else {
+ // recursively search for the next box along the path
+ subresults = MP4Demuxer.findBox(data.subarray(i + 8, end), path.slice(1));
+ if (subresults.length) {
+ results = results.concat(subresults);
+ }
+ }
+ }
+ i = end;
+ }
+
+ // we've finished searching all of data
+ return results;
+ }
+
+ /**
+ * Parses an MP4 initialization segment and extracts stream type and
+ * timescale values for any declared tracks. Timescale values indicate the
+ * number of clock ticks per second to assume for time-based values
+ * elsewhere in the MP4.
+ *
+ * To determine the start time of an MP4, you need two pieces of
+ * information: the timescale unit and the earliest base media decode
+ * time. Multiple timescales can be specified within an MP4 but the
+ * base media decode time is always expressed in the timescale from
+ * the media header box for the track:
+ * ```
+ * moov > trak > mdia > mdhd.timescale
+ * moov > trak > mdia > hdlr
+ * ```
+ * @param init {Uint8Array} the bytes of the init segment
+ * @return {object} a hash of track type to timescale values or null if
+ * the init segment is malformed.
+ */
+
+ }, {
+ key: 'parseInitSegment',
+ value: function parseInitSegment(initSegment) {
+ var result = [];
+ var traks = MP4Demuxer.findBox(initSegment, ['moov', 'trak']);
+
+ traks.forEach(function (trak) {
+ var tkhd = MP4Demuxer.findBox(trak, ['tkhd'])[0];
+ if (tkhd) {
+ var version = tkhd[0];
+ var index = version === 0 ? 12 : 20;
+ var trackId = tkhd[index] << 24 | tkhd[index + 1] << 16 | tkhd[index + 2] << 8 | tkhd[index + 3];
+
+ trackId = trackId < 0 ? 4294967296 + trackId : trackId;
+
+ var mdhd = MP4Demuxer.findBox(trak, ['mdia', 'mdhd'])[0];
+ if (mdhd) {
+ version = mdhd[0];
+ index = version === 0 ? 12 : 20;
+ var timescale = mdhd[index] << 24 | mdhd[index + 1] << 16 | mdhd[index + 2] << 8 | mdhd[index + 3];
+
+ var hdlr = MP4Demuxer.findBox(trak, ['mdia', 'hdlr'])[0];
+ if (hdlr) {
+ var hdlrType = MP4Demuxer.bin2str(hdlr.subarray(8, 12));
+ var type = { 'soun': 'audio', 'vide': 'video' }[hdlrType];
+ if (type) {
+ result[trackId] = { timescale: timescale, type: type };
+ result[type] = { timescale: timescale, id: trackId };
+ }
+ }
+ }
+ }
+ });
+ return result;
+ }
+
+ /**
+ * Determine the base media decode start time, in seconds, for an MP4
+ * fragment. If multiple fragments are specified, the earliest time is
+ * returned.
+ *
+ * The base media decode time can be parsed from track fragment
+ * metadata:
+ * ```
+ * moof > traf > tfdt.baseMediaDecodeTime
+ * ```
+ * It requires the timescale value from the mdhd to interpret.
+ *
+ * @param timescale {object} a hash of track ids to timescale values.
+ * @return {number} the earliest base media decode start time for the
+ * fragment, in seconds
+ */
+
+ }, {
+ key: 'startDTS',
+ value: function startDTS(initData, fragment) {
+ var trafs, baseTimes, result;
+
+ // we need info from two childrend of each track fragment box
+ trafs = MP4Demuxer.findBox(fragment, ['moof', 'traf']);
+
+ // determine the start times for each track
+ baseTimes = [].concat.apply([], trafs.map(function (traf) {
+ return MP4Demuxer.findBox(traf, ['tfhd']).map(function (tfhd) {
+ var id, scale, baseTime;
+
+ // get the track id from the tfhd
+ id = tfhd[4] << 24 | tfhd[5] << 16 | tfhd[6] << 8 | tfhd[7];
+ // assume a 90kHz clock if no timescale was specified
+ scale = initData[id].timescale || 90e3;
+
+ // get the base media decode time from the tfdt
+ baseTime = MP4Demuxer.findBox(traf, ['tfdt']).map(function (tfdt) {
+ var version, result;
+
+ version = tfdt[0];
+ result = tfdt[4] << 24 | tfdt[5] << 16 | tfdt[6] << 8 | tfdt[7];
+ if (version === 1) {
+ result *= Math.pow(2, 32);
+ result += tfdt[8] << 24 | tfdt[9] << 16 | tfdt[10] << 8 | tfdt[11];
+ }
+ return result;
+ })[0];
+ baseTime = baseTime || Infinity;
+
+ // convert base time to seconds
+ return baseTime / scale;
+ });
+ }));
+
+ // return the minimum
+ result = Math.min.apply(null, baseTimes);
+ return isFinite(result) ? result : 0;
+ }
+ }]);
+
+ return MP4Demuxer;
+}();
+
+exports.default = MP4Demuxer;
+
+},{"32":32}],28:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
+ * SAMPLE-AES decrypter
+ */
+
+var _decrypter = _dereq_(18);
+
+var _decrypter2 = _interopRequireDefault(_decrypter);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var SampleAesDecrypter = function () {
+ function SampleAesDecrypter(observer, config, decryptdata, discardEPB) {
+ _classCallCheck(this, SampleAesDecrypter);
+
+ this.decryptdata = decryptdata;
+ this.discardEPB = discardEPB;
+ this.decrypter = new _decrypter2.default(observer, config);
+ }
+
+ _createClass(SampleAesDecrypter, [{
+ key: 'decryptBuffer',
+ value: function decryptBuffer(encryptedData, callback) {
+ this.decrypter.decrypt(encryptedData, this.decryptdata.key.buffer, this.decryptdata.iv.buffer, callback);
+ }
+
+ // AAC - encrypt all full 16 bytes blocks starting from offset 16
+
+ }, {
+ key: 'decryptAacSample',
+ value: function decryptAacSample(samples, sampleIndex, callback, sync) {
+ var curUnit = samples[sampleIndex].unit;
+ var encryptedData = curUnit.subarray(16, curUnit.length - curUnit.length % 16);
+ var encryptedBuffer = encryptedData.buffer.slice(encryptedData.byteOffset, encryptedData.byteOffset + encryptedData.length);
+
+ var localthis = this;
+ this.decryptBuffer(encryptedBuffer, function (decryptedData) {
+ decryptedData = new Uint8Array(decryptedData);
+ curUnit.set(decryptedData, 16);
+
+ if (!sync) {
+ localthis.decryptAacSamples(samples, sampleIndex + 1, callback);
+ }
+ });
+ }
+ }, {
+ key: 'decryptAacSamples',
+ value: function decryptAacSamples(samples, sampleIndex, callback) {
+ for (;; sampleIndex++) {
+ if (sampleIndex >= samples.length) {
+ callback();
+ return;
+ }
+
+ if (samples[sampleIndex].unit.length < 32) {
+ continue;
+ }
+
+ var sync = this.decrypter.isSync();
+
+ this.decryptAacSample(samples, sampleIndex, callback, sync);
+
+ if (!sync) {
+ return;
+ }
+ }
+ }
+
+ // AVC - encrypt one 16 bytes block out of ten, starting from offset 32
+
+ }, {
+ key: 'getAvcEncryptedData',
+ value: function getAvcEncryptedData(decodedData) {
+ var encryptedDataLen = Math.floor((decodedData.length - 48) / 160) * 16 + 16;
+ var encryptedData = new Int8Array(encryptedDataLen);
+ var outputPos = 0;
+ for (var inputPos = 32; inputPos <= decodedData.length - 16; inputPos += 160, outputPos += 16) {
+ encryptedData.set(decodedData.subarray(inputPos, inputPos + 16), outputPos);
+ }
+ return encryptedData;
+ }
+ }, {
+ key: 'getAvcDecryptedUnit',
+ value: function getAvcDecryptedUnit(decodedData, decryptedData) {
+ decryptedData = new Uint8Array(decryptedData);
+ var inputPos = 0;
+ for (var outputPos = 32; outputPos <= decodedData.length - 16; outputPos += 160, inputPos += 16) {
+ decodedData.set(decryptedData.subarray(inputPos, inputPos + 16), outputPos);
+ }
+ return decodedData;
+ }
+ }, {
+ key: 'decryptAvcSample',
+ value: function decryptAvcSample(samples, sampleIndex, unitIndex, callback, curUnit, sync) {
+ var decodedData = this.discardEPB(curUnit.data);
+ var encryptedData = this.getAvcEncryptedData(decodedData);
+ var localthis = this;
+
+ this.decryptBuffer(encryptedData.buffer, function (decryptedData) {
+ curUnit.data = localthis.getAvcDecryptedUnit(decodedData, decryptedData);
+
+ if (!sync) {
+ localthis.decryptAvcSamples(samples, sampleIndex, unitIndex + 1, callback);
+ }
+ });
+ }
+ }, {
+ key: 'decryptAvcSamples',
+ value: function decryptAvcSamples(samples, sampleIndex, unitIndex, callback) {
+ for (;; sampleIndex++, unitIndex = 0) {
+ if (sampleIndex >= samples.length) {
+ callback();
+ return;
+ }
+
+ var curUnits = samples[sampleIndex].units;
+ for (;; unitIndex++) {
+ if (unitIndex >= curUnits.length) {
+ break;
+ }
+
+ var curUnit = curUnits[unitIndex];
+ if (curUnit.length <= 48 || curUnit.type !== 1 && curUnit.type !== 5) {
+ continue;
+ }
+
+ var sync = this.decrypter.isSync();
+
+ this.decryptAvcSample(samples, sampleIndex, unitIndex, callback, curUnit, sync);
+
+ if (!sync) {
+ return;
+ }
+ }
+ }
+ }
+ }]);
+
+ return SampleAesDecrypter;
+}();
+
+exports.default = SampleAesDecrypter;
+
+},{"18":18}],29:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
+ * highly optimized TS demuxer:
+ * parse PAT, PMT
+ * extract PES packet from audio and video PIDs
+ * extract AVC/H264 NAL units and AAC/ADTS samples from PES packet
+ * trigger the remuxer upon parsing completion
+ * it also tries to workaround as best as it can audio codec switch (HE-AAC to AAC and vice versa), without having to restart the MediaSource.
+ * it also controls the remuxing process :
+ * upon discontinuity or level switch detection, it will also notifies the remuxer so that it can reset its state.
+ */
+
+// import Hex from '../utils/hex';
+
+
+var _adts = _dereq_(21);
+
+var _adts2 = _interopRequireDefault(_adts);
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _expGolomb = _dereq_(25);
+
+var _expGolomb2 = _interopRequireDefault(_expGolomb);
+
+var _sampleAes = _dereq_(28);
+
+var _sampleAes2 = _interopRequireDefault(_sampleAes);
+
+var _logger = _dereq_(50);
+
+var _errors = _dereq_(30);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var TSDemuxer = function () {
+ function TSDemuxer(observer, remuxer, config, typeSupported) {
+ _classCallCheck(this, TSDemuxer);
+
+ this.observer = observer;
+ this.config = config;
+ this.typeSupported = typeSupported;
+ this.remuxer = remuxer;
+ this.sampleAes = null;
+ }
+
+ _createClass(TSDemuxer, [{
+ key: 'setDecryptData',
+ value: function setDecryptData(decryptdata) {
+ if (decryptdata != null && decryptdata.key != null && decryptdata.method === 'SAMPLE-AES') {
+ this.sampleAes = new _sampleAes2.default(this.observer, this.config, decryptdata, this.discardEPB);
+ } else {
+ this.sampleAes = null;
+ }
+ }
+ }, {
+ key: 'resetInitSegment',
+ value: function resetInitSegment(initSegment, audioCodec, videoCodec, duration) {
+ this.pmtParsed = false;
+ this._pmtId = -1;
+ this._avcTrack = { container: 'video/mp2t', type: 'video', id: -1, inputTimeScale: 90000, sequenceNumber: 0, samples: [], len: 0, dropped: 0 };
+ this._audioTrack = { container: 'video/mp2t', type: 'audio', id: -1, inputTimeScale: 90000, sequenceNumber: 0, samples: [], len: 0, isAAC: true };
+ this._id3Track = { type: 'id3', id: -1, inputTimeScale: 90000, sequenceNumber: 0, samples: [], len: 0 };
+ this._txtTrack = { type: 'text', id: -1, inputTimeScale: 90000, sequenceNumber: 0, samples: [], len: 0 };
+ // flush any partial content
+ this.aacOverFlow = null;
+ this.aacLastPTS = null;
+ this.avcSample = null;
+ this.audioCodec = audioCodec;
+ this.videoCodec = videoCodec;
+ this._duration = duration;
+ }
+ }, {
+ key: 'resetTimeStamp',
+ value: function resetTimeStamp() {}
+
+ // feed incoming data to the front of the parsing pipeline
+
+ }, {
+ key: 'append',
+ value: function append(data, timeOffset, contiguous, accurateTimeOffset) {
+ var start,
+ len = data.length,
+ stt,
+ pid,
+ atf,
+ offset,
+ pes,
+ unknownPIDs = false;
+ this.contiguous = contiguous;
+ var pmtParsed = this.pmtParsed,
+ avcTrack = this._avcTrack,
+ audioTrack = this._audioTrack,
+ id3Track = this._id3Track,
+ avcId = avcTrack.id,
+ audioId = audioTrack.id,
+ id3Id = id3Track.id,
+ pmtId = this._pmtId,
+ avcData = avcTrack.pesData,
+ audioData = audioTrack.pesData,
+ id3Data = id3Track.pesData,
+ parsePAT = this._parsePAT,
+ parsePMT = this._parsePMT,
+ parsePES = this._parsePES,
+ parseAVCPES = this._parseAVCPES.bind(this),
+ parseAACPES = this._parseAACPES.bind(this),
+ parseMPEGPES = this._parseMPEGPES.bind(this),
+ parseID3PES = this._parseID3PES.bind(this);
+
+ // don't parse last TS packet if incomplete
+ len -= len % 188;
+ // loop through TS packets
+ for (start = 0; start < len; start += 188) {
+ if (data[start] === 0x47) {
+ stt = !!(data[start + 1] & 0x40);
+ // pid is a 13-bit field starting at the last bit of TS[1]
+ pid = ((data[start + 1] & 0x1f) << 8) + data[start + 2];
+ atf = (data[start + 3] & 0x30) >> 4;
+ // if an adaption field is present, its length is specified by the fifth byte of the TS packet header.
+ if (atf > 1) {
+ offset = start + 5 + data[start + 4];
+ // continue if there is only adaptation field
+ if (offset === start + 188) {
+ continue;
+ }
+ } else {
+ offset = start + 4;
+ }
+ switch (pid) {
+ case avcId:
+ if (stt) {
+ if (avcData && (pes = parsePES(avcData))) {
+ parseAVCPES(pes, false);
+ }
+ avcData = { data: [], size: 0 };
+ }
+ if (avcData) {
+ avcData.data.push(data.subarray(offset, start + 188));
+ avcData.size += start + 188 - offset;
+ }
+ break;
+ case audioId:
+ if (stt) {
+ if (audioData && (pes = parsePES(audioData))) {
+ if (audioTrack.isAAC) {
+ parseAACPES(pes);
+ } else {
+ parseMPEGPES(pes);
+ }
+ }
+ audioData = { data: [], size: 0 };
+ }
+ if (audioData) {
+ audioData.data.push(data.subarray(offset, start + 188));
+ audioData.size += start + 188 - offset;
+ }
+ break;
+ case id3Id:
+ if (stt) {
+ if (id3Data && (pes = parsePES(id3Data))) {
+ parseID3PES(pes);
+ }
+ id3Data = { data: [], size: 0 };
+ }
+ if (id3Data) {
+ id3Data.data.push(data.subarray(offset, start + 188));
+ id3Data.size += start + 188 - offset;
+ }
+ break;
+ case 0:
+ if (stt) {
+ offset += data[offset] + 1;
+ }
+ pmtId = this._pmtId = parsePAT(data, offset);
+ break;
+ case pmtId:
+ if (stt) {
+ offset += data[offset] + 1;
+ }
+ var parsedPIDs = parsePMT(data, offset, this.typeSupported.mpeg === true || this.typeSupported.mp3 === true, this.sampleAes != null);
+
+ // only update track id if track PID found while parsing PMT
+ // this is to avoid resetting the PID to -1 in case
+ // track PID transiently disappears from the stream
+ // this could happen in case of transient missing audio samples for example
+ avcId = parsedPIDs.avc;
+ if (avcId > 0) {
+ avcTrack.id = avcId;
+ }
+ audioId = parsedPIDs.audio;
+ if (audioId > 0) {
+ audioTrack.id = audioId;
+ audioTrack.isAAC = parsedPIDs.isAAC;
+ }
+ id3Id = parsedPIDs.id3;
+ if (id3Id > 0) {
+ id3Track.id = id3Id;
+ }
+ if (unknownPIDs && !pmtParsed) {
+ _logger.logger.log('reparse from beginning');
+ unknownPIDs = false;
+ // we set it to -188, the += 188 in the for loop will reset start to 0
+ start = -188;
+ }
+ pmtParsed = this.pmtParsed = true;
+ break;
+ case 17:
+ case 0x1fff:
+ break;
+ default:
+ unknownPIDs = true;
+ break;
+ }
+ } else {
+ this.observer.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.FRAG_PARSING_ERROR, fatal: false, reason: 'TS packet did not start with 0x47' });
+ }
+ }
+ // try to parse last PES packets
+ if (avcData && (pes = parsePES(avcData))) {
+ parseAVCPES(pes, true);
+ avcTrack.pesData = null;
+ } else {
+ // either avcData null or PES truncated, keep it for next frag parsing
+ avcTrack.pesData = avcData;
+ }
+
+ if (audioData && (pes = parsePES(audioData))) {
+ if (audioTrack.isAAC) {
+ parseAACPES(pes);
+ } else {
+ parseMPEGPES(pes);
+ }
+ audioTrack.pesData = null;
+ } else {
+ if (audioData && audioData.size) {
+ _logger.logger.log('last AAC PES packet truncated,might overlap between fragments');
+ }
+ // either audioData null or PES truncated, keep it for next frag parsing
+ audioTrack.pesData = audioData;
+ }
+
+ if (id3Data && (pes = parsePES(id3Data))) {
+ parseID3PES(pes);
+ id3Track.pesData = null;
+ } else {
+ // either id3Data null or PES truncated, keep it for next frag parsing
+ id3Track.pesData = id3Data;
+ }
+
+ if (this.sampleAes == null) {
+ this.remuxer.remux(audioTrack, avcTrack, id3Track, this._txtTrack, timeOffset, contiguous, accurateTimeOffset);
+ } else {
+ this.decryptAndRemux(audioTrack, avcTrack, id3Track, this._txtTrack, timeOffset, contiguous, accurateTimeOffset);
+ }
+ }
+ }, {
+ key: 'decryptAndRemux',
+ value: function decryptAndRemux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset) {
+ if (audioTrack.samples && audioTrack.isAAC) {
+ var localthis = this;
+ this.sampleAes.decryptAacSamples(audioTrack.samples, 0, function () {
+ localthis.decryptAndRemuxAvc(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset);
+ });
+ } else {
+ this.decryptAndRemuxAvc(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset);
+ }
+ }
+ }, {
+ key: 'decryptAndRemuxAvc',
+ value: function decryptAndRemuxAvc(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset) {
+ if (videoTrack.samples) {
+ var localthis = this;
+ this.sampleAes.decryptAvcSamples(videoTrack.samples, 0, 0, function () {
+ localthis.remuxer.remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset);
+ });
+ } else {
+ this.remuxer.remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset);
+ }
+ }
+ }, {
+ key: 'destroy',
+ value: function destroy() {
+ this._initPTS = this._initDTS = undefined;
+ this._duration = 0;
+ }
+ }, {
+ key: '_parsePAT',
+ value: function _parsePAT(data, offset) {
+ // skip the PSI header and parse the first PMT entry
+ return (data[offset + 10] & 0x1F) << 8 | data[offset + 11];
+ //logger.log('PMT PID:' + this._pmtId);
+ }
+ }, {
+ key: '_parsePMT',
+ value: function _parsePMT(data, offset, mpegSupported, isSampleAes) {
+ var sectionLength,
+ tableEnd,
+ programInfoLength,
+ pid,
+ result = { audio: -1, avc: -1, id3: -1, isAAC: true };
+ sectionLength = (data[offset + 1] & 0x0f) << 8 | data[offset + 2];
+ tableEnd = offset + 3 + sectionLength - 4;
+ // to determine where the table is, we have to figure out how
+ // long the program info descriptors are
+ programInfoLength = (data[offset + 10] & 0x0f) << 8 | data[offset + 11];
+ // advance the offset to the first entry in the mapping table
+ offset += 12 + programInfoLength;
+ while (offset < tableEnd) {
+ pid = (data[offset + 1] & 0x1F) << 8 | data[offset + 2];
+ switch (data[offset]) {
+ case 0xcf:
+ // SAMPLE-AES AAC
+ if (!isSampleAes) {
+ _logger.logger.log('unkown stream type:' + data[offset]);
+ break;
+ }
+ /* falls through */
+
+ // ISO/IEC 13818-7 ADTS AAC (MPEG-2 lower bit-rate audio)
+ case 0x0f:
+ //logger.log('AAC PID:' + pid);
+ if (result.audio === -1) {
+ result.audio = pid;
+ }
+ break;
+
+ // Packetized metadata (ID3)
+ case 0x15:
+ //logger.log('ID3 PID:' + pid);
+ if (result.id3 === -1) {
+ result.id3 = pid;
+ }
+ break;
+
+ case 0xdb:
+ // SAMPLE-AES AVC
+ if (!isSampleAes) {
+ _logger.logger.log('unkown stream type:' + data[offset]);
+ break;
+ }
+ /* falls through */
+
+ // ITU-T Rec. H.264 and ISO/IEC 14496-10 (lower bit-rate video)
+ case 0x1b:
+ //logger.log('AVC PID:' + pid);
+ if (result.avc === -1) {
+ result.avc = pid;
+ }
+ break;
+
+ // ISO/IEC 11172-3 (MPEG-1 audio)
+ // or ISO/IEC 13818-3 (MPEG-2 halved sample rate audio)
+ case 0x03:
+ case 0x04:
+ //logger.log('MPEG PID:' + pid);
+ if (!mpegSupported) {
+ _logger.logger.log('MPEG audio found, not supported in this browser for now');
+ } else if (result.audio === -1) {
+ result.audio = pid;
+ result.isAAC = false;
+ }
+ break;
+
+ case 0x24:
+ _logger.logger.warn('HEVC stream type found, not supported for now');
+ break;
+
+ default:
+ _logger.logger.log('unkown stream type:' + data[offset]);
+ break;
+ }
+ // move to the next table entry
+ // skip past the elementary stream descriptors, if present
+ offset += ((data[offset + 3] & 0x0F) << 8 | data[offset + 4]) + 5;
+ }
+ return result;
+ }
+ }, {
+ key: '_parsePES',
+ value: function _parsePES(stream) {
+ var i = 0,
+ frag,
+ pesFlags,
+ pesPrefix,
+ pesLen,
+ pesHdrLen,
+ pesData,
+ pesPts,
+ pesDts,
+ payloadStartOffset,
+ data = stream.data;
+ // safety check
+ if (!stream || stream.size === 0) {
+ return null;
+ }
+
+ // we might need up to 19 bytes to read PES header
+ // if first chunk of data is less than 19 bytes, let's merge it with following ones until we get 19 bytes
+ // usually only one merge is needed (and this is rare ...)
+ while (data[0].length < 19 && data.length > 1) {
+ var newData = new Uint8Array(data[0].length + data[1].length);
+ newData.set(data[0]);
+ newData.set(data[1], data[0].length);
+ data[0] = newData;
+ data.splice(1, 1);
+ }
+ //retrieve PTS/DTS from first fragment
+ frag = data[0];
+ pesPrefix = (frag[0] << 16) + (frag[1] << 8) + frag[2];
+ if (pesPrefix === 1) {
+ pesLen = (frag[4] << 8) + frag[5];
+ // if PES parsed length is not zero and greater than total received length, stop parsing. PES might be truncated
+ // minus 6 : PES header size
+ if (pesLen && pesLen > stream.size - 6) {
+ return null;
+ }
+ pesFlags = frag[7];
+ if (pesFlags & 0xC0) {
+ /* PES header described here : http://dvd.sourceforge.net/dvdinfo/pes-hdr.html
+ as PTS / DTS is 33 bit we cannot use bitwise operator in JS,
+ as Bitwise operators treat their operands as a sequence of 32 bits */
+ pesPts = (frag[9] & 0x0E) * 536870912 + // 1 << 29
+ (frag[10] & 0xFF) * 4194304 + // 1 << 22
+ (frag[11] & 0xFE) * 16384 + // 1 << 14
+ (frag[12] & 0xFF) * 128 + // 1 << 7
+ (frag[13] & 0xFE) / 2;
+ // check if greater than 2^32 -1
+ if (pesPts > 4294967295) {
+ // decrement 2^33
+ pesPts -= 8589934592;
+ }
+ if (pesFlags & 0x40) {
+ pesDts = (frag[14] & 0x0E) * 536870912 + // 1 << 29
+ (frag[15] & 0xFF) * 4194304 + // 1 << 22
+ (frag[16] & 0xFE) * 16384 + // 1 << 14
+ (frag[17] & 0xFF) * 128 + // 1 << 7
+ (frag[18] & 0xFE) / 2;
+ // check if greater than 2^32 -1
+ if (pesDts > 4294967295) {
+ // decrement 2^33
+ pesDts -= 8589934592;
+ }
+ if (pesPts - pesDts > 60 * 90000) {
+ _logger.logger.warn(Math.round((pesPts - pesDts) / 90000) + 's delta between PTS and DTS, align them');
+ pesPts = pesDts;
+ }
+ } else {
+ pesDts = pesPts;
+ }
+ }
+ pesHdrLen = frag[8];
+ // 9 bytes : 6 bytes for PES header + 3 bytes for PES extension
+ payloadStartOffset = pesHdrLen + 9;
+
+ stream.size -= payloadStartOffset;
+ //reassemble PES packet
+ pesData = new Uint8Array(stream.size);
+ for (var j = 0, dataLen = data.length; j < dataLen; j++) {
+ frag = data[j];
+ var len = frag.byteLength;
+ if (payloadStartOffset) {
+ if (payloadStartOffset > len) {
+ // trim full frag if PES header bigger than frag
+ payloadStartOffset -= len;
+ continue;
+ } else {
+ // trim partial frag if PES header smaller than frag
+ frag = frag.subarray(payloadStartOffset);
+ len -= payloadStartOffset;
+ payloadStartOffset = 0;
+ }
+ }
+ pesData.set(frag, i);
+ i += len;
+ }
+ if (pesLen) {
+ // payload size : remove PES header + PES extension
+ pesLen -= pesHdrLen + 3;
+ }
+ return { data: pesData, pts: pesPts, dts: pesDts, len: pesLen };
+ } else {
+ return null;
+ }
+ }
+ }, {
+ key: 'pushAccesUnit',
+ value: function pushAccesUnit(avcSample, avcTrack) {
+ if (avcSample.units.length && avcSample.frame) {
+ var samples = avcTrack.samples;
+ var nbSamples = samples.length;
+ // only push AVC sample if starting with a keyframe is not mandatory OR
+ // if keyframe already found in this fragment OR
+ // keyframe found in last fragment (track.sps) AND
+ // samples already appended (we already found a keyframe in this fragment) OR fragment is contiguous
+ if (!this.config.forceKeyFrameOnDiscontinuity || avcSample.key === true || avcTrack.sps && (nbSamples || this.contiguous)) {
+ avcSample.id = nbSamples;
+ samples.push(avcSample);
+ } else {
+ // dropped samples, track it
+ avcTrack.dropped++;
+ }
+ }
+ if (avcSample.debug.length) {
+ _logger.logger.log(avcSample.pts + '/' + avcSample.dts + ':' + avcSample.debug);
+ }
+ }
+ }, {
+ key: '_parseAVCPES',
+ value: function _parseAVCPES(pes, last) {
+ var _this = this;
+
+ //logger.log('parse new PES');
+ var track = this._avcTrack,
+ units = this._parseAVCNALu(pes.data),
+ debug = false,
+ expGolombDecoder,
+ avcSample = this.avcSample,
+ push,
+ i;
+ //free pes.data to save up some memory
+ pes.data = null;
+
+ units.forEach(function (unit) {
+ switch (unit.type) {
+ //NDR
+ case 1:
+ push = true;
+ if (debug && avcSample) {
+ avcSample.debug += 'NDR ';
+ }
+ avcSample.frame = true;
+ // retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR
+ var data = unit.data;
+ if (data.length > 4) {
+ var sliceType = new _expGolomb2.default(data).readSliceType();
+ // 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice
+ // SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples.
+ // An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice.
+ // I slice: A slice that is not an SI slice that is decoded using intra prediction only.
+ //if (sliceType === 2 || sliceType === 7) {
+ if (sliceType === 2 || sliceType === 4 || sliceType === 7 || sliceType === 9) {
+ avcSample.key = true;
+ }
+ }
+ break;
+ //IDR
+ case 5:
+ push = true;
+ // handle PES not starting with AUD
+ if (!avcSample) {
+ avcSample = _this.avcSample = _this._createAVCSample(true, pes.pts, pes.dts, '');
+ }
+ if (debug) {
+ avcSample.debug += 'IDR ';
+ }
+ avcSample.key = true;
+ avcSample.frame = true;
+ break;
+ //SEI
+ case 6:
+ push = true;
+ if (debug && avcSample) {
+ avcSample.debug += 'SEI ';
+ }
+ expGolombDecoder = new _expGolomb2.default(_this.discardEPB(unit.data));
+
+ // skip frameType
+ expGolombDecoder.readUByte();
+
+ var payloadType = 0;
+ var payloadSize = 0;
+ var endOfCaptions = false;
+ var b = 0;
+
+ while (!endOfCaptions && expGolombDecoder.bytesAvailable > 1) {
+ payloadType = 0;
+ do {
+ b = expGolombDecoder.readUByte();
+ payloadType += b;
+ } while (b === 0xFF);
+
+ // Parse payload size.
+ payloadSize = 0;
+ do {
+ b = expGolombDecoder.readUByte();
+ payloadSize += b;
+ } while (b === 0xFF);
+
+ // TODO: there can be more than one payload in an SEI packet...
+ // TODO: need to read type and size in a while loop to get them all
+ if (payloadType === 4 && expGolombDecoder.bytesAvailable !== 0) {
+
+ endOfCaptions = true;
+
+ var countryCode = expGolombDecoder.readUByte();
+
+ if (countryCode === 181) {
+ var providerCode = expGolombDecoder.readUShort();
+
+ if (providerCode === 49) {
+ var userStructure = expGolombDecoder.readUInt();
+
+ if (userStructure === 0x47413934) {
+ var userDataType = expGolombDecoder.readUByte();
+
+ // Raw CEA-608 bytes wrapped in CEA-708 packet
+ if (userDataType === 3) {
+ var firstByte = expGolombDecoder.readUByte();
+ var secondByte = expGolombDecoder.readUByte();
+
+ var totalCCs = 31 & firstByte;
+ var byteArray = [firstByte, secondByte];
+
+ for (i = 0; i < totalCCs; i++) {
+ // 3 bytes per CC
+ byteArray.push(expGolombDecoder.readUByte());
+ byteArray.push(expGolombDecoder.readUByte());
+ byteArray.push(expGolombDecoder.readUByte());
+ }
+
+ _this._insertSampleInOrder(_this._txtTrack.samples, { type: 3, pts: pes.pts, bytes: byteArray });
+ }
+ }
+ }
+ }
+ } else if (payloadSize < expGolombDecoder.bytesAvailable) {
+ for (i = 0; i < payloadSize; i++) {
+ expGolombDecoder.readUByte();
+ }
+ }
+ }
+ break;
+ //SPS
+ case 7:
+ push = true;
+ if (debug && avcSample) {
+ avcSample.debug += 'SPS ';
+ }
+ if (!track.sps) {
+ expGolombDecoder = new _expGolomb2.default(unit.data);
+ var config = expGolombDecoder.readSPS();
+ track.width = config.width;
+ track.height = config.height;
+ track.pixelRatio = config.pixelRatio;
+ track.sps = [unit.data];
+ track.duration = _this._duration;
+ var codecarray = unit.data.subarray(1, 4);
+ var codecstring = 'avc1.';
+ for (i = 0; i < 3; i++) {
+ var h = codecarray[i].toString(16);
+ if (h.length < 2) {
+ h = '0' + h;
+ }
+ codecstring += h;
+ }
+ track.codec = codecstring;
+ }
+ break;
+ //PPS
+ case 8:
+ push = true;
+ if (debug && avcSample) {
+ avcSample.debug += 'PPS ';
+ }
+ if (!track.pps) {
+ track.pps = [unit.data];
+ }
+ break;
+ // AUD
+ case 9:
+ push = false;
+ if (avcSample) {
+ _this.pushAccesUnit(avcSample, track);
+ }
+ avcSample = _this.avcSample = _this._createAVCSample(false, pes.pts, pes.dts, debug ? 'AUD ' : '');
+ break;
+ // Filler Data
+ case 12:
+ push = false;
+ break;
+ default:
+ push = false;
+ if (avcSample) {
+ avcSample.debug += 'unknown NAL ' + unit.type + ' ';
+ }
+ break;
+ }
+ if (avcSample && push) {
+ var _units = avcSample.units;
+ _units.push(unit);
+ }
+ });
+ // if last PES packet, push samples
+ if (last && avcSample) {
+ this.pushAccesUnit(avcSample, track);
+ this.avcSample = null;
+ }
+ }
+ }, {
+ key: '_createAVCSample',
+ value: function _createAVCSample(key, pts, dts, debug) {
+ return { key: key, pts: pts, dts: dts, units: [], debug: debug };
+ }
+ }, {
+ key: '_insertSampleInOrder',
+ value: function _insertSampleInOrder(arr, data) {
+ var len = arr.length;
+ if (len > 0) {
+ if (data.pts >= arr[len - 1].pts) {
+ arr.push(data);
+ } else {
+ for (var pos = len - 1; pos >= 0; pos--) {
+ if (data.pts < arr[pos].pts) {
+ arr.splice(pos, 0, data);
+ break;
+ }
+ }
+ }
+ } else {
+ arr.push(data);
+ }
+ }
+ }, {
+ key: '_getLastNalUnit',
+ value: function _getLastNalUnit() {
+ var avcSample = this.avcSample,
+ lastUnit = void 0;
+ // try to fallback to previous sample if current one is empty
+ if (!avcSample || avcSample.units.length === 0) {
+ var track = this._avcTrack,
+ samples = track.samples;
+ avcSample = samples[samples.length - 1];
+ }
+ if (avcSample) {
+ var units = avcSample.units;
+ lastUnit = units[units.length - 1];
+ }
+ return lastUnit;
+ }
+ }, {
+ key: '_parseAVCNALu',
+ value: function _parseAVCNALu(array) {
+ var i = 0,
+ len = array.byteLength,
+ value,
+ overflow,
+ track = this._avcTrack,
+ state = track.naluState || 0,
+ lastState = state;
+ var units = [],
+ unit,
+ unitType,
+ lastUnitStart = -1,
+ lastUnitType;
+ //logger.log('PES:' + Hex.hexDump(array));
+
+ if (state === -1) {
+ // special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet
+ lastUnitStart = 0;
+ // NALu type is value read from offset 0
+ lastUnitType = array[0] & 0x1f;
+ state = 0;
+ i = 1;
+ }
+
+ while (i < len) {
+ value = array[i++];
+ // optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case
+ if (!state) {
+ state = value ? 0 : 1;
+ continue;
+ }
+ if (state === 1) {
+ state = value ? 0 : 2;
+ continue;
+ }
+ // here we have state either equal to 2 or 3
+ if (!value) {
+ state = 3;
+ } else if (value === 1) {
+ if (lastUnitStart >= 0) {
+ unit = { data: array.subarray(lastUnitStart, i - state - 1), type: lastUnitType };
+ //logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);
+ units.push(unit);
+ } else {
+ // lastUnitStart is undefined => this is the first start code found in this PES packet
+ // first check if start code delimiter is overlapping between 2 PES packets,
+ // ie it started in last packet (lastState not zero)
+ // and ended at the beginning of this PES packet (i <= 4 - lastState)
+ var lastUnit = this._getLastNalUnit();
+ if (lastUnit) {
+ if (lastState && i <= 4 - lastState) {
+ // start delimiter overlapping between PES packets
+ // strip start delimiter bytes from the end of last NAL unit
+ // check if lastUnit had a state different from zero
+ if (lastUnit.state) {
+ // strip last bytes
+ lastUnit.data = lastUnit.data.subarray(0, lastUnit.data.byteLength - lastState);
+ }
+ }
+ // If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.
+ overflow = i - state - 1;
+ if (overflow > 0) {
+ //logger.log('first NALU found with overflow:' + overflow);
+ var tmp = new Uint8Array(lastUnit.data.byteLength + overflow);
+ tmp.set(lastUnit.data, 0);
+ tmp.set(array.subarray(0, overflow), lastUnit.data.byteLength);
+ lastUnit.data = tmp;
+ }
+ }
+ }
+ // check if we can read unit type
+ if (i < len) {
+ unitType = array[i] & 0x1f;
+ //logger.log('find NALU @ offset:' + i + ',type:' + unitType);
+ lastUnitStart = i;
+ lastUnitType = unitType;
+ state = 0;
+ } else {
+ // not enough byte to read unit type. let's read it on next PES parsing
+ state = -1;
+ }
+ } else {
+ state = 0;
+ }
+ }
+ if (lastUnitStart >= 0 && state >= 0) {
+ unit = { data: array.subarray(lastUnitStart, len), type: lastUnitType, state: state };
+ units.push(unit);
+ //logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);
+ }
+ // no NALu found
+ if (units.length === 0) {
+ // append pes.data to previous NAL unit
+ var _lastUnit = this._getLastNalUnit();
+ if (_lastUnit) {
+ var _tmp = new Uint8Array(_lastUnit.data.byteLength + array.byteLength);
+ _tmp.set(_lastUnit.data, 0);
+ _tmp.set(array, _lastUnit.data.byteLength);
+ _lastUnit.data = _tmp;
+ }
+ }
+ track.naluState = state;
+ return units;
+ }
+
+ /**
+ * remove Emulation Prevention bytes from a RBSP
+ */
+
+ }, {
+ key: 'discardEPB',
+ value: function discardEPB(data) {
+ var length = data.byteLength,
+ EPBPositions = [],
+ i = 1,
+ newLength,
+ newData;
+
+ // Find all `Emulation Prevention Bytes`
+ while (i < length - 2) {
+ if (data[i] === 0 && data[i + 1] === 0 && data[i + 2] === 0x03) {
+ EPBPositions.push(i + 2);
+ i += 2;
+ } else {
+ i++;
+ }
+ }
+
+ // If no Emulation Prevention Bytes were found just return the original
+ // array
+ if (EPBPositions.length === 0) {
+ return data;
+ }
+
+ // Create a new array to hold the NAL unit data
+ newLength = length - EPBPositions.length;
+ newData = new Uint8Array(newLength);
+ var sourceIndex = 0;
+
+ for (i = 0; i < newLength; sourceIndex++, i++) {
+ if (sourceIndex === EPBPositions[0]) {
+ // Skip this byte
+ sourceIndex++;
+ // Remove this position index
+ EPBPositions.shift();
+ }
+ newData[i] = data[sourceIndex];
+ }
+ return newData;
+ }
+ }, {
+ key: '_parseAACPES',
+ value: function _parseAACPES(pes) {
+ var track = this._audioTrack,
+ data = pes.data,
+ pts = pes.pts,
+ startOffset = 0,
+ aacOverFlow = this.aacOverFlow,
+ aacLastPTS = this.aacLastPTS,
+ config,
+ frameLength,
+ frameDuration,
+ frameIndex,
+ offset,
+ headerLength,
+ stamp,
+ len,
+ aacSample;
+ if (aacOverFlow) {
+ var tmp = new Uint8Array(aacOverFlow.byteLength + data.byteLength);
+ tmp.set(aacOverFlow, 0);
+ tmp.set(data, aacOverFlow.byteLength);
+ //logger.log(`AAC: append overflowing ${aacOverFlow.byteLength} bytes to beginning of new PES`);
+ data = tmp;
+ }
+ // look for ADTS header (0xFFFx)
+ for (offset = startOffset, len = data.length; offset < len - 1; offset++) {
+ if (data[offset] === 0xff && (data[offset + 1] & 0xf0) === 0xf0) {
+ break;
+ }
+ }
+ // if ADTS header does not start straight from the beginning of the PES payload, raise an error
+ if (offset) {
+ var reason, fatal;
+ if (offset < len - 1) {
+ reason = 'AAC PES did not start with ADTS header,offset:' + offset;
+ fatal = false;
+ } else {
+ reason = 'no ADTS header found in AAC PES';
+ fatal = true;
+ }
+ _logger.logger.warn('parsing error:' + reason);
+ this.observer.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.FRAG_PARSING_ERROR, fatal: fatal, reason: reason });
+ if (fatal) {
+ return;
+ }
+ }
+ if (!track.samplerate) {
+ var audioCodec = this.audioCodec;
+ config = _adts2.default.getAudioConfig(this.observer, data, offset, audioCodec);
+ track.config = config.config;
+ track.samplerate = config.samplerate;
+ track.channelCount = config.channelCount;
+ track.codec = config.codec;
+ track.manifestCodec = config.manifestCodec;
+ track.duration = this._duration;
+ _logger.logger.log('parsed codec:' + track.codec + ',rate:' + config.samplerate + ',nb channel:' + config.channelCount);
+ }
+ frameIndex = 0;
+ frameDuration = 1024 * 90000 / track.samplerate;
+
+ // if last AAC frame is overflowing, we should ensure timestamps are contiguous:
+ // first sample PTS should be equal to last sample PTS + frameDuration
+ if (aacOverFlow && aacLastPTS) {
+ var newPTS = aacLastPTS + frameDuration;
+ if (Math.abs(newPTS - pts) > 1) {
+ _logger.logger.log('AAC: align PTS for overlapping frames by ' + Math.round((newPTS - pts) / 90));
+ pts = newPTS;
+ }
+ }
+
+ while (offset + 5 < len) {
+ // The protection skip bit tells us if we have 2 bytes of CRC data at the end of the ADTS header
+ headerLength = !!(data[offset + 1] & 0x01) ? 7 : 9;
+ // retrieve frame size
+ frameLength = (data[offset + 3] & 0x03) << 11 | data[offset + 4] << 3 | (data[offset + 5] & 0xE0) >>> 5;
+ frameLength -= headerLength;
+ //stamp = pes.pts;
+
+ if (frameLength > 0 && offset + headerLength + frameLength <= len) {
+ stamp = pts + frameIndex * frameDuration;
+ //logger.log(`AAC frame, offset/length/total/pts:${offset+headerLength}/${frameLength}/${data.byteLength}/${(stamp/90).toFixed(0)}`);
+ aacSample = { unit: data.subarray(offset + headerLength, offset + headerLength + frameLength), pts: stamp, dts: stamp };
+ track.samples.push(aacSample);
+ track.len += frameLength;
+ offset += frameLength + headerLength;
+ frameIndex++;
+ // look for ADTS header (0xFFFx)
+ for (; offset < len - 1; offset++) {
+ if (data[offset] === 0xff && (data[offset + 1] & 0xf0) === 0xf0) {
+ break;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ if (offset < len) {
+ aacOverFlow = data.subarray(offset, len);
+ //logger.log(`AAC: overflow detected:${len-offset}`);
+ } else {
+ aacOverFlow = null;
+ }
+ this.aacOverFlow = aacOverFlow;
+ this.aacLastPTS = stamp;
+ }
+ }, {
+ key: '_parseMPEGPES',
+ value: function _parseMPEGPES(pes) {
+ var data = pes.data;
+ var pts = pes.pts;
+ var length = data.length;
+ var frameIndex = 0;
+ var offset = 0;
+ var parsed;
+
+ while (offset < length && (parsed = this._parseMpeg(data, offset, length, frameIndex++, pts)) > 0) {
+ offset += parsed;
+ }
+ }
+ }, {
+ key: '_onMpegFrame',
+ value: function _onMpegFrame(data, bitRate, sampleRate, channelCount, frameIndex, pts) {
+ var frameDuration = 1152 / sampleRate * 1000;
+ var stamp = pts + frameIndex * frameDuration;
+ var track = this._audioTrack;
+
+ track.config = [];
+ track.channelCount = channelCount;
+ track.samplerate = sampleRate;
+ track.duration = this._duration;
+ track.samples.push({ unit: data, pts: stamp, dts: stamp });
+ track.len += data.length;
+ }
+ }, {
+ key: '_onMpegNoise',
+ value: function _onMpegNoise(data) {
+ _logger.logger.warn('mpeg audio has noise: ' + data.length + ' bytes');
+ }
+ }, {
+ key: '_parseMpeg',
+ value: function _parseMpeg(data, start, end, frameIndex, pts) {
+ var BitratesMap = [32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160];
+ var SamplingRateMap = [44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000];
+
+ if (start + 2 > end) {
+ return -1; // we need at least 2 bytes to detect sync pattern
+ }
+ if (data[start] === 0xFF || (data[start + 1] & 0xE0) === 0xE0) {
+ // Using http://www.datavoyage.com/mpgscript/mpeghdr.htm as a reference
+ if (start + 24 > end) {
+ return -1;
+ }
+ var headerB = data[start + 1] >> 3 & 3;
+ var headerC = data[start + 1] >> 1 & 3;
+ var headerE = data[start + 2] >> 4 & 15;
+ var headerF = data[start + 2] >> 2 & 3;
+ var headerG = !!(data[start + 2] & 2);
+ if (headerB !== 1 && headerE !== 0 && headerE !== 15 && headerF !== 3) {
+ var columnInBitrates = headerB === 3 ? 3 - headerC : headerC === 3 ? 3 : 4;
+ var bitRate = BitratesMap[columnInBitrates * 14 + headerE - 1] * 1000;
+ var columnInSampleRates = headerB === 3 ? 0 : headerB === 2 ? 1 : 2;
+ var sampleRate = SamplingRateMap[columnInSampleRates * 3 + headerF];
+ var padding = headerG ? 1 : 0;
+ var channelCount = data[start + 3] >> 6 === 3 ? 1 : 2; // If bits of channel mode are `11` then it is a single channel (Mono)
+ var frameLength = headerC === 3 ? (headerB === 3 ? 12 : 6) * bitRate / sampleRate + padding << 2 : (headerB === 3 ? 144 : 72) * bitRate / sampleRate + padding | 0;
+ if (start + frameLength > end) {
+ return -1;
+ }
+ if (this._onMpegFrame) {
+ this._onMpegFrame(data.subarray(start, start + frameLength), bitRate, sampleRate, channelCount, frameIndex, pts);
+ }
+ return frameLength;
+ }
+ }
+ // noise or ID3, trying to skip
+ var offset = start + 2;
+ while (offset < end) {
+ if (data[offset - 1] === 0xFF && (data[offset] & 0xE0) === 0xE0) {
+ // sync pattern is found
+ if (this._onMpegNoise) {
+ this._onMpegNoise(data.subarray(start, offset - 1));
+ }
+ return offset - start - 1;
+ }
+ offset++;
+ }
+ return -1;
+ }
+ }, {
+ key: '_parseID3PES',
+ value: function _parseID3PES(pes) {
+ this._id3Track.samples.push(pes);
+ }
+ }], [{
+ key: 'probe',
+ value: function probe(data) {
+ // a TS fragment should contain at least 3 TS packets, a PAT, a PMT, and one PID, each starting with 0x47
+ if (data.length >= 3 * 188 && data[0] === 0x47 && data[188] === 0x47 && data[2 * 188] === 0x47) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }]);
+
+ return TSDemuxer;
+}();
+
+exports.default = TSDemuxer;
+
+},{"21":21,"25":25,"28":28,"30":30,"32":32,"50":50}],30:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+var ErrorTypes = exports.ErrorTypes = {
+ // Identifier for a network error (loading error / timeout ...)
+ NETWORK_ERROR: 'networkError',
+ // Identifier for a media Error (video/parsing/mediasource error)
+ MEDIA_ERROR: 'mediaError',
+ // Identifier for a mux Error (demuxing/remuxing)
+ MUX_ERROR: 'muxError',
+ // Identifier for all other errors
+ OTHER_ERROR: 'otherError'
+};
+
+var ErrorDetails = exports.ErrorDetails = {
+ // Identifier for a manifest load error - data: { url : faulty URL, response : { code: error code, text: error text }}
+ MANIFEST_LOAD_ERROR: 'manifestLoadError',
+ // Identifier for a manifest load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}
+ MANIFEST_LOAD_TIMEOUT: 'manifestLoadTimeOut',
+ // Identifier for a manifest parsing error - data: { url : faulty URL, reason : error reason}
+ MANIFEST_PARSING_ERROR: 'manifestParsingError',
+ // Identifier for a manifest with only incompatible codecs error - data: { url : faulty URL, reason : error reason}
+ MANIFEST_INCOMPATIBLE_CODECS_ERROR: 'manifestIncompatibleCodecsError',
+ // Identifier for a level load error - data: { url : faulty URL, response : { code: error code, text: error text }}
+ LEVEL_LOAD_ERROR: 'levelLoadError',
+ // Identifier for a level load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}
+ LEVEL_LOAD_TIMEOUT: 'levelLoadTimeOut',
+ // Identifier for a level switch error - data: { level : faulty level Id, event : error description}
+ LEVEL_SWITCH_ERROR: 'levelSwitchError',
+ // Identifier for an audio track load error - data: { url : faulty URL, response : { code: error code, text: error text }}
+ AUDIO_TRACK_LOAD_ERROR: 'audioTrackLoadError',
+ // Identifier for an audio track load timeout - data: { url : faulty URL, response : { code: error code, text: error text }}
+ AUDIO_TRACK_LOAD_TIMEOUT: 'audioTrackLoadTimeOut',
+ // Identifier for fragment load error - data: { frag : fragment object, response : { code: error code, text: error text }}
+ FRAG_LOAD_ERROR: 'fragLoadError',
+ // Identifier for fragment loop loading error - data: { frag : fragment object}
+ FRAG_LOOP_LOADING_ERROR: 'fragLoopLoadingError',
+ // Identifier for fragment load timeout error - data: { frag : fragment object}
+ FRAG_LOAD_TIMEOUT: 'fragLoadTimeOut',
+ // Identifier for a fragment decryption error event - data: {id : demuxer Id,frag: fragment object, reason : parsing error description }
+ FRAG_DECRYPT_ERROR: 'fragDecryptError',
+ // Identifier for a fragment parsing error event - data: { id : demuxer Id, reason : parsing error description }
+ // will be renamed DEMUX_PARSING_ERROR and switched to MUX_ERROR in the next major release
+ FRAG_PARSING_ERROR: 'fragParsingError',
+ // Identifier for a remux alloc error event - data: { id : demuxer Id, frag : fragment object, bytes : nb of bytes on which allocation failed , reason : error text }
+ REMUX_ALLOC_ERROR: 'remuxAllocError',
+ // Identifier for decrypt key load error - data: { frag : fragment object, response : { code: error code, text: error text }}
+ KEY_LOAD_ERROR: 'keyLoadError',
+ // Identifier for decrypt key load timeout error - data: { frag : fragment object}
+ KEY_LOAD_TIMEOUT: 'keyLoadTimeOut',
+ // Triggered when an exception occurs while adding a sourceBuffer to MediaSource - data : { err : exception , mimeType : mimeType }
+ BUFFER_ADD_CODEC_ERROR: 'bufferAddCodecError',
+ // Identifier for a buffer append error - data: append error description
+ BUFFER_APPEND_ERROR: 'bufferAppendError',
+ // Identifier for a buffer appending error event - data: appending error description
+ BUFFER_APPENDING_ERROR: 'bufferAppendingError',
+ // Identifier for a buffer stalled error event
+ BUFFER_STALLED_ERROR: 'bufferStalledError',
+ // Identifier for a buffer full event
+ BUFFER_FULL_ERROR: 'bufferFullError',
+ // Identifier for a buffer seek over hole event
+ BUFFER_SEEK_OVER_HOLE: 'bufferSeekOverHole',
+ // Identifier for a buffer nudge on stall (playback is stuck although currentTime is in a buffered area)
+ BUFFER_NUDGE_ON_STALL: 'bufferNudgeOnStall',
+ // Identifier for an internal exception happening inside hls.js while handling an event
+ INTERNAL_EXCEPTION: 'internalException',
+ // Malformed WebVTT contents
+ WEBVTT_EXCEPTION: 'webVTTException'
+};
+
+},{}],31:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
+ *
+ * All objects in the event handling chain should inherit from this class
+ *
+ */
+
+var _logger = _dereq_(50);
+
+var _errors = _dereq_(30);
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var EventHandler = function () {
+ function EventHandler(hls) {
+ _classCallCheck(this, EventHandler);
+
+ this.hls = hls;
+ this.onEvent = this.onEvent.bind(this);
+
+ for (var _len = arguments.length, events = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ events[_key - 1] = arguments[_key];
+ }
+
+ this.handledEvents = events;
+ this.useGenericHandler = true;
+
+ this.registerListeners();
+ }
+
+ _createClass(EventHandler, [{
+ key: 'destroy',
+ value: function destroy() {
+ this.unregisterListeners();
+ }
+ }, {
+ key: 'isEventHandler',
+ value: function isEventHandler() {
+ return _typeof(this.handledEvents) === 'object' && this.handledEvents.length && typeof this.onEvent === 'function';
+ }
+ }, {
+ key: 'registerListeners',
+ value: function registerListeners() {
+ if (this.isEventHandler()) {
+ this.handledEvents.forEach(function (event) {
+ if (event === 'hlsEventGeneric') {
+ throw new Error('Forbidden event name: ' + event);
+ }
+ this.hls.on(event, this.onEvent);
+ }.bind(this));
+ }
+ }
+ }, {
+ key: 'unregisterListeners',
+ value: function unregisterListeners() {
+ if (this.isEventHandler()) {
+ this.handledEvents.forEach(function (event) {
+ this.hls.off(event, this.onEvent);
+ }.bind(this));
+ }
+ }
+
+ /**
+ * arguments: event (string), data (any)
+ */
+
+ }, {
+ key: 'onEvent',
+ value: function onEvent(event, data) {
+ this.onEventGeneric(event, data);
+ }
+ }, {
+ key: 'onEventGeneric',
+ value: function onEventGeneric(event, data) {
+ var eventToFunction = function eventToFunction(event, data) {
+ var funcName = 'on' + event.replace('hls', '');
+ if (typeof this[funcName] !== 'function') {
+ throw new Error('Event ' + event + ' has no generic handler in this ' + this.constructor.name + ' class (tried ' + funcName + ')');
+ }
+ return this[funcName].bind(this, data);
+ };
+ try {
+ eventToFunction.call(this, event, data).call();
+ } catch (err) {
+ _logger.logger.error('internal error happened while processing ' + event + ':' + err.message);
+ this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.OTHER_ERROR, details: _errors.ErrorDetails.INTERNAL_EXCEPTION, fatal: false, event: event, err: err });
+ }
+ }
+ }]);
+
+ return EventHandler;
+}();
+
+exports.default = EventHandler;
+
+},{"30":30,"32":32,"50":50}],32:[function(_dereq_,module,exports){
+'use strict';
+
+module.exports = {
+ // fired before MediaSource is attaching to media element - data: { media }
+ MEDIA_ATTACHING: 'hlsMediaAttaching',
+ // fired when MediaSource has been succesfully attached to media element - data: { }
+ MEDIA_ATTACHED: 'hlsMediaAttached',
+ // fired before detaching MediaSource from media element - data: { }
+ MEDIA_DETACHING: 'hlsMediaDetaching',
+ // fired when MediaSource has been detached from media element - data: { }
+ MEDIA_DETACHED: 'hlsMediaDetached',
+ // fired when we buffer is going to be resetted
+ BUFFER_RESET: 'hlsBufferReset',
+ // fired when we know about the codecs that we need buffers for to push into - data: {tracks : { container, codec, levelCodec, initSegment, metadata }}
+ BUFFER_CODECS: 'hlsBufferCodecs',
+ // fired when sourcebuffers have been created data: { tracks : tracks}
+ BUFFER_CREATED: 'hlsBufferCreated',
+ // fired when we append a segment to the buffer - data: { segment: segment object }
+ BUFFER_APPENDING: 'hlsBufferAppending',
+ // fired when we are done with appending a media segment to the buffer data : { parent : segment parent that triggered BUFFER_APPENDING , pending : nb of segments waiting for appending for this segment parent}
+ BUFFER_APPENDED: 'hlsBufferAppended',
+ // fired when the stream is finished and we want to notify the media buffer that there will be no more data
+ BUFFER_EOS: 'hlsBufferEos',
+ // fired when the media buffer should be flushed - data {startOffset, endOffset}
+ BUFFER_FLUSHING: 'hlsBufferFlushing',
+ // fired when the media has been flushed
+ BUFFER_FLUSHED: 'hlsBufferFlushed',
+ // fired to signal that a manifest loading starts - data: { url : manifestURL}
+ MANIFEST_LOADING: 'hlsManifestLoading',
+ // fired after manifest has been loaded - data: { levels : [available quality levels] , audioTracks : [ available audio tracks], url : manifestURL, stats : { trequest, tfirst, tload, mtime}}
+ MANIFEST_LOADED: 'hlsManifestLoaded',
+ // fired after manifest has been parsed - data: { levels : [available quality levels] , firstLevel : index of first quality level appearing in Manifest}
+ MANIFEST_PARSED: 'hlsManifestParsed',
+ // fired when a level switch is requested - data: { level : id of new level } // deprecated in favor LEVEL_SWITCHING
+ LEVEL_SWITCH: 'hlsLevelSwitch',
+ // fired when a level switch is requested - data: { level : id of new level }
+ LEVEL_SWITCHING: 'hlsLevelSwitching',
+ // fired when a level switch is effective - data: { level : id of new level }
+ LEVEL_SWITCHED: 'hlsLevelSwitched',
+ // fired when a level playlist loading starts - data: { url : level URL level : id of level being loaded}
+ LEVEL_LOADING: 'hlsLevelLoading',
+ // fired when a level playlist loading finishes - data: { details : levelDetails object, level : id of loaded level, stats : { trequest, tfirst, tload, mtime} }
+ LEVEL_LOADED: 'hlsLevelLoaded',
+ // fired when a level's details have been updated based on previous details, after it has been loaded. - data: { details : levelDetails object, level : id of updated level }
+ LEVEL_UPDATED: 'hlsLevelUpdated',
+ // fired when a level's PTS information has been updated after parsing a fragment - data: { details : levelDetails object, level : id of updated level, drift: PTS drift observed when parsing last fragment }
+ LEVEL_PTS_UPDATED: 'hlsLevelPtsUpdated',
+ // fired to notify that audio track lists has been updated data: { audioTracks : audioTracks}
+ AUDIO_TRACKS_UPDATED: 'hlsAudioTracksUpdated',
+ // fired when an audio track switch occurs - data: { id : audio track id} // deprecated in favor AUDIO_TRACK_SWITCHING
+ AUDIO_TRACK_SWITCH: 'hlsAudioTrackSwitch',
+ // fired when an audio track switching is requested - data: { id : audio track id}
+ AUDIO_TRACK_SWITCHING: 'hlsAudioTrackSwitching',
+ // fired when an audio track switch actually occurs - data: { id : audio track id}
+ AUDIO_TRACK_SWITCHED: 'hlsAudioTrackSwitched',
+ // fired when an audio track loading starts - data: { url : audio track URL id : audio track id}
+ AUDIO_TRACK_LOADING: 'hlsAudioTrackLoading',
+ // fired when an audio track loading finishes - data: { details : levelDetails object, id : audio track id, stats : { trequest, tfirst, tload, mtime} }
+ AUDIO_TRACK_LOADED: 'hlsAudioTrackLoaded',
+ // fired to notify that subtitle track lists has been updated data: { subtitleTracks : subtitleTracks}
+ SUBTITLE_TRACKS_UPDATED: 'hlsSubtitleTracksUpdated',
+ // fired when an subtitle track switch occurs - data: { id : subtitle track id}
+ SUBTITLE_TRACK_SWITCH: 'hlsSubtitleTrackSwitch',
+ // fired when an subtitle track loading starts - data: { url : subtitle track URL id : subtitle track id}
+ SUBTITLE_TRACK_LOADING: 'hlsSubtitleTrackLoading',
+ // fired when an subtitle track loading finishes - data: { details : levelDetails object, id : subtitle track id, stats : { trequest, tfirst, tload, mtime} }
+ SUBTITLE_TRACK_LOADED: 'hlsSubtitleTrackLoaded',
+ // fired when a subtitle fragment has been processed - data: { success : boolean, frag : the processed frag}
+ SUBTITLE_FRAG_PROCESSED: 'hlsSubtitleFragProcessed',
+ // fired when the first timestamp is found. - data: { id : demuxer id, initPTS: initPTS , frag : fragment object}
+ INIT_PTS_FOUND: 'hlsInitPtsFound',
+ // fired when a fragment loading starts - data: { frag : fragment object}
+ FRAG_LOADING: 'hlsFragLoading',
+ // fired when a fragment loading is progressing - data: { frag : fragment object, { trequest, tfirst, loaded}}
+ FRAG_LOAD_PROGRESS: 'hlsFragLoadProgress',
+ // Identifier for fragment load aborting for emergency switch down - data: {frag : fragment object}
+ FRAG_LOAD_EMERGENCY_ABORTED: 'hlsFragLoadEmergencyAborted',
+ // fired when a fragment loading is completed - data: { frag : fragment object, payload : fragment payload, stats : { trequest, tfirst, tload, length}}
+ FRAG_LOADED: 'hlsFragLoaded',
+ // fired when a fragment has finished decrypting - data: { id : demuxer id, frag: fragment object, stats : {tstart,tdecrypt} }
+ FRAG_DECRYPTED: 'hlsFragDecrypted',
+ // fired when Init Segment has been extracted from fragment - data: { id : demuxer id, frag: fragment object, moov : moov MP4 box, codecs : codecs found while parsing fragment}
+ FRAG_PARSING_INIT_SEGMENT: 'hlsFragParsingInitSegment',
+ // fired when parsing sei text is completed - data: { id : demuxer id, , frag: fragment object, samples : [ sei samples pes ] }
+ FRAG_PARSING_USERDATA: 'hlsFragParsingUserdata',
+ // fired when parsing id3 is completed - data: { id : demuxer id, frag: fragment object, samples : [ id3 samples pes ] }
+ FRAG_PARSING_METADATA: 'hlsFragParsingMetadata',
+ // fired when data have been extracted from fragment - data: { id : demuxer id, frag: fragment object, data1 : moof MP4 box or TS fragments, data2 : mdat MP4 box or null}
+ FRAG_PARSING_DATA: 'hlsFragParsingData',
+ // fired when fragment parsing is completed - data: { id : demuxer id,frag: fragment object }
+ FRAG_PARSED: 'hlsFragParsed',
+ // fired when fragment remuxed MP4 boxes have all been appended into SourceBuffer - data: { id : demuxer id,frag : fragment object, stats : { trequest, tfirst, tload, tparsed, tbuffered, length} }
+ FRAG_BUFFERED: 'hlsFragBuffered',
+ // fired when fragment matching with current media position is changing - data : { id : demuxer id, frag : fragment object }
+ FRAG_CHANGED: 'hlsFragChanged',
+ // Identifier for a FPS drop event - data: {curentDropped, currentDecoded, totalDroppedFrames}
+ FPS_DROP: 'hlsFpsDrop',
+ //triggered when FPS drop triggers auto level capping - data: {level, droppedlevel}
+ FPS_DROP_LEVEL_CAPPING: 'hlsFpsDropLevelCapping',
+ // Identifier for an error event - data: { type : error type, details : error details, fatal : if true, hls.js cannot/will not try to recover, if false, hls.js will try to recover,other error specific data}
+ ERROR: 'hlsError',
+ // fired when hls.js instance starts destroying. Different from MEDIA_DETACHED as one could want to detach and reattach a media to the instance of hls.js to handle mid-rolls for example
+ DESTROYING: 'hlsDestroying',
+ // fired when a decrypt key loading starts - data: { frag : fragment object}
+ KEY_LOADING: 'hlsKeyLoading',
+ // fired when a decrypt key loading is completed - data: { frag : fragment object, payload : key payload, stats : { trequest, tfirst, tload, length}}
+ KEY_LOADED: 'hlsKeyLoaded',
+ // fired upon stream controller state transitions - data: {previousState, nextState}
+ STREAM_STATE_TRANSITION: 'hlsStreamStateTransition'
+};
+
+},{}],33:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+/**
+ * AAC helper
+ */
+
+var AAC = function () {
+ function AAC() {
+ _classCallCheck(this, AAC);
+ }
+
+ _createClass(AAC, null, [{
+ key: 'getSilentFrame',
+ value: function getSilentFrame(codec, channelCount) {
+ switch (codec) {
+ case 'mp4a.40.2':
+ if (channelCount === 1) {
+ return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x23, 0x80]);
+ } else if (channelCount === 2) {
+ return new Uint8Array([0x21, 0x00, 0x49, 0x90, 0x02, 0x19, 0x00, 0x23, 0x80]);
+ } else if (channelCount === 3) {
+ return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x8e]);
+ } else if (channelCount === 4) {
+ return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x80, 0x2c, 0x80, 0x08, 0x02, 0x38]);
+ } else if (channelCount === 5) {
+ return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x38]);
+ } else if (channelCount === 6) {
+ return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x00, 0xb2, 0x00, 0x20, 0x08, 0xe0]);
+ }
+ break;
+ // handle HE-AAC below (mp4a.40.5 / mp4a.40.29)
+ default:
+ if (channelCount === 1) {
+ // ffmpeg -y -f lavfi -i "aevalsrc=0:d=0.05" -c:a libfdk_aac -profile:a aac_he -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
+ return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x4e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x1c, 0x6, 0xf1, 0xc1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);
+ } else if (channelCount === 2) {
+ // ffmpeg -y -f lavfi -i "aevalsrc=0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
+ return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);
+ } else if (channelCount === 3) {
+ // ffmpeg -y -f lavfi -i "aevalsrc=0|0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
+ return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);
+ }
+ break;
+ }
+ return null;
+ }
+ }]);
+
+ return AAC;
+}();
+
+exports.default = AAC;
+
+},{}],34:[function(_dereq_,module,exports){
+"use strict";
+
+/**
+ * Buffer Helper utils, providing methods dealing buffer length retrieval
+*/
+
+var BufferHelper = {
+ isBuffered: function isBuffered(media, position) {
+ if (media) {
+ var buffered = media.buffered;
+ for (var i = 0; i < buffered.length; i++) {
+ if (position >= buffered.start(i) && position <= buffered.end(i)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ },
+
+ bufferInfo: function bufferInfo(media, pos, maxHoleDuration) {
+ if (media) {
+ var vbuffered = media.buffered,
+ buffered = [],
+ i;
+ for (i = 0; i < vbuffered.length; i++) {
+ buffered.push({ start: vbuffered.start(i), end: vbuffered.end(i) });
+ }
+ return this.bufferedInfo(buffered, pos, maxHoleDuration);
+ } else {
+ return { len: 0, start: pos, end: pos, nextStart: undefined };
+ }
+ },
+
+ bufferedInfo: function bufferedInfo(buffered, pos, maxHoleDuration) {
+ var buffered2 = [],
+
+ // bufferStart and bufferEnd are buffer boundaries around current video position
+ bufferLen,
+ bufferStart,
+ bufferEnd,
+ bufferStartNext,
+ i;
+ // sort on buffer.start/smaller end (IE does not always return sorted buffered range)
+ buffered.sort(function (a, b) {
+ var diff = a.start - b.start;
+ if (diff) {
+ return diff;
+ } else {
+ return b.end - a.end;
+ }
+ });
+ // there might be some small holes between buffer time range
+ // consider that holes smaller than maxHoleDuration are irrelevant and build another
+ // buffer time range representations that discards those holes
+ for (i = 0; i < buffered.length; i++) {
+ var buf2len = buffered2.length;
+ if (buf2len) {
+ var buf2end = buffered2[buf2len - 1].end;
+ // if small hole (value between 0 or maxHoleDuration ) or overlapping (negative)
+ if (buffered[i].start - buf2end < maxHoleDuration) {
+ // merge overlapping time ranges
+ // update lastRange.end only if smaller than item.end
+ // e.g. [ 1, 15] with [ 2,8] => [ 1,15] (no need to modify lastRange.end)
+ // whereas [ 1, 8] with [ 2,15] => [ 1,15] ( lastRange should switch from [1,8] to [1,15])
+ if (buffered[i].end > buf2end) {
+ buffered2[buf2len - 1].end = buffered[i].end;
+ }
+ } else {
+ // big hole
+ buffered2.push(buffered[i]);
+ }
+ } else {
+ // first value
+ buffered2.push(buffered[i]);
+ }
+ }
+ for (i = 0, bufferLen = 0, bufferStart = bufferEnd = pos; i < buffered2.length; i++) {
+ var start = buffered2[i].start,
+ end = buffered2[i].end;
+ //logger.log('buf start/end:' + buffered.start(i) + '/' + buffered.end(i));
+ if (pos + maxHoleDuration >= start && pos < end) {
+ // play position is inside this buffer TimeRange, retrieve end of buffer position and buffer length
+ bufferStart = start;
+ bufferEnd = end;
+ bufferLen = bufferEnd - pos;
+ } else if (pos + maxHoleDuration < start) {
+ bufferStartNext = start;
+ break;
+ }
+ }
+ return { len: bufferLen, start: bufferStart, end: bufferEnd, nextStart: bufferStartNext };
+ }
+};
+
+module.exports = BufferHelper;
+
+},{}],35:[function(_dereq_,module,exports){
+'use strict';
+
+var _logger = _dereq_(50);
+
+var LevelHelper = {
+
+ mergeDetails: function mergeDetails(oldDetails, newDetails) {
+ var start = Math.max(oldDetails.startSN, newDetails.startSN) - newDetails.startSN,
+ end = Math.min(oldDetails.endSN, newDetails.endSN) - newDetails.startSN,
+ delta = newDetails.startSN - oldDetails.startSN,
+ oldfragments = oldDetails.fragments,
+ newfragments = newDetails.fragments,
+ ccOffset = 0,
+ PTSFrag;
+
+ // check if old/new playlists have fragments in common
+ if (end < start) {
+ newDetails.PTSKnown = false;
+ return;
+ }
+ // loop through overlapping SN and update startPTS , cc, and duration if any found
+ for (var i = start; i <= end; i++) {
+ var oldFrag = oldfragments[delta + i],
+ newFrag = newfragments[i];
+ if (newFrag && oldFrag) {
+ ccOffset = oldFrag.cc - newFrag.cc;
+ if (!isNaN(oldFrag.startPTS)) {
+ newFrag.start = newFrag.startPTS = oldFrag.startPTS;
+ newFrag.endPTS = oldFrag.endPTS;
+ newFrag.duration = oldFrag.duration;
+ PTSFrag = newFrag;
+ }
+ }
+ }
+
+ if (ccOffset) {
+ _logger.logger.log('discontinuity sliding from playlist, take drift into account');
+ for (i = 0; i < newfragments.length; i++) {
+ newfragments[i].cc += ccOffset;
+ }
+ }
+
+ // if at least one fragment contains PTS info, recompute PTS information for all fragments
+ if (PTSFrag) {
+ LevelHelper.updateFragPTSDTS(newDetails, PTSFrag.sn, PTSFrag.startPTS, PTSFrag.endPTS, PTSFrag.startDTS, PTSFrag.endDTS);
+ } else {
+ // ensure that delta is within oldfragments range
+ // also adjust sliding in case delta is 0 (we could have old=[50-60] and new=old=[50-61])
+ // in that case we also need to adjust start offset of all fragments
+ if (delta >= 0 && delta < oldfragments.length) {
+ // adjust start by sliding offset
+ var sliding = oldfragments[delta].start;
+ for (i = 0; i < newfragments.length; i++) {
+ newfragments[i].start += sliding;
+ }
+ }
+ }
+ // if we are here, it means we have fragments overlapping between
+ // old and new level. reliable PTS info is thus relying on old level
+ newDetails.PTSKnown = oldDetails.PTSKnown;
+ return;
+ },
+
+ updateFragPTSDTS: function updateFragPTSDTS(details, sn, startPTS, endPTS, startDTS, endDTS) {
+ var fragIdx, fragments, frag, i;
+ // exit if sn out of range
+ if (!details || sn < details.startSN || sn > details.endSN) {
+ return 0;
+ }
+ fragIdx = sn - details.startSN;
+ fragments = details.fragments;
+ frag = fragments[fragIdx];
+ if (!isNaN(frag.startPTS)) {
+ // delta PTS between audio and video
+ var deltaPTS = Math.abs(frag.startPTS - startPTS);
+ if (isNaN(frag.deltaPTS)) {
+ frag.deltaPTS = deltaPTS;
+ } else {
+ frag.deltaPTS = Math.max(deltaPTS, frag.deltaPTS);
+ }
+ startPTS = Math.min(startPTS, frag.startPTS);
+ endPTS = Math.max(endPTS, frag.endPTS);
+ startDTS = Math.min(startDTS, frag.startDTS);
+ endDTS = Math.max(endDTS, frag.endDTS);
+ }
+
+ var drift = startPTS - frag.start;
+
+ frag.start = frag.startPTS = startPTS;
+ frag.endPTS = endPTS;
+ frag.startDTS = startDTS;
+ frag.endDTS = endDTS;
+ frag.duration = endPTS - startPTS;
+ // adjust fragment PTS/duration from seqnum-1 to frag 0
+ for (i = fragIdx; i > 0; i--) {
+ LevelHelper.updatePTS(fragments, i, i - 1);
+ }
+
+ // adjust fragment PTS/duration from seqnum to last frag
+ for (i = fragIdx; i < fragments.length - 1; i++) {
+ LevelHelper.updatePTS(fragments, i, i + 1);
+ }
+ details.PTSKnown = true;
+ //logger.log(` frag start/end:${startPTS.toFixed(3)}/${endPTS.toFixed(3)}`);
+
+ return drift;
+ },
+
+ updatePTS: function updatePTS(fragments, fromIdx, toIdx) {
+ var fragFrom = fragments[fromIdx],
+ fragTo = fragments[toIdx],
+ fragToPTS = fragTo.startPTS;
+ // if we know startPTS[toIdx]
+ if (!isNaN(fragToPTS)) {
+ // update fragment duration.
+ // it helps to fix drifts between playlist reported duration and fragment real duration
+ if (toIdx > fromIdx) {
+ fragFrom.duration = fragToPTS - fragFrom.start;
+ if (fragFrom.duration < 0) {
+ _logger.logger.warn('negative duration computed for frag ' + fragFrom.sn + ',level ' + fragFrom.level + ', there should be some duration drift between playlist and fragment!');
+ }
+ } else {
+ fragTo.duration = fragFrom.start - fragToPTS;
+ if (fragTo.duration < 0) {
+ _logger.logger.warn('negative duration computed for frag ' + fragTo.sn + ',level ' + fragTo.level + ', there should be some duration drift between playlist and fragment!');
+ }
+ }
+ } else {
+ // we dont know startPTS[toIdx]
+ if (toIdx > fromIdx) {
+ fragTo.start = fragFrom.start + fragFrom.duration;
+ } else {
+ fragTo.start = fragFrom.start - fragTo.duration;
+ }
+ }
+ }
+}; /**
+ * Level Helper class, providing methods dealing with playlist sliding and drift
+ */
+
+module.exports = LevelHelper;
+
+},{"50":50}],36:[function(_dereq_,module,exports){
+/**
+ * HLS interface
+ */
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _urlToolkit = _dereq_(2);
+
+var _urlToolkit2 = _interopRequireDefault(_urlToolkit);
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _errors = _dereq_(30);
+
+var _playlistLoader = _dereq_(40);
+
+var _playlistLoader2 = _interopRequireDefault(_playlistLoader);
+
+var _fragmentLoader = _dereq_(38);
+
+var _fragmentLoader2 = _interopRequireDefault(_fragmentLoader);
+
+var _keyLoader = _dereq_(39);
+
+var _keyLoader2 = _interopRequireDefault(_keyLoader);
+
+var _streamController = _dereq_(12);
+
+var _streamController2 = _interopRequireDefault(_streamController);
+
+var _levelController = _dereq_(11);
+
+var _levelController2 = _interopRequireDefault(_levelController);
+
+var _logger = _dereq_(50);
+
+var _events3 = _dereq_(1);
+
+var _events4 = _interopRequireDefault(_events3);
+
+var _config = _dereq_(4);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var Hls = function () {
+ _createClass(Hls, null, [{
+ key: 'isSupported',
+ value: function isSupported() {
+ window.MediaSource = window.MediaSource || window.WebKitMediaSource;
+ return window.MediaSource && typeof window.MediaSource.isTypeSupported === 'function' && window.MediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"');
+ }
+ }, {
+ key: 'version',
+ get: function get() {
+ // replaced with browserify-versionify transform
+ return '0.7.5';
+ }
+ }, {
+ key: 'Events',
+ get: function get() {
+ return _events2.default;
+ }
+ }, {
+ key: 'ErrorTypes',
+ get: function get() {
+ return _errors.ErrorTypes;
+ }
+ }, {
+ key: 'ErrorDetails',
+ get: function get() {
+ return _errors.ErrorDetails;
+ }
+ }, {
+ key: 'DefaultConfig',
+ get: function get() {
+ if (!Hls.defaultConfig) {
+ return _config.hlsDefaultConfig;
+ }
+ return Hls.defaultConfig;
+ },
+ set: function set(defaultConfig) {
+ Hls.defaultConfig = defaultConfig;
+ }
+ }]);
+
+ function Hls() {
+ var _this = this;
+
+ var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+
+ _classCallCheck(this, Hls);
+
+ var defaultConfig = Hls.DefaultConfig;
+
+ if ((config.liveSyncDurationCount || config.liveMaxLatencyDurationCount) && (config.liveSyncDuration || config.liveMaxLatencyDuration)) {
+ throw new Error('Illegal hls.js config: don\'t mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration');
+ }
+
+ for (var prop in defaultConfig) {
+ if (prop in config) {
+ continue;
+ }
+ config[prop] = defaultConfig[prop];
+ }
+
+ if (config.liveMaxLatencyDurationCount !== undefined && config.liveMaxLatencyDurationCount <= config.liveSyncDurationCount) {
+ throw new Error('Illegal hls.js config: "liveMaxLatencyDurationCount" must be gt "liveSyncDurationCount"');
+ }
+
+ if (config.liveMaxLatencyDuration !== undefined && (config.liveMaxLatencyDuration <= config.liveSyncDuration || config.liveSyncDuration === undefined)) {
+ throw new Error('Illegal hls.js config: "liveMaxLatencyDuration" must be gt "liveSyncDuration"');
+ }
+
+ (0, _logger.enableLogs)(config.debug);
+ this.config = config;
+ this._autoLevelCapping = -1;
+ // observer setup
+ var observer = this.observer = new _events4.default();
+ observer.trigger = function trigger(event) {
+ for (var _len = arguments.length, data = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ data[_key - 1] = arguments[_key];
+ }
+
+ observer.emit.apply(observer, [event, event].concat(data));
+ };
+
+ observer.off = function off(event) {
+ for (var _len2 = arguments.length, data = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
+ data[_key2 - 1] = arguments[_key2];
+ }
+
+ observer.removeListener.apply(observer, [event].concat(data));
+ };
+ this.on = observer.on.bind(observer);
+ this.off = observer.off.bind(observer);
+ this.trigger = observer.trigger.bind(observer);
+
+ // core controllers and network loaders
+ var abrController = this.abrController = new config.abrController(this);
+ var bufferController = new config.bufferController(this);
+ var capLevelController = new config.capLevelController(this);
+ var fpsController = new config.fpsController(this);
+ var playListLoader = new _playlistLoader2.default(this);
+ var fragmentLoader = new _fragmentLoader2.default(this);
+ var keyLoader = new _keyLoader2.default(this);
+
+ // network controllers
+ var levelController = this.levelController = new _levelController2.default(this);
+ var streamController = this.streamController = new _streamController2.default(this);
+ var networkControllers = [levelController, streamController];
+
+ // optional audio stream controller
+ var Controller = config.audioStreamController;
+ if (Controller) {
+ networkControllers.push(new Controller(this));
+ }
+ this.networkControllers = networkControllers;
+
+ var coreComponents = [playListLoader, fragmentLoader, keyLoader, abrController, bufferController, capLevelController, fpsController];
+
+ // optional audio track and subtitle controller
+ Controller = config.audioTrackController;
+ if (Controller) {
+ var audioTrackController = new Controller(this);
+ this.audioTrackController = audioTrackController;
+ coreComponents.push(audioTrackController);
+ }
+
+ Controller = config.subtitleTrackController;
+ if (Controller) {
+ var subtitleTrackController = new Controller(this);
+ this.subtitleTrackController = subtitleTrackController;
+ coreComponents.push(subtitleTrackController);
+ }
+
+ // optional subtitle controller
+ [config.subtitleStreamController, config.timelineController].forEach(function (Controller) {
+ if (Controller) {
+ coreComponents.push(new Controller(_this));
+ }
+ });
+ this.coreComponents = coreComponents;
+ }
+
+ _createClass(Hls, [{
+ key: 'destroy',
+ value: function destroy() {
+ _logger.logger.log('destroy');
+ this.trigger(_events2.default.DESTROYING);
+ this.detachMedia();
+ this.coreComponents.concat(this.networkControllers).forEach(function (component) {
+ component.destroy();
+ });
+ this.url = null;
+ this.observer.removeAllListeners();
+ this._autoLevelCapping = -1;
+ }
+ }, {
+ key: 'attachMedia',
+ value: function attachMedia(media) {
+ _logger.logger.log('attachMedia');
+ this.media = media;
+ this.trigger(_events2.default.MEDIA_ATTACHING, { media: media });
+ }
+ }, {
+ key: 'detachMedia',
+ value: function detachMedia() {
+ _logger.logger.log('detachMedia');
+ this.trigger(_events2.default.MEDIA_DETACHING);
+ this.media = null;
+ }
+ }, {
+ key: 'loadSource',
+ value: function loadSource(url) {
+ url = _urlToolkit2.default.buildAbsoluteURL(window.location.href, url, { alwaysNormalize: true });
+ _logger.logger.log('loadSource:' + url);
+ this.url = url;
+ // when attaching to a source URL, trigger a playlist load
+ this.trigger(_events2.default.MANIFEST_LOADING, { url: url });
+ }
+ }, {
+ key: 'startLoad',
+ value: function startLoad() {
+ var startPosition = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : -1;
+
+ _logger.logger.log('startLoad(' + startPosition + ')');
+ this.networkControllers.forEach(function (controller) {
+ controller.startLoad(startPosition);
+ });
+ }
+ }, {
+ key: 'stopLoad',
+ value: function stopLoad() {
+ _logger.logger.log('stopLoad');
+ this.networkControllers.forEach(function (controller) {
+ controller.stopLoad();
+ });
+ }
+ }, {
+ key: 'swapAudioCodec',
+ value: function swapAudioCodec() {
+ _logger.logger.log('swapAudioCodec');
+ this.streamController.swapAudioCodec();
+ }
+ }, {
+ key: 'recoverMediaError',
+ value: function recoverMediaError() {
+ _logger.logger.log('recoverMediaError');
+ var media = this.media;
+ this.detachMedia();
+ this.attachMedia(media);
+ }
+
+ /** Return all quality levels **/
+
+ }, {
+ key: 'levels',
+ get: function get() {
+ return this.levelController.levels;
+ }
+
+ /** Return current playback quality level **/
+
+ }, {
+ key: 'currentLevel',
+ get: function get() {
+ return this.streamController.currentLevel;
+ }
+
+ /* set quality level immediately (-1 for automatic level selection) */
+ ,
+ set: function set(newLevel) {
+ _logger.logger.log('set currentLevel:' + newLevel);
+ this.loadLevel = newLevel;
+ this.streamController.immediateLevelSwitch();
+ }
+
+ /** Return next playback quality level (quality level of next fragment) **/
+
+ }, {
+ key: 'nextLevel',
+ get: function get() {
+ return this.streamController.nextLevel;
+ }
+
+ /* set quality level for next fragment (-1 for automatic level selection) */
+ ,
+ set: function set(newLevel) {
+ _logger.logger.log('set nextLevel:' + newLevel);
+ this.levelController.manualLevel = newLevel;
+ this.streamController.nextLevelSwitch();
+ }
+
+ /** Return the quality level of current/last loaded fragment **/
+
+ }, {
+ key: 'loadLevel',
+ get: function get() {
+ return this.levelController.level;
+ }
+
+ /* set quality level for current/next loaded fragment (-1 for automatic level selection) */
+ ,
+ set: function set(newLevel) {
+ _logger.logger.log('set loadLevel:' + newLevel);
+ this.levelController.manualLevel = newLevel;
+ }
+
+ /** Return the quality level of next loaded fragment **/
+
+ }, {
+ key: 'nextLoadLevel',
+ get: function get() {
+ return this.levelController.nextLoadLevel;
+ }
+
+ /** set quality level of next loaded fragment **/
+ ,
+ set: function set(level) {
+ this.levelController.nextLoadLevel = level;
+ }
+
+ /** Return first level (index of first level referenced in manifest)
+ **/
+
+ }, {
+ key: 'firstLevel',
+ get: function get() {
+ return Math.max(this.levelController.firstLevel, this.minAutoLevel);
+ }
+
+ /** set first level (index of first level referenced in manifest)
+ **/
+ ,
+ set: function set(newLevel) {
+ _logger.logger.log('set firstLevel:' + newLevel);
+ this.levelController.firstLevel = newLevel;
+ }
+
+ /** Return start level (level of first fragment that will be played back)
+ if not overrided by user, first level appearing in manifest will be used as start level
+ if -1 : automatic start level selection, playback will start from level matching download bandwidth (determined from download of first segment)
+ **/
+
+ }, {
+ key: 'startLevel',
+ get: function get() {
+ return this.levelController.startLevel;
+ }
+
+ /** set start level (level of first fragment that will be played back)
+ if not overrided by user, first level appearing in manifest will be used as start level
+ if -1 : automatic start level selection, playback will start from level matching download bandwidth (determined from download of first segment)
+ **/
+ ,
+ set: function set(newLevel) {
+ _logger.logger.log('set startLevel:' + newLevel);
+ var hls = this;
+ // if not in automatic start level detection, ensure startLevel is greater than minAutoLevel
+ if (newLevel !== -1) {
+ newLevel = Math.max(newLevel, hls.minAutoLevel);
+ }
+ hls.levelController.startLevel = newLevel;
+ }
+
+ /** Return the capping/max level value that could be used by automatic level selection algorithm **/
+
+ }, {
+ key: 'autoLevelCapping',
+ get: function get() {
+ return this._autoLevelCapping;
+ }
+
+ /** set the capping/max level value that could be used by automatic level selection algorithm **/
+ ,
+ set: function set(newLevel) {
+ _logger.logger.log('set autoLevelCapping:' + newLevel);
+ this._autoLevelCapping = newLevel;
+ }
+
+ /* check if we are in automatic level selection mode */
+
+ }, {
+ key: 'autoLevelEnabled',
+ get: function get() {
+ return this.levelController.manualLevel === -1;
+ }
+
+ /* return manual level */
+
+ }, {
+ key: 'manualLevel',
+ get: function get() {
+ return this.levelController.manualLevel;
+ }
+
+ /* return min level selectable in auto mode according to config.minAutoBitrate */
+
+ }, {
+ key: 'minAutoLevel',
+ get: function get() {
+ var hls = this,
+ levels = hls.levels,
+ minAutoBitrate = hls.config.minAutoBitrate,
+ len = levels ? levels.length : 0;
+ for (var i = 0; i < len; i++) {
+ var levelNextBitrate = levels[i].realBitrate ? Math.max(levels[i].realBitrate, levels[i].bitrate) : levels[i].bitrate;
+ if (levelNextBitrate > minAutoBitrate) {
+ return i;
+ }
+ }
+ return 0;
+ }
+
+ /* return max level selectable in auto mode according to autoLevelCapping */
+
+ }, {
+ key: 'maxAutoLevel',
+ get: function get() {
+ var hls = this;
+ var levels = hls.levels;
+ var autoLevelCapping = hls.autoLevelCapping;
+ var maxAutoLevel = void 0;
+ if (autoLevelCapping === -1 && levels && levels.length) {
+ maxAutoLevel = levels.length - 1;
+ } else {
+ maxAutoLevel = autoLevelCapping;
+ }
+ return maxAutoLevel;
+ }
+
+ // return next auto level
+
+ }, {
+ key: 'nextAutoLevel',
+ get: function get() {
+ var hls = this;
+ // ensure next auto level is between min and max auto level
+ return Math.min(Math.max(hls.abrController.nextAutoLevel, hls.minAutoLevel), hls.maxAutoLevel);
+ }
+
+ // this setter is used to force next auto level
+ // this is useful to force a switch down in auto mode : in case of load error on level N, hls.js can set nextAutoLevel to N-1 for example)
+ // forced value is valid for one fragment. upon succesful frag loading at forced level, this value will be resetted to -1 by ABR controller
+ ,
+ set: function set(nextLevel) {
+ var hls = this;
+ hls.abrController.nextAutoLevel = Math.max(hls.minAutoLevel, nextLevel);
+ }
+
+ /** get alternate audio tracks list from playlist **/
+
+ }, {
+ key: 'audioTracks',
+ get: function get() {
+ var audioTrackController = this.audioTrackController;
+ return audioTrackController ? audioTrackController.audioTracks : [];
+ }
+
+ /** get index of the selected audio track (index in audio track lists) **/
+
+ }, {
+ key: 'audioTrack',
+ get: function get() {
+ var audioTrackController = this.audioTrackController;
+ return audioTrackController ? audioTrackController.audioTrack : -1;
+ }
+
+ /** select an audio track, based on its index in audio track lists**/
+ ,
+ set: function set(audioTrackId) {
+ var audioTrackController = this.audioTrackController;
+ if (audioTrackController) {
+ audioTrackController.audioTrack = audioTrackId;
+ }
+ }
+ }, {
+ key: 'liveSyncPosition',
+ get: function get() {
+ return this.streamController.liveSyncPosition;
+ }
+
+ /** get alternate subtitle tracks list from playlist **/
+
+ }, {
+ key: 'subtitleTracks',
+ get: function get() {
+ var subtitleTrackController = this.subtitleTrackController;
+ return subtitleTrackController ? subtitleTrackController.subtitleTracks : [];
+ }
+
+ /** get index of the selected subtitle track (index in subtitle track lists) **/
+
+ }, {
+ key: 'subtitleTrack',
+ get: function get() {
+ var subtitleTrackController = this.subtitleTrackController;
+ return subtitleTrackController ? subtitleTrackController.subtitleTrack : -1;
+ }
+
+ /** select an subtitle track, based on its index in subtitle track lists**/
+ ,
+ set: function set(subtitleTrackId) {
+ var subtitleTrackController = this.subtitleTrackController;
+ if (subtitleTrackController) {
+ subtitleTrackController.subtitleTrack = subtitleTrackId;
+ }
+ }
+ }]);
+
+ return Hls;
+}();
+
+exports.default = Hls;
+
+},{"1":1,"11":11,"12":12,"2":2,"30":30,"32":32,"38":38,"39":39,"4":4,"40":40,"50":50}],37:[function(_dereq_,module,exports){
+'use strict';
+
+// This is mostly for support of the es6 module export
+// syntax with the babel compiler, it looks like it doesnt support
+// function exports like we are used to in node/commonjs
+module.exports = _dereq_(36).default;
+
+},{"36":36}],38:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = _dereq_(31);
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+var _errors = _dereq_(30);
+
+var _logger = _dereq_(50);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+ * Fragment Loader
+ */
+
+var FragmentLoader = function (_EventHandler) {
+ _inherits(FragmentLoader, _EventHandler);
+
+ function FragmentLoader(hls) {
+ _classCallCheck(this, FragmentLoader);
+
+ var _this = _possibleConstructorReturn(this, (FragmentLoader.__proto__ || Object.getPrototypeOf(FragmentLoader)).call(this, hls, _events2.default.FRAG_LOADING));
+
+ _this.loaders = {};
+ return _this;
+ }
+
+ _createClass(FragmentLoader, [{
+ key: 'destroy',
+ value: function destroy() {
+ var loaders = this.loaders;
+ for (var loaderName in loaders) {
+ var loader = loaders[loaderName];
+ if (loader) {
+ loader.destroy();
+ }
+ }
+ this.loaders = {};
+ _eventHandler2.default.prototype.destroy.call(this);
+ }
+ }, {
+ key: 'onFragLoading',
+ value: function onFragLoading(data) {
+ var frag = data.frag,
+ type = frag.type,
+ loader = this.loaders[type],
+ config = this.hls.config;
+
+ frag.loaded = 0;
+ if (loader) {
+ _logger.logger.warn('abort previous fragment loader for type:' + type);
+ loader.abort();
+ }
+ loader = this.loaders[type] = frag.loader = typeof config.fLoader !== 'undefined' ? new config.fLoader(config) : new config.loader(config);
+
+ var loaderContext = void 0,
+ loaderConfig = void 0,
+ loaderCallbacks = void 0;
+ loaderContext = { url: frag.url, frag: frag, responseType: 'arraybuffer', progressData: false };
+ var start = frag.byteRangeStartOffset,
+ end = frag.byteRangeEndOffset;
+ if (!isNaN(start) && !isNaN(end)) {
+ loaderContext.rangeStart = start;
+ loaderContext.rangeEnd = end;
+ }
+ loaderConfig = { timeout: config.fragLoadingTimeOut, maxRetry: 0, retryDelay: 0, maxRetryDelay: config.fragLoadingMaxRetryTimeout };
+ loaderCallbacks = { onSuccess: this.loadsuccess.bind(this), onError: this.loaderror.bind(this), onTimeout: this.loadtimeout.bind(this), onProgress: this.loadprogress.bind(this) };
+ loader.load(loaderContext, loaderConfig, loaderCallbacks);
+ }
+ }, {
+ key: 'loadsuccess',
+ value: function loadsuccess(response, stats, context) {
+ var payload = response.data,
+ frag = context.frag;
+ // detach fragment loader on load success
+ frag.loader = undefined;
+ this.loaders[frag.type] = undefined;
+ this.hls.trigger(_events2.default.FRAG_LOADED, { payload: payload, frag: frag, stats: stats });
+ }
+ }, {
+ key: 'loaderror',
+ value: function loaderror(response, context) {
+ var loader = context.loader;
+ if (loader) {
+ loader.abort();
+ }
+ this.loaders[context.type] = undefined;
+ this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: _errors.ErrorDetails.FRAG_LOAD_ERROR, fatal: false, frag: context.frag, response: response });
+ }
+ }, {
+ key: 'loadtimeout',
+ value: function loadtimeout(stats, context) {
+ var loader = context.loader;
+ if (loader) {
+ loader.abort();
+ }
+ this.loaders[context.type] = undefined;
+ this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: _errors.ErrorDetails.FRAG_LOAD_TIMEOUT, fatal: false, frag: context.frag });
+ }
+
+ // data will be used for progressive parsing
+
+ }, {
+ key: 'loadprogress',
+ value: function loadprogress(stats, context, data) {
+ // jshint ignore:line
+ var frag = context.frag;
+ frag.loaded = stats.loaded;
+ this.hls.trigger(_events2.default.FRAG_LOAD_PROGRESS, { frag: frag, stats: stats });
+ }
+ }]);
+
+ return FragmentLoader;
+}(_eventHandler2.default);
+
+exports.default = FragmentLoader;
+
+},{"30":30,"31":31,"32":32,"50":50}],39:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = _dereq_(31);
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+var _errors = _dereq_(30);
+
+var _logger = _dereq_(50);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /*
+ * Decrypt key Loader
+ */
+
+var KeyLoader = function (_EventHandler) {
+ _inherits(KeyLoader, _EventHandler);
+
+ function KeyLoader(hls) {
+ _classCallCheck(this, KeyLoader);
+
+ var _this = _possibleConstructorReturn(this, (KeyLoader.__proto__ || Object.getPrototypeOf(KeyLoader)).call(this, hls, _events2.default.KEY_LOADING));
+
+ _this.loaders = {};
+ _this.decryptkey = null;
+ _this.decrypturl = null;
+ return _this;
+ }
+
+ _createClass(KeyLoader, [{
+ key: 'destroy',
+ value: function destroy() {
+ for (var loaderName in this.loaders) {
+ var loader = this.loaders[loaderName];
+ if (loader) {
+ loader.destroy();
+ }
+ }
+ this.loaders = {};
+ _eventHandler2.default.prototype.destroy.call(this);
+ }
+ }, {
+ key: 'onKeyLoading',
+ value: function onKeyLoading(data) {
+ var frag = data.frag,
+ type = frag.type,
+ loader = this.loaders[type],
+ decryptdata = frag.decryptdata,
+ uri = decryptdata.uri;
+ // if uri is different from previous one or if decrypt key not retrieved yet
+ if (uri !== this.decrypturl || this.decryptkey === null) {
+ var config = this.hls.config;
+
+ if (loader) {
+ _logger.logger.warn('abort previous key loader for type:' + type);
+ loader.abort();
+ }
+ frag.loader = this.loaders[type] = new config.loader(config);
+ this.decrypturl = uri;
+ this.decryptkey = null;
+
+ var loaderContext = void 0,
+ loaderConfig = void 0,
+ loaderCallbacks = void 0;
+ loaderContext = { url: uri, frag: frag, responseType: 'arraybuffer' };
+ loaderConfig = { timeout: config.fragLoadingTimeOut, maxRetry: config.fragLoadingMaxRetry, retryDelay: config.fragLoadingRetryDelay, maxRetryDelay: config.fragLoadingMaxRetryTimeout };
+ loaderCallbacks = { onSuccess: this.loadsuccess.bind(this), onError: this.loaderror.bind(this), onTimeout: this.loadtimeout.bind(this) };
+ frag.loader.load(loaderContext, loaderConfig, loaderCallbacks);
+ } else if (this.decryptkey) {
+ // we already loaded this key, return it
+ decryptdata.key = this.decryptkey;
+ this.hls.trigger(_events2.default.KEY_LOADED, { frag: frag });
+ }
+ }
+ }, {
+ key: 'loadsuccess',
+ value: function loadsuccess(response, stats, context) {
+ var frag = context.frag;
+ this.decryptkey = frag.decryptdata.key = new Uint8Array(response.data);
+ // detach fragment loader on load success
+ frag.loader = undefined;
+ this.loaders[frag.type] = undefined;
+ this.hls.trigger(_events2.default.KEY_LOADED, { frag: frag });
+ }
+ }, {
+ key: 'loaderror',
+ value: function loaderror(response, context) {
+ var frag = context.frag,
+ loader = frag.loader;
+ if (loader) {
+ loader.abort();
+ }
+ this.loaders[context.type] = undefined;
+ this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: _errors.ErrorDetails.KEY_LOAD_ERROR, fatal: false, frag: frag, response: response });
+ }
+ }, {
+ key: 'loadtimeout',
+ value: function loadtimeout(stats, context) {
+ var frag = context.frag,
+ loader = frag.loader;
+ if (loader) {
+ loader.abort();
+ }
+ this.loaders[context.type] = undefined;
+ this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: _errors.ErrorDetails.KEY_LOAD_TIMEOUT, fatal: false, frag: frag });
+ }
+ }]);
+
+ return KeyLoader;
+}(_eventHandler2.default);
+
+exports.default = KeyLoader;
+
+},{"30":30,"31":31,"32":32,"50":50}],40:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
+ * Playlist Loader
+ */
+
+var _urlToolkit = _dereq_(2);
+
+var _urlToolkit2 = _interopRequireDefault(_urlToolkit);
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _eventHandler = _dereq_(31);
+
+var _eventHandler2 = _interopRequireDefault(_eventHandler);
+
+var _errors = _dereq_(30);
+
+var _attrList = _dereq_(44);
+
+var _attrList2 = _interopRequireDefault(_attrList);
+
+var _logger = _dereq_(50);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+// https://regex101.com is your friend
+var MASTER_PLAYLIST_REGEX = /#EXT-X-STREAM-INF:([^\n\r]*)[\r\n]+([^\r\n]+)/g;
+var MASTER_PLAYLIST_MEDIA_REGEX = /#EXT-X-MEDIA:(.*)/g;
+var LEVEL_PLAYLIST_REGEX_FAST = /#EXTINF:(\d*(?:\.\d+)?)(?:,(.*))?|(?!#)(\S.+)|#EXT-X-BYTERANGE: *(.+)|#EXT-X-PROGRAM-DATE-TIME:(.+)|#.*/g;
+var LEVEL_PLAYLIST_REGEX_SLOW = /(?:(?:#(EXTM3U))|(?:#EXT-X-(PLAYLIST-TYPE):(.+))|(?:#EXT-X-(MEDIA-SEQUENCE): *(\d+))|(?:#EXT-X-(TARGETDURATION): *(\d+))|(?:#EXT-X-(KEY):(.+))|(?:#EXT-X-(START):(.+))|(?:#EXT-X-(ENDLIST))|(?:#EXT-X-(DISCONTINUITY-SEQ)UENCE:(\d+))|(?:#EXT-X-(DIS)CONTINUITY))|(?:#EXT-X-(VERSION):(\d+))|(?:#EXT-X-(MAP):(.+))|(?:(#)(.*):(.*))|(?:(#)(.*))(?:.*)\r?\n?/;
+
+var LevelKey = function () {
+ function LevelKey() {
+ _classCallCheck(this, LevelKey);
+
+ this.method = null;
+ this.key = null;
+ this.iv = null;
+ this._uri = null;
+ }
+
+ _createClass(LevelKey, [{
+ key: 'uri',
+ get: function get() {
+ if (!this._uri && this.reluri) {
+ this._uri = _urlToolkit2.default.buildAbsoluteURL(this.baseuri, this.reluri, { alwaysNormalize: true });
+ }
+ return this._uri;
+ }
+ }]);
+
+ return LevelKey;
+}();
+
+var Fragment = function () {
+ function Fragment() {
+ _classCallCheck(this, Fragment);
+
+ this._url = null;
+ this._byteRange = null;
+ this._decryptdata = null;
+ this.tagList = [];
+ }
+
+ _createClass(Fragment, [{
+ key: 'createInitializationVector',
+
+
+ /**
+ * Utility method for parseLevelPlaylist to create an initialization vector for a given segment
+ * @returns {Uint8Array}
+ */
+ value: function createInitializationVector(segmentNumber) {
+ var uint8View = new Uint8Array(16);
+
+ for (var i = 12; i < 16; i++) {
+ uint8View[i] = segmentNumber >> 8 * (15 - i) & 0xff;
+ }
+
+ return uint8View;
+ }
+
+ /**
+ * Utility method for parseLevelPlaylist to get a fragment's decryption data from the currently parsed encryption key data
+ * @param levelkey - a playlist's encryption info
+ * @param segmentNumber - the fragment's segment number
+ * @returns {*} - an object to be applied as a fragment's decryptdata
+ */
+
+ }, {
+ key: 'fragmentDecryptdataFromLevelkey',
+ value: function fragmentDecryptdataFromLevelkey(levelkey, segmentNumber) {
+ var decryptdata = levelkey;
+
+ if (levelkey && levelkey.method && levelkey.uri && !levelkey.iv) {
+ decryptdata = new LevelKey();
+ decryptdata.method = levelkey.method;
+ decryptdata.baseuri = levelkey.baseuri;
+ decryptdata.reluri = levelkey.reluri;
+ decryptdata.iv = this.createInitializationVector(segmentNumber);
+ }
+
+ return decryptdata;
+ }
+ }, {
+ key: 'cloneObj',
+ value: function cloneObj(obj) {
+ return JSON.parse(JSON.stringify(obj));
+ }
+ }, {
+ key: 'url',
+ get: function get() {
+ if (!this._url && this.relurl) {
+ this._url = _urlToolkit2.default.buildAbsoluteURL(this.baseurl, this.relurl, { alwaysNormalize: true });
+ }
+ return this._url;
+ },
+ set: function set(value) {
+ this._url = value;
+ }
+ }, {
+ key: 'programDateTime',
+ get: function get() {
+ if (!this._programDateTime && this.rawProgramDateTime) {
+ this._programDateTime = new Date(Date.parse(this.rawProgramDateTime));
+ }
+ return this._programDateTime;
+ }
+ }, {
+ key: 'byteRange',
+ get: function get() {
+ if (!this._byteRange) {
+ var byteRange = this._byteRange = [];
+ if (this.rawByteRange) {
+ var params = this.rawByteRange.split('@', 2);
+ if (params.length === 1) {
+ var lastByteRangeEndOffset = this.lastByteRangeEndOffset;
+ byteRange[0] = lastByteRangeEndOffset ? lastByteRangeEndOffset : 0;
+ } else {
+ byteRange[0] = parseInt(params[1]);
+ }
+ byteRange[1] = parseInt(params[0]) + byteRange[0];
+ }
+ }
+ return this._byteRange;
+ }
+ }, {
+ key: 'byteRangeStartOffset',
+ get: function get() {
+ return this.byteRange[0];
+ }
+ }, {
+ key: 'byteRangeEndOffset',
+ get: function get() {
+ return this.byteRange[1];
+ }
+ }, {
+ key: 'decryptdata',
+ get: function get() {
+ if (!this._decryptdata) {
+ this._decryptdata = this.fragmentDecryptdataFromLevelkey(this.levelkey, this.sn);
+ }
+ return this._decryptdata;
+ }
+ }]);
+
+ return Fragment;
+}();
+
+var PlaylistLoader = function (_EventHandler) {
+ _inherits(PlaylistLoader, _EventHandler);
+
+ function PlaylistLoader(hls) {
+ _classCallCheck(this, PlaylistLoader);
+
+ var _this = _possibleConstructorReturn(this, (PlaylistLoader.__proto__ || Object.getPrototypeOf(PlaylistLoader)).call(this, hls, _events2.default.MANIFEST_LOADING, _events2.default.LEVEL_LOADING, _events2.default.AUDIO_TRACK_LOADING, _events2.default.SUBTITLE_TRACK_LOADING));
+
+ _this.loaders = {};
+ return _this;
+ }
+
+ _createClass(PlaylistLoader, [{
+ key: 'destroy',
+ value: function destroy() {
+ for (var loaderName in this.loaders) {
+ var loader = this.loaders[loaderName];
+ if (loader) {
+ loader.destroy();
+ }
+ }
+ this.loaders = {};
+ _eventHandler2.default.prototype.destroy.call(this);
+ }
+ }, {
+ key: 'onManifestLoading',
+ value: function onManifestLoading(data) {
+ this.load(data.url, { type: 'manifest' });
+ }
+ }, {
+ key: 'onLevelLoading',
+ value: function onLevelLoading(data) {
+ this.load(data.url, { type: 'level', level: data.level, id: data.id });
+ }
+ }, {
+ key: 'onAudioTrackLoading',
+ value: function onAudioTrackLoading(data) {
+ this.load(data.url, { type: 'audioTrack', id: data.id });
+ }
+ }, {
+ key: 'onSubtitleTrackLoading',
+ value: function onSubtitleTrackLoading(data) {
+ this.load(data.url, { type: 'subtitleTrack', id: data.id });
+ }
+ }, {
+ key: 'load',
+ value: function load(url, context) {
+ var loader = this.loaders[context.type];
+ if (loader) {
+ var loaderContext = loader.context;
+ if (loaderContext && loaderContext.url === url) {
+ _logger.logger.trace('playlist request ongoing');
+ return;
+ } else {
+ _logger.logger.warn('abort previous loader for type:' + context.type);
+ loader.abort();
+ }
+ }
+ var config = this.hls.config,
+ retry = void 0,
+ timeout = void 0,
+ retryDelay = void 0,
+ maxRetryDelay = void 0;
+ if (context.type === 'manifest') {
+ retry = config.manifestLoadingMaxRetry;
+ timeout = config.manifestLoadingTimeOut;
+ retryDelay = config.manifestLoadingRetryDelay;
+ maxRetryDelay = config.manifestLoadingMaxRetryTimeout;
+ } else {
+ retry = config.levelLoadingMaxRetry;
+ timeout = config.levelLoadingTimeOut;
+ retryDelay = config.levelLoadingRetryDelay;
+ maxRetryDelay = config.levelLoadingMaxRetryTimeout;
+ _logger.logger.log('loading playlist for ' + context.type + ' ' + (context.level || context.id));
+ }
+ loader = this.loaders[context.type] = context.loader = typeof config.pLoader !== 'undefined' ? new config.pLoader(config) : new config.loader(config);
+ context.url = url;
+ context.responseType = '';
+
+ var loaderConfig = void 0,
+ loaderCallbacks = void 0;
+ loaderConfig = { timeout: timeout, maxRetry: retry, retryDelay: retryDelay, maxRetryDelay: maxRetryDelay };
+ loaderCallbacks = { onSuccess: this.loadsuccess.bind(this), onError: this.loaderror.bind(this), onTimeout: this.loadtimeout.bind(this) };
+ loader.load(context, loaderConfig, loaderCallbacks);
+ }
+ }, {
+ key: 'resolve',
+ value: function resolve(url, baseUrl) {
+ return _urlToolkit2.default.buildAbsoluteURL(baseUrl, url, { alwaysNormalize: true });
+ }
+ }, {
+ key: 'parseMasterPlaylist',
+ value: function parseMasterPlaylist(string, baseurl) {
+ var levels = [],
+ result = void 0;
+ MASTER_PLAYLIST_REGEX.lastIndex = 0;
+ while ((result = MASTER_PLAYLIST_REGEX.exec(string)) != null) {
+ var level = {};
+
+ var attrs = level.attrs = new _attrList2.default(result[1]);
+ level.url = this.resolve(result[2], baseurl);
+
+ var resolution = attrs.decimalResolution('RESOLUTION');
+ if (resolution) {
+ level.width = resolution.width;
+ level.height = resolution.height;
+ }
+ level.bitrate = attrs.decimalInteger('AVERAGE-BANDWIDTH') || attrs.decimalInteger('BANDWIDTH');
+ level.name = attrs.NAME;
+
+ var codecs = attrs.CODECS;
+ if (codecs) {
+ codecs = codecs.split(/[ ,]+/);
+ for (var i = 0; i < codecs.length; i++) {
+ var codec = codecs[i];
+ if (codec.indexOf('avc1') !== -1) {
+ level.videoCodec = this.avc1toavcoti(codec);
+ } else {
+ level.audioCodec = codec;
+ }
+ }
+ }
+
+ levels.push(level);
+ }
+ return levels;
+ }
+ }, {
+ key: 'parseMasterPlaylistMedia',
+ value: function parseMasterPlaylistMedia(string, baseurl, type) {
+ var result = void 0,
+ medias = [],
+ id = 0;
+ MASTER_PLAYLIST_MEDIA_REGEX.lastIndex = 0;
+ while ((result = MASTER_PLAYLIST_MEDIA_REGEX.exec(string)) != null) {
+ var media = {};
+ var attrs = new _attrList2.default(result[1]);
+ if (attrs.TYPE === type) {
+ media.groupId = attrs['GROUP-ID'];
+ media.name = attrs.NAME;
+ media.type = type;
+ media.default = attrs.DEFAULT === 'YES';
+ media.autoselect = attrs.AUTOSELECT === 'YES';
+ media.forced = attrs.FORCED === 'YES';
+ if (attrs.URI) {
+ media.url = this.resolve(attrs.URI, baseurl);
+ }
+ media.lang = attrs.LANGUAGE;
+ if (!media.name) {
+ media.name = media.lang;
+ }
+ media.id = id++;
+ medias.push(media);
+ }
+ }
+ return medias;
+ }
+ }, {
+ key: 'avc1toavcoti',
+ value: function avc1toavcoti(codec) {
+ var result,
+ avcdata = codec.split('.');
+ if (avcdata.length > 2) {
+ result = avcdata.shift() + '.';
+ result += parseInt(avcdata.shift()).toString(16);
+ result += ('000' + parseInt(avcdata.shift()).toString(16)).substr(-4);
+ } else {
+ result = codec;
+ }
+ return result;
+ }
+ }, {
+ key: 'parseLevelPlaylist',
+ value: function parseLevelPlaylist(string, baseurl, id, type) {
+ var currentSN = 0,
+ totalduration = 0,
+ level = { type: null, version: null, url: baseurl, fragments: [], live: true, startSN: 0 },
+ levelkey = new LevelKey(),
+ cc = 0,
+ prevFrag = null,
+ frag = new Fragment(),
+ result,
+ i;
+
+ LEVEL_PLAYLIST_REGEX_FAST.lastIndex = 0;
+
+ while ((result = LEVEL_PLAYLIST_REGEX_FAST.exec(string)) !== null) {
+ var duration = result[1];
+ if (duration) {
+ // INF
+ frag.duration = parseFloat(duration);
+ // avoid sliced strings https://github.com/video-dev/hls.js/issues/939
+ var title = (' ' + result[2]).slice(1);
+ frag.title = title ? title : null;
+ frag.tagList.push(title ? ['INF', duration, title] : ['INF', duration]);
+ } else if (result[3]) {
+ // url
+ if (!isNaN(frag.duration)) {
+ var sn = currentSN++;
+ frag.type = type;
+ frag.start = totalduration;
+ frag.levelkey = levelkey;
+ frag.sn = sn;
+ frag.level = id;
+ frag.cc = cc;
+ frag.baseurl = baseurl;
+ // avoid sliced strings https://github.com/video-dev/hls.js/issues/939
+ frag.relurl = (' ' + result[3]).slice(1);
+
+ level.fragments.push(frag);
+ prevFrag = frag;
+ totalduration += frag.duration;
+
+ frag = new Fragment();
+ }
+ } else if (result[4]) {
+ // X-BYTERANGE
+ frag.rawByteRange = (' ' + result[4]).slice(1);
+ if (prevFrag) {
+ var lastByteRangeEndOffset = prevFrag.byteRangeEndOffset;
+ if (lastByteRangeEndOffset) {
+ frag.lastByteRangeEndOffset = lastByteRangeEndOffset;
+ }
+ }
+ } else if (result[5]) {
+ // PROGRAM-DATE-TIME
+ // avoid sliced strings https://github.com/video-dev/hls.js/issues/939
+ frag.rawProgramDateTime = (' ' + result[5]).slice(1);
+ frag.tagList.push(['PROGRAM-DATE-TIME', frag.rawProgramDateTime]);
+ } else {
+ result = result[0].match(LEVEL_PLAYLIST_REGEX_SLOW);
+ for (i = 1; i < result.length; i++) {
+ if (result[i] !== undefined) {
+ break;
+ }
+ }
+
+ // avoid sliced strings https://github.com/video-dev/hls.js/issues/939
+ var value1 = (' ' + result[i + 1]).slice(1);
+ var value2 = (' ' + result[i + 2]).slice(1);
+
+ switch (result[i]) {
+ case '#':
+ frag.tagList.push(value2 ? [value1, value2] : [value1]);
+ break;
+ case 'PLAYLIST-TYPE':
+ level.type = value1.toUpperCase();
+ break;
+ case 'MEDIA-SEQUENCE':
+ currentSN = level.startSN = parseInt(value1);
+ break;
+ case 'TARGETDURATION':
+ level.targetduration = parseFloat(value1);
+ break;
+ case 'VERSION':
+ level.version = parseInt(value1);
+ break;
+ case 'EXTM3U':
+ break;
+ case 'ENDLIST':
+ level.live = false;
+ break;
+ case 'DIS':
+ cc++;
+ frag.tagList.push(['DIS']);
+ break;
+ case 'DISCONTINUITY-SEQ':
+ cc = parseInt(value1);
+ break;
+ case 'KEY':
+ // https://tools.ietf.org/html/draft-pantos-http-live-streaming-08#section-3.4.4
+ var decryptparams = value1;
+ var keyAttrs = new _attrList2.default(decryptparams);
+ var decryptmethod = keyAttrs.enumeratedString('METHOD'),
+ decrypturi = keyAttrs.URI,
+ decryptiv = keyAttrs.hexadecimalInteger('IV');
+ if (decryptmethod) {
+ levelkey = new LevelKey();
+ if (decrypturi && ['AES-128', 'SAMPLE-AES'].indexOf(decryptmethod) >= 0) {
+ levelkey.method = decryptmethod;
+ // URI to get the key
+ levelkey.baseuri = baseurl;
+ levelkey.reluri = decrypturi;
+ levelkey.key = null;
+ // Initialization Vector (IV)
+ levelkey.iv = decryptiv;
+ }
+ }
+ break;
+ case 'START':
+ var startParams = value1;
+ var startAttrs = new _attrList2.default(startParams);
+ var startTimeOffset = startAttrs.decimalFloatingPoint('TIME-OFFSET');
+ //TIME-OFFSET can be 0
+ if (!isNaN(startTimeOffset)) {
+ level.startTimeOffset = startTimeOffset;
+ }
+ break;
+ case 'MAP':
+ var mapAttrs = new _attrList2.default(value1);
+ frag.relurl = mapAttrs.URI;
+ frag.rawByteRange = mapAttrs.BYTERANGE;
+ frag.baseurl = baseurl;
+ frag.level = id;
+ frag.type = type;
+ frag.sn = 'initSegment';
+ level.initSegment = frag;
+ frag = new Fragment();
+ break;
+ default:
+ _logger.logger.warn('line parsed but not handled: ' + result);
+ break;
+ }
+ }
+ }
+ frag = prevFrag;
+ //logger.log('found ' + level.fragments.length + ' fragments');
+ if (frag && !frag.relurl) {
+ level.fragments.pop();
+ totalduration -= frag.duration;
+ }
+ level.totalduration = totalduration;
+ level.averagetargetduration = totalduration / level.fragments.length;
+ level.endSN = currentSN - 1;
+ return level;
+ }
+ }, {
+ key: 'loadsuccess',
+ value: function loadsuccess(response, stats, context) {
+ var string = response.data,
+ url = response.url,
+ type = context.type,
+ id = context.id,
+ level = context.level,
+ hls = this.hls;
+
+ this.loaders[type] = undefined;
+ // responseURL not supported on some browsers (it is used to detect URL redirection)
+ // data-uri mode also not supported (but no need to detect redirection)
+ if (url === undefined || url.indexOf('data:') === 0) {
+ // fallback to initial URL
+ url = context.url;
+ }
+ stats.tload = performance.now();
+ //stats.mtime = new Date(target.getResponseHeader('Last-Modified'));
+ if (string.indexOf('#EXTM3U') === 0) {
+ if (string.indexOf('#EXTINF:') > 0) {
+ var isLevel = type !== 'audioTrack' && type !== 'subtitleTrack',
+ levelId = !isNaN(level) ? level : !isNaN(id) ? id : 0,
+ levelDetails = this.parseLevelPlaylist(string, url, levelId, type === 'audioTrack' ? 'audio' : type === 'subtitleTrack' ? 'subtitle' : 'main');
+ levelDetails.tload = stats.tload;
+ if (type === 'manifest') {
+ // first request, stream manifest (no master playlist), fire manifest loaded event with level details
+ hls.trigger(_events2.default.MANIFEST_LOADED, { levels: [{ url: url, details: levelDetails }], audioTracks: [], url: url, stats: stats });
+ }
+ stats.tparsed = performance.now();
+ if (levelDetails.targetduration) {
+ if (isLevel) {
+ hls.trigger(_events2.default.LEVEL_LOADED, { details: levelDetails, level: level || 0, id: id || 0, stats: stats });
+ } else {
+ if (type === 'audioTrack') {
+ hls.trigger(_events2.default.AUDIO_TRACK_LOADED, { details: levelDetails, id: id, stats: stats });
+ } else if (type === 'subtitleTrack') {
+ hls.trigger(_events2.default.SUBTITLE_TRACK_LOADED, { details: levelDetails, id: id, stats: stats });
+ }
+ }
+ } else {
+ hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: _errors.ErrorDetails.MANIFEST_PARSING_ERROR, fatal: true, url: url, reason: 'invalid targetduration' });
+ }
+ } else {
+ var levels = this.parseMasterPlaylist(string, url);
+ // multi level playlist, parse level info
+ if (levels.length) {
+ var audioTracks = this.parseMasterPlaylistMedia(string, url, 'AUDIO');
+ var subtitles = this.parseMasterPlaylistMedia(string, url, 'SUBTITLES');
+ if (audioTracks.length) {
+ // check if we have found an audio track embedded in main playlist (audio track without URI attribute)
+ var embeddedAudioFound = false;
+ audioTracks.forEach(function (audioTrack) {
+ if (!audioTrack.url) {
+ embeddedAudioFound = true;
+ }
+ });
+ // if no embedded audio track defined, but audio codec signaled in quality level, we need to signal this main audio track
+ // this could happen with playlists with alt audio rendition in which quality levels (main) contains both audio+video. but with mixed audio track not signaled
+ if (embeddedAudioFound === false && levels[0].audioCodec && !levels[0].attrs.AUDIO) {
+ _logger.logger.log('audio codec signaled in quality level, but no embedded audio track signaled, create one');
+ audioTracks.unshift({ type: 'main', name: 'main' });
+ }
+ }
+ hls.trigger(_events2.default.MANIFEST_LOADED, { levels: levels, audioTracks: audioTracks, subtitles: subtitles, url: url, stats: stats });
+ } else {
+ hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: _errors.ErrorDetails.MANIFEST_PARSING_ERROR, fatal: true, url: url, reason: 'no level found in manifest' });
+ }
+ }
+ } else {
+ hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: _errors.ErrorDetails.MANIFEST_PARSING_ERROR, fatal: true, url: url, reason: 'no EXTM3U delimiter' });
+ }
+ }
+ }, {
+ key: 'loaderror',
+ value: function loaderror(response, context) {
+ var details,
+ fatal,
+ loader = context.loader;
+ switch (context.type) {
+ case 'manifest':
+ details = _errors.ErrorDetails.MANIFEST_LOAD_ERROR;
+ fatal = true;
+ break;
+ case 'level':
+ details = _errors.ErrorDetails.LEVEL_LOAD_ERROR;
+ fatal = false;
+ break;
+ case 'audioTrack':
+ details = _errors.ErrorDetails.AUDIO_TRACK_LOAD_ERROR;
+ fatal = false;
+ break;
+ }
+ if (loader) {
+ loader.abort();
+ this.loaders[context.type] = undefined;
+ }
+ this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: details, fatal: fatal, url: loader.url, loader: loader, response: response, context: context });
+ }
+ }, {
+ key: 'loadtimeout',
+ value: function loadtimeout(stats, context) {
+ var details,
+ fatal,
+ loader = context.loader;
+ switch (context.type) {
+ case 'manifest':
+ details = _errors.ErrorDetails.MANIFEST_LOAD_TIMEOUT;
+ fatal = true;
+ break;
+ case 'level':
+ details = _errors.ErrorDetails.LEVEL_LOAD_TIMEOUT;
+ fatal = false;
+ break;
+ case 'audioTrack':
+ details = _errors.ErrorDetails.AUDIO_TRACK_LOAD_TIMEOUT;
+ fatal = false;
+ break;
+ }
+ if (loader) {
+ loader.abort();
+ this.loaders[context.type] = undefined;
+ }
+ this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.NETWORK_ERROR, details: details, fatal: fatal, url: loader.url, loader: loader, context: context });
+ }
+ }]);
+
+ return PlaylistLoader;
+}(_eventHandler2.default);
+
+exports.default = PlaylistLoader;
+
+},{"2":2,"30":30,"31":31,"32":32,"44":44,"50":50}],41:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+/**
+ * Generate MP4 Box
+*/
+
+//import Hex from '../utils/hex';
+
+var UINT32_MAX = Math.pow(2, 32) - 1;
+
+var MP4 = function () {
+ function MP4() {
+ _classCallCheck(this, MP4);
+ }
+
+ _createClass(MP4, null, [{
+ key: 'init',
+ value: function init() {
+ MP4.types = {
+ avc1: [], // codingname
+ avcC: [],
+ btrt: [],
+ dinf: [],
+ dref: [],
+ esds: [],
+ ftyp: [],
+ hdlr: [],
+ mdat: [],
+ mdhd: [],
+ mdia: [],
+ mfhd: [],
+ minf: [],
+ moof: [],
+ moov: [],
+ mp4a: [],
+ '.mp3': [],
+ mvex: [],
+ mvhd: [],
+ pasp: [],
+ sdtp: [],
+ stbl: [],
+ stco: [],
+ stsc: [],
+ stsd: [],
+ stsz: [],
+ stts: [],
+ tfdt: [],
+ tfhd: [],
+ traf: [],
+ trak: [],
+ trun: [],
+ trex: [],
+ tkhd: [],
+ vmhd: [],
+ smhd: []
+ };
+
+ var i;
+ for (i in MP4.types) {
+ if (MP4.types.hasOwnProperty(i)) {
+ MP4.types[i] = [i.charCodeAt(0), i.charCodeAt(1), i.charCodeAt(2), i.charCodeAt(3)];
+ }
+ }
+
+ var videoHdlr = new Uint8Array([0x00, // version 0
+ 0x00, 0x00, 0x00, // flags
+ 0x00, 0x00, 0x00, 0x00, // pre_defined
+ 0x76, 0x69, 0x64, 0x65, // handler_type: 'vide'
+ 0x00, 0x00, 0x00, 0x00, // reserved
+ 0x00, 0x00, 0x00, 0x00, // reserved
+ 0x00, 0x00, 0x00, 0x00, // reserved
+ 0x56, 0x69, 0x64, 0x65, 0x6f, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00 // name: 'VideoHandler'
+ ]);
+
+ var audioHdlr = new Uint8Array([0x00, // version 0
+ 0x00, 0x00, 0x00, // flags
+ 0x00, 0x00, 0x00, 0x00, // pre_defined
+ 0x73, 0x6f, 0x75, 0x6e, // handler_type: 'soun'
+ 0x00, 0x00, 0x00, 0x00, // reserved
+ 0x00, 0x00, 0x00, 0x00, // reserved
+ 0x00, 0x00, 0x00, 0x00, // reserved
+ 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00 // name: 'SoundHandler'
+ ]);
+
+ MP4.HDLR_TYPES = {
+ 'video': videoHdlr,
+ 'audio': audioHdlr
+ };
+
+ var dref = new Uint8Array([0x00, // version 0
+ 0x00, 0x00, 0x00, // flags
+ 0x00, 0x00, 0x00, 0x01, // entry_count
+ 0x00, 0x00, 0x00, 0x0c, // entry_size
+ 0x75, 0x72, 0x6c, 0x20, // 'url' type
+ 0x00, // version 0
+ 0x00, 0x00, 0x01 // entry_flags
+ ]);
+
+ var stco = new Uint8Array([0x00, // version
+ 0x00, 0x00, 0x00, // flags
+ 0x00, 0x00, 0x00, 0x00 // entry_count
+ ]);
+
+ MP4.STTS = MP4.STSC = MP4.STCO = stco;
+
+ MP4.STSZ = new Uint8Array([0x00, // version
+ 0x00, 0x00, 0x00, // flags
+ 0x00, 0x00, 0x00, 0x00, // sample_size
+ 0x00, 0x00, 0x00, 0x00]);
+ MP4.VMHD = new Uint8Array([0x00, // version
+ 0x00, 0x00, 0x01, // flags
+ 0x00, 0x00, // graphicsmode
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // opcolor
+ ]);
+ MP4.SMHD = new Uint8Array([0x00, // version
+ 0x00, 0x00, 0x00, // flags
+ 0x00, 0x00, // balance
+ 0x00, 0x00 // reserved
+ ]);
+
+ MP4.STSD = new Uint8Array([0x00, // version 0
+ 0x00, 0x00, 0x00, // flags
+ 0x00, 0x00, 0x00, 0x01]); // entry_count
+
+ var majorBrand = new Uint8Array([105, 115, 111, 109]); // isom
+ var avc1Brand = new Uint8Array([97, 118, 99, 49]); // avc1
+ var minorVersion = new Uint8Array([0, 0, 0, 1]);
+
+ MP4.FTYP = MP4.box(MP4.types.ftyp, majorBrand, minorVersion, majorBrand, avc1Brand);
+ MP4.DINF = MP4.box(MP4.types.dinf, MP4.box(MP4.types.dref, dref));
+ }
+ }, {
+ key: 'box',
+ value: function box(type) {
+ var payload = Array.prototype.slice.call(arguments, 1),
+ size = 8,
+ i = payload.length,
+ len = i,
+ result;
+ // calculate the total size we need to allocate
+ while (i--) {
+ size += payload[i].byteLength;
+ }
+ result = new Uint8Array(size);
+ result[0] = size >> 24 & 0xff;
+ result[1] = size >> 16 & 0xff;
+ result[2] = size >> 8 & 0xff;
+ result[3] = size & 0xff;
+ result.set(type, 4);
+ // copy the payload into the result
+ for (i = 0, size = 8; i < len; i++) {
+ // copy payload[i] array @ offset size
+ result.set(payload[i], size);
+ size += payload[i].byteLength;
+ }
+ return result;
+ }
+ }, {
+ key: 'hdlr',
+ value: function hdlr(type) {
+ return MP4.box(MP4.types.hdlr, MP4.HDLR_TYPES[type]);
+ }
+ }, {
+ key: 'mdat',
+ value: function mdat(data) {
+ return MP4.box(MP4.types.mdat, data);
+ }
+ }, {
+ key: 'mdhd',
+ value: function mdhd(timescale, duration) {
+ duration *= timescale;
+ var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1));
+ var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));
+ return MP4.box(MP4.types.mdhd, new Uint8Array([0x01, // version 1
+ 0x00, 0x00, 0x00, // flags
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, // creation_time
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // modification_time
+ timescale >> 24 & 0xFF, timescale >> 16 & 0xFF, timescale >> 8 & 0xFF, timescale & 0xFF, // timescale
+ upperWordDuration >> 24, upperWordDuration >> 16 & 0xFF, upperWordDuration >> 8 & 0xFF, upperWordDuration & 0xFF, lowerWordDuration >> 24, lowerWordDuration >> 16 & 0xFF, lowerWordDuration >> 8 & 0xFF, lowerWordDuration & 0xFF, 0x55, 0xc4, // 'und' language (undetermined)
+ 0x00, 0x00]));
+ }
+ }, {
+ key: 'mdia',
+ value: function mdia(track) {
+ return MP4.box(MP4.types.mdia, MP4.mdhd(track.timescale, track.duration), MP4.hdlr(track.type), MP4.minf(track));
+ }
+ }, {
+ key: 'mfhd',
+ value: function mfhd(sequenceNumber) {
+ return MP4.box(MP4.types.mfhd, new Uint8Array([0x00, 0x00, 0x00, 0x00, // flags
+ sequenceNumber >> 24, sequenceNumber >> 16 & 0xFF, sequenceNumber >> 8 & 0xFF, sequenceNumber & 0xFF]));
+ }
+ }, {
+ key: 'minf',
+ value: function minf(track) {
+ if (track.type === 'audio') {
+ return MP4.box(MP4.types.minf, MP4.box(MP4.types.smhd, MP4.SMHD), MP4.DINF, MP4.stbl(track));
+ } else {
+ return MP4.box(MP4.types.minf, MP4.box(MP4.types.vmhd, MP4.VMHD), MP4.DINF, MP4.stbl(track));
+ }
+ }
+ }, {
+ key: 'moof',
+ value: function moof(sn, baseMediaDecodeTime, track) {
+ return MP4.box(MP4.types.moof, MP4.mfhd(sn), MP4.traf(track, baseMediaDecodeTime));
+ }
+ /**
+ * @param tracks... (optional) {array} the tracks associated with this movie
+ */
+
+ }, {
+ key: 'moov',
+ value: function moov(tracks) {
+ var i = tracks.length,
+ boxes = [];
+
+ while (i--) {
+ boxes[i] = MP4.trak(tracks[i]);
+ }
+
+ return MP4.box.apply(null, [MP4.types.moov, MP4.mvhd(tracks[0].timescale, tracks[0].duration)].concat(boxes).concat(MP4.mvex(tracks)));
+ }
+ }, {
+ key: 'mvex',
+ value: function mvex(tracks) {
+ var i = tracks.length,
+ boxes = [];
+
+ while (i--) {
+ boxes[i] = MP4.trex(tracks[i]);
+ }
+ return MP4.box.apply(null, [MP4.types.mvex].concat(boxes));
+ }
+ }, {
+ key: 'mvhd',
+ value: function mvhd(timescale, duration) {
+ duration *= timescale;
+ var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1));
+ var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));
+ var bytes = new Uint8Array([0x01, // version 1
+ 0x00, 0x00, 0x00, // flags
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, // creation_time
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // modification_time
+ timescale >> 24 & 0xFF, timescale >> 16 & 0xFF, timescale >> 8 & 0xFF, timescale & 0xFF, // timescale
+ upperWordDuration >> 24, upperWordDuration >> 16 & 0xFF, upperWordDuration >> 8 & 0xFF, upperWordDuration & 0xFF, lowerWordDuration >> 24, lowerWordDuration >> 16 & 0xFF, lowerWordDuration >> 8 & 0xFF, lowerWordDuration & 0xFF, 0x00, 0x01, 0x00, 0x00, // 1.0 rate
+ 0x01, 0x00, // 1.0 volume
+ 0x00, 0x00, // reserved
+ 0x00, 0x00, 0x00, 0x00, // reserved
+ 0x00, 0x00, 0x00, 0x00, // reserved
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // transformation: unity matrix
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pre_defined
+ 0xff, 0xff, 0xff, 0xff // next_track_ID
+ ]);
+ return MP4.box(MP4.types.mvhd, bytes);
+ }
+ }, {
+ key: 'sdtp',
+ value: function sdtp(track) {
+ var samples = track.samples || [],
+ bytes = new Uint8Array(4 + samples.length),
+ flags,
+ i;
+ // leave the full box header (4 bytes) all zero
+ // write the sample table
+ for (i = 0; i < samples.length; i++) {
+ flags = samples[i].flags;
+ bytes[i + 4] = flags.dependsOn << 4 | flags.isDependedOn << 2 | flags.hasRedundancy;
+ }
+
+ return MP4.box(MP4.types.sdtp, bytes);
+ }
+ }, {
+ key: 'stbl',
+ value: function stbl(track) {
+ return MP4.box(MP4.types.stbl, MP4.stsd(track), MP4.box(MP4.types.stts, MP4.STTS), MP4.box(MP4.types.stsc, MP4.STSC), MP4.box(MP4.types.stsz, MP4.STSZ), MP4.box(MP4.types.stco, MP4.STCO));
+ }
+ }, {
+ key: 'avc1',
+ value: function avc1(track) {
+ var sps = [],
+ pps = [],
+ i,
+ data,
+ len;
+ // assemble the SPSs
+
+ for (i = 0; i < track.sps.length; i++) {
+ data = track.sps[i];
+ len = data.byteLength;
+ sps.push(len >>> 8 & 0xFF);
+ sps.push(len & 0xFF);
+ sps = sps.concat(Array.prototype.slice.call(data)); // SPS
+ }
+
+ // assemble the PPSs
+ for (i = 0; i < track.pps.length; i++) {
+ data = track.pps[i];
+ len = data.byteLength;
+ pps.push(len >>> 8 & 0xFF);
+ pps.push(len & 0xFF);
+ pps = pps.concat(Array.prototype.slice.call(data));
+ }
+
+ var avcc = MP4.box(MP4.types.avcC, new Uint8Array([0x01, // version
+ sps[3], // profile
+ sps[4], // profile compat
+ sps[5], // level
+ 0xfc | 3, // lengthSizeMinusOne, hard-coded to 4 bytes
+ 0xE0 | track.sps.length // 3bit reserved (111) + numOfSequenceParameterSets
+ ].concat(sps).concat([track.pps.length // numOfPictureParameterSets
+ ]).concat(pps))),
+ // "PPS"
+ width = track.width,
+ height = track.height,
+ hSpacing = track.pixelRatio[0],
+ vSpacing = track.pixelRatio[1];
+ //console.log('avcc:' + Hex.hexDump(avcc));
+ return MP4.box(MP4.types.avc1, new Uint8Array([0x00, 0x00, 0x00, // reserved
+ 0x00, 0x00, 0x00, // reserved
+ 0x00, 0x01, // data_reference_index
+ 0x00, 0x00, // pre_defined
+ 0x00, 0x00, // reserved
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // pre_defined
+ width >> 8 & 0xFF, width & 0xff, // width
+ height >> 8 & 0xFF, height & 0xff, // height
+ 0x00, 0x48, 0x00, 0x00, // horizresolution
+ 0x00, 0x48, 0x00, 0x00, // vertresolution
+ 0x00, 0x00, 0x00, 0x00, // reserved
+ 0x00, 0x01, // frame_count
+ 0x12, 0x64, 0x61, 0x69, 0x6C, //dailymotion/hls.js
+ 0x79, 0x6D, 0x6F, 0x74, 0x69, 0x6F, 0x6E, 0x2F, 0x68, 0x6C, 0x73, 0x2E, 0x6A, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // compressorname
+ 0x00, 0x18, // depth = 24
+ 0x11, 0x11]), // pre_defined = -1
+ avcc, MP4.box(MP4.types.btrt, new Uint8Array([0x00, 0x1c, 0x9c, 0x80, // bufferSizeDB
+ 0x00, 0x2d, 0xc6, 0xc0, // maxBitrate
+ 0x00, 0x2d, 0xc6, 0xc0])), // avgBitrate
+ MP4.box(MP4.types.pasp, new Uint8Array([hSpacing >> 24, // hSpacing
+ hSpacing >> 16 & 0xFF, hSpacing >> 8 & 0xFF, hSpacing & 0xFF, vSpacing >> 24, // vSpacing
+ vSpacing >> 16 & 0xFF, vSpacing >> 8 & 0xFF, vSpacing & 0xFF])));
+ }
+ }, {
+ key: 'esds',
+ value: function esds(track) {
+ var configlen = track.config.length;
+ return new Uint8Array([0x00, // version 0
+ 0x00, 0x00, 0x00, // flags
+
+ 0x03, // descriptor_type
+ 0x17 + configlen, // length
+ 0x00, 0x01, //es_id
+ 0x00, // stream_priority
+
+ 0x04, // descriptor_type
+ 0x0f + configlen, // length
+ 0x40, //codec : mpeg4_audio
+ 0x15, // stream_type
+ 0x00, 0x00, 0x00, // buffer_size
+ 0x00, 0x00, 0x00, 0x00, // maxBitrate
+ 0x00, 0x00, 0x00, 0x00, // avgBitrate
+
+ 0x05 // descriptor_type
+ ].concat([configlen]).concat(track.config).concat([0x06, 0x01, 0x02])); // GASpecificConfig)); // length + audio config descriptor
+ }
+ }, {
+ key: 'mp4a',
+ value: function mp4a(track) {
+ var samplerate = track.samplerate;
+ return MP4.box(MP4.types.mp4a, new Uint8Array([0x00, 0x00, 0x00, // reserved
+ 0x00, 0x00, 0x00, // reserved
+ 0x00, 0x01, // data_reference_index
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
+ 0x00, track.channelCount, // channelcount
+ 0x00, 0x10, // sampleSize:16bits
+ 0x00, 0x00, 0x00, 0x00, // reserved2
+ samplerate >> 8 & 0xFF, samplerate & 0xff, //
+ 0x00, 0x00]), MP4.box(MP4.types.esds, MP4.esds(track)));
+ }
+ }, {
+ key: 'mp3',
+ value: function mp3(track) {
+ var samplerate = track.samplerate;
+ return MP4.box(MP4.types['.mp3'], new Uint8Array([0x00, 0x00, 0x00, // reserved
+ 0x00, 0x00, 0x00, // reserved
+ 0x00, 0x01, // data_reference_index
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
+ 0x00, track.channelCount, // channelcount
+ 0x00, 0x10, // sampleSize:16bits
+ 0x00, 0x00, 0x00, 0x00, // reserved2
+ samplerate >> 8 & 0xFF, samplerate & 0xff, //
+ 0x00, 0x00]));
+ }
+ }, {
+ key: 'stsd',
+ value: function stsd(track) {
+ if (track.type === 'audio') {
+ if (!track.isAAC && track.codec === 'mp3') {
+ return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp3(track));
+ }
+ return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track));
+ } else {
+ return MP4.box(MP4.types.stsd, MP4.STSD, MP4.avc1(track));
+ }
+ }
+ }, {
+ key: 'tkhd',
+ value: function tkhd(track) {
+ var id = track.id,
+ duration = track.duration * track.timescale,
+ width = track.width,
+ height = track.height,
+ upperWordDuration = Math.floor(duration / (UINT32_MAX + 1)),
+ lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));
+ return MP4.box(MP4.types.tkhd, new Uint8Array([0x01, // version 1
+ 0x00, 0x00, 0x07, // flags
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, // creation_time
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // modification_time
+ id >> 24 & 0xFF, id >> 16 & 0xFF, id >> 8 & 0xFF, id & 0xFF, // track_ID
+ 0x00, 0x00, 0x00, 0x00, // reserved
+ upperWordDuration >> 24, upperWordDuration >> 16 & 0xFF, upperWordDuration >> 8 & 0xFF, upperWordDuration & 0xFF, lowerWordDuration >> 24, lowerWordDuration >> 16 & 0xFF, lowerWordDuration >> 8 & 0xFF, lowerWordDuration & 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
+ 0x00, 0x00, // layer
+ 0x00, 0x00, // alternate_group
+ 0x00, 0x00, // non-audio track volume
+ 0x00, 0x00, // reserved
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, // transformation: unity matrix
+ width >> 8 & 0xFF, width & 0xFF, 0x00, 0x00, // width
+ height >> 8 & 0xFF, height & 0xFF, 0x00, 0x00 // height
+ ]));
+ }
+ }, {
+ key: 'traf',
+ value: function traf(track, baseMediaDecodeTime) {
+ var sampleDependencyTable = MP4.sdtp(track),
+ id = track.id,
+ upperWordBaseMediaDecodeTime = Math.floor(baseMediaDecodeTime / (UINT32_MAX + 1)),
+ lowerWordBaseMediaDecodeTime = Math.floor(baseMediaDecodeTime % (UINT32_MAX + 1));
+ return MP4.box(MP4.types.traf, MP4.box(MP4.types.tfhd, new Uint8Array([0x00, // version 0
+ 0x00, 0x00, 0x00, // flags
+ id >> 24, id >> 16 & 0XFF, id >> 8 & 0XFF, id & 0xFF])), MP4.box(MP4.types.tfdt, new Uint8Array([0x01, // version 1
+ 0x00, 0x00, 0x00, // flags
+ upperWordBaseMediaDecodeTime >> 24, upperWordBaseMediaDecodeTime >> 16 & 0XFF, upperWordBaseMediaDecodeTime >> 8 & 0XFF, upperWordBaseMediaDecodeTime & 0xFF, lowerWordBaseMediaDecodeTime >> 24, lowerWordBaseMediaDecodeTime >> 16 & 0XFF, lowerWordBaseMediaDecodeTime >> 8 & 0XFF, lowerWordBaseMediaDecodeTime & 0xFF])), MP4.trun(track, sampleDependencyTable.length + 16 + // tfhd
+ 20 + // tfdt
+ 8 + // traf header
+ 16 + // mfhd
+ 8 + // moof header
+ 8), // mdat header
+ sampleDependencyTable);
+ }
+
+ /**
+ * Generate a track box.
+ * @param track {object} a track definition
+ * @return {Uint8Array} the track box
+ */
+
+ }, {
+ key: 'trak',
+ value: function trak(track) {
+ track.duration = track.duration || 0xffffffff;
+ return MP4.box(MP4.types.trak, MP4.tkhd(track), MP4.mdia(track));
+ }
+ }, {
+ key: 'trex',
+ value: function trex(track) {
+ var id = track.id;
+ return MP4.box(MP4.types.trex, new Uint8Array([0x00, // version 0
+ 0x00, 0x00, 0x00, // flags
+ id >> 24, id >> 16 & 0XFF, id >> 8 & 0XFF, id & 0xFF, // track_ID
+ 0x00, 0x00, 0x00, 0x01, // default_sample_description_index
+ 0x00, 0x00, 0x00, 0x00, // default_sample_duration
+ 0x00, 0x00, 0x00, 0x00, // default_sample_size
+ 0x00, 0x01, 0x00, 0x01 // default_sample_flags
+ ]));
+ }
+ }, {
+ key: 'trun',
+ value: function trun(track, offset) {
+ var samples = track.samples || [],
+ len = samples.length,
+ arraylen = 12 + 16 * len,
+ array = new Uint8Array(arraylen),
+ i,
+ sample,
+ duration,
+ size,
+ flags,
+ cts;
+ offset += 8 + arraylen;
+ array.set([0x00, // version 0
+ 0x00, 0x0f, 0x01, // flags
+ len >>> 24 & 0xFF, len >>> 16 & 0xFF, len >>> 8 & 0xFF, len & 0xFF, // sample_count
+ offset >>> 24 & 0xFF, offset >>> 16 & 0xFF, offset >>> 8 & 0xFF, offset & 0xFF // data_offset
+ ], 0);
+ for (i = 0; i < len; i++) {
+ sample = samples[i];
+ duration = sample.duration;
+ size = sample.size;
+ flags = sample.flags;
+ cts = sample.cts;
+ array.set([duration >>> 24 & 0xFF, duration >>> 16 & 0xFF, duration >>> 8 & 0xFF, duration & 0xFF, // sample_duration
+ size >>> 24 & 0xFF, size >>> 16 & 0xFF, size >>> 8 & 0xFF, size & 0xFF, // sample_size
+ flags.isLeading << 2 | flags.dependsOn, flags.isDependedOn << 6 | flags.hasRedundancy << 4 | flags.paddingValue << 1 | flags.isNonSync, flags.degradPrio & 0xF0 << 8, flags.degradPrio & 0x0F, // sample_flags
+ cts >>> 24 & 0xFF, cts >>> 16 & 0xFF, cts >>> 8 & 0xFF, cts & 0xFF // sample_composition_time_offset
+ ], 12 + 16 * i);
+ }
+ return MP4.box(MP4.types.trun, array);
+ }
+ }, {
+ key: 'initSegment',
+ value: function initSegment(tracks) {
+ if (!MP4.types) {
+ MP4.init();
+ }
+ var movie = MP4.moov(tracks),
+ result;
+ result = new Uint8Array(MP4.FTYP.byteLength + movie.byteLength);
+ result.set(MP4.FTYP);
+ result.set(movie, MP4.FTYP.byteLength);
+ return result;
+ }
+ }]);
+
+ return MP4;
+}();
+
+exports.default = MP4;
+
+},{}],42:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
+ * fMP4 remuxer
+ */
+
+var _aac = _dereq_(33);
+
+var _aac2 = _interopRequireDefault(_aac);
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+var _logger = _dereq_(50);
+
+var _mp4Generator = _dereq_(41);
+
+var _mp4Generator2 = _interopRequireDefault(_mp4Generator);
+
+var _errors = _dereq_(30);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var MP4Remuxer = function () {
+ function MP4Remuxer(observer, config, typeSupported, vendor) {
+ _classCallCheck(this, MP4Remuxer);
+
+ this.observer = observer;
+ this.config = config;
+ this.typeSupported = typeSupported;
+ var userAgent = navigator.userAgent;
+ this.isSafari = vendor && vendor.indexOf('Apple') > -1 && userAgent && !userAgent.match('CriOS');
+ this.ISGenerated = false;
+ }
+
+ _createClass(MP4Remuxer, [{
+ key: 'destroy',
+ value: function destroy() {}
+ }, {
+ key: 'resetTimeStamp',
+ value: function resetTimeStamp(defaultTimeStamp) {
+ this._initPTS = this._initDTS = defaultTimeStamp;
+ }
+ }, {
+ key: 'resetInitSegment',
+ value: function resetInitSegment() {
+ this.ISGenerated = false;
+ }
+ }, {
+ key: 'remux',
+ value: function remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset) {
+ // generate Init Segment if needed
+ if (!this.ISGenerated) {
+ this.generateIS(audioTrack, videoTrack, timeOffset);
+ }
+
+ if (this.ISGenerated) {
+ // Purposefully remuxing audio before video, so that remuxVideo can use nextAudioPts, which is
+ // calculated in remuxAudio.
+ //logger.log('nb AAC samples:' + audioTrack.samples.length);
+ if (audioTrack.samples.length) {
+ var audioData = this.remuxAudio(audioTrack, timeOffset, contiguous, accurateTimeOffset);
+ //logger.log('nb AVC samples:' + videoTrack.samples.length);
+ if (videoTrack.samples.length) {
+ var audioTrackLength = void 0;
+ if (audioData) {
+ audioTrackLength = audioData.endPTS - audioData.startPTS;
+ }
+ this.remuxVideo(videoTrack, timeOffset, contiguous, audioTrackLength);
+ }
+ } else {
+ var videoData = void 0;
+ //logger.log('nb AVC samples:' + videoTrack.samples.length);
+ if (videoTrack.samples.length) {
+ videoData = this.remuxVideo(videoTrack, timeOffset, contiguous);
+ }
+ if (videoData && audioTrack.codec) {
+ this.remuxEmptyAudio(audioTrack, timeOffset, contiguous, videoData);
+ }
+ }
+ }
+ //logger.log('nb ID3 samples:' + audioTrack.samples.length);
+ if (id3Track.samples.length) {
+ this.remuxID3(id3Track, timeOffset);
+ }
+ //logger.log('nb ID3 samples:' + audioTrack.samples.length);
+ if (textTrack.samples.length) {
+ this.remuxText(textTrack, timeOffset);
+ }
+ //notify end of parsing
+ this.observer.trigger(_events2.default.FRAG_PARSED);
+ }
+ }, {
+ key: 'generateIS',
+ value: function generateIS(audioTrack, videoTrack, timeOffset) {
+ var observer = this.observer,
+ audioSamples = audioTrack.samples,
+ videoSamples = videoTrack.samples,
+ typeSupported = this.typeSupported,
+ container = 'audio/mp4',
+ tracks = {},
+ data = { tracks: tracks },
+ computePTSDTS = this._initPTS === undefined,
+ initPTS,
+ initDTS;
+
+ if (computePTSDTS) {
+ initPTS = initDTS = Infinity;
+ }
+ if (audioTrack.config && audioSamples.length) {
+ // let's use audio sampling rate as MP4 time scale.
+ // rationale is that there is a integer nb of audio frames per audio sample (1024 for AAC)
+ // using audio sampling rate here helps having an integer MP4 frame duration
+ // this avoids potential rounding issue and AV sync issue
+ audioTrack.timescale = audioTrack.samplerate;
+ _logger.logger.log('audio sampling rate : ' + audioTrack.samplerate);
+ if (!audioTrack.isAAC) {
+ if (typeSupported.mpeg) {
+ // Chrome and Safari
+ container = 'audio/mpeg';
+ audioTrack.codec = '';
+ } else if (typeSupported.mp3) {
+ // Firefox
+ audioTrack.codec = 'mp3';
+ }
+ }
+ tracks.audio = {
+ container: container,
+ codec: audioTrack.codec,
+ initSegment: !audioTrack.isAAC && typeSupported.mpeg ? new Uint8Array() : _mp4Generator2.default.initSegment([audioTrack]),
+ metadata: {
+ channelCount: audioTrack.channelCount
+ }
+ };
+ if (computePTSDTS) {
+ // remember first PTS of this demuxing context. for audio, PTS = DTS
+ initPTS = initDTS = audioSamples[0].pts - audioTrack.inputTimeScale * timeOffset;
+ }
+ }
+
+ if (videoTrack.sps && videoTrack.pps && videoSamples.length) {
+ // let's use input time scale as MP4 video timescale
+ // we use input time scale straight away to avoid rounding issues on frame duration / cts computation
+ var inputTimeScale = videoTrack.inputTimeScale;
+ videoTrack.timescale = inputTimeScale;
+ tracks.video = {
+ container: 'video/mp4',
+ codec: videoTrack.codec,
+ initSegment: _mp4Generator2.default.initSegment([videoTrack]),
+ metadata: {
+ width: videoTrack.width,
+ height: videoTrack.height
+ }
+ };
+ if (computePTSDTS) {
+ initPTS = Math.min(initPTS, videoSamples[0].pts - inputTimeScale * timeOffset);
+ initDTS = Math.min(initDTS, videoSamples[0].dts - inputTimeScale * timeOffset);
+ this.observer.trigger(_events2.default.INIT_PTS_FOUND, { initPTS: initPTS });
+ }
+ }
+
+ if (Object.keys(tracks).length) {
+ observer.trigger(_events2.default.FRAG_PARSING_INIT_SEGMENT, data);
+ this.ISGenerated = true;
+ if (computePTSDTS) {
+ this._initPTS = initPTS;
+ this._initDTS = initDTS;
+ }
+ } else {
+ observer.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.FRAG_PARSING_ERROR, fatal: false, reason: 'no audio/video samples found' });
+ }
+ }
+ }, {
+ key: 'remuxVideo',
+ value: function remuxVideo(track, timeOffset, contiguous, audioTrackLength) {
+ var offset = 8,
+ timeScale = track.timescale,
+ mp4SampleDuration,
+ mdat,
+ moof,
+ firstPTS,
+ firstDTS,
+ nextDTS,
+ lastPTS,
+ lastDTS,
+ inputSamples = track.samples,
+ outputSamples = [],
+ nbSamples = inputSamples.length,
+ ptsNormalize = this._PTSNormalize,
+ initDTS = this._initDTS;
+
+ // for (let i = 0; i < track.samples.length; i++) {
+ // let avcSample = track.samples[i];
+ // let units = avcSample.units;
+ // let unitsString = '';
+ // for (let j = 0; j < units.length ; j++) {
+ // unitsString += units[j].type + ',';
+ // if (units[j].data.length < 500) {
+ // unitsString += Hex.hexDump(units[j].data);
+ // }
+ // }
+ // logger.log(avcSample.pts + '/' + avcSample.dts + ',' + unitsString + avcSample.units.length);
+ // }
+
+ // sort video samples by DTS then PTS then demux id order
+ inputSamples.sort(function (a, b) {
+ var deltadts = a.dts - b.dts;
+ var deltapts = a.pts - b.pts;
+ return deltadts ? deltadts : deltapts ? deltapts : a.id - b.id;
+ });
+
+ // handle broken streams with PTS < DTS, tolerance up 200ms (18000 in 90kHz timescale)
+ var PTSDTSshift = inputSamples.reduce(function (prev, curr) {
+ return Math.max(Math.min(prev, curr.pts - curr.dts), -18000);
+ }, 0);
+ if (PTSDTSshift < 0) {
+ _logger.logger.warn('PTS < DTS detected in video samples, shifting DTS by ' + Math.round(PTSDTSshift / 90) + ' ms to overcome this issue');
+ for (var i = 0; i < inputSamples.length; i++) {
+ inputSamples[i].dts += PTSDTSshift;
+ }
+ }
+
+ // PTS is coded on 33bits, and can loop from -2^32 to 2^32
+ // ptsNormalize will make PTS/DTS value monotonic, we use last known DTS value as reference value
+ var nextAvcDts = void 0;
+ // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1)
+ if (contiguous) {
+ // if parsed fragment is contiguous with last one, let's use last DTS value as reference
+ nextAvcDts = this.nextAvcDts;
+ } else {
+ // if not contiguous, let's use target timeOffset
+ nextAvcDts = timeOffset * timeScale;
+ }
+
+ // compute first DTS and last DTS, normalize them against reference value
+ var sample = inputSamples[0];
+ firstDTS = Math.max(ptsNormalize(sample.dts - initDTS, nextAvcDts), 0);
+ firstPTS = Math.max(ptsNormalize(sample.pts - initDTS, nextAvcDts), 0);
+
+ // check timestamp continuity accross consecutive fragments (this is to remove inter-fragment gap/hole)
+ var delta = Math.round((firstDTS - nextAvcDts) / 90);
+ // if fragment are contiguous, detect hole/overlapping between fragments
+ if (contiguous) {
+ if (delta) {
+ if (delta > 1) {
+ _logger.logger.log('AVC:' + delta + ' ms hole between fragments detected,filling it');
+ } else if (delta < -1) {
+ _logger.logger.log('AVC:' + -delta + ' ms overlapping between fragments detected');
+ }
+ // remove hole/gap : set DTS to next expected DTS
+ firstDTS = nextAvcDts;
+ inputSamples[0].dts = firstDTS + initDTS;
+ // offset PTS as well, ensure that PTS is smaller or equal than new DTS
+ firstPTS = Math.max(firstPTS - delta, nextAvcDts);
+ inputSamples[0].pts = firstPTS + initDTS;
+ _logger.logger.log('Video/PTS/DTS adjusted: ' + Math.round(firstPTS / 90) + '/' + Math.round(firstDTS / 90) + ',delta:' + delta + ' ms');
+ }
+ }
+ nextDTS = firstDTS;
+
+ // compute lastPTS/lastDTS
+ sample = inputSamples[inputSamples.length - 1];
+ lastDTS = Math.max(ptsNormalize(sample.dts - initDTS, nextAvcDts), 0);
+ lastPTS = Math.max(ptsNormalize(sample.pts - initDTS, nextAvcDts), 0);
+ lastPTS = Math.max(lastPTS, lastDTS);
+
+ var isSafari = this.isSafari;
+ // on Safari let's signal the same sample duration for all samples
+ // sample duration (as expected by trun MP4 boxes), should be the delta between sample DTS
+ // set this constant duration as being the avg delta between consecutive DTS.
+ if (isSafari) {
+ mp4SampleDuration = Math.round((lastDTS - firstDTS) / (inputSamples.length - 1));
+ }
+
+ var nbNalu = 0,
+ naluLen = 0;
+ for (var _i = 0; _i < nbSamples; _i++) {
+ // compute total/avc sample length and nb of NAL units
+ var _sample = inputSamples[_i],
+ units = _sample.units,
+ nbUnits = units.length,
+ sampleLen = 0;
+ for (var j = 0; j < nbUnits; j++) {
+ sampleLen += units[j].data.length;
+ }
+ naluLen += sampleLen;
+ nbNalu += nbUnits;
+ _sample.length = sampleLen;
+
+ // normalize PTS/DTS
+ if (isSafari) {
+ // sample DTS is computed using a constant decoding offset (mp4SampleDuration) between samples
+ _sample.dts = firstDTS + _i * mp4SampleDuration;
+ } else {
+ // ensure sample monotonic DTS
+ _sample.dts = Math.max(ptsNormalize(_sample.dts - initDTS, nextAvcDts), firstDTS);
+ }
+ // we normalize PTS against nextAvcDts, we also substract initDTS (some streams don't start @ PTS O)
+ // and we ensure that computed value is greater or equal than sample DTS
+ _sample.pts = Math.max(ptsNormalize(_sample.pts - initDTS, nextAvcDts), _sample.dts);
+ }
+
+ /* concatenate the video data and construct the mdat in place
+ (need 8 more bytes to fill length and mpdat type) */
+ var mdatSize = naluLen + 4 * nbNalu + 8;
+ try {
+ mdat = new Uint8Array(mdatSize);
+ } catch (err) {
+ this.observer.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MUX_ERROR, details: _errors.ErrorDetails.REMUX_ALLOC_ERROR, fatal: false, bytes: mdatSize, reason: 'fail allocating video mdat ' + mdatSize });
+ return;
+ }
+ var view = new DataView(mdat.buffer);
+ view.setUint32(0, mdatSize);
+ mdat.set(_mp4Generator2.default.types.mdat, 4);
+
+ for (var _i2 = 0; _i2 < nbSamples; _i2++) {
+ var avcSample = inputSamples[_i2],
+ avcSampleUnits = avcSample.units,
+ mp4SampleLength = 0,
+ compositionTimeOffset = void 0;
+ // convert NALU bitstream to MP4 format (prepend NALU with size field)
+ for (var _j = 0, _nbUnits = avcSampleUnits.length; _j < _nbUnits; _j++) {
+ var unit = avcSampleUnits[_j],
+ unitData = unit.data,
+ unitDataLen = unit.data.byteLength;
+ view.setUint32(offset, unitDataLen);
+ offset += 4;
+ mdat.set(unitData, offset);
+ offset += unitDataLen;
+ mp4SampleLength += 4 + unitDataLen;
+ }
+
+ if (!isSafari) {
+ // expected sample duration is the Decoding Timestamp diff of consecutive samples
+ if (_i2 < nbSamples - 1) {
+ mp4SampleDuration = inputSamples[_i2 + 1].dts - avcSample.dts;
+ } else {
+ var config = this.config,
+ lastFrameDuration = avcSample.dts - inputSamples[_i2 > 0 ? _i2 - 1 : _i2].dts;
+ if (config.stretchShortVideoTrack) {
+ // In some cases, a segment's audio track duration may exceed the video track duration.
+ // Since we've already remuxed audio, and we know how long the audio track is, we look to
+ // see if the delta to the next segment is longer than the minimum of maxBufferHole and
+ // maxSeekHole. If so, playback would potentially get stuck, so we artificially inflate
+ // the duration of the last frame to minimize any potential gap between segments.
+ var maxBufferHole = config.maxBufferHole,
+ maxSeekHole = config.maxSeekHole,
+ gapTolerance = Math.floor(Math.min(maxBufferHole, maxSeekHole) * timeScale),
+ deltaToFrameEnd = (audioTrackLength ? firstPTS + audioTrackLength * timeScale : this.nextAudioPts) - avcSample.pts;
+ if (deltaToFrameEnd > gapTolerance) {
+ // We subtract lastFrameDuration from deltaToFrameEnd to try to prevent any video
+ // frame overlap. maxBufferHole/maxSeekHole should be >> lastFrameDuration anyway.
+ mp4SampleDuration = deltaToFrameEnd - lastFrameDuration;
+ if (mp4SampleDuration < 0) {
+ mp4SampleDuration = lastFrameDuration;
+ }
+ _logger.logger.log('It is approximately ' + deltaToFrameEnd / 90 + ' ms to the next segment; using duration ' + mp4SampleDuration / 90 + ' ms for the last video frame.');
+ } else {
+ mp4SampleDuration = lastFrameDuration;
+ }
+ } else {
+ mp4SampleDuration = lastFrameDuration;
+ }
+ }
+ compositionTimeOffset = Math.round(avcSample.pts - avcSample.dts);
+ } else {
+ compositionTimeOffset = Math.max(0, mp4SampleDuration * Math.round((avcSample.pts - avcSample.dts) / mp4SampleDuration));
+ }
+
+ //console.log('PTS/DTS/initDTS/normPTS/normDTS/relative PTS : ${avcSample.pts}/${avcSample.dts}/${initDTS}/${ptsnorm}/${dtsnorm}/${(avcSample.pts/4294967296).toFixed(3)}');
+ outputSamples.push({
+ size: mp4SampleLength,
+ // constant duration
+ duration: mp4SampleDuration,
+ cts: compositionTimeOffset,
+ flags: {
+ isLeading: 0,
+ isDependedOn: 0,
+ hasRedundancy: 0,
+ degradPrio: 0,
+ dependsOn: avcSample.key ? 2 : 1,
+ isNonSync: avcSample.key ? 0 : 1
+ }
+ });
+ }
+ // next AVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
+ this.nextAvcDts = lastDTS + mp4SampleDuration;
+ var dropped = track.dropped;
+ track.len = 0;
+ track.nbNalu = 0;
+ track.dropped = 0;
+ if (outputSamples.length && navigator.userAgent.toLowerCase().indexOf('chrome') > -1) {
+ var flags = outputSamples[0].flags;
+ // chrome workaround, mark first sample as being a Random Access Point to avoid sourcebuffer append issue
+ // https://code.google.com/p/chromium/issues/detail?id=229412
+ flags.dependsOn = 2;
+ flags.isNonSync = 0;
+ }
+ track.samples = outputSamples;
+ moof = _mp4Generator2.default.moof(track.sequenceNumber++, firstDTS, track);
+ track.samples = [];
+
+ var data = {
+ data1: moof,
+ data2: mdat,
+ startPTS: firstPTS / timeScale,
+ endPTS: (lastPTS + mp4SampleDuration) / timeScale,
+ startDTS: firstDTS / timeScale,
+ endDTS: this.nextAvcDts / timeScale,
+ type: 'video',
+ nb: outputSamples.length,
+ dropped: dropped
+ };
+ this.observer.trigger(_events2.default.FRAG_PARSING_DATA, data);
+ return data;
+ }
+ }, {
+ key: 'remuxAudio',
+ value: function remuxAudio(track, timeOffset, contiguous, accurateTimeOffset) {
+ var inputTimeScale = track.inputTimeScale,
+ mp4timeScale = track.timescale,
+ scaleFactor = inputTimeScale / mp4timeScale,
+ mp4SampleDuration = track.isAAC ? 1024 : 1152,
+ inputSampleDuration = mp4SampleDuration * scaleFactor,
+ ptsNormalize = this._PTSNormalize,
+ initDTS = this._initDTS,
+ rawMPEG = !track.isAAC && this.typeSupported.mpeg;
+
+ var view,
+ offset = rawMPEG ? 0 : 8,
+ audioSample,
+ mp4Sample,
+ unit,
+ mdat,
+ moof,
+ firstPTS,
+ firstDTS,
+ lastDTS,
+ pts,
+ dts,
+ ptsnorm,
+ dtsnorm,
+ outputSamples = [],
+ inputSamples = [],
+ fillFrame,
+ newStamp,
+ nextAudioPts;
+
+ track.samples.sort(function (a, b) {
+ return a.pts - b.pts;
+ });
+ inputSamples = track.samples;
+
+ // for audio samples, also consider consecutive fragments as being contiguous (even if a level switch occurs),
+ // for sake of clarity:
+ // consecutive fragments are frags with
+ // - less than 100ms gaps between new time offset and next expected PTS OR
+ // - less than 20 audio frames distance
+ // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1)
+ // this helps ensuring audio continuity
+ // and this also avoids audio glitches/cut when switching quality, or reporting wrong duration on first audio frame
+
+ nextAudioPts = this.nextAudioPts;
+ contiguous |= inputSamples.length && nextAudioPts && (Math.abs(timeOffset - nextAudioPts / inputTimeScale) < 0.1 || Math.abs(inputSamples[0].pts - nextAudioPts - initDTS) < 20 * inputSampleDuration);
+
+ if (!contiguous) {
+ // if fragments are not contiguous, let's use timeOffset to compute next Audio PTS
+ nextAudioPts = timeOffset * inputTimeScale;
+ }
+ // If the audio track is missing samples, the frames seem to get "left-shifted" within the
+ // resulting mp4 segment, causing sync issues and leaving gaps at the end of the audio segment.
+ // In an effort to prevent this from happening, we inject frames here where there are gaps.
+ // When possible, we inject a silent frame; when that's not possible, we duplicate the last
+ // frame.
+
+ // only inject/drop audio frames in case time offset is accurate
+ if (accurateTimeOffset && track.isAAC) {
+ for (var i = 0, nextPtsNorm = nextAudioPts; i < inputSamples.length;) {
+ // First, let's see how far off this frame is from where we expect it to be
+ var sample = inputSamples[i],
+ ptsNorm = ptsNormalize(sample.pts - initDTS, nextAudioPts),
+ delta = ptsNorm - nextPtsNorm;
+
+ // If we're overlapping by more than a duration, drop this sample
+ if (delta <= -inputSampleDuration) {
+ _logger.logger.warn('Dropping 1 audio frame @ ' + (nextPtsNorm / inputTimeScale).toFixed(3) + 's due to ' + Math.abs(1000 * delta / inputTimeScale) + ' ms overlap.');
+ inputSamples.splice(i, 1);
+ track.len -= sample.unit.length;
+ // Don't touch nextPtsNorm or i
+ }
+ // Otherwise, if we're more than a frame away from where we should be, insert missing frames
+ // also only inject silent audio frames if currentTime !== 0 (nextPtsNorm !== 0)
+ else if (delta >= inputSampleDuration && nextPtsNorm) {
+ var missing = Math.round(delta / inputSampleDuration);
+ _logger.logger.warn('Injecting ' + missing + ' audio frame @ ' + (nextPtsNorm / inputTimeScale).toFixed(3) + 's due to ' + 1000 * delta / inputTimeScale + ' ms gap.');
+ for (var j = 0; j < missing; j++) {
+ newStamp = nextPtsNorm + initDTS;
+ newStamp = Math.max(newStamp, initDTS);
+ fillFrame = _aac2.default.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
+ if (!fillFrame) {
+ _logger.logger.log('Unable to get silent frame for given audio codec; duplicating last frame instead.');
+ fillFrame = sample.unit.subarray();
+ }
+ inputSamples.splice(i, 0, { unit: fillFrame, pts: newStamp, dts: newStamp });
+ track.len += fillFrame.length;
+ nextPtsNorm += inputSampleDuration;
+ i += 1;
+ }
+
+ // Adjust sample to next expected pts
+ sample.pts = sample.dts = nextPtsNorm + initDTS;
+ nextPtsNorm += inputSampleDuration;
+ i += 1;
+ }
+ // Otherwise, we're within half a frame duration, so just adjust pts
+ else {
+ if (Math.abs(delta) > 0.1 * inputSampleDuration) {
+ //logger.log(`Invalid frame delta ${Math.round(ptsNorm - nextPtsNorm + inputSampleDuration)} at PTS ${Math.round(ptsNorm / 90)} (should be ${Math.round(inputSampleDuration)}).`);
+ }
+ nextPtsNorm += inputSampleDuration;
+ if (i === 0) {
+ sample.pts = sample.dts = initDTS + nextAudioPts;
+ } else {
+ sample.pts = sample.dts = inputSamples[i - 1].pts + inputSampleDuration;
+ }
+ i += 1;
+ }
+ }
+ }
+
+ for (var _j2 = 0, _nbSamples = inputSamples.length; _j2 < _nbSamples; _j2++) {
+ audioSample = inputSamples[_j2];
+ unit = audioSample.unit;
+ pts = audioSample.pts - initDTS;
+ dts = audioSample.dts - initDTS;
+ //logger.log(`Audio/PTS:${Math.round(pts/90)}`);
+ // if not first sample
+ if (lastDTS !== undefined) {
+ ptsnorm = ptsNormalize(pts, lastDTS);
+ dtsnorm = ptsNormalize(dts, lastDTS);
+ mp4Sample.duration = Math.round((dtsnorm - lastDTS) / scaleFactor);
+ } else {
+ ptsnorm = ptsNormalize(pts, nextAudioPts);
+ dtsnorm = ptsNormalize(dts, nextAudioPts);
+ var _delta = Math.round(1000 * (ptsnorm - nextAudioPts) / inputTimeScale),
+ numMissingFrames = 0;
+ // if fragment are contiguous, detect hole/overlapping between fragments
+ // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1)
+ if (contiguous && track.isAAC) {
+ // log delta
+ if (_delta) {
+ if (_delta > 0) {
+ numMissingFrames = Math.round((ptsnorm - nextAudioPts) / inputSampleDuration);
+ _logger.logger.log(_delta + ' ms hole between AAC samples detected,filling it');
+ if (numMissingFrames > 0) {
+ fillFrame = _aac2.default.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
+ if (!fillFrame) {
+ fillFrame = unit.subarray();
+ }
+ track.len += numMissingFrames * fillFrame.length;
+ }
+ // if we have frame overlap, overlapping for more than half a frame duraion
+ } else if (_delta < -12) {
+ // drop overlapping audio frames... browser will deal with it
+ _logger.logger.log(-_delta + ' ms overlapping between AAC samples detected, drop frame');
+ track.len -= unit.byteLength;
+ continue;
+ }
+ // set PTS/DTS to expected PTS/DTS
+ ptsnorm = dtsnorm = nextAudioPts;
+ }
+ }
+ // remember first PTS of our audioSamples, ensure value is positive
+ firstPTS = Math.max(0, ptsnorm);
+ firstDTS = Math.max(0, dtsnorm);
+ if (track.len > 0) {
+ /* concatenate the audio data and construct the mdat in place
+ (need 8 more bytes to fill length and mdat type) */
+
+ var mdatSize = rawMPEG ? track.len : track.len + 8;
+ try {
+ mdat = new Uint8Array(mdatSize);
+ } catch (err) {
+ this.observer.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MUX_ERROR, details: _errors.ErrorDetails.REMUX_ALLOC_ERROR, fatal: false, bytes: mdatSize, reason: 'fail allocating audio mdat ' + mdatSize });
+ return;
+ }
+ if (!rawMPEG) {
+ view = new DataView(mdat.buffer);
+ view.setUint32(0, mdatSize);
+ mdat.set(_mp4Generator2.default.types.mdat, 4);
+ }
+ } else {
+ // no audio samples
+ return;
+ }
+ for (var _i3 = 0; _i3 < numMissingFrames; _i3++) {
+ newStamp = ptsnorm - (numMissingFrames - _i3) * inputSampleDuration;
+ fillFrame = _aac2.default.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
+ if (!fillFrame) {
+ _logger.logger.log('Unable to get silent frame for given audio codec; duplicating this frame instead.');
+ fillFrame = unit.subarray();
+ }
+ mdat.set(fillFrame, offset);
+ offset += fillFrame.byteLength;
+ mp4Sample = {
+ size: fillFrame.byteLength,
+ cts: 0,
+ duration: 1024,
+ flags: {
+ isLeading: 0,
+ isDependedOn: 0,
+ hasRedundancy: 0,
+ degradPrio: 0,
+ dependsOn: 1
+ }
+ };
+ outputSamples.push(mp4Sample);
+ }
+ }
+ mdat.set(unit, offset);
+ var unitLen = unit.byteLength;
+ offset += unitLen;
+ //console.log('PTS/DTS/initDTS/normPTS/normDTS/relative PTS : ${audioSample.pts}/${audioSample.dts}/${initDTS}/${ptsnorm}/${dtsnorm}/${(audioSample.pts/4294967296).toFixed(3)}');
+ mp4Sample = {
+ size: unitLen,
+ cts: 0,
+ duration: 0,
+ flags: {
+ isLeading: 0,
+ isDependedOn: 0,
+ hasRedundancy: 0,
+ degradPrio: 0,
+ dependsOn: 1
+ }
+ };
+ outputSamples.push(mp4Sample);
+ lastDTS = dtsnorm;
+ }
+ var lastSampleDuration = 0;
+ var nbSamples = outputSamples.length;
+ //set last sample duration as being identical to previous sample
+ if (nbSamples >= 2) {
+ lastSampleDuration = outputSamples[nbSamples - 2].duration;
+ mp4Sample.duration = lastSampleDuration;
+ }
+ if (nbSamples) {
+ // next audio sample PTS should be equal to last sample PTS + duration
+ this.nextAudioPts = ptsnorm + scaleFactor * lastSampleDuration;
+ //logger.log('Audio/PTS/PTSend:' + audioSample.pts.toFixed(0) + '/' + this.nextAacDts.toFixed(0));
+ track.len = 0;
+ track.samples = outputSamples;
+ if (rawMPEG) {
+ moof = new Uint8Array();
+ } else {
+ moof = _mp4Generator2.default.moof(track.sequenceNumber++, firstDTS / scaleFactor, track);
+ }
+ track.samples = [];
+ var audioData = {
+ data1: moof,
+ data2: mdat,
+ startPTS: firstPTS / inputTimeScale,
+ endPTS: this.nextAudioPts / inputTimeScale,
+ startDTS: firstDTS / inputTimeScale,
+ endDTS: (dtsnorm + scaleFactor * lastSampleDuration) / inputTimeScale,
+ type: 'audio',
+ nb: nbSamples
+ };
+ this.observer.trigger(_events2.default.FRAG_PARSING_DATA, audioData);
+ return audioData;
+ }
+ return null;
+ }
+ }, {
+ key: 'remuxEmptyAudio',
+ value: function remuxEmptyAudio(track, timeOffset, contiguous, videoData) {
+ var inputTimeScale = track.inputTimeScale,
+ mp4timeScale = track.samplerate ? track.samplerate : inputTimeScale,
+ scaleFactor = inputTimeScale / mp4timeScale,
+ nextAudioPts = this.nextAudioPts,
+
+
+ // sync with video's timestamp
+ startDTS = (nextAudioPts !== undefined ? nextAudioPts : videoData.startDTS * inputTimeScale) + this._initDTS,
+ endDTS = videoData.endDTS * inputTimeScale + this._initDTS,
+
+ // one sample's duration value
+ sampleDuration = 1024,
+ frameDuration = scaleFactor * sampleDuration,
+
+
+ // samples count of this segment's duration
+ nbSamples = Math.ceil((endDTS - startDTS) / frameDuration),
+
+
+ // silent frame
+ silentFrame = _aac2.default.getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
+
+ _logger.logger.warn('remux empty Audio');
+ // Can't remux if we can't generate a silent frame...
+ if (!silentFrame) {
+ _logger.logger.trace('Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec!');
+ return;
+ }
+
+ var samples = [];
+ for (var i = 0; i < nbSamples; i++) {
+ var stamp = startDTS + i * frameDuration;
+ samples.push({ unit: silentFrame, pts: stamp, dts: stamp });
+ track.len += silentFrame.length;
+ }
+ track.samples = samples;
+
+ this.remuxAudio(track, timeOffset, contiguous);
+ }
+ }, {
+ key: 'remuxID3',
+ value: function remuxID3(track, timeOffset) {
+ var length = track.samples.length,
+ sample;
+ var inputTimeScale = track.inputTimeScale;
+ var initPTS = this._initPTS;
+ var initDTS = this._initDTS;
+ // consume samples
+ if (length) {
+ for (var index = 0; index < length; index++) {
+ sample = track.samples[index];
+ // setting id3 pts, dts to relative time
+ // using this._initPTS and this._initDTS to calculate relative time
+ sample.pts = (sample.pts - initPTS) / inputTimeScale;
+ sample.dts = (sample.dts - initDTS) / inputTimeScale;
+ }
+ this.observer.trigger(_events2.default.FRAG_PARSING_METADATA, {
+ samples: track.samples
+ });
+ }
+
+ track.samples = [];
+ timeOffset = timeOffset;
+ }
+ }, {
+ key: 'remuxText',
+ value: function remuxText(track, timeOffset) {
+ track.samples.sort(function (a, b) {
+ return a.pts - b.pts;
+ });
+
+ var length = track.samples.length,
+ sample;
+ var inputTimeScale = track.inputTimeScale;
+ var initPTS = this._initPTS;
+ // consume samples
+ if (length) {
+ for (var index = 0; index < length; index++) {
+ sample = track.samples[index];
+ // setting text pts, dts to relative time
+ // using this._initPTS and this._initDTS to calculate relative time
+ sample.pts = (sample.pts - initPTS) / inputTimeScale;
+ }
+ this.observer.trigger(_events2.default.FRAG_PARSING_USERDATA, {
+ samples: track.samples
+ });
+ }
+
+ track.samples = [];
+ timeOffset = timeOffset;
+ }
+ }, {
+ key: '_PTSNormalize',
+ value: function _PTSNormalize(value, reference) {
+ var offset;
+ if (reference === undefined) {
+ return value;
+ }
+ if (reference < value) {
+ // - 2^33
+ offset = -8589934592;
+ } else {
+ // + 2^33
+ offset = 8589934592;
+ }
+ /* PTS is 33bit (from 0 to 2^33 -1)
+ if diff between value and reference is bigger than half of the amplitude (2^32) then it means that
+ PTS looping occured. fill the gap */
+ while (Math.abs(value - reference) > 4294967296) {
+ value += offset;
+ }
+ return value;
+ }
+ }]);
+
+ return MP4Remuxer;
+}();
+
+exports.default = MP4Remuxer;
+
+},{"30":30,"32":32,"33":33,"41":41,"50":50}],43:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
+ * passthrough remuxer
+ */
+
+
+var _events = _dereq_(32);
+
+var _events2 = _interopRequireDefault(_events);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var PassThroughRemuxer = function () {
+ function PassThroughRemuxer(observer) {
+ _classCallCheck(this, PassThroughRemuxer);
+
+ this.observer = observer;
+ }
+
+ _createClass(PassThroughRemuxer, [{
+ key: 'destroy',
+ value: function destroy() {}
+ }, {
+ key: 'resetTimeStamp',
+ value: function resetTimeStamp() {}
+ }, {
+ key: 'resetInitSegment',
+ value: function resetInitSegment() {}
+ }, {
+ key: 'remux',
+ value: function remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, contiguous, accurateTimeOffset, rawData) {
+ var observer = this.observer;
+ var streamType = '';
+ if (audioTrack) {
+ streamType += 'audio';
+ }
+ if (videoTrack) {
+ streamType += 'video';
+ }
+ observer.trigger(_events2.default.FRAG_PARSING_DATA, {
+ data1: rawData,
+ startPTS: timeOffset,
+ startDTS: timeOffset,
+ type: streamType,
+ nb: 1,
+ dropped: 0
+ });
+ //notify end of parsing
+ observer.trigger(_events2.default.FRAG_PARSED);
+ }
+ }]);
+
+ return PassThroughRemuxer;
+}();
+
+exports.default = PassThroughRemuxer;
+
+},{"32":32}],44:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var DECIMAL_RESOLUTION_REGEX = /^(\d+)x(\d+)$/;
+var ATTR_LIST_REGEX = /\s*(.+?)\s*=((?:\".*?\")|.*?)(?:,|$)/g;
+
+// adapted from https://github.com/kanongil/node-m3u8parse/blob/master/attrlist.js
+
+var AttrList = function () {
+ function AttrList(attrs) {
+ _classCallCheck(this, AttrList);
+
+ if (typeof attrs === 'string') {
+ attrs = AttrList.parseAttrList(attrs);
+ }
+ for (var attr in attrs) {
+ if (attrs.hasOwnProperty(attr)) {
+ this[attr] = attrs[attr];
+ }
+ }
+ }
+
+ _createClass(AttrList, [{
+ key: 'decimalInteger',
+ value: function decimalInteger(attrName) {
+ var intValue = parseInt(this[attrName], 10);
+ if (intValue > Number.MAX_SAFE_INTEGER) {
+ return Infinity;
+ }
+ return intValue;
+ }
+ }, {
+ key: 'hexadecimalInteger',
+ value: function hexadecimalInteger(attrName) {
+ if (this[attrName]) {
+ var stringValue = (this[attrName] || '0x').slice(2);
+ stringValue = (stringValue.length & 1 ? '0' : '') + stringValue;
+
+ var value = new Uint8Array(stringValue.length / 2);
+ for (var i = 0; i < stringValue.length / 2; i++) {
+ value[i] = parseInt(stringValue.slice(i * 2, i * 2 + 2), 16);
+ }
+ return value;
+ } else {
+ return null;
+ }
+ }
+ }, {
+ key: 'hexadecimalIntegerAsNumber',
+ value: function hexadecimalIntegerAsNumber(attrName) {
+ var intValue = parseInt(this[attrName], 16);
+ if (intValue > Number.MAX_SAFE_INTEGER) {
+ return Infinity;
+ }
+ return intValue;
+ }
+ }, {
+ key: 'decimalFloatingPoint',
+ value: function decimalFloatingPoint(attrName) {
+ return parseFloat(this[attrName]);
+ }
+ }, {
+ key: 'enumeratedString',
+ value: function enumeratedString(attrName) {
+ return this[attrName];
+ }
+ }, {
+ key: 'decimalResolution',
+ value: function decimalResolution(attrName) {
+ var res = DECIMAL_RESOLUTION_REGEX.exec(this[attrName]);
+ if (res === null) {
+ return undefined;
+ }
+ return {
+ width: parseInt(res[1], 10),
+ height: parseInt(res[2], 10)
+ };
+ }
+ }], [{
+ key: 'parseAttrList',
+ value: function parseAttrList(input) {
+ var match,
+ attrs = {};
+ ATTR_LIST_REGEX.lastIndex = 0;
+ while ((match = ATTR_LIST_REGEX.exec(input)) !== null) {
+ var value = match[2],
+ quote = '"';
+
+ if (value.indexOf(quote) === 0 && value.lastIndexOf(quote) === value.length - 1) {
+ value = value.slice(1, -1);
+ }
+ attrs[match[1]] = value;
+ }
+ return attrs;
+ }
+ }]);
+
+ return AttrList;
+}();
+
+exports.default = AttrList;
+
+},{}],45:[function(_dereq_,module,exports){
+"use strict";
+
+var BinarySearch = {
+ /**
+ * Searches for an item in an array which matches a certain condition.
+ * This requires the condition to only match one item in the array,
+ * and for the array to be ordered.
+ *
+ * @param {Array} list The array to search.
+ * @param {Function} comparisonFunction
+ * Called and provided a candidate item as the first argument.
+ * Should return:
+ * > -1 if the item should be located at a lower index than the provided item.
+ * > 1 if the item should be located at a higher index than the provided item.
+ * > 0 if the item is the item you're looking for.
+ *
+ * @return {*} The object if it is found or null otherwise.
+ */
+ search: function search(list, comparisonFunction) {
+ var minIndex = 0;
+ var maxIndex = list.length - 1;
+ var currentIndex = null;
+ var currentElement = null;
+
+ while (minIndex <= maxIndex) {
+ currentIndex = (minIndex + maxIndex) / 2 | 0;
+ currentElement = list[currentIndex];
+
+ var comparisonResult = comparisonFunction(currentElement);
+ if (comparisonResult > 0) {
+ minIndex = currentIndex + 1;
+ } else if (comparisonResult < 0) {
+ maxIndex = currentIndex - 1;
+ } else {
+ return currentElement;
+ }
+ }
+
+ return null;
+ }
+};
+
+module.exports = BinarySearch;
+
+},{}],46:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+/**
+ *
+ * This code was ported from the dash.js project at:
+ * https://github.com/Dash-Industry-Forum/dash.js/blob/development/externals/cea608-parser.js
+ * https://github.com/Dash-Industry-Forum/dash.js/commit/8269b26a761e0853bb21d78780ed945144ecdd4d#diff-71bc295a2d6b6b7093a1d3290d53a4b2
+ *
+ * The original copyright appears below:
+ *
+ * The copyright in this software is being made available under the BSD License,
+ * included below. This software may be subject to other third party and contributor
+ * rights, including patent rights, and no such rights are granted under this license.
+ *
+ * Copyright (c) 2015-2016, DASH Industry Forum.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * 2. Neither the name of Dash Industry Forum nor the names of its
+ * contributors may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/**
+ * Exceptions from regular ASCII. CodePoints are mapped to UTF-16 codes
+ */
+
+var specialCea608CharsCodes = {
+ 0x2a: 0xe1, // lowercase a, acute accent
+ 0x5c: 0xe9, // lowercase e, acute accent
+ 0x5e: 0xed, // lowercase i, acute accent
+ 0x5f: 0xf3, // lowercase o, acute accent
+ 0x60: 0xfa, // lowercase u, acute accent
+ 0x7b: 0xe7, // lowercase c with cedilla
+ 0x7c: 0xf7, // division symbol
+ 0x7d: 0xd1, // uppercase N tilde
+ 0x7e: 0xf1, // lowercase n tilde
+ 0x7f: 0x2588, // Full block
+ // THIS BLOCK INCLUDES THE 16 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
+ // THAT COME FROM HI BYTE=0x11 AND LOW BETWEEN 0x30 AND 0x3F
+ // THIS MEANS THAT \x50 MUST BE ADDED TO THE VALUES
+ 0x80: 0xae, // Registered symbol (R)
+ 0x81: 0xb0, // degree sign
+ 0x82: 0xbd, // 1/2 symbol
+ 0x83: 0xbf, // Inverted (open) question mark
+ 0x84: 0x2122, // Trademark symbol (TM)
+ 0x85: 0xa2, // Cents symbol
+ 0x86: 0xa3, // Pounds sterling
+ 0x87: 0x266a, // Music 8'th note
+ 0x88: 0xe0, // lowercase a, grave accent
+ 0x89: 0x20, // transparent space (regular)
+ 0x8a: 0xe8, // lowercase e, grave accent
+ 0x8b: 0xe2, // lowercase a, circumflex accent
+ 0x8c: 0xea, // lowercase e, circumflex accent
+ 0x8d: 0xee, // lowercase i, circumflex accent
+ 0x8e: 0xf4, // lowercase o, circumflex accent
+ 0x8f: 0xfb, // lowercase u, circumflex accent
+ // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
+ // THAT COME FROM HI BYTE=0x12 AND LOW BETWEEN 0x20 AND 0x3F
+ 0x90: 0xc1, // capital letter A with acute
+ 0x91: 0xc9, // capital letter E with acute
+ 0x92: 0xd3, // capital letter O with acute
+ 0x93: 0xda, // capital letter U with acute
+ 0x94: 0xdc, // capital letter U with diaresis
+ 0x95: 0xfc, // lowercase letter U with diaeresis
+ 0x96: 0x2018, // opening single quote
+ 0x97: 0xa1, // inverted exclamation mark
+ 0x98: 0x2a, // asterisk
+ 0x99: 0x2019, // closing single quote
+ 0x9a: 0x2501, // box drawings heavy horizontal
+ 0x9b: 0xa9, // copyright sign
+ 0x9c: 0x2120, // Service mark
+ 0x9d: 0x2022, // (round) bullet
+ 0x9e: 0x201c, // Left double quotation mark
+ 0x9f: 0x201d, // Right double quotation mark
+ 0xa0: 0xc0, // uppercase A, grave accent
+ 0xa1: 0xc2, // uppercase A, circumflex
+ 0xa2: 0xc7, // uppercase C with cedilla
+ 0xa3: 0xc8, // uppercase E, grave accent
+ 0xa4: 0xca, // uppercase E, circumflex
+ 0xa5: 0xcb, // capital letter E with diaresis
+ 0xa6: 0xeb, // lowercase letter e with diaresis
+ 0xa7: 0xce, // uppercase I, circumflex
+ 0xa8: 0xcf, // uppercase I, with diaresis
+ 0xa9: 0xef, // lowercase i, with diaresis
+ 0xaa: 0xd4, // uppercase O, circumflex
+ 0xab: 0xd9, // uppercase U, grave accent
+ 0xac: 0xf9, // lowercase u, grave accent
+ 0xad: 0xdb, // uppercase U, circumflex
+ 0xae: 0xab, // left-pointing double angle quotation mark
+ 0xaf: 0xbb, // right-pointing double angle quotation mark
+ // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
+ // THAT COME FROM HI BYTE=0x13 AND LOW BETWEEN 0x20 AND 0x3F
+ 0xb0: 0xc3, // Uppercase A, tilde
+ 0xb1: 0xe3, // Lowercase a, tilde
+ 0xb2: 0xcd, // Uppercase I, acute accent
+ 0xb3: 0xcc, // Uppercase I, grave accent
+ 0xb4: 0xec, // Lowercase i, grave accent
+ 0xb5: 0xd2, // Uppercase O, grave accent
+ 0xb6: 0xf2, // Lowercase o, grave accent
+ 0xb7: 0xd5, // Uppercase O, tilde
+ 0xb8: 0xf5, // Lowercase o, tilde
+ 0xb9: 0x7b, // Open curly brace
+ 0xba: 0x7d, // Closing curly brace
+ 0xbb: 0x5c, // Backslash
+ 0xbc: 0x5e, // Caret
+ 0xbd: 0x5f, // Underscore
+ 0xbe: 0x7c, // Pipe (vertical line)
+ 0xbf: 0x223c, // Tilde operator
+ 0xc0: 0xc4, // Uppercase A, umlaut
+ 0xc1: 0xe4, // Lowercase A, umlaut
+ 0xc2: 0xd6, // Uppercase O, umlaut
+ 0xc3: 0xf6, // Lowercase o, umlaut
+ 0xc4: 0xdf, // Esszett (sharp S)
+ 0xc5: 0xa5, // Yen symbol
+ 0xc6: 0xa4, // Generic currency sign
+ 0xc7: 0x2503, // Box drawings heavy vertical
+ 0xc8: 0xc5, // Uppercase A, ring
+ 0xc9: 0xe5, // Lowercase A, ring
+ 0xca: 0xd8, // Uppercase O, stroke
+ 0xcb: 0xf8, // Lowercase o, strok
+ 0xcc: 0x250f, // Box drawings heavy down and right
+ 0xcd: 0x2513, // Box drawings heavy down and left
+ 0xce: 0x2517, // Box drawings heavy up and right
+ 0xcf: 0x251b // Box drawings heavy up and left
+};
+
+/**
+ * Utils
+ */
+var getCharForByte = function getCharForByte(byte) {
+ var charCode = byte;
+ if (specialCea608CharsCodes.hasOwnProperty(byte)) {
+ charCode = specialCea608CharsCodes[byte];
+ }
+ return String.fromCharCode(charCode);
+};
+
+var NR_ROWS = 15,
+ NR_COLS = 100;
+// Tables to look up row from PAC data
+var rowsLowCh1 = { 0x11: 1, 0x12: 3, 0x15: 5, 0x16: 7, 0x17: 9, 0x10: 11, 0x13: 12, 0x14: 14 };
+var rowsHighCh1 = { 0x11: 2, 0x12: 4, 0x15: 6, 0x16: 8, 0x17: 10, 0x13: 13, 0x14: 15 };
+var rowsLowCh2 = { 0x19: 1, 0x1A: 3, 0x1D: 5, 0x1E: 7, 0x1F: 9, 0x18: 11, 0x1B: 12, 0x1C: 14 };
+var rowsHighCh2 = { 0x19: 2, 0x1A: 4, 0x1D: 6, 0x1E: 8, 0x1F: 10, 0x1B: 13, 0x1C: 15 };
+
+var backgroundColors = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta', 'black', 'transparent'];
+
+/**
+ * Simple logger class to be able to write with time-stamps and filter on level.
+ */
+var logger = {
+ verboseFilter: { 'DATA': 3, 'DEBUG': 3, 'INFO': 2, 'WARNING': 2, 'TEXT': 1, 'ERROR': 0 },
+ time: null,
+ verboseLevel: 0, // Only write errors
+ setTime: function setTime(newTime) {
+ this.time = newTime;
+ },
+ log: function log(severity, msg) {
+ var minLevel = this.verboseFilter[severity];
+ if (this.verboseLevel >= minLevel) {
+ console.log(this.time + ' [' + severity + '] ' + msg);
+ }
+ }
+};
+
+var numArrayToHexArray = function numArrayToHexArray(numArray) {
+ var hexArray = [];
+ for (var j = 0; j < numArray.length; j++) {
+ hexArray.push(numArray[j].toString(16));
+ }
+ return hexArray;
+};
+
+var PenState = function () {
+ function PenState(foreground, underline, italics, background, flash) {
+ _classCallCheck(this, PenState);
+
+ this.foreground = foreground || 'white';
+ this.underline = underline || false;
+ this.italics = italics || false;
+ this.background = background || 'black';
+ this.flash = flash || false;
+ }
+
+ _createClass(PenState, [{
+ key: 'reset',
+ value: function reset() {
+ this.foreground = 'white';
+ this.underline = false;
+ this.italics = false;
+ this.background = 'black';
+ this.flash = false;
+ }
+ }, {
+ key: 'setStyles',
+ value: function setStyles(styles) {
+ var attribs = ['foreground', 'underline', 'italics', 'background', 'flash'];
+ for (var i = 0; i < attribs.length; i++) {
+ var style = attribs[i];
+ if (styles.hasOwnProperty(style)) {
+ this[style] = styles[style];
+ }
+ }
+ }
+ }, {
+ key: 'isDefault',
+ value: function isDefault() {
+ return this.foreground === 'white' && !this.underline && !this.italics && this.background === 'black' && !this.flash;
+ }
+ }, {
+ key: 'equals',
+ value: function equals(other) {
+ return this.foreground === other.foreground && this.underline === other.underline && this.italics === other.italics && this.background === other.background && this.flash === other.flash;
+ }
+ }, {
+ key: 'copy',
+ value: function copy(newPenState) {
+ this.foreground = newPenState.foreground;
+ this.underline = newPenState.underline;
+ this.italics = newPenState.italics;
+ this.background = newPenState.background;
+ this.flash = newPenState.flash;
+ }
+ }, {
+ key: 'toString',
+ value: function toString() {
+ return 'color=' + this.foreground + ', underline=' + this.underline + ', italics=' + this.italics + ', background=' + this.background + ', flash=' + this.flash;
+ }
+ }]);
+
+ return PenState;
+}();
+
+/**
+ * Unicode character with styling and background.
+ * @constructor
+ */
+
+
+var StyledUnicodeChar = function () {
+ function StyledUnicodeChar(uchar, foreground, underline, italics, background, flash) {
+ _classCallCheck(this, StyledUnicodeChar);
+
+ this.uchar = uchar || ' '; // unicode character
+ this.penState = new PenState(foreground, underline, italics, background, flash);
+ }
+
+ _createClass(StyledUnicodeChar, [{
+ key: 'reset',
+ value: function reset() {
+ this.uchar = ' ';
+ this.penState.reset();
+ }
+ }, {
+ key: 'setChar',
+ value: function setChar(uchar, newPenState) {
+ this.uchar = uchar;
+ this.penState.copy(newPenState);
+ }
+ }, {
+ key: 'setPenState',
+ value: function setPenState(newPenState) {
+ this.penState.copy(newPenState);
+ }
+ }, {
+ key: 'equals',
+ value: function equals(other) {
+ return this.uchar === other.uchar && this.penState.equals(other.penState);
+ }
+ }, {
+ key: 'copy',
+ value: function copy(newChar) {
+ this.uchar = newChar.uchar;
+ this.penState.copy(newChar.penState);
+ }
+ }, {
+ key: 'isEmpty',
+ value: function isEmpty() {
+ return this.uchar === ' ' && this.penState.isDefault();
+ }
+ }]);
+
+ return StyledUnicodeChar;
+}();
+
+/**
+ * CEA-608 row consisting of NR_COLS instances of StyledUnicodeChar.
+ * @constructor
+ */
+
+
+var Row = function () {
+ function Row() {
+ _classCallCheck(this, Row);
+
+ this.chars = [];
+ for (var i = 0; i < NR_COLS; i++) {
+ this.chars.push(new StyledUnicodeChar());
+ }
+ this.pos = 0;
+ this.currPenState = new PenState();
+ }
+
+ _createClass(Row, [{
+ key: 'equals',
+ value: function equals(other) {
+ var equal = true;
+ for (var i = 0; i < NR_COLS; i++) {
+ if (!this.chars[i].equals(other.chars[i])) {
+ equal = false;
+ break;
+ }
+ }
+ return equal;
+ }
+ }, {
+ key: 'copy',
+ value: function copy(other) {
+ for (var i = 0; i < NR_COLS; i++) {
+ this.chars[i].copy(other.chars[i]);
+ }
+ }
+ }, {
+ key: 'isEmpty',
+ value: function isEmpty() {
+ var empty = true;
+ for (var i = 0; i < NR_COLS; i++) {
+ if (!this.chars[i].isEmpty()) {
+ empty = false;
+ break;
+ }
+ }
+ return empty;
+ }
+
+ /**
+ * Set the cursor to a valid column.
+ */
+
+ }, {
+ key: 'setCursor',
+ value: function setCursor(absPos) {
+ if (this.pos !== absPos) {
+ this.pos = absPos;
+ }
+ if (this.pos < 0) {
+ logger.log('ERROR', 'Negative cursor position ' + this.pos);
+ this.pos = 0;
+ } else if (this.pos > NR_COLS) {
+ logger.log('ERROR', 'Too large cursor position ' + this.pos);
+ this.pos = NR_COLS;
+ }
+ }
+
+ /**
+ * Move the cursor relative to current position.
+ */
+
+ }, {
+ key: 'moveCursor',
+ value: function moveCursor(relPos) {
+ var newPos = this.pos + relPos;
+ if (relPos > 1) {
+ for (var i = this.pos + 1; i < newPos + 1; i++) {
+ this.chars[i].setPenState(this.currPenState);
+ }
+ }
+ this.setCursor(newPos);
+ }
+
+ /**
+ * Backspace, move one step back and clear character.
+ */
+
+ }, {
+ key: 'backSpace',
+ value: function backSpace() {
+ this.moveCursor(-1);
+ this.chars[this.pos].setChar(' ', this.currPenState);
+ }
+ }, {
+ key: 'insertChar',
+ value: function insertChar(byte) {
+ if (byte >= 0x90) {
+ //Extended char
+ this.backSpace();
+ }
+ var char = getCharForByte(byte);
+ if (this.pos >= NR_COLS) {
+ logger.log('ERROR', 'Cannot insert ' + byte.toString(16) + ' (' + char + ') at position ' + this.pos + '. Skipping it!');
+ return;
+ }
+ this.chars[this.pos].setChar(char, this.currPenState);
+ this.moveCursor(1);
+ }
+ }, {
+ key: 'clearFromPos',
+ value: function clearFromPos(startPos) {
+ var i;
+ for (i = startPos; i < NR_COLS; i++) {
+ this.chars[i].reset();
+ }
+ }
+ }, {
+ key: 'clear',
+ value: function clear() {
+ this.clearFromPos(0);
+ this.pos = 0;
+ this.currPenState.reset();
+ }
+ }, {
+ key: 'clearToEndOfRow',
+ value: function clearToEndOfRow() {
+ this.clearFromPos(this.pos);
+ }
+ }, {
+ key: 'getTextString',
+ value: function getTextString() {
+ var chars = [];
+ var empty = true;
+ for (var i = 0; i < NR_COLS; i++) {
+ var char = this.chars[i].uchar;
+ if (char !== ' ') {
+ empty = false;
+ }
+ chars.push(char);
+ }
+ if (empty) {
+ return '';
+ } else {
+ return chars.join('');
+ }
+ }
+ }, {
+ key: 'setPenStyles',
+ value: function setPenStyles(styles) {
+ this.currPenState.setStyles(styles);
+ var currChar = this.chars[this.pos];
+ currChar.setPenState(this.currPenState);
+ }
+ }]);
+
+ return Row;
+}();
+
+/**
+ * Keep a CEA-608 screen of 32x15 styled characters
+ * @constructor
+*/
+
+
+var CaptionScreen = function () {
+ function CaptionScreen() {
+ _classCallCheck(this, CaptionScreen);
+
+ this.rows = [];
+ for (var i = 0; i < NR_ROWS; i++) {
+ this.rows.push(new Row()); // Note that we use zero-based numbering (0-14)
+ }
+ this.currRow = NR_ROWS - 1;
+ this.nrRollUpRows = null;
+ this.reset();
+ }
+
+ _createClass(CaptionScreen, [{
+ key: 'reset',
+ value: function reset() {
+ for (var i = 0; i < NR_ROWS; i++) {
+ this.rows[i].clear();
+ }
+ this.currRow = NR_ROWS - 1;
+ }
+ }, {
+ key: 'equals',
+ value: function equals(other) {
+ var equal = true;
+ for (var i = 0; i < NR_ROWS; i++) {
+ if (!this.rows[i].equals(other.rows[i])) {
+ equal = false;
+ break;
+ }
+ }
+ return equal;
+ }
+ }, {
+ key: 'copy',
+ value: function copy(other) {
+ for (var i = 0; i < NR_ROWS; i++) {
+ this.rows[i].copy(other.rows[i]);
+ }
+ }
+ }, {
+ key: 'isEmpty',
+ value: function isEmpty() {
+ var empty = true;
+ for (var i = 0; i < NR_ROWS; i++) {
+ if (!this.rows[i].isEmpty()) {
+ empty = false;
+ break;
+ }
+ }
+ return empty;
+ }
+ }, {
+ key: 'backSpace',
+ value: function backSpace() {
+ var row = this.rows[this.currRow];
+ row.backSpace();
+ }
+ }, {
+ key: 'clearToEndOfRow',
+ value: function clearToEndOfRow() {
+ var row = this.rows[this.currRow];
+ row.clearToEndOfRow();
+ }
+
+ /**
+ * Insert a character (without styling) in the current row.
+ */
+
+ }, {
+ key: 'insertChar',
+ value: function insertChar(char) {
+ var row = this.rows[this.currRow];
+ row.insertChar(char);
+ }
+ }, {
+ key: 'setPen',
+ value: function setPen(styles) {
+ var row = this.rows[this.currRow];
+ row.setPenStyles(styles);
+ }
+ }, {
+ key: 'moveCursor',
+ value: function moveCursor(relPos) {
+ var row = this.rows[this.currRow];
+ row.moveCursor(relPos);
+ }
+ }, {
+ key: 'setCursor',
+ value: function setCursor(absPos) {
+ logger.log('INFO', 'setCursor: ' + absPos);
+ var row = this.rows[this.currRow];
+ row.setCursor(absPos);
+ }
+ }, {
+ key: 'setPAC',
+ value: function setPAC(pacData) {
+ logger.log('INFO', 'pacData = ' + JSON.stringify(pacData));
+ var newRow = pacData.row - 1;
+ if (this.nrRollUpRows && newRow < this.nrRollUpRows - 1) {
+ newRow = this.nrRollUpRows - 1;
+ }
+
+ //Make sure this only affects Roll-up Captions by checking this.nrRollUpRows
+ if (this.nrRollUpRows && this.currRow !== newRow) {
+ //clear all rows first
+ for (var i = 0; i < NR_ROWS; i++) {
+ this.rows[i].clear();
+ }
+
+ //Copy this.nrRollUpRows rows from lastOutputScreen and place it in the newRow location
+ //topRowIndex - the start of rows to copy (inclusive index)
+ var topRowIndex = this.currRow + 1 - this.nrRollUpRows;
+ //We only copy if the last position was already shown.
+ //We use the cueStartTime value to check this.
+ var lastOutputScreen = this.lastOutputScreen;
+ if (lastOutputScreen) {
+ var prevLineTime = lastOutputScreen.rows[topRowIndex].cueStartTime;
+ if (prevLineTime && prevLineTime < logger.time) {
+ for (var _i = 0; _i < this.nrRollUpRows; _i++) {
+ this.rows[newRow - this.nrRollUpRows + _i + 1].copy(lastOutputScreen.rows[topRowIndex + _i]);
+ }
+ }
+ }
+ }
+
+ this.currRow = newRow;
+ var row = this.rows[this.currRow];
+ if (pacData.indent !== null) {
+ var indent = pacData.indent;
+ var prevPos = Math.max(indent - 1, 0);
+ row.setCursor(pacData.indent);
+ pacData.color = row.chars[prevPos].penState.foreground;
+ }
+ var styles = { foreground: pacData.color, underline: pacData.underline, italics: pacData.italics, background: 'black', flash: false };
+ this.setPen(styles);
+ }
+
+ /**
+ * Set background/extra foreground, but first do back_space, and then insert space (backwards compatibility).
+ */
+
+ }, {
+ key: 'setBkgData',
+ value: function setBkgData(bkgData) {
+
+ logger.log('INFO', 'bkgData = ' + JSON.stringify(bkgData));
+ this.backSpace();
+ this.setPen(bkgData);
+ this.insertChar(0x20); //Space
+ }
+ }, {
+ key: 'setRollUpRows',
+ value: function setRollUpRows(nrRows) {
+ this.nrRollUpRows = nrRows;
+ }
+ }, {
+ key: 'rollUp',
+ value: function rollUp() {
+ if (this.nrRollUpRows === null) {
+ logger.log('DEBUG', 'roll_up but nrRollUpRows not set yet');
+ return; //Not properly setup
+ }
+ logger.log('TEXT', this.getDisplayText());
+ var topRowIndex = this.currRow + 1 - this.nrRollUpRows;
+ var topRow = this.rows.splice(topRowIndex, 1)[0];
+ topRow.clear();
+ this.rows.splice(this.currRow, 0, topRow);
+ logger.log('INFO', 'Rolling up');
+ //logger.log('TEXT', this.get_display_text())
+ }
+
+ /**
+ * Get all non-empty rows with as unicode text.
+ */
+
+ }, {
+ key: 'getDisplayText',
+ value: function getDisplayText(asOneRow) {
+ asOneRow = asOneRow || false;
+ var displayText = [];
+ var text = '';
+ var rowNr = -1;
+ for (var i = 0; i < NR_ROWS; i++) {
+ var rowText = this.rows[i].getTextString();
+ if (rowText) {
+ rowNr = i + 1;
+ if (asOneRow) {
+ displayText.push('Row ' + rowNr + ': \'' + rowText + '\'');
+ } else {
+ displayText.push(rowText.trim());
+ }
+ }
+ }
+ if (displayText.length > 0) {
+ if (asOneRow) {
+ text = '[' + displayText.join(' | ') + ']';
+ } else {
+ text = displayText.join('\n');
+ }
+ }
+ return text;
+ }
+ }, {
+ key: 'getTextAndFormat',
+ value: function getTextAndFormat() {
+ return this.rows;
+ }
+ }]);
+
+ return CaptionScreen;
+}();
+
+//var modes = ['MODE_ROLL-UP', 'MODE_POP-ON', 'MODE_PAINT-ON', 'MODE_TEXT'];
+
+var Cea608Channel = function () {
+ function Cea608Channel(channelNumber, outputFilter) {
+ _classCallCheck(this, Cea608Channel);
+
+ this.chNr = channelNumber;
+ this.outputFilter = outputFilter;
+ this.mode = null;
+ this.verbose = 0;
+ this.displayedMemory = new CaptionScreen();
+ this.nonDisplayedMemory = new CaptionScreen();
+ this.lastOutputScreen = new CaptionScreen();
+ this.currRollUpRow = this.displayedMemory.rows[NR_ROWS - 1];
+ this.writeScreen = this.displayedMemory;
+ this.mode = null;
+ this.cueStartTime = null; // Keeps track of where a cue started.
+ }
+
+ _createClass(Cea608Channel, [{
+ key: 'reset',
+ value: function reset() {
+ this.mode = null;
+ this.displayedMemory.reset();
+ this.nonDisplayedMemory.reset();
+ this.lastOutputScreen.reset();
+ this.currRollUpRow = this.displayedMemory.rows[NR_ROWS - 1];
+ this.writeScreen = this.displayedMemory;
+ this.mode = null;
+ this.cueStartTime = null;
+ this.lastCueEndTime = null;
+ }
+ }, {
+ key: 'getHandler',
+ value: function getHandler() {
+ return this.outputFilter;
+ }
+ }, {
+ key: 'setHandler',
+ value: function setHandler(newHandler) {
+ this.outputFilter = newHandler;
+ }
+ }, {
+ key: 'setPAC',
+ value: function setPAC(pacData) {
+ this.writeScreen.setPAC(pacData);
+ }
+ }, {
+ key: 'setBkgData',
+ value: function setBkgData(bkgData) {
+ this.writeScreen.setBkgData(bkgData);
+ }
+ }, {
+ key: 'setMode',
+ value: function setMode(newMode) {
+ if (newMode === this.mode) {
+ return;
+ }
+ this.mode = newMode;
+ logger.log('INFO', 'MODE=' + newMode);
+ if (this.mode === 'MODE_POP-ON') {
+ this.writeScreen = this.nonDisplayedMemory;
+ } else {
+ this.writeScreen = this.displayedMemory;
+ this.writeScreen.reset();
+ }
+ if (this.mode !== 'MODE_ROLL-UP') {
+ this.displayedMemory.nrRollUpRows = null;
+ this.nonDisplayedMemory.nrRollUpRows = null;
+ }
+ this.mode = newMode;
+ }
+ }, {
+ key: 'insertChars',
+ value: function insertChars(chars) {
+ for (var i = 0; i < chars.length; i++) {
+ this.writeScreen.insertChar(chars[i]);
+ }
+ var screen = this.writeScreen === this.displayedMemory ? 'DISP' : 'NON_DISP';
+ logger.log('INFO', screen + ': ' + this.writeScreen.getDisplayText(true));
+ if (this.mode === 'MODE_PAINT-ON' || this.mode === 'MODE_ROLL-UP') {
+ logger.log('TEXT', 'DISPLAYED: ' + this.displayedMemory.getDisplayText(true));
+ this.outputDataUpdate();
+ }
+ }
+ }, {
+ key: 'ccRCL',
+ value: function ccRCL() {
+ // Resume Caption Loading (switch mode to Pop On)
+ logger.log('INFO', 'RCL - Resume Caption Loading');
+ this.setMode('MODE_POP-ON');
+ }
+ }, {
+ key: 'ccBS',
+ value: function ccBS() {
+ // BackSpace
+ logger.log('INFO', 'BS - BackSpace');
+ if (this.mode === 'MODE_TEXT') {
+ return;
+ }
+ this.writeScreen.backSpace();
+ if (this.writeScreen === this.displayedMemory) {
+ this.outputDataUpdate();
+ }
+ }
+ }, {
+ key: 'ccAOF',
+ value: function ccAOF() {
+ // Reserved (formerly Alarm Off)
+ return;
+ }
+ }, {
+ key: 'ccAON',
+ value: function ccAON() {
+ // Reserved (formerly Alarm On)
+ return;
+ }
+ }, {
+ key: 'ccDER',
+ value: function ccDER() {
+ // Delete to End of Row
+ logger.log('INFO', 'DER- Delete to End of Row');
+ this.writeScreen.clearToEndOfRow();
+ this.outputDataUpdate();
+ }
+ }, {
+ key: 'ccRU',
+ value: function ccRU(nrRows) {
+ //Roll-Up Captions-2,3,or 4 Rows
+ logger.log('INFO', 'RU(' + nrRows + ') - Roll Up');
+ this.writeScreen = this.displayedMemory;
+ this.setMode('MODE_ROLL-UP');
+ this.writeScreen.setRollUpRows(nrRows);
+ }
+ }, {
+ key: 'ccFON',
+ value: function ccFON() {
+ //Flash On
+ logger.log('INFO', 'FON - Flash On');
+ this.writeScreen.setPen({ flash: true });
+ }
+ }, {
+ key: 'ccRDC',
+ value: function ccRDC() {
+ // Resume Direct Captioning (switch mode to PaintOn)
+ logger.log('INFO', 'RDC - Resume Direct Captioning');
+ this.setMode('MODE_PAINT-ON');
+ }
+ }, {
+ key: 'ccTR',
+ value: function ccTR() {
+ // Text Restart in text mode (not supported, however)
+ logger.log('INFO', 'TR');
+ this.setMode('MODE_TEXT');
+ }
+ }, {
+ key: 'ccRTD',
+ value: function ccRTD() {
+ // Resume Text Display in Text mode (not supported, however)
+ logger.log('INFO', 'RTD');
+ this.setMode('MODE_TEXT');
+ }
+ }, {
+ key: 'ccEDM',
+ value: function ccEDM() {
+ // Erase Displayed Memory
+ logger.log('INFO', 'EDM - Erase Displayed Memory');
+ this.displayedMemory.reset();
+ this.outputDataUpdate();
+ }
+ }, {
+ key: 'ccCR',
+ value: function ccCR() {
+ // Carriage Return
+ logger.log('CR - Carriage Return');
+ this.writeScreen.rollUp();
+ this.outputDataUpdate();
+ }
+ }, {
+ key: 'ccENM',
+ value: function ccENM() {
+ //Erase Non-Displayed Memory
+ logger.log('INFO', 'ENM - Erase Non-displayed Memory');
+ this.nonDisplayedMemory.reset();
+ }
+ }, {
+ key: 'ccEOC',
+ value: function ccEOC() {
+ //End of Caption (Flip Memories)
+ logger.log('INFO', 'EOC - End Of Caption');
+ if (this.mode === 'MODE_POP-ON') {
+ var tmp = this.displayedMemory;
+ this.displayedMemory = this.nonDisplayedMemory;
+ this.nonDisplayedMemory = tmp;
+ this.writeScreen = this.nonDisplayedMemory;
+ logger.log('TEXT', 'DISP: ' + this.displayedMemory.getDisplayText());
+ }
+ this.outputDataUpdate();
+ }
+ }, {
+ key: 'ccTO',
+ value: function ccTO(nrCols) {
+ // Tab Offset 1,2, or 3 columns
+ logger.log('INFO', 'TO(' + nrCols + ') - Tab Offset');
+ this.writeScreen.moveCursor(nrCols);
+ }
+ }, {
+ key: 'ccMIDROW',
+ value: function ccMIDROW(secondByte) {
+ // Parse MIDROW command
+ var styles = { flash: false };
+ styles.underline = secondByte % 2 === 1;
+ styles.italics = secondByte >= 0x2e;
+ if (!styles.italics) {
+ var colorIndex = Math.floor(secondByte / 2) - 0x10;
+ var colors = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta'];
+ styles.foreground = colors[colorIndex];
+ } else {
+ styles.foreground = 'white';
+ }
+ logger.log('INFO', 'MIDROW: ' + JSON.stringify(styles));
+ this.writeScreen.setPen(styles);
+ }
+ }, {
+ key: 'outputDataUpdate',
+ value: function outputDataUpdate() {
+ var t = logger.time;
+ if (t === null) {
+ return;
+ }
+ if (this.outputFilter) {
+ if (this.outputFilter.updateData) {
+ this.outputFilter.updateData(t, this.displayedMemory);
+ }
+ if (this.cueStartTime === null && !this.displayedMemory.isEmpty()) {
+ // Start of a new cue
+ this.cueStartTime = t;
+ } else {
+ if (!this.displayedMemory.equals(this.lastOutputScreen)) {
+ if (this.outputFilter.newCue) {
+ this.outputFilter.newCue(this.cueStartTime, t, this.lastOutputScreen);
+ }
+ this.cueStartTime = this.displayedMemory.isEmpty() ? null : t;
+ }
+ }
+ this.lastOutputScreen.copy(this.displayedMemory);
+ }
+ }
+ }, {
+ key: 'cueSplitAtTime',
+ value: function cueSplitAtTime(t) {
+ if (this.outputFilter) {
+ if (!this.displayedMemory.isEmpty()) {
+ if (this.outputFilter.newCue) {
+ this.outputFilter.newCue(this.cueStartTime, t, this.displayedMemory);
+ }
+ this.cueStartTime = t;
+ }
+ }
+ }
+ }]);
+
+ return Cea608Channel;
+}();
+
+var Cea608Parser = function () {
+ function Cea608Parser(field, out1, out2) {
+ _classCallCheck(this, Cea608Parser);
+
+ this.field = field || 1;
+ this.outputs = [out1, out2];
+ this.channels = [new Cea608Channel(1, out1), new Cea608Channel(2, out2)];
+ this.currChNr = -1; // Will be 1 or 2
+ this.lastCmdA = null; // First byte of last command
+ this.lastCmdB = null; // Second byte of last command
+ this.bufferedData = [];
+ this.startTime = null;
+ this.lastTime = null;
+ this.dataCounters = { 'padding': 0, 'char': 0, 'cmd': 0, 'other': 0 };
+ }
+
+ _createClass(Cea608Parser, [{
+ key: 'getHandler',
+ value: function getHandler(index) {
+ return this.channels[index].getHandler();
+ }
+ }, {
+ key: 'setHandler',
+ value: function setHandler(index, newHandler) {
+ this.channels[index].setHandler(newHandler);
+ }
+
+ /**
+ * Add data for time t in forms of list of bytes (unsigned ints). The bytes are treated as pairs.
+ */
+
+ }, {
+ key: 'addData',
+ value: function addData(t, byteList) {
+ var cmdFound,
+ a,
+ b,
+ charsFound = false;
+
+ this.lastTime = t;
+ logger.setTime(t);
+
+ for (var i = 0; i < byteList.length; i += 2) {
+ a = byteList[i] & 0x7f;
+ b = byteList[i + 1] & 0x7f;
+ if (a === 0 && b === 0) {
+ this.dataCounters.padding += 2;
+ continue;
+ } else {
+ logger.log('DATA', '[' + numArrayToHexArray([byteList[i], byteList[i + 1]]) + '] -> (' + numArrayToHexArray([a, b]) + ')');
+ }
+ cmdFound = this.parseCmd(a, b);
+ if (!cmdFound) {
+ cmdFound = this.parseMidrow(a, b);
+ }
+ if (!cmdFound) {
+ cmdFound = this.parsePAC(a, b);
+ }
+ if (!cmdFound) {
+ cmdFound = this.parseBackgroundAttributes(a, b);
+ }
+ if (!cmdFound) {
+ charsFound = this.parseChars(a, b);
+ if (charsFound) {
+ if (this.currChNr && this.currChNr >= 0) {
+ var channel = this.channels[this.currChNr - 1];
+ channel.insertChars(charsFound);
+ } else {
+ logger.log('WARNING', 'No channel found yet. TEXT-MODE?');
+ }
+ }
+ }
+ if (cmdFound) {
+ this.dataCounters.cmd += 2;
+ } else if (charsFound) {
+ this.dataCounters.char += 2;
+ } else {
+ this.dataCounters.other += 2;
+ logger.log('WARNING', 'Couldn\'t parse cleaned data ' + numArrayToHexArray([a, b]) + ' orig: ' + numArrayToHexArray([byteList[i], byteList[i + 1]]));
+ }
+ }
+ }
+
+ /**
+ * Parse Command.
+ * @returns {Boolean} Tells if a command was found
+ */
+
+ }, {
+ key: 'parseCmd',
+ value: function parseCmd(a, b) {
+ var chNr = null;
+
+ var cond1 = (a === 0x14 || a === 0x1C) && 0x20 <= b && b <= 0x2F;
+ var cond2 = (a === 0x17 || a === 0x1F) && 0x21 <= b && b <= 0x23;
+ if (!(cond1 || cond2)) {
+ return false;
+ }
+
+ if (a === this.lastCmdA && b === this.lastCmdB) {
+ this.lastCmdA = null;
+ this.lastCmdB = null; // Repeated commands are dropped (once)
+ logger.log('DEBUG', 'Repeated command (' + numArrayToHexArray([a, b]) + ') is dropped');
+ return true;
+ }
+
+ if (a === 0x14 || a === 0x17) {
+ chNr = 1;
+ } else {
+ chNr = 2; // (a === 0x1C || a=== 0x1f)
+ }
+
+ var channel = this.channels[chNr - 1];
+
+ if (a === 0x14 || a === 0x1C) {
+ if (b === 0x20) {
+ channel.ccRCL();
+ } else if (b === 0x21) {
+ channel.ccBS();
+ } else if (b === 0x22) {
+ channel.ccAOF();
+ } else if (b === 0x23) {
+ channel.ccAON();
+ } else if (b === 0x24) {
+ channel.ccDER();
+ } else if (b === 0x25) {
+ channel.ccRU(2);
+ } else if (b === 0x26) {
+ channel.ccRU(3);
+ } else if (b === 0x27) {
+ channel.ccRU(4);
+ } else if (b === 0x28) {
+ channel.ccFON();
+ } else if (b === 0x29) {
+ channel.ccRDC();
+ } else if (b === 0x2A) {
+ channel.ccTR();
+ } else if (b === 0x2B) {
+ channel.ccRTD();
+ } else if (b === 0x2C) {
+ channel.ccEDM();
+ } else if (b === 0x2D) {
+ channel.ccCR();
+ } else if (b === 0x2E) {
+ channel.ccENM();
+ } else if (b === 0x2F) {
+ channel.ccEOC();
+ }
+ } else {
+ //a == 0x17 || a == 0x1F
+ channel.ccTO(b - 0x20);
+ }
+ this.lastCmdA = a;
+ this.lastCmdB = b;
+ this.currChNr = chNr;
+ return true;
+ }
+
+ /**
+ * Parse midrow styling command
+ * @returns {Boolean}
+ */
+
+ }, {
+ key: 'parseMidrow',
+ value: function parseMidrow(a, b) {
+ var chNr = null;
+
+ if ((a === 0x11 || a === 0x19) && 0x20 <= b && b <= 0x2f) {
+ if (a === 0x11) {
+ chNr = 1;
+ } else {
+ chNr = 2;
+ }
+ if (chNr !== this.currChNr) {
+ logger.log('ERROR', 'Mismatch channel in midrow parsing');
+ return false;
+ }
+ var channel = this.channels[chNr - 1];
+ channel.ccMIDROW(b);
+ logger.log('DEBUG', 'MIDROW (' + numArrayToHexArray([a, b]) + ')');
+ return true;
+ }
+ return false;
+ }
+ /**
+ * Parse Preable Access Codes (Table 53).
+ * @returns {Boolean} Tells if PAC found
+ */
+
+ }, {
+ key: 'parsePAC',
+ value: function parsePAC(a, b) {
+
+ var chNr = null;
+ var row = null;
+
+ var case1 = (0x11 <= a && a <= 0x17 || 0x19 <= a && a <= 0x1F) && 0x40 <= b && b <= 0x7F;
+ var case2 = (a === 0x10 || a === 0x18) && 0x40 <= b && b <= 0x5F;
+ if (!(case1 || case2)) {
+ return false;
+ }
+
+ if (a === this.lastCmdA && b === this.lastCmdB) {
+ this.lastCmdA = null;
+ this.lastCmdB = null;
+ return true; // Repeated commands are dropped (once)
+ }
+
+ chNr = a <= 0x17 ? 1 : 2;
+
+ if (0x40 <= b && b <= 0x5F) {
+ row = chNr === 1 ? rowsLowCh1[a] : rowsLowCh2[a];
+ } else {
+ // 0x60 <= b <= 0x7F
+ row = chNr === 1 ? rowsHighCh1[a] : rowsHighCh2[a];
+ }
+ var pacData = this.interpretPAC(row, b);
+ var channel = this.channels[chNr - 1];
+ channel.setPAC(pacData);
+ this.lastCmdA = a;
+ this.lastCmdB = b;
+ this.currChNr = chNr;
+ return true;
+ }
+
+ /**
+ * Interpret the second byte of the pac, and return the information.
+ * @returns {Object} pacData with style parameters.
+ */
+
+ }, {
+ key: 'interpretPAC',
+ value: function interpretPAC(row, byte) {
+ var pacIndex = byte;
+ var pacData = { color: null, italics: false, indent: null, underline: false, row: row };
+
+ if (byte > 0x5F) {
+ pacIndex = byte - 0x60;
+ } else {
+ pacIndex = byte - 0x40;
+ }
+ pacData.underline = (pacIndex & 1) === 1;
+ if (pacIndex <= 0xd) {
+ pacData.color = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta', 'white'][Math.floor(pacIndex / 2)];
+ } else if (pacIndex <= 0xf) {
+ pacData.italics = true;
+ pacData.color = 'white';
+ } else {
+ pacData.indent = Math.floor((pacIndex - 0x10) / 2) * 4;
+ }
+ return pacData; // Note that row has zero offset. The spec uses 1.
+ }
+
+ /**
+ * Parse characters.
+ * @returns An array with 1 to 2 codes corresponding to chars, if found. null otherwise.
+ */
+
+ }, {
+ key: 'parseChars',
+ value: function parseChars(a, b) {
+
+ var channelNr = null,
+ charCodes = null,
+ charCode1 = null;
+
+ if (a >= 0x19) {
+ channelNr = 2;
+ charCode1 = a - 8;
+ } else {
+ channelNr = 1;
+ charCode1 = a;
+ }
+ if (0x11 <= charCode1 && charCode1 <= 0x13) {
+ // Special character
+ var oneCode = b;
+ if (charCode1 === 0x11) {
+ oneCode = b + 0x50;
+ } else if (charCode1 === 0x12) {
+ oneCode = b + 0x70;
+ } else {
+ oneCode = b + 0x90;
+ }
+ logger.log('INFO', 'Special char \'' + getCharForByte(oneCode) + '\' in channel ' + channelNr);
+ charCodes = [oneCode];
+ } else if (0x20 <= a && a <= 0x7f) {
+ charCodes = b === 0 ? [a] : [a, b];
+ }
+ if (charCodes) {
+ var hexCodes = numArrayToHexArray(charCodes);
+ logger.log('DEBUG', 'Char codes = ' + hexCodes.join(','));
+ this.lastCmdA = null;
+ this.lastCmdB = null;
+ }
+ return charCodes;
+ }
+
+ /**
+ * Parse extended background attributes as well as new foreground color black.
+ * @returns{Boolean} Tells if background attributes are found
+ */
+
+ }, {
+ key: 'parseBackgroundAttributes',
+ value: function parseBackgroundAttributes(a, b) {
+ var bkgData, index, chNr, channel;
+
+ var case1 = (a === 0x10 || a === 0x18) && 0x20 <= b && b <= 0x2f;
+ var case2 = (a === 0x17 || a === 0x1f) && 0x2d <= b && b <= 0x2f;
+ if (!(case1 || case2)) {
+ return false;
+ }
+ bkgData = {};
+ if (a === 0x10 || a === 0x18) {
+ index = Math.floor((b - 0x20) / 2);
+ bkgData.background = backgroundColors[index];
+ if (b % 2 === 1) {
+ bkgData.background = bkgData.background + '_semi';
+ }
+ } else if (b === 0x2d) {
+ bkgData.background = 'transparent';
+ } else {
+ bkgData.foreground = 'black';
+ if (b === 0x2f) {
+ bkgData.underline = true;
+ }
+ }
+ chNr = a < 0x18 ? 1 : 2;
+ channel = this.channels[chNr - 1];
+ channel.setBkgData(bkgData);
+ this.lastCmdA = null;
+ this.lastCmdB = null;
+ return true;
+ }
+
+ /**
+ * Reset state of parser and its channels.
+ */
+
+ }, {
+ key: 'reset',
+ value: function reset() {
+ for (var i = 0; i < this.channels.length; i++) {
+ if (this.channels[i]) {
+ this.channels[i].reset();
+ }
+ }
+ this.lastCmdA = null;
+ this.lastCmdB = null;
+ }
+
+ /**
+ * Trigger the generation of a cue, and the start of a new one if displayScreens are not empty.
+ */
+
+ }, {
+ key: 'cueSplitAtTime',
+ value: function cueSplitAtTime(t) {
+ for (var i = 0; i < this.channels.length; i++) {
+ if (this.channels[i]) {
+ this.channels[i].cueSplitAtTime(t);
+ }
+ }
+ }
+ }]);
+
+ return Cea608Parser;
+}();
+
+exports.default = Cea608Parser;
+
+},{}],47:[function(_dereq_,module,exports){
+'use strict';
+
+var _vttparser = _dereq_(53);
+
+var Cues = {
+
+ newCue: function newCue(track, startTime, endTime, captionScreen) {
+ var row;
+ var cue;
+ var indenting;
+ var indent;
+ var text;
+ var VTTCue = window.VTTCue || window.TextTrackCue;
+
+ for (var r = 0; r < captionScreen.rows.length; r++) {
+ row = captionScreen.rows[r];
+ indenting = true;
+ indent = 0;
+ text = '';
+
+ if (!row.isEmpty()) {
+ for (var c = 0; c < row.chars.length; c++) {
+ if (row.chars[c].uchar.match(/\s/) && indenting) {
+ indent++;
+ } else {
+ text += row.chars[c].uchar;
+ indenting = false;
+ }
+ }
+ //To be used for cleaning-up orphaned roll-up captions
+ row.cueStartTime = startTime;
+
+ // Give a slight bump to the endTime if it's equal to startTime to avoid a SyntaxError in IE
+ if (startTime === endTime) {
+ endTime += 0.0001;
+ }
+
+ cue = new VTTCue(startTime, endTime, (0, _vttparser.fixLineBreaks)(text.trim()));
+
+ if (indent >= 16) {
+ indent--;
+ } else {
+ indent++;
+ }
+
+ // VTTCue.line get's flakey when using controls, so let's now include line 13&14
+ // also, drop line 1 since it's to close to the top
+ if (navigator.userAgent.match(/Firefox\//)) {
+ cue.line = r + 1;
+ } else {
+ cue.line = r > 7 ? r - 2 : r + 1;
+ }
+ cue.align = 'left';
+ // Clamp the position between 0 and 100 - if out of these bounds, Firefox throws an exception and captions break
+ cue.position = Math.max(0, Math.min(100, 100 * (indent / 32) + (navigator.userAgent.match(/Firefox\//) ? 50 : 0)));
+ track.addCue(cue);
+ }
+ }
+ }
+
+};
+
+module.exports = Cues;
+
+},{"53":53}],48:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /*
+ * EWMA Bandwidth Estimator
+ * - heavily inspired from shaka-player
+ * Tracks bandwidth samples and estimates available bandwidth.
+ * Based on the minimum of two exponentially-weighted moving averages with
+ * different half-lives.
+ */
+
+var _ewma = _dereq_(49);
+
+var _ewma2 = _interopRequireDefault(_ewma);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var EwmaBandWidthEstimator = function () {
+ function EwmaBandWidthEstimator(hls, slow, fast, defaultEstimate) {
+ _classCallCheck(this, EwmaBandWidthEstimator);
+
+ this.hls = hls;
+ this.defaultEstimate_ = defaultEstimate;
+ this.minWeight_ = 0.001;
+ this.minDelayMs_ = 50;
+ this.slow_ = new _ewma2.default(slow);
+ this.fast_ = new _ewma2.default(fast);
+ }
+
+ _createClass(EwmaBandWidthEstimator, [{
+ key: 'sample',
+ value: function sample(durationMs, numBytes) {
+ durationMs = Math.max(durationMs, this.minDelayMs_);
+ var bandwidth = 8000 * numBytes / durationMs,
+
+ //console.log('instant bw:'+ Math.round(bandwidth));
+ // we weight sample using loading duration....
+ weight = durationMs / 1000;
+ this.fast_.sample(weight, bandwidth);
+ this.slow_.sample(weight, bandwidth);
+ }
+ }, {
+ key: 'canEstimate',
+ value: function canEstimate() {
+ var fast = this.fast_;
+ return fast && fast.getTotalWeight() >= this.minWeight_;
+ }
+ }, {
+ key: 'getEstimate',
+ value: function getEstimate() {
+ if (this.canEstimate()) {
+ //console.log('slow estimate:'+ Math.round(this.slow_.getEstimate()));
+ //console.log('fast estimate:'+ Math.round(this.fast_.getEstimate()));
+ // Take the minimum of these two estimates. This should have the effect of
+ // adapting down quickly, but up more slowly.
+ return Math.min(this.fast_.getEstimate(), this.slow_.getEstimate());
+ } else {
+ return this.defaultEstimate_;
+ }
+ }
+ }, {
+ key: 'destroy',
+ value: function destroy() {}
+ }]);
+
+ return EwmaBandWidthEstimator;
+}();
+
+exports.default = EwmaBandWidthEstimator;
+
+},{"49":49}],49:[function(_dereq_,module,exports){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+/*
+ * compute an Exponential Weighted moving average
+ * - https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
+ * - heavily inspired from shaka-player
+ */
+
+var EWMA = function () {
+
+ // About half of the estimated value will be from the last |halfLife| samples by weight.
+ function EWMA(halfLife) {
+ _classCallCheck(this, EWMA);
+
+ // Larger values of alpha expire historical data more slowly.
+ this.alpha_ = halfLife ? Math.exp(Math.log(0.5) / halfLife) : 0;
+ this.estimate_ = 0;
+ this.totalWeight_ = 0;
+ }
+
+ _createClass(EWMA, [{
+ key: "sample",
+ value: function sample(weight, value) {
+ var adjAlpha = Math.pow(this.alpha_, weight);
+ this.estimate_ = value * (1 - adjAlpha) + adjAlpha * this.estimate_;
+ this.totalWeight_ += weight;
+ }
+ }, {
+ key: "getTotalWeight",
+ value: function getTotalWeight() {
+ return this.totalWeight_;
+ }
+ }, {
+ key: "getEstimate",
+ value: function getEstimate() {
+ if (this.alpha_) {
+ var zeroFactor = 1 - Math.pow(this.alpha_, this.totalWeight_);
+ return this.estimate_ / zeroFactor;
+ } else {
+ return this.estimate_;
+ }
+ }
+ }]);
+
+ return EWMA;
+}();
+
+exports.default = EWMA;
+
+},{}],50:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
+
+function noop() {}
+
+var fakeLogger = {
+ trace: noop,
+ debug: noop,
+ log: noop,
+ warn: noop,
+ info: noop,
+ error: noop
+};
+
+var exportedLogger = fakeLogger;
+
+/*globals self: false */
+
+//let lastCallTime;
+// function formatMsgWithTimeInfo(type, msg) {
+// const now = Date.now();
+// const diff = lastCallTime ? '+' + (now - lastCallTime) : '0';
+// lastCallTime = now;
+// msg = (new Date(now)).toISOString() + ' | [' + type + '] > ' + msg + ' ( ' + diff + ' ms )';
+// return msg;
+// }
+
+function formatMsg(type, msg) {
+ msg = '[' + type + '] > ' + msg;
+ return msg;
+}
+
+function consolePrintFn(type) {
+ var func = self.console[type];
+ if (func) {
+ return function () {
+ for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+
+ if (args[0]) {
+ args[0] = formatMsg(type, args[0]);
+ }
+ func.apply(self.console, args);
+ };
+ }
+ return noop;
+}
+
+function exportLoggerFunctions(debugConfig) {
+ for (var _len2 = arguments.length, functions = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
+ functions[_key2 - 1] = arguments[_key2];
+ }
+
+ functions.forEach(function (type) {
+ exportedLogger[type] = debugConfig[type] ? debugConfig[type].bind(debugConfig) : consolePrintFn(type);
+ });
+}
+
+var enableLogs = exports.enableLogs = function enableLogs(debugConfig) {
+ if (debugConfig === true || (typeof debugConfig === 'undefined' ? 'undefined' : _typeof(debugConfig)) === 'object') {
+ exportLoggerFunctions(debugConfig,
+ // Remove out from list here to hard-disable a log-level
+ //'trace',
+ 'debug', 'log', 'info', 'warn', 'error');
+ // Some browsers don't allow to use bind on console object anyway
+ // fallback to default if needed
+ try {
+ exportedLogger.log();
+ } catch (e) {
+ exportedLogger = fakeLogger;
+ }
+ } else {
+ exportedLogger = fakeLogger;
+ }
+};
+
+var logger = exports.logger = exportedLogger;
+
+},{}],51:[function(_dereq_,module,exports){
+'use strict';
+
+/**
+ * TimeRanges to string helper
+ */
+
+var TimeRanges = {
+ toString: function toString(r) {
+ var log = '',
+ len = r.length;
+ for (var i = 0; i < len; i++) {
+ log += '[' + r.start(i).toFixed(3) + ',' + r.end(i).toFixed(3) + ']';
+ }
+ return log;
+ }
+};
+
+module.exports = TimeRanges;
+
+},{}],52:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+/**
+ * Copyright 2013 vtt.js Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+exports.default = function () {
+ if (typeof window !== 'undefined' && window.VTTCue) {
+ return window.VTTCue;
+ }
+
+ var autoKeyword = 'auto';
+ var directionSetting = {
+ '': true,
+ lr: true,
+ rl: true
+ };
+ var alignSetting = {
+ start: true,
+ middle: true,
+ end: true,
+ left: true,
+ right: true
+ };
+
+ function findDirectionSetting(value) {
+ if (typeof value !== 'string') {
+ return false;
+ }
+ var dir = directionSetting[value.toLowerCase()];
+ return dir ? value.toLowerCase() : false;
+ }
+
+ function findAlignSetting(value) {
+ if (typeof value !== 'string') {
+ return false;
+ }
+ var align = alignSetting[value.toLowerCase()];
+ return align ? value.toLowerCase() : false;
+ }
+
+ function extend(obj) {
+ var i = 1;
+ for (; i < arguments.length; i++) {
+ var cobj = arguments[i];
+ for (var p in cobj) {
+ obj[p] = cobj[p];
+ }
+ }
+
+ return obj;
+ }
+
+ function VTTCue(startTime, endTime, text) {
+ var cue = this;
+ var isIE8 = function () {
+ if (typeof navigator === 'undefined') {
+ return;
+ }
+ return (/MSIE\s8\.0/.test(navigator.userAgent)
+ );
+ }();
+ var baseObj = {};
+
+ if (isIE8) {
+ cue = document.createElement('custom');
+ } else {
+ baseObj.enumerable = true;
+ }
+
+ /**
+ * Shim implementation specific properties. These properties are not in
+ * the spec.
+ */
+
+ // Lets us know when the VTTCue's data has changed in such a way that we need
+ // to recompute its display state. This lets us compute its display state
+ // lazily.
+ cue.hasBeenReset = false;
+
+ /**
+ * VTTCue and TextTrackCue properties
+ * http://dev.w3.org/html5/webvtt/#vttcue-interface
+ */
+
+ var _id = '';
+ var _pauseOnExit = false;
+ var _startTime = startTime;
+ var _endTime = endTime;
+ var _text = text;
+ var _region = null;
+ var _vertical = '';
+ var _snapToLines = true;
+ var _line = 'auto';
+ var _lineAlign = 'start';
+ var _position = 50;
+ var _positionAlign = 'middle';
+ var _size = 50;
+ var _align = 'middle';
+
+ Object.defineProperty(cue, 'id', extend({}, baseObj, {
+ get: function get() {
+ return _id;
+ },
+ set: function set(value) {
+ _id = '' + value;
+ }
+ }));
+
+ Object.defineProperty(cue, 'pauseOnExit', extend({}, baseObj, {
+ get: function get() {
+ return _pauseOnExit;
+ },
+ set: function set(value) {
+ _pauseOnExit = !!value;
+ }
+ }));
+
+ Object.defineProperty(cue, 'startTime', extend({}, baseObj, {
+ get: function get() {
+ return _startTime;
+ },
+ set: function set(value) {
+ if (typeof value !== 'number') {
+ throw new TypeError('Start time must be set to a number.');
+ }
+ _startTime = value;
+ this.hasBeenReset = true;
+ }
+ }));
+
+ Object.defineProperty(cue, 'endTime', extend({}, baseObj, {
+ get: function get() {
+ return _endTime;
+ },
+ set: function set(value) {
+ if (typeof value !== 'number') {
+ throw new TypeError('End time must be set to a number.');
+ }
+ _endTime = value;
+ this.hasBeenReset = true;
+ }
+ }));
+
+ Object.defineProperty(cue, 'text', extend({}, baseObj, {
+ get: function get() {
+ return _text;
+ },
+ set: function set(value) {
+ _text = '' + value;
+ this.hasBeenReset = true;
+ }
+ }));
+
+ Object.defineProperty(cue, 'region', extend({}, baseObj, {
+ get: function get() {
+ return _region;
+ },
+ set: function set(value) {
+ _region = value;
+ this.hasBeenReset = true;
+ }
+ }));
+
+ Object.defineProperty(cue, 'vertical', extend({}, baseObj, {
+ get: function get() {
+ return _vertical;
+ },
+ set: function set(value) {
+ var setting = findDirectionSetting(value);
+ // Have to check for false because the setting an be an empty string.
+ if (setting === false) {
+ throw new SyntaxError('An invalid or illegal string was specified.');
+ }
+ _vertical = setting;
+ this.hasBeenReset = true;
+ }
+ }));
+
+ Object.defineProperty(cue, 'snapToLines', extend({}, baseObj, {
+ get: function get() {
+ return _snapToLines;
+ },
+ set: function set(value) {
+ _snapToLines = !!value;
+ this.hasBeenReset = true;
+ }
+ }));
+
+ Object.defineProperty(cue, 'line', extend({}, baseObj, {
+ get: function get() {
+ return _line;
+ },
+ set: function set(value) {
+ if (typeof value !== 'number' && value !== autoKeyword) {
+ throw new SyntaxError('An invalid number or illegal string was specified.');
+ }
+ _line = value;
+ this.hasBeenReset = true;
+ }
+ }));
+
+ Object.defineProperty(cue, 'lineAlign', extend({}, baseObj, {
+ get: function get() {
+ return _lineAlign;
+ },
+ set: function set(value) {
+ var setting = findAlignSetting(value);
+ if (!setting) {
+ throw new SyntaxError('An invalid or illegal string was specified.');
+ }
+ _lineAlign = setting;
+ this.hasBeenReset = true;
+ }
+ }));
+
+ Object.defineProperty(cue, 'position', extend({}, baseObj, {
+ get: function get() {
+ return _position;
+ },
+ set: function set(value) {
+ if (value < 0 || value > 100) {
+ throw new Error('Position must be between 0 and 100.');
+ }
+ _position = value;
+ this.hasBeenReset = true;
+ }
+ }));
+
+ Object.defineProperty(cue, 'positionAlign', extend({}, baseObj, {
+ get: function get() {
+ return _positionAlign;
+ },
+ set: function set(value) {
+ var setting = findAlignSetting(value);
+ if (!setting) {
+ throw new SyntaxError('An invalid or illegal string was specified.');
+ }
+ _positionAlign = setting;
+ this.hasBeenReset = true;
+ }
+ }));
+
+ Object.defineProperty(cue, 'size', extend({}, baseObj, {
+ get: function get() {
+ return _size;
+ },
+ set: function set(value) {
+ if (value < 0 || value > 100) {
+ throw new Error('Size must be between 0 and 100.');
+ }
+ _size = value;
+ this.hasBeenReset = true;
+ }
+ }));
+
+ Object.defineProperty(cue, 'align', extend({}, baseObj, {
+ get: function get() {
+ return _align;
+ },
+ set: function set(value) {
+ var setting = findAlignSetting(value);
+ if (!setting) {
+ throw new SyntaxError('An invalid or illegal string was specified.');
+ }
+ _align = setting;
+ this.hasBeenReset = true;
+ }
+ }));
+
+ /**
+ * Other spec defined properties
+ */
+
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state
+ cue.displayState = undefined;
+
+ if (isIE8) {
+ return cue;
+ }
+ }
+
+ /**
+ * VTTCue methods
+ */
+
+ VTTCue.prototype.getCueAsHTML = function () {
+ // Assume WebVTT.convertCueToDOMTree is on the global.
+ var WebVTT = window.WebVTT;
+ return WebVTT.convertCueToDOMTree(window, this.text);
+ };
+
+ return VTTCue;
+}();
+
+},{}],53:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.fixLineBreaks = undefined;
+
+var _vttcue = _dereq_(52);
+
+var _vttcue2 = _interopRequireDefault(_vttcue);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var StringDecoder = function StringDecoder() {
+ return {
+ decode: function decode(data) {
+ if (!data) {
+ return '';
+ }
+ if (typeof data !== 'string') {
+ throw new Error('Error - expected string data.');
+ }
+ return decodeURIComponent(encodeURIComponent(data));
+ }
+ };
+}; /*
+ * Source: https://github.com/mozilla/vtt.js/blob/master/dist/vtt.js#L1716
+ */
+
+function VTTParser() {
+ this.window = window;
+ this.state = 'INITIAL';
+ this.buffer = '';
+ this.decoder = new StringDecoder();
+ this.regionList = [];
+}
+
+// Try to parse input as a time stamp.
+function parseTimeStamp(input) {
+
+ function computeSeconds(h, m, s, f) {
+ return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000;
+ }
+
+ var m = input.match(/^(\d+):(\d{2})(:\d{2})?\.(\d{3})/);
+ if (!m) {
+ return null;
+ }
+
+ if (m[3]) {
+ // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds]
+ return computeSeconds(m[1], m[2], m[3].replace(':', ''), m[4]);
+ } else if (m[1] > 59) {
+ // Timestamp takes the form of [hours]:[minutes].[milliseconds]
+ // First position is hours as it's over 59.
+ return computeSeconds(m[1], m[2], 0, m[4]);
+ } else {
+ // Timestamp takes the form of [minutes]:[seconds].[milliseconds]
+ return computeSeconds(0, m[1], m[2], m[4]);
+ }
+}
+
+// A settings object holds key/value pairs and will ignore anything but the first
+// assignment to a specific key.
+function Settings() {
+ this.values = Object.create(null);
+}
+
+Settings.prototype = {
+ // Only accept the first assignment to any key.
+ set: function set(k, v) {
+ if (!this.get(k) && v !== '') {
+ this.values[k] = v;
+ }
+ },
+ // Return the value for a key, or a default value.
+ // If 'defaultKey' is passed then 'dflt' is assumed to be an object with
+ // a number of possible default values as properties where 'defaultKey' is
+ // the key of the property that will be chosen; otherwise it's assumed to be
+ // a single value.
+ get: function get(k, dflt, defaultKey) {
+ if (defaultKey) {
+ return this.has(k) ? this.values[k] : dflt[defaultKey];
+ }
+ return this.has(k) ? this.values[k] : dflt;
+ },
+ // Check whether we have a value for a key.
+ has: function has(k) {
+ return k in this.values;
+ },
+ // Accept a setting if its one of the given alternatives.
+ alt: function alt(k, v, a) {
+ for (var n = 0; n < a.length; ++n) {
+ if (v === a[n]) {
+ this.set(k, v);
+ break;
+ }
+ }
+ },
+ // Accept a setting if its a valid (signed) integer.
+ integer: function integer(k, v) {
+ if (/^-?\d+$/.test(v)) {
+ // integer
+ this.set(k, parseInt(v, 10));
+ }
+ },
+ // Accept a setting if its a valid percentage.
+ percent: function percent(k, v) {
+ var m;
+ if (m = v.match(/^([\d]{1,3})(\.[\d]*)?%$/)) {
+ v = parseFloat(v);
+ if (v >= 0 && v <= 100) {
+ this.set(k, v);
+ return true;
+ }
+ }
+ return false;
+ }
+};
+
+// Helper function to parse input into groups separated by 'groupDelim', and
+// interprete each group as a key/value pair separated by 'keyValueDelim'.
+function parseOptions(input, callback, keyValueDelim, groupDelim) {
+ var groups = groupDelim ? input.split(groupDelim) : [input];
+ for (var i in groups) {
+ if (typeof groups[i] !== 'string') {
+ continue;
+ }
+ var kv = groups[i].split(keyValueDelim);
+ if (kv.length !== 2) {
+ continue;
+ }
+ var k = kv[0];
+ var v = kv[1];
+ callback(k, v);
+ }
+}
+
+var defaults = new _vttcue2.default(0, 0, 0);
+// 'middle' was changed to 'center' in the spec: https://github.com/w3c/webvtt/pull/244
+// Chrome and Safari don't yet support this change, but FF does
+var center = defaults.align === 'middle' ? 'middle' : 'center';
+
+function parseCue(input, cue, regionList) {
+ // Remember the original input if we need to throw an error.
+ var oInput = input;
+ // 4.1 WebVTT timestamp
+ function consumeTimeStamp() {
+ var ts = parseTimeStamp(input);
+ if (ts === null) {
+ throw new Error('Malformed timestamp: ' + oInput);
+ }
+ // Remove time stamp from input.
+ input = input.replace(/^[^\sa-zA-Z-]+/, '');
+ return ts;
+ }
+
+ // 4.4.2 WebVTT cue settings
+ function consumeCueSettings(input, cue) {
+ var settings = new Settings();
+
+ parseOptions(input, function (k, v) {
+ switch (k) {
+ case 'region':
+ // Find the last region we parsed with the same region id.
+ for (var i = regionList.length - 1; i >= 0; i--) {
+ if (regionList[i].id === v) {
+ settings.set(k, regionList[i].region);
+ break;
+ }
+ }
+ break;
+ case 'vertical':
+ settings.alt(k, v, ['rl', 'lr']);
+ break;
+ case 'line':
+ var vals = v.split(','),
+ vals0 = vals[0];
+ settings.integer(k, vals0);
+ if (settings.percent(k, vals0)) {
+ settings.set('snapToLines', false);
+ }
+ settings.alt(k, vals0, ['auto']);
+ if (vals.length === 2) {
+ settings.alt('lineAlign', vals[1], ['start', center, 'end']);
+ }
+ break;
+ case 'position':
+ vals = v.split(',');
+ settings.percent(k, vals[0]);
+ if (vals.length === 2) {
+ settings.alt('positionAlign', vals[1], ['start', center, 'end', 'line-left', 'line-right', 'auto']);
+ }
+ break;
+ case 'size':
+ settings.percent(k, v);
+ break;
+ case 'align':
+ settings.alt(k, v, ['start', center, 'end', 'left', 'right']);
+ break;
+ }
+ }, /:/, /\s/);
+
+ // Apply default values for any missing fields.
+ cue.region = settings.get('region', null);
+ cue.vertical = settings.get('vertical', '');
+ var line = settings.get('line', 'auto');
+ if (line === 'auto' && defaults.line === -1) {
+ // set numeric line number for Safari
+ line = -1;
+ }
+ cue.line = line;
+ cue.lineAlign = settings.get('lineAlign', 'start');
+ cue.snapToLines = settings.get('snapToLines', true);
+ cue.size = settings.get('size', 100);
+ cue.align = settings.get('align', center);
+ var position = settings.get('position', 'auto');
+ if (position === 'auto' && defaults.position === 50) {
+ // set numeric position for Safari
+ position = cue.align === 'start' || cue.align === 'left' ? 0 : cue.align === 'end' || cue.align === 'right' ? 100 : 50;
+ }
+ cue.position = position;
+ }
+
+ function skipWhitespace() {
+ input = input.replace(/^\s+/, '');
+ }
+
+ // 4.1 WebVTT cue timings.
+ skipWhitespace();
+ cue.startTime = consumeTimeStamp(); // (1) collect cue start time
+ skipWhitespace();
+ if (input.substr(0, 3) !== '-->') {
+ // (3) next characters must match '-->'
+ throw new Error('Malformed time stamp (time stamps must be separated by \'-->\'): ' + oInput);
+ }
+ input = input.substr(3);
+ skipWhitespace();
+ cue.endTime = consumeTimeStamp(); // (5) collect cue end time
+
+ // 4.1 WebVTT cue settings list.
+ skipWhitespace();
+ consumeCueSettings(input, cue);
+}
+
+function fixLineBreaks(input) {
+ return input.replace(/ /gi, '\n');
+}
+
+VTTParser.prototype = {
+ parse: function parse(data) {
+ var self = this;
+
+ // If there is no data then we won't decode it, but will just try to parse
+ // whatever is in buffer already. This may occur in circumstances, for
+ // example when flush() is called.
+ if (data) {
+ // Try to decode the data that we received.
+ self.buffer += self.decoder.decode(data, { stream: true });
+ }
+
+ function collectNextLine() {
+ var buffer = self.buffer;
+ var pos = 0;
+
+ buffer = fixLineBreaks(buffer);
+
+ while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') {
+ ++pos;
+ }
+ var line = buffer.substr(0, pos);
+ // Advance the buffer early in case we fail below.
+ if (buffer[pos] === '\r') {
+ ++pos;
+ }
+ if (buffer[pos] === '\n') {
+ ++pos;
+ }
+ self.buffer = buffer.substr(pos);
+ return line;
+ }
+
+ // 3.2 WebVTT metadata header syntax
+ function parseHeader(input) {
+ parseOptions(input, function (k, v) {
+ switch (k) {
+ case 'Region':
+ // 3.3 WebVTT region metadata header syntax
+ console.log('parse region', v);
+ //parseRegion(v);
+ break;
+ }
+ }, /:/);
+ }
+
+ // 5.1 WebVTT file parsing.
+ try {
+ var line;
+ if (self.state === 'INITIAL') {
+ // We can't start parsing until we have the first line.
+ if (!/\r\n|\n/.test(self.buffer)) {
+ return this;
+ }
+
+ line = collectNextLine();
+
+ var m = line.match(/^WEBVTT([ \t].*)?$/);
+ if (!m || !m[0]) {
+ throw new Error('Malformed WebVTT signature.');
+ }
+
+ self.state = 'HEADER';
+ }
+
+ var alreadyCollectedLine = false;
+ while (self.buffer) {
+ // We can't parse a line until we have the full line.
+ if (!/\r\n|\n/.test(self.buffer)) {
+ return this;
+ }
+
+ if (!alreadyCollectedLine) {
+ line = collectNextLine();
+ } else {
+ alreadyCollectedLine = false;
+ }
+
+ switch (self.state) {
+ case 'HEADER':
+ // 13-18 - Allow a header (metadata) under the WEBVTT line.
+ if (/:/.test(line)) {
+ parseHeader(line);
+ } else if (!line) {
+ // An empty line terminates the header and starts the body (cues).
+ self.state = 'ID';
+ }
+ continue;
+ case 'NOTE':
+ // Ignore NOTE blocks.
+ if (!line) {
+ self.state = 'ID';
+ }
+ continue;
+ case 'ID':
+ // Check for the start of NOTE blocks.
+ if (/^NOTE($|[ \t])/.test(line)) {
+ self.state = 'NOTE';
+ break;
+ }
+ // 19-29 - Allow any number of line terminators, then initialize new cue values.
+ if (!line) {
+ continue;
+ }
+ self.cue = new _vttcue2.default(0, 0, '');
+ self.state = 'CUE';
+ // 30-39 - Check if self line contains an optional identifier or timing data.
+ if (line.indexOf('-->') === -1) {
+ self.cue.id = line;
+ continue;
+ }
+ // Process line as start of a cue.
+ /*falls through*/
+ case 'CUE':
+ // 40 - Collect cue timings and settings.
+ try {
+ parseCue(line, self.cue, self.regionList);
+ } catch (e) {
+ // In case of an error ignore rest of the cue.
+ self.cue = null;
+ self.state = 'BADCUE';
+ continue;
+ }
+ self.state = 'CUETEXT';
+ continue;
+ case 'CUETEXT':
+ var hasSubstring = line.indexOf('-->') !== -1;
+ // 34 - If we have an empty line then report the cue.
+ // 35 - If we have the special substring '-->' then report the cue,
+ // but do not collect the line as we need to process the current
+ // one as a new cue.
+ if (!line || hasSubstring && (alreadyCollectedLine = true)) {
+ // We are done parsing self cue.
+ if (self.oncue) {
+ self.oncue(self.cue);
+ }
+ self.cue = null;
+ self.state = 'ID';
+ continue;
+ }
+ if (self.cue.text) {
+ self.cue.text += '\n';
+ }
+ self.cue.text += line;
+ continue;
+ case 'BADCUE':
+ // BADCUE
+ // 54-62 - Collect and discard the remaining cue.
+ if (!line) {
+ self.state = 'ID';
+ }
+ continue;
+ }
+ }
+ } catch (e) {
+
+ // If we are currently parsing a cue, report what we have.
+ if (self.state === 'CUETEXT' && self.cue && self.oncue) {
+ self.oncue(self.cue);
+ }
+ self.cue = null;
+ // Enter BADWEBVTT state if header was not parsed correctly otherwise
+ // another exception occurred so enter BADCUE state.
+ self.state = self.state === 'INITIAL' ? 'BADWEBVTT' : 'BADCUE';
+ }
+ return this;
+ },
+ flush: function flush() {
+ var self = this;
+ try {
+ // Finish decoding the stream.
+ self.buffer += self.decoder.decode();
+ // Synthesize the end of the current cue or region.
+ if (self.cue || self.state === 'HEADER') {
+ self.buffer += '\n\n';
+ self.parse();
+ }
+ // If we've flushed, parsed, and we're still on the INITIAL state then
+ // that means we don't have enough of the stream to parse the first
+ // line.
+ if (self.state === 'INITIAL') {
+ throw new Error('Malformed WebVTT signature.');
+ }
+ } catch (e) {
+ throw e;
+ }
+ if (self.onflush) {
+ self.onflush();
+ }
+ return this;
+ }
+};
+
+exports.fixLineBreaks = fixLineBreaks;
+exports.default = VTTParser;
+
+},{"52":52}],54:[function(_dereq_,module,exports){
+'use strict';
+
+var _vttparser = _dereq_(53);
+
+var _vttparser2 = _interopRequireDefault(_vttparser);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var cueString2millis = function cueString2millis(timeString) {
+ var ts = parseInt(timeString.substr(-3));
+ var secs = parseInt(timeString.substr(-6, 2));
+ var mins = parseInt(timeString.substr(-9, 2));
+ var hours = timeString.length > 9 ? parseInt(timeString.substr(0, timeString.indexOf(':'))) : 0;
+
+ if (isNaN(ts) || isNaN(secs) || isNaN(mins) || isNaN(hours)) {
+ return -1;
+ }
+
+ ts += 1000 * secs;
+ ts += 60 * 1000 * mins;
+ ts += 60 * 60 * 1000 * hours;
+
+ return ts;
+};
+
+var calculateOffset = function calculateOffset(vttCCs, cc, presentationTime) {
+ var currCC = vttCCs[cc];
+ var prevCC = vttCCs[currCC.prevCC];
+
+ // This is the first discontinuity or cues have been processed since the last discontinuity
+ // Offset = current discontinuity time
+ if (!prevCC || !prevCC.new && currCC.new) {
+ vttCCs.ccOffset = vttCCs.presentationOffset = currCC.start;
+ currCC.new = false;
+ return;
+ }
+
+ // There have been discontinuities since cues were last parsed.
+ // Offset = time elapsed
+ while (prevCC && prevCC.new) {
+ vttCCs.ccOffset += currCC.start - prevCC.start;
+ currCC.new = false;
+ currCC = prevCC;
+ prevCC = vttCCs[currCC.prevCC];
+ }
+
+ vttCCs.presentationOffset = presentationTime;
+};
+
+var WebVTTParser = {
+ parse: function parse(vttByteArray, syncPTS, vttCCs, cc, callBack, errorCallBack) {
+ // Convert byteArray into string, replacing any somewhat exotic linefeeds with "\n", then split on that character.
+ var re = /\r\n|\n\r|\n|\r/g;
+ var vttLines = String.fromCharCode.apply(null, new Uint8Array(vttByteArray)).trim().replace(re, '\n').split('\n');
+ var cueTime = '00:00.000';
+ var mpegTs = 0;
+ var localTime = 0;
+ var presentationTime = 0;
+ var cues = [];
+ var parsingError = void 0;
+ var inHeader = true;
+ // let VTTCue = VTTCue || window.TextTrackCue;
+
+ // Create parser object using VTTCue with TextTrackCue fallback on certain browsers.
+ var parser = new _vttparser2.default();
+
+ parser.oncue = function (cue) {
+ // Adjust cue timing; clamp cues to start no earlier than - and drop cues that don't end after - 0 on timeline.
+ var currCC = vttCCs[cc];
+ var cueOffset = vttCCs.ccOffset;
+
+ // Update offsets for new discontinuities
+ if (currCC && currCC.new) {
+ if (localTime) {
+ // When local time is provided, offset = discontinuity start time - local time
+ cueOffset = vttCCs.ccOffset = currCC.start;
+ } else {
+ calculateOffset(vttCCs, cc, presentationTime);
+ }
+ }
+
+ if (presentationTime && !localTime) {
+ // If we have MPEGTS but no LOCAL time, offset = presentation time + discontinuity offset
+ cueOffset = presentationTime + vttCCs.ccOffset - vttCCs.presentationOffset;
+ }
+
+ cue.startTime += cueOffset - localTime;
+ cue.endTime += cueOffset - localTime;
+
+ // Fix encoding of special characters. TODO: Test with all sorts of weird characters.
+ cue.text = decodeURIComponent(escape(cue.text));
+ if (cue.endTime > 0) {
+ cues.push(cue);
+ }
+ };
+
+ parser.onparsingerror = function (e) {
+ parsingError = e;
+ };
+
+ parser.onflush = function () {
+ if (parsingError && errorCallBack) {
+ errorCallBack(parsingError);
+ return;
+ }
+ callBack(cues);
+ };
+
+ // Go through contents line by line.
+ vttLines.forEach(function (line) {
+ if (inHeader) {
+ // Look for X-TIMESTAMP-MAP in header.
+ if (line.startsWith('X-TIMESTAMP-MAP=')) {
+ // Once found, no more are allowed anyway, so stop searching.
+ inHeader = false;
+ // Extract LOCAL and MPEGTS.
+ line.substr(16).split(',').forEach(function (timestamp) {
+ if (timestamp.startsWith('LOCAL:')) {
+ cueTime = timestamp.substr(6);
+ } else if (timestamp.startsWith('MPEGTS:')) {
+ mpegTs = parseInt(timestamp.substr(7));
+ }
+ });
+ try {
+ // Calculate subtitle offset in milliseconds.
+ // If sync PTS is less than zero, we have a 33-bit wraparound, which is fixed by adding 2^33 = 8589934592.
+ syncPTS = syncPTS < 0 ? syncPTS + 8589934592 : syncPTS;
+ // Adjust MPEGTS by sync PTS.
+ mpegTs -= syncPTS;
+ // Convert cue time to seconds
+ localTime = cueString2millis(cueTime) / 1000;
+ // Convert MPEGTS to seconds from 90kHz.
+ presentationTime = mpegTs / 90000;
+
+ if (localTime === -1) {
+ parsingError = new Error('Malformed X-TIMESTAMP-MAP: ' + line);
+ }
+ } catch (e) {
+ parsingError = new Error('Malformed X-TIMESTAMP-MAP: ' + line);
+ }
+ // Return without parsing X-TIMESTAMP-MAP line.
+ return;
+ } else if (line === '') {
+ inHeader = false;
+ }
+ }
+ // Parse line by default.
+ parser.parse(line + '\n');
+ });
+
+ parser.flush();
+ }
+};
+
+module.exports = WebVTTParser;
+
+},{"53":53}],55:[function(_dereq_,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); /**
+ * XHR based logger
+ */
+
+var _logger = _dereq_(50);
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+var XhrLoader = function () {
+ function XhrLoader(config) {
+ _classCallCheck(this, XhrLoader);
+
+ if (config && config.xhrSetup) {
+ this.xhrSetup = config.xhrSetup;
+ }
+ }
+
+ _createClass(XhrLoader, [{
+ key: 'destroy',
+ value: function destroy() {
+ this.abort();
+ this.loader = null;
+ }
+ }, {
+ key: 'abort',
+ value: function abort() {
+ var loader = this.loader;
+ if (loader && loader.readyState !== 4) {
+ this.stats.aborted = true;
+ loader.abort();
+ }
+
+ window.clearTimeout(this.requestTimeout);
+ this.requestTimeout = null;
+ window.clearTimeout(this.retryTimeout);
+ this.retryTimeout = null;
+ }
+ }, {
+ key: 'load',
+ value: function load(context, config, callbacks) {
+ this.context = context;
+ this.config = config;
+ this.callbacks = callbacks;
+ this.stats = { trequest: performance.now(), retry: 0 };
+ this.retryDelay = config.retryDelay;
+ this.loadInternal();
+ }
+ }, {
+ key: 'loadInternal',
+ value: function loadInternal() {
+ var xhr,
+ context = this.context;
+
+ if (typeof XDomainRequest !== 'undefined') {
+ xhr = this.loader = new XDomainRequest();
+ } else {
+ xhr = this.loader = new XMLHttpRequest();
+ }
+ var stats = this.stats;
+ stats.tfirst = 0;
+ stats.loaded = 0;
+ var xhrSetup = this.xhrSetup;
+ if (xhrSetup) {
+ try {
+ xhrSetup(xhr, context.url);
+ } catch (e) {
+ // fix xhrSetup: (xhr, url) => {xhr.setRequestHeader("Content-Language", "test");}
+ // not working, as xhr.setRequestHeader expects xhr.readyState === OPEN
+ xhr.open('GET', context.url, true);
+ xhrSetup(xhr, context.url);
+ }
+ }
+
+ if (!xhr.readyState) {
+ xhr.open('GET', context.url, true);
+ }
+ if (context.rangeEnd) {
+ xhr.setRequestHeader('Range', 'bytes=' + context.rangeStart + '-' + (context.rangeEnd - 1));
+ }
+ xhr.onreadystatechange = this.readystatechange.bind(this);
+ xhr.onprogress = this.loadprogress.bind(this);
+ xhr.responseType = context.responseType;
+
+ // setup timeout before we perform request
+ this.requestTimeout = window.setTimeout(this.loadtimeout.bind(this), this.config.timeout);
+ xhr.send();
+ }
+ }, {
+ key: 'readystatechange',
+ value: function readystatechange(event) {
+ var xhr = event.currentTarget,
+ readyState = xhr.readyState,
+ stats = this.stats,
+ context = this.context,
+ config = this.config;
+
+ // don't proceed if xhr has been aborted
+ if (stats.aborted) {
+ return;
+ }
+
+ // >= HEADERS_RECEIVED
+ if (readyState >= 2) {
+ // clear xhr timeout and rearm it if readyState less than 4
+ window.clearTimeout(this.requestTimeout);
+ if (stats.tfirst === 0) {
+ stats.tfirst = Math.max(performance.now(), stats.trequest);
+ }
+ if (readyState === 4) {
+ var status = xhr.status;
+ // http status between 200 to 299 are all successful
+ if (status >= 200 && status < 300) {
+ stats.tload = Math.max(stats.tfirst, performance.now());
+ var data = void 0,
+ len = void 0;
+ if (context.responseType === 'arraybuffer') {
+ data = xhr.response;
+ len = data.byteLength;
+ } else {
+ data = xhr.responseText;
+ len = data.length;
+ }
+ stats.loaded = stats.total = len;
+ var response = { url: xhr.responseURL, data: data };
+ this.callbacks.onSuccess(response, stats, context);
+ } else {
+ // if max nb of retries reached or if http status between 400 and 499 (such error cannot be recovered, retrying is useless), return error
+ if (stats.retry >= config.maxRetry || status >= 400 && status < 499) {
+ _logger.logger.error(status + ' while loading ' + context.url);
+ this.callbacks.onError({ code: status, text: xhr.statusText }, context);
+ } else {
+ // retry
+ _logger.logger.warn(status + ' while loading ' + context.url + ', retrying in ' + this.retryDelay + '...');
+ // aborts and resets internal state
+ this.destroy();
+ // schedule retry
+ this.retryTimeout = window.setTimeout(this.loadInternal.bind(this), this.retryDelay);
+ // set exponential backoff
+ this.retryDelay = Math.min(2 * this.retryDelay, config.maxRetryDelay);
+ stats.retry++;
+ }
+ }
+ } else {
+ // readyState >= 2 AND readyState !==4 (readyState = HEADERS_RECEIVED || LOADING) rearm timeout as xhr not finished yet
+ this.requestTimeout = window.setTimeout(this.loadtimeout.bind(this), config.timeout);
+ }
+ }
+ }
+ }, {
+ key: 'loadtimeout',
+ value: function loadtimeout() {
+ _logger.logger.warn('timeout while loading ' + this.context.url);
+ this.callbacks.onTimeout(this.stats, this.context);
+ }
+ }, {
+ key: 'loadprogress',
+ value: function loadprogress(event) {
+ var stats = this.stats;
+ stats.loaded = event.loaded;
+ if (event.lengthComputable) {
+ stats.total = event.total;
+ }
+ var onProgress = this.callbacks.onProgress;
+ if (onProgress) {
+ // last args is to provide on progress data
+ onProgress(stats, this.context, null);
+ }
+ }
+ }]);
+
+ return XhrLoader;
+}();
+
+exports.default = XhrLoader;
+
+},{"50":50}]},{},[37])(37)
+});
+//# sourceMappingURL=hls.js.map
diff --git a/video/ckplayer/hls/hls.min.js b/video/ckplayer/hls/hls.min.js
new file mode 100644
index 0000000..3a95d08
--- /dev/null
+++ b/video/ckplayer/hls/hls.min.js
@@ -0,0 +1,7 @@
+!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.Hls=e()}}(function(){var e;return function e(t,r,i){function a(s,o){if(!r[s]){if(!t[s]){var l="function"==typeof require&&require;if(!o&&l)return l(s,!0);if(n)return n(s,!0);var u=new Error("Cannot find module '"+s+"'");throw u.code="MODULE_NOT_FOUND",u}var d=r[s]={exports:{}};t[s][0].call(d.exports,function(e){var r=t[s][1][e];return a(r?r:e)},d,d.exports,e,t,r,i)}return r[s].exports}for(var n="function"==typeof require&&require,s=0;s0&&this._events[e].length>r&&(this._events[e].warned=!0,console.trace),this},i.prototype.on=i.prototype.addListener,i.prototype.once=function(e,t){function r(){this.removeListener(e,r),i||(i=!0,t.apply(this,arguments))}if(!a(t))throw TypeError("listener must be a function");var i=!1;return r.listener=t,this.on(e,r),this},i.prototype.removeListener=function(e,t){var r,i,n,o;if(!a(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;if(r=this._events[e],n=r.length,i=-1,r===t||a(r.listener)&&r.listener===t)delete this._events[e],this._events.removeListener&&this.emit("removeListener",e,t);else if(s(r)){for(o=n;o-- >0;)if(r[o]===t||r[o].listener&&r[o].listener===t){i=o;break}if(i<0)return this;1===r.length?(r.length=0,delete this._events[e]):r.splice(i,1),this._events.removeListener&&this.emit("removeListener",e,t)}return this},i.prototype.removeAllListeners=function(e){var t,r;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[e]&&delete this._events[e],this;if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);return this.removeAllListeners("removeListener"),this._events={},this}if(r=this._events[e],a(r))this.removeListener(e,r);else if(r)for(;r.length;)this.removeListener(e,r[r.length-1]);return delete this._events[e],this},i.prototype.listeners=function(e){return this._events&&this._events[e]?a(this._events[e])?[this._events[e]]:this._events[e].slice():[]},i.prototype.listenerCount=function(e){if(this._events){var t=this._events[e];if(a(t))return 1;if(t)return t.length}return 0},i.listenerCount=function(e,t){return e.listenerCount(t)}},{}],2:[function(t,r,i){!function(t){var a=/^((?:[^\/;?#]+:)?)(\/\/[^\/\;?#]*)?(.*?)??(;.*?)?(\?.*?)?(#.*?)?$/,n=/^([^\/;?#]*)(.*)$/,s={buildAbsoluteURL:function(e,t,r){if(r=r||{},e=e.trim(),!(t=t.trim())){if(!r.alwaysNormalize)return e;var i=this.parseURL(e);if(!o)throw new Error("Error trying to parse base URL.");return i.path=s.normalizePath(i.path),s.buildURLFromParts(i)}var a=this.parseURL(t);if(!a)throw new Error("Error trying to parse relative URL.");if(a.scheme)return r.alwaysNormalize?(a.path=s.normalizePath(a.path),s.buildURLFromParts(a)):t;var o=this.parseURL(e);if(!o)throw new Error("Error trying to parse base URL.");if(!o.netLoc&&o.path&&"/"!==o.path[0]){var l=n.exec(o.path);o.netLoc=l[1],o.path=l[2]}o.netLoc&&!o.path&&(o.path="/");var u={scheme:o.scheme,netLoc:a.netLoc,path:null,params:a.params,query:a.query,fragment:a.fragment};if(!a.netLoc&&(u.netLoc=o.netLoc,"/"!==a.path[0]))if(a.path){var d=o.path,f=d.substring(0,d.lastIndexOf("/")+1)+a.path;u.path=s.normalizePath(f)}else u.path=o.path,a.params||(u.params=o.params,a.query||(u.query=o.query));return null===u.path&&(u.path=r.alwaysNormalize?s.normalizePath(a.path):a.path),s.buildURLFromParts(u)},parseURL:function(e){var t=a.exec(e);return t?{scheme:t[1]||"",netLoc:t[2]||"",path:t[3]||"",params:t[4]||"",query:t[5]||"",fragment:t[6]||""}:null},normalizePath:function(e){for(e=e.split("").reverse().join("").replace(/(?:\/|^)\.(?=\/)/g,"");e.length!==(e=e.replace(/(?:\/|^)\.\.\/(?!\.\.\/).*?(?=\/)/g,"")).length;);return e.split("").reverse().join("")},buildURLFromParts:function(e){return e.scheme+e.netLoc+e.path+e.params+e.query+e.fragment}};"object"==typeof i&&"object"==typeof r?r.exports=s:"function"==typeof e&&e.amd?e([],function(){return s}):"object"==typeof i?i.URLToolkit=s:t.URLToolkit=s}(this)},{}],3:[function(e,t,r){var i=arguments[3],a=arguments[4],n=arguments[5],s=JSON.stringify;t.exports=function(e,t){function r(e){p[e]=!0;for(var t in a[e][1]){var i=a[e][1][t];p[i]||r(i)}}for(var o,l=Object.keys(n),u=0,d=l.length;u500*r.duration/o){var l=e.levels,d=Math.max(1,n.bw?n.bw/8:1e3*n.loaded/s),f=l[r.level],c=f.realBitrate?Math.max(f.realBitrate,f.bitrate):f.bitrate,g=n.total?n.total:Math.max(n.loaded,Math.round(r.duration*c/8)),p=t.currentTime,y=(g-n.loaded)/d,m=(h.default.bufferInfo(t,p,e.config.maxBufferHole).end-p)/o;if(m<2*r.duration/o&&y>m){var E=void 0,b=void 0;for(b=r.level-1;b>a;b--){var T=l[b].realBitrate?Math.max(l[b].realBitrate,l[b].bitrate):l[b].bitrate;if((E=r.duration*T/(6.4*d))=i;u--){var d=l[u],f=d.details,c=f?f.totalduration/f.fragments.length:t,h=!!f&&f.live,g=void 0;g=u<=e?s*r:o*r;var p=l[u].realBitrate?Math.max(l[u].realBitrate,l[u].bitrate):l[u].bitrate,y=p*c/g;if(v.logger.trace("level/adjustedbw/bitrate/avgDuration/maxFetchDuration/fetchDuration: "+u+"/"+Math.round(g)+"/"+p+"/"+c+"/"+n+"/"+y),g>p&&(!y||h||y=0)return c;v.logger.trace("rebuffering expected to happen, lets try to find a quality level minimizing the rebuffering");var g=o?Math.min(o,i.maxStarvationDelay):i.maxStarvationDelay,p=i.abrBandWidthFactor,y=i.abrBandWidthUpFactor;if(0===f){var m=this.bitrateTestDelay;if(m){g=(o?Math.min(o,i.maxLoadingDelay):i.maxLoadingDelay)-m,v.logger.trace("bitrate test took "+Math.round(1e3*m)+"ms, set first fragment max fetchDuration to "+Math.round(1e3*g)+" ms"),p=y=1}}return c=this._findBestLevel(s,o,d,a,t,f+g,p,y,r),Math.max(c,0)}}]),t}(f.default);r.default=m},{30:30,31:31,32:32,34:34,48:48,50:50}],6:[function(e,t,r){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(r,"__esModule",{value:!0});var o=function(){function e(e,t){for(var r=0;r0&&e===-1?(k.logger.log("audio:override startPosition with lastCurrentTime @"+t.toFixed(3)),this.state=R.IDLE):(this.lastCurrentTime=this.startPosition?this.startPosition:e,this.state=R.STARTING),this.nextLoadPosition=this.startPosition=this.lastCurrentTime,this.tick()}else this.startPosition=e,this.state=R.STOPPED}},{key:"stopLoad",value:function(){var e=this.fragCurrent;e&&(e.loader&&e.loader.abort(),this.fragCurrent=null),this.fragPrevious=null,this.demuxer&&(this.demuxer.destroy(),this.demuxer=null),this.state=R.STOPPED}},{key:"tick",value:function(){1===++this.ticks&&(this.doTick(),this.ticks>1&&setTimeout(this.tick,1),this.ticks=0)}},{key:"doTick",value:function(){var e,t,r,i=this.hls,a=i.config;switch(this.state){case R.ERROR:case R.PAUSED:case R.BUFFER_FLUSHING:break;case R.STARTING:this.state=R.WAITING_TRACK,this.loadedmetadata=!1;break;case R.IDLE:var n=this.tracks;if(!n)break;if(!this.media&&(this.startFragRequested||!a.startFragPrefetch))break;e=this.loadedmetadata?this.media.currentTime:this.nextLoadPosition;var s=this.mediaBuffer?this.mediaBuffer:this.media,o=f.default.bufferInfo(s,e,a.maxBufferHole),l=o.len,d=o.end,c=this.fragPrevious,h=a.maxMaxBufferLength,g=this.audioSwitch,p=this.trackId;if((lE||o.nextStart))return;k.logger.log("alt audio track ahead of main track, seek to start of alt audio track"),this.media.currentTime=E+.05}if(r.initSegment&&!r.initSegment.data)T=r.initSegment;else if(d<=E){if(T=y[0],r.live&&T.loadIdx&&T.loadIdx===this.fragLoadIdx){var A=o.nextStart?o.nextStart:E;return k.logger.log("no alt audio available @currentTime:"+this.media.currentTime+", seeking @"+(A+.05)),void(this.media.currentTime=A+.05)}}else{var S=void 0,L=a.maxFragLookUpTolerance,w=c?y[c.sn-y[0].sn+1]:void 0,D=function(e){var t=Math.min(L,e.duration);return e.start+e.duration-t<=d?1:e.start-t>d&&e.start?-1:0};db-L&&(L=0),S=w&&!D(w)?w:u.default.search(y,D)):S=y[m-1],S&&(T=S,E=S.start,c&&T.level===c.level&&T.sn===c.sn&&(T.snO&&Math.abs(this.fragLoadIdx-T.loadIdx)=P||C)&&(k.logger.log("audioStreamController: retryDate reached, switch back to IDLE state"),this.state=R.IDLE);break;case R.WAITING_INIT_PTS:case R.STOPPED:case R.FRAG_LOADING:case R.PARSING:case R.PARSED:case R.ENDED:}}},{key:"onMediaAttached",value:function(e){var t=this.media=this.mediaBuffer=e.media;this.onvseeking=this.onMediaSeeking.bind(this),this.onvended=this.onMediaEnded.bind(this),t.addEventListener("seeking",this.onvseeking),t.addEventListener("ended",this.onvended);var r=this.config;this.tracks&&r.autoStartLoad&&this.startLoad(r.startPosition)}},{key:"onMediaDetaching",value:function(){var e=this.media;e&&e.ended&&(k.logger.log("MSE detaching and video ended, reset startPosition"),this.startPosition=this.lastCurrentTime=0);var t=this.tracks;t&&t.forEach(function(e){e.details&&e.details.fragments.forEach(function(e){e.loadCounter=void 0})}),e&&(e.removeEventListener("seeking",this.onvseeking),e.removeEventListener("ended",this.onvended),this.onvseeking=this.onvseeked=this.onvended=null),this.media=this.mediaBuffer=null,this.loadedmetadata=!1,this.stopLoad()}},{key:"onMediaSeeking",value:function(){this.state===R.ENDED&&(this.state=R.IDLE),this.media&&(this.lastCurrentTime=this.media.currentTime),void 0!==this.fragLoadIdx&&(this.fragLoadIdx+=2*this.config.fragLoadingLoopThreshold),this.tick()}},{key:"onMediaEnded",value:function(){this.startPosition=this.lastCurrentTime=0}},{key:"onAudioTracksUpdated",value:function(e){k.logger.log("audio tracks updated"),this.tracks=e.audioTracks}},{key:"onAudioTrackSwitching",value:function(e){var t=!!e.url;this.trackId=e.id,this.state=R.IDLE,this.fragCurrent=null,this.state=R.PAUSED,this.waitingFragment=null,t?this.timer||(this.timer=setInterval(this.ontick,100)):this.demuxer&&(this.demuxer.destroy(),this.demuxer=null),t&&(this.audioSwitch=!0,this.state=R.IDLE,void 0!==this.fragLoadIdx&&(this.fragLoadIdx+=2*this.config.fragLoadingLoopThreshold)),this.tick()}},{key:"onAudioTrackLoaded",value:function(e){var t=e.details,r=e.id,i=this.tracks[r],a=t.totalduration,n=0;if(k.logger.log("track "+r+" loaded ["+t.startSN+","+t.endSN+"],duration:"+a),t.live){var s=i.details;s&&t.fragments.length>0?(E.default.mergeDetails(s,t),n=t.fragments[0].start,t.PTSKnown?k.logger.log("live audio playlist sliding:"+n.toFixed(3)):k.logger.log("live audio playlist - outdated PTS, unknown sliding")):(t.PTSKnown=!1,k.logger.log("live audio playlist - first load, unknown sliding"))}else t.PTSKnown=!1;if(i.details=t,!this.startFragRequested){if(this.startPosition===-1){var o=t.startTimeOffset;isNaN(o)?this.startPosition=0:(k.logger.log("start time offset found in playlist, adjust startPosition to "+o),this.startPosition=o)}this.nextLoadPosition=this.startPosition}this.state===R.WAITING_TRACK&&(this.state=R.IDLE),this.tick()}},{key:"onKeyLoaded",value:function(){this.state===R.KEY_LOADING&&(this.state=R.IDLE,this.tick())}},{key:"onFragLoaded",value:function(e){var t=this.fragCurrent,r=e.frag;if(this.state===R.FRAG_LOADING&&t&&"audio"===r.type&&r.level===t.level&&r.sn===t.sn){var i=this.tracks[this.trackId],a=i.details,n=a.totalduration,s=t.level,o=t.sn,l=t.cc,u=this.config.defaultAudioCodec||i.audioCodec||"mp4a.40.2",d=this.stats=e.stats;if("initSegment"===o)this.state=R.IDLE,d.tparsed=d.tbuffered=performance.now(),a.initSegment.data=e.payload,this.hls.trigger(v.default.FRAG_BUFFERED,{stats:d,frag:t,id:"audio"}),this.tick();else{this.state=R.PARSING,this.appended=!1,this.demuxer||(this.demuxer=new h.default(this.hls,"audio"));var f=this.initPTS[l],c=a.initSegment?a.initSegment.data:[];if(c||void 0!==f){this.pendingBuffering=!0,k.logger.log("Demuxing "+o+" of ["+a.startSN+" ,"+a.endSN+"],track "+s);this.demuxer.push(e.payload,c,u,null,t,n,!1,f)}else k.logger.log("unknown video PTS for continuity counter "+l+", waiting for video PTS before demuxing audio frag "+o+" of ["+a.startSN+" ,"+a.endSN+"],track "+s),this.waitingFragment=e,this.state=R.WAITING_INIT_PTS}}this.fragLoadError=0}},{key:"onFragParsingInitSegment",value:function(e){var t=this.fragCurrent,r=e.frag;if(t&&"audio"===e.id&&r.sn===t.sn&&r.level===t.level&&this.state===R.PARSING){var i=e.tracks,a=void 0;if(i.video&&delete i.video,a=i.audio){a.levelCodec="mp4a.40.2",a.id=e.id,this.hls.trigger(v.default.BUFFER_CODECS,i),k.logger.log("audio track:audio,container:"+a.container+",codecs[level/parsed]=["+a.levelCodec+"/"+a.codec+"]");var n=a.initSegment;if(n){var s={type:"audio",data:n,parent:"audio",content:"initSegment"};this.audioSwitch?this.pendingData=[s]:(this.appended=!0,this.pendingBuffering=!0,this.hls.trigger(v.default.BUFFER_APPENDING,s))}this.tick()}}}},{key:"onFragParsingData",value:function(e){var t=this,r=this.fragCurrent,i=e.frag;if(r&&"audio"===e.id&&"audio"===e.type&&i.sn===r.sn&&i.level===r.level&&this.state===R.PARSING){var a=this.trackId,n=this.tracks[a],s=this.hls;isNaN(e.endPTS)&&(e.endPTS=e.startPTS+r.duration,e.endDTS=e.startDTS+r.duration),k.logger.log("parsed "+e.type+",PTS:["+e.startPTS.toFixed(3)+","+e.endPTS.toFixed(3)+"],DTS:["+e.startDTS.toFixed(3)+"/"+e.endDTS.toFixed(3)+"],nb:"+e.nb),E.default.updateFragPTSDTS(n.details,r.sn,e.startPTS,e.endPTS);var o=this.audioSwitch,l=this.media,u=!1;if(o&&l)if(l.readyState){var d=l.currentTime;k.logger.log("switching audio track : currentTime:"+d),d>=e.startPTS&&(k.logger.log("switching audio track : flushing all audio"),this.state=R.BUFFER_FLUSHING,s.trigger(v.default.BUFFER_FLUSHING,{startOffset:0,endOffset:Number.POSITIVE_INFINITY,type:"audio"}),u=!0,this.audioSwitch=!1,s.trigger(v.default.AUDIO_TRACK_SWITCHED,{id:a}))}else this.audioSwitch=!1,s.trigger(v.default.AUDIO_TRACK_SWITCHED,{id:a});var f=this.pendingData;this.audioSwitch||([e.data1,e.data2].forEach(function(t){t&&t.length&&f.push({type:e.type,data:t,parent:"audio",content:"data"})}),!u&&f.length&&(f.forEach(function(e){t.state===R.PARSING&&(t.pendingBuffering=!0,t.hls.trigger(v.default.BUFFER_APPENDING,e))}),this.pendingData=[],this.appended=!0)),this.tick()}}},{key:"onFragParsed",value:function(e){var t=this.fragCurrent,r=e.frag;t&&"audio"===e.id&&r.sn===t.sn&&r.level===t.level&&this.state===R.PARSING&&(this.stats.tparsed=performance.now(),this.state=R.PARSED,this._checkAppendedParsed())}},{key:"onBufferCreated",value:function(e){var t=e.tracks.audio;t&&(this.mediaBuffer=t.buffer,this.loadedmetadata=!0)}},{key:"onBufferAppended",value:function(e){if("audio"===e.parent){var t=this.state;t!==R.PARSING&&t!==R.PARSED||(this.pendingBuffering=e.pending>0,this._checkAppendedParsed())}}},{key:"_checkAppendedParsed",value:function(){if(!(this.state!==R.PARSED||this.appended&&this.pendingBuffering)){var e=this.fragCurrent,t=this.stats,r=this.hls;if(e){this.fragPrevious=e,t.tbuffered=performance.now(),r.trigger(v.default.FRAG_BUFFERED,{stats:t,frag:e,id:"audio"});var i=this.mediaBuffer?this.mediaBuffer:this.media;k.logger.log("audio buffered : "+T.default.toString(i.buffered)),this.audioSwitch&&this.appended&&(this.audioSwitch=!1,r.trigger(v.default.AUDIO_TRACK_SWITCHED,{id:this.trackId})),this.state=R.IDLE}this.tick()}}},{key:"onError",value:function(e){var t=e.frag;if(!t||"audio"===t.type)switch(e.details){case _.ErrorDetails.FRAG_LOAD_ERROR:case _.ErrorDetails.FRAG_LOAD_TIMEOUT:if(!e.fatal){var r=this.fragLoadError;r?r++:r=1;var i=this.config;if(r<=i.fragLoadingMaxRetry){this.fragLoadError=r,t.loadCounter=0;var a=Math.min(Math.pow(2,r-1)*i.fragLoadingRetryDelay,i.fragLoadingMaxRetryTimeout);k.logger.warn("audioStreamController: frag loading failed, retry in "+a+" ms"),this.retryDate=performance.now()+a,this.state=R.FRAG_LOADING_WAITING_RETRY}else k.logger.error("audioStreamController: "+e.details+" reaches max retry, redispatch as fatal ..."),e.fatal=!0,this.state=R.ERROR}break;case _.ErrorDetails.FRAG_LOOP_LOADING_ERROR:case _.ErrorDetails.AUDIO_TRACK_LOAD_ERROR:case _.ErrorDetails.AUDIO_TRACK_LOAD_TIMEOUT:case _.ErrorDetails.KEY_LOAD_ERROR:case _.ErrorDetails.KEY_LOAD_TIMEOUT:this.state!==R.ERROR&&(this.state=e.fatal?R.ERROR:R.IDLE,k.logger.warn("audioStreamController: "+e.details+" while loading frag,switch to "+this.state+" state ..."));break;case _.ErrorDetails.BUFFER_FULL_ERROR:if("audio"===e.parent&&(this.state===R.PARSING||this.state===R.PARSED)){var n=this.mediaBuffer,s=this.media.currentTime;if(n&&f.default.isBuffered(n,s)&&f.default.isBuffered(n,s+.5)){var o=this.config;o.maxMaxBufferLength>=o.maxBufferLength&&(o.maxMaxBufferLength/=2,k.logger.warn("audio:reduce max buffer length to "+o.maxMaxBufferLength+"s"),this.fragLoadIdx+=2*o.fragLoadingLoopThreshold),this.state=R.IDLE}else k.logger.warn("buffer full error also media.currentTime is not buffered, flush audio buffer"),this.fragCurrent=null,this.state=R.BUFFER_FLUSHING,this.hls.trigger(v.default.BUFFER_FLUSHING,{startOffset:0,endOffset:Number.POSITIVE_INFINITY,type:"audio"})}}}},{key:"onBufferFlushed",value:function(){var e=this,t=this.pendingData;t&&t.length?(k.logger.log("appending pending audio data on Buffer Flushed"),t.forEach(function(t){e.hls.trigger(v.default.BUFFER_APPENDING,t)}),this.appended=!0,this.pendingData=[],this.state=R.PARSED):(this.state=R.IDLE,this.fragPrevious=null,this.tick())}},{key:"state",set:function(e){if(this.state!==e){var t=this.state;this._state=e,k.logger.log("audio stream:"+t+"->"+e)}},get:function(){return this._state}}]),t}(y.default);r.default=A},{24:24,30:30,31:31,32:32,34:34,35:35,45:45,50:50,51:51}],7:[function(e,t,r){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(r,"__esModule",{value:!0});var o=function(){function e(e,t){for(var r=0;r1&&setTimeout(this.tick,1),this.ticks=0)}},{key:"doTick",value:function(){this.updateTrack(this.trackId)}},{key:"onManifestLoading",value:function(){this.tracks=[],this.trackId=-1}},{key:"onManifestLoaded",value:function(e){var t=this,r=e.audioTracks||[],i=!1;this.tracks=r,this.hls.trigger(u.default.AUDIO_TRACKS_UPDATED,{audioTracks:r});var a=0;r.forEach(function(e){if(e.default)return t.audioTrack=a,void(i=!0);a++}),i===!1&&r.length&&(c.logger.log("no default audio track defined, use first audio track as default"),this.audioTrack=0)}},{key:"onAudioTrackLoaded",value:function(e){e.id=0&&e=0&&e.1){var a=i.updating;try{i.abort()}catch(e){a=!0,c.logger.warn("can not abort audio buffer: "+e)}a?this.audioTimestampOffset=e.start:(c.logger.warn("change mpeg audio timestamp offset from "+i.timestampOffset+" to "+e.start),i.timestampOffset=e.start)}}}},{key:"onManifestParsed",value:function(e){var t=e.audio,r=e.video,i=0;e.altAudio&&(t||r)&&(i=(t?1:0)+(r?1:0),c.logger.log(i+" sourceBuffer(s) expected")),this.sourceBufferNb=i}},{key:"onMediaAttaching",value:function(e){var t=this.media=e.media;if(t){var r=this.mediaSource=new MediaSource;this.onmso=this.onMediaSourceOpen.bind(this),this.onmse=this.onMediaSourceEnded.bind(this),this.onmsc=this.onMediaSourceClose.bind(this),r.addEventListener("sourceopen",this.onmso),r.addEventListener("sourceended",this.onmse),r.addEventListener("sourceclose",this.onmsc),t.src=URL.createObjectURL(r)}}},{key:"onMediaDetaching",value:function(){c.logger.log("media source detaching");var e=this.mediaSource;if(e){if("open"===e.readyState)try{e.endOfStream()}catch(e){c.logger.warn("onMediaDetaching:"+e.message+" while calling endOfStream")}e.removeEventListener("sourceopen",this.onmso),e.removeEventListener("sourceended",this.onmse),e.removeEventListener("sourceclose",this.onmsc),this.media&&(URL.revokeObjectURL(this.media.src),this.media.removeAttribute("src"),this.media.load()),this.mediaSource=null,this.media=null,this.pendingTracks={},this.tracks={},this.sourceBuffer={},this.flushRange=[],this.segments=[],this.appended=0}this.onmso=this.onmse=this.onmsc=null,this.hls.trigger(u.default.MEDIA_DETACHED)}},{key:"onMediaSourceOpen",value:function(){c.logger.log("media source opened"),this.hls.trigger(u.default.MEDIA_ATTACHED,{media:this.media});var e=this.mediaSource;e&&e.removeEventListener("sourceopen",this.onmso),this.checkPendingTracks()}},{key:"checkPendingTracks",value:function(){var e=this.pendingTracks,t=Object.keys(e).length;t&&(this.sourceBufferNb<=t||0===this.sourceBufferNb)&&(this.createSourceBuffers(e),this.pendingTracks={},this.doAppending())}},{key:"onMediaSourceClose",value:function(){c.logger.log("media source closed")}},{key:"onMediaSourceEnded",value:function(){c.logger.log("media source ended")}},{key:"onSBUpdateEnd",value:function(){if(this.audioTimestampOffset){var e=this.sourceBuffer.audio;c.logger.warn("change mpeg audio timestamp offset from "+e.timestampOffset+" to "+this.audioTimestampOffset),e.timestampOffset=this.audioTimestampOffset,delete this.audioTimestampOffset}this._needsFlush&&this.doFlush(),this._needsEos&&this.checkEos(),this.appending=!1;var t=this.parent,r=this.segments.reduce(function(e,r){return r.parent===t?e+1:e},0);this.hls.trigger(u.default.BUFFER_APPENDED,{parent:t,pending:r}),this._needsFlush||this.doAppending(),this.updateMediaElementDuration()}},{key:"onSBUpdateError",value:function(e){c.logger.error("sourceBuffer error:",e),this.hls.trigger(u.default.ERROR,{type:h.ErrorTypes.MEDIA_ERROR,details:h.ErrorDetails.BUFFER_APPENDING_ERROR,fatal:!1})}},{key:"onBufferReset",value:function(){var e=this.sourceBuffer;for(var t in e){var r=e[t];try{this.mediaSource.removeSourceBuffer(r),r.removeEventListener("updateend",this.onsbue),r.removeEventListener("error",this.onsbe)}catch(e){}}this.sourceBuffer={},this.flushRange=[],this.segments=[],this.appended=0}},{key:"onBufferCodecs",value:function(e){if(0===Object.keys(this.sourceBuffer).length){for(var t in e)this.pendingTracks[t]=e[t];var r=this.mediaSource;r&&"open"===r.readyState&&this.checkPendingTracks()}}},{key:"createSourceBuffers",value:function(e){var t=this.sourceBuffer,r=this.mediaSource;for(var i in e)if(!t[i]){var a=e[i],n=a.levelCodec||a.codec,s=a.container+";codecs="+n;c.logger.log("creating sourceBuffer("+s+")");try{var o=t[i]=r.addSourceBuffer(s);o.addEventListener("updateend",this.onsbue),o.addEventListener("error",this.onsbe),this.tracks[i]={codec:n,container:a.container},a.buffer=o}catch(e){c.logger.error("error while trying to add sourceBuffer:"+e.message),this.hls.trigger(u.default.ERROR,{type:h.ErrorTypes.MEDIA_ERROR,details:h.ErrorDetails.BUFFER_ADD_CODEC_ERROR,fatal:!1,err:e,mimeType:s})}}this.hls.trigger(u.default.BUFFER_CREATED,{tracks:e})}},{key:"onBufferAppending",value:function(e){this._needsFlush||(this.segments?this.segments.push(e):this.segments=[e],this.doAppending())}},{key:"onBufferAppendFail",value:function(e){c.logger.error("sourceBuffer error:",e.event),this.hls.trigger(u.default.ERROR,{type:h.ErrorTypes.MEDIA_ERROR,details:h.ErrorDetails.BUFFER_APPENDING_ERROR,fatal:!1})}},{key:"onBufferEos",value:function(e){var t=this.sourceBuffer,r=e.type;for(var i in t)r&&i!==r||t[i].ended||(t[i].ended=!0,c.logger.log(i+" sourceBuffer now EOS"));this.checkEos()}},{key:"checkEos",value:function(){var e=this.sourceBuffer,t=this.mediaSource;if(!t||"open"!==t.readyState)return void(this._needsEos=!1);for(var r in e){var i=e[r];if(!i.ended)return;if(i.updating)return void(this._needsEos=!0)}c.logger.log("all media data available, signal endOfStream() to MediaSource and stop loading fragment");try{t.endOfStream()}catch(e){c.logger.warn("exception while calling mediaSource.endOfStream()")}this._needsEos=!1}},{key:"onBufferFlushing",value:function(e){this.flushRange.push({start:e.startOffset,end:e.endOffset,type:e.type}),this.flushBufferCounter=0,this.doFlush()}},{key:"onLevelUpdated",value:function(e){var t=e.details;0!==t.fragments.length&&(this._levelDuration=t.totalduration+t.fragments[0].start,this.updateMediaElementDuration())}},{key:"updateMediaElementDuration",value:function(){var e=this.media,t=this.mediaSource,r=this.sourceBuffer,i=this._levelDuration;if(null!==i&&e&&t&&r&&0!==e.readyState&&"open"===t.readyState){for(var a in r)if(r[a].updating)return;null===this._msDuration&&(this._msDuration=t.duration);var n=e.duration;(i>this._msDuration&&i>n||n===1/0||isNaN(n))&&(c.logger.log("Updating mediasource duration to "+i.toFixed(3)),this._msDuration=t.duration=i)}}},{key:"doFlush",value:function(){for(;this.flushRange.length;){var e=this.flushRange[0];if(!this.flushBuffer(e.start,e.end,e.type))return void(this._needsFlush=!0);this.flushRange.shift(),this.flushBufferCounter=0}if(0===this.flushRange.length){this._needsFlush=!1;var t=0,r=this.sourceBuffer;try{for(var i in r)t+=r[i].buffered.length}catch(e){c.logger.error("error while accessing sourceBuffer.buffered")}this.appended=t,this.hls.trigger(u.default.BUFFER_FLUSHED)}}},{key:"doAppending",value:function(){var e=this.hls,t=this.sourceBuffer,r=this.segments;if(Object.keys(t).length){if(this.media.error)return this.segments=[],void c.logger.error("trying to append although a media error occured, flush segment and abort");if(this.appending)return;if(r&&r.length){var i=r.shift();try{var a=i.type,n=t[a];n?n.updating?r.unshift(i):(n.ended=!1,this.parent=i.parent,n.appendBuffer(i.data),this.appendError=0,this.appended++,this.appending=!0):this.onSBUpdateEnd()}catch(t){c.logger.error("error while trying to append buffer:"+t.message),r.unshift(i);var s={type:h.ErrorTypes.MEDIA_ERROR,parent:i.parent};if(22===t.code)return this.segments=[],s.details=h.ErrorDetails.BUFFER_FULL_ERROR,s.fatal=!1,void e.trigger(u.default.ERROR,s);if(this.appendError?this.appendError++:this.appendError=1,s.details=h.ErrorDetails.BUFFER_APPEND_ERROR,this.appendError>e.config.appendErrorMaxRetry)return c.logger.log("fail "+e.config.appendErrorMaxRetry+" times to append segment in sourceBuffer"),r=[],s.fatal=!0,void e.trigger(u.default.ERROR,s);s.fatal=!1,e.trigger(u.default.ERROR,s)}}}}},{key:"flushBuffer",value:function(e,t,r){var i,a,n,s,o,l,u=this.sourceBuffer;if(Object.keys(u).length){if(c.logger.log("flushBuffer,pos/start/end: "+this.media.currentTime.toFixed(3)+"/"+e+"/"+t),this.flushBufferCounter.5)return this.flushBufferCounter++,c.logger.log("flush "+d+" ["+o+","+l+"], of ["+n+","+s+"], pos:"+this.media.currentTime),i.remove(o,l),!1}catch(e){c.logger.warn("exception while accessing sourcebuffer, it might have been removed from MediaSource")}}}else c.logger.warn("abort flushing too many retries");c.logger.log("buffer flushed")}return!0}}]),t}(f.default);r.default=g},{30:30,31:31,32:32,50:50}],9:[function(e,t,r){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(r,"__esModule",{value:!0});var o=function(){function e(e,t){for(var r=0;rthis.autoLevelCapping&&t.streamController.nextLevelSwitch(),this.autoLevelCapping=t.autoLevelCapping}}}},{key:"getMaxLevel",value:function(e){var t=0,r=void 0,i=void 0,a=this.mediaWidth,n=this.mediaHeight,s=0,o=0;for(r=0;r<=e&&(i=this.levels[r],!this.isLevelRestricted(r))&&(t=r,s=i.width,o=i.height,!(a<=s||n<=o));r++);return t}},{key:"isLevelRestricted",value:function(e){return!(!this.restrictedLevels||this.restrictedLevels.indexOf(e)===-1)}},{key:"contentScaleFactor",get:function(){var e=1;try{e=window.devicePixelRatio}catch(e){}return e}},{key:"mediaWidth",get:function(){var e=void 0,t=this.media;return t&&(e=t.width||t.clientWidth||t.offsetWidth,e*=this.contentScaleFactor),e}},{key:"mediaHeight",get:function(){var e=void 0,t=this.media;return t&&(e=t.height||t.clientHeight||t.offsetHeight,e*=this.contentScaleFactor),e}}]),t}(f.default);r.default=c},{31:31,32:32}],10:[function(e,t,r){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(r,"__esModule",{value:!0});var o=function(){function e(e,t){for(var r=0;r0&&n>l.config.fpsDroppedMonitoringThreshold*s){var d=l.currentLevel;c.logger.warn("drop FPS ratio greater than max allowed value for currentLevel: "+d),d>0&&(l.autoLevelCapping===-1||l.autoLevelCapping>=d)&&(d-=1,l.trigger(u.default.FPS_DROP_LEVEL_CAPPING,{level:d,droppedLevel:l.currentLevel}),l.autoLevelCapping=d,l.streamController.nextLevelSwitch())}}this.lastTime=i,this.lastDroppedFrames=r,this.lastDecodedFrames=t}}},{key:"checkFPSInterval",value:function(){var e=this.video;if(e)if(this.isVideoPlaybackQualityAvailable){var t=e.getVideoPlaybackQuality();this.checkFPS(e,t.totalVideoFrames,t.droppedVideoFrames)}else this.checkFPS(e,e.webkitDecodedFrameCount,e.webkitDroppedFrameCount)}}]),t}(f.default);r.default=h},{31:31,32:32,50:50}],11:[function(e,t,r){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(r,"__esModule",{value:!0});var o=function(){function e(e,t){for(var r=0;r0})}else o.trigger(u.default.ERROR,{type:h.ErrorTypes.MEDIA_ERROR,details:h.ErrorDetails.MANIFEST_INCOMPATIBLE_CODECS_ERROR,fatal:!0,url:o.url,reason:"no level with compatible codecs found in manifest"})}},{key:"setLevelInternal",value:function(e){var t=this._levels,r=this.hls;if(e>=0&&e1&&a.loadErrore&&(this._level===e&&void 0!==t[e].details||this.setLevelInternal(e))}},{key:"manualLevel",get:function(){return this._manualLevel},set:function(e){this._manualLevel=e,void 0===this._startLevel&&(this._startLevel=e),e!==-1&&(this.level=e)}},{key:"firstLevel",get:function(){return this._firstLevel},set:function(e){this._firstLevel=e}},{key:"startLevel",get:function(){if(void 0===this._startLevel){var e=this.hls.config.startLevel;return void 0!==e?e:this._firstLevel}return this._startLevel},set:function(e){this._startLevel=e}},{key:"nextLoadLevel",get:function(){return this._manualLevel!==-1?this._manualLevel:this.hls.nextAutoLevel},set:function(e){this.level=e,this._manualLevel===-1&&(this.hls.nextAutoLevel=e)}}]),t}(f.default);r.default=p},{30:30,31:31,32:32,34:34,50:50}],12:[function(e,t,r){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(r,"__esModule",{value:!0});var o=function(){function e(e,t){for(var r=0;r0&&e===-1&&(k.logger.log("override startPosition with lastCurrentTime @"+t.toFixed(3)),e=t),this.state=R.IDLE,this.nextLoadPosition=this.startPosition=this.lastCurrentTime=e,this.tick()}else this.forceStartLoad=!0,this.state=R.STOPPED}},{key:"stopLoad",value:function(){var e=this.fragCurrent;e&&(e.loader&&e.loader.abort(),this.fragCurrent=null),this.fragPrevious=null,this.demuxer&&(this.demuxer.destroy(),this.demuxer=null),this.state=R.STOPPED,this.forceStartLoad=!1}},{key:"tick",value:function(){1===++this.ticks&&(this.doTick(),this.ticks>1&&setTimeout(this.tick,1),this.ticks=0)}},{key:"doTick",value:function(){switch(this.state){case R.ERROR:break;case R.BUFFER_FLUSHING:this.fragLoadError=0;break;case R.IDLE:if(!this._doTickIdle())return;break;case R.WAITING_LEVEL:var e=this.levels[this.level];e&&e.details&&(this.state=R.IDLE);break;case R.FRAG_LOADING_WAITING_RETRY:var t=performance.now(),r=this.retryDate;(!r||t>=r||this.media&&this.media.seeking)&&(k.logger.log("mediaController: retryDate reached, switch back to IDLE state"),this.state=R.IDLE);break;case R.ERROR:case R.STOPPED:case R.FRAG_LOADING:case R.PARSING:case R.PARSED:case R.ENDED:}this._checkBuffer(),this._checkFragmentChanged()}},{key:"_doTickIdle",value:function(){var e=this.hls,t=e.config,r=this.media;if(void 0!==this.levelLastLoaded&&!r&&(this.startFragRequested||!t.startFragPrefetch))return!0;var i=void 0;i=this.loadedmetadata?r.currentTime:this.nextLoadPosition;var a=e.nextLoadLevel,n=this.levels[a],s=n.bitrate,o=void 0;o=s?Math.max(8*t.maxBufferSize/s,t.maxBufferLength):t.maxBufferLength,o=Math.min(o,t.maxMaxBufferLength);var l=f.default.bufferInfo(this.mediaBuffer?this.mediaBuffer:r,i,t.maxBufferHole),u=l.len;if(u>=o)return!0;k.logger.trace("buffer length of "+u.toFixed(3)+" is below max of "+o.toFixed(3)+". checking for more payload ..."),this.level=e.nextLoadLevel=a;var d=n.details;if(void 0===d||d.live&&this.levelLastLoaded!==a)return this.state=R.WAITING_LEVEL,!0;var c=this.fragPrevious;if(!d.live&&c&&c.sn===d.endSN){if(Math.min(r.duration,c.start+c.duration)-Math.max(l.end,c.start)<=Math.max(.2,c.duration/2)){var h={};return this.altAudio&&(h.type="video"),this.hls.trigger(v.default.BUFFER_EOS,h),this.state=R.ENDED,!0}}return this._fetchPayloadOrEos(i,l,d)}},{key:"_fetchPayloadOrEos",value:function(e,t,r){var i=this.fragPrevious,a=this.level,n=r.fragments,s=n.length;if(0===s)return!1;var o=n[0].start,l=n[s-1].start+n[s-1].duration,u=t.end,d=void 0;if(r.initSegment&&!r.initSegment.data)d=r.initSegment;else if(r.live){var f=this.config.initialLiveManifestSize;if(sf&&(l.currentTime=f)}if(e.PTSKnown&&t>i&&l&&l.readyState)return null;if(this.startFragRequested&&!e.PTSKnown){if(a){var c=a.sn+1;c>=e.startSN&&c<=e.endSN&&(u=n[c-e.startSN],k.logger.log("live playlist, switching playlist, load frag with next SN: "+u.sn))}u||(u=n[Math.min(s-1,Math.round(s/2))],k.logger.log("live playlist, switching playlist, unknown, load middle frag : "+u.sn))}return u}},{key:"_findFragment",value:function(e,t,r,i,a,n,s){var o=this.hls.config,l=void 0,d=void 0,f=o.maxFragLookUpTolerance,c=t?i[t.sn-i[0].sn+1]:void 0,h=function(e){var t=Math.min(f,e.duration);return e.start+e.duration-t<=a?1:e.start-t>a&&e.start?-1:0};if(an-f&&(f=0),d=c&&!h(c)?c:u.default.search(i,h)):d=i[r-1],d){l=d;var g=l.sn-s.startSN,v=t&&l.level===t.level,p=i[g-1],y=i[g+1];if(v&&l.sn===t.sn)if(l.sno.maxBufferHole&&t.dropped&&g?(l=p,k.logger.warn("SN just loaded, with large PTS gap between audio and video, maybe frag is not starting with a keyframe ? load previous one to try to overcome this"),t.loadCounter--):(l=y,k.logger.log("SN just loaded, load next one: "+l.sn))
+}else l=null;else l.dropped&&!v&&(y&&y.backtracked?(k.logger.warn("Already backtracked from fragment "+(g+1)+", will not backtrack to fragment "+g+". Loading fragment "+(g+1)),l=y):(k.logger.warn("Loaded fragment with dropped frames, backtracking 1 segment to find a keyframe"),l.dropped=0,p?(p.loadCounter&&p.loadCounter--,l=p):l=null))}return l}},{key:"_loadFragmentOrKey",value:function(e,t,r,i,a){var n=this.hls,s=n.config;if(!e.decryptdata||null==e.decryptdata.uri||null!=e.decryptdata.key){if(k.logger.log("Loading "+e.sn+" of ["+r.startSN+" ,"+r.endSN+"],level "+t+", currentTime:"+i.toFixed(3)+",bufferEnd:"+a.toFixed(3)),void 0!==this.fragLoadIdx?this.fragLoadIdx++:this.fragLoadIdx=0,e.loadCounter){e.loadCounter++;var o=s.fragLoadingLoopThreshold;if(e.loadCounter>o&&Math.abs(this.fragLoadIdx-e.loadIdx)t.endPTS?1:0})}},{key:"followingBufferedFrag",value:function(e){return e?this.getBufferedFrag(e.endPTS+.5):null}},{key:"_checkFragmentChanged",value:function(){var e,t,r=this.media;if(r&&r.readyState&&r.seeking===!1&&(t=r.currentTime,t>r.playbackRate*this.lastCurrentTime&&(this.lastCurrentTime=t),f.default.isBuffered(r,t)?e=this.getBufferedFrag(t):f.default.isBuffered(r,t+.1)&&(e=this.getBufferedFrag(t+.1)),e)){var i=e;if(i!==this.fragPlaying){this.hls.trigger(v.default.FRAG_CHANGED,{frag:i});var a=i.level;this.fragPlaying&&this.fragPlaying.level===a||this.hls.trigger(v.default.LEVEL_SWITCHED,{level:a}),this.fragPlaying=i}}}},{key:"immediateLevelSwitch",value:function(){if(k.logger.log("immediateLevelSwitch"),!this.immediateSwitch){this.immediateSwitch=!0;var e=this.media,t=void 0;e?(t=e.paused,e.pause()):t=!0,this.previouslyPaused=t}var r=this.fragCurrent;r&&r.loader&&r.loader.abort(),this.fragCurrent=null,this.fragLoadIdx+=2*this.config.fragLoadingLoopThreshold,this.flushMainBuffer(0,Number.POSITIVE_INFINITY)}},{key:"immediateLevelSwitchEnd",value:function(){var e=this.media;e&&e.buffered.length&&(this.immediateSwitch=!1,f.default.isBuffered(e,e.currentTime)&&(e.currentTime-=1e-4),this.previouslyPaused||e.play())}},{key:"nextLevelSwitch",value:function(){var e=this.media;if(e&&e.readyState){var t=void 0,r=void 0,i=void 0;if(this.fragLoadIdx+=2*this.config.fragLoadingLoopThreshold,r=this.getBufferedFrag(e.currentTime),r&&r.startPTS>1&&this.flushMainBuffer(0,r.startPTS-1),e.paused)t=0;else{var a=this.hls.nextLoadLevel,n=this.levels[a],s=this.fragLastKbps;t=s&&this.fragCurrent?this.fragCurrent.duration*n.bitrate/(1e3*s)+1:0}if((i=this.getBufferedFrag(e.currentTime+t))&&(i=this.followingBufferedFrag(i))){var o=this.fragCurrent;o&&o.loader&&o.loader.abort(),this.fragCurrent=null,this.flushMainBuffer(i.startPTS,Number.POSITIVE_INFINITY)}}}},{key:"flushMainBuffer",value:function(e,t){this.state=R.BUFFER_FLUSHING;var r={startOffset:e,endOffset:t};this.altAudio&&(r.type="video"),this.hls.trigger(v.default.BUFFER_FLUSHING,r)}},{key:"onMediaAttached",value:function(e){var t=this.media=this.mediaBuffer=e.media;this.onvseeking=this.onMediaSeeking.bind(this),this.onvseeked=this.onMediaSeeked.bind(this),this.onvended=this.onMediaEnded.bind(this),t.addEventListener("seeking",this.onvseeking),t.addEventListener("seeked",this.onvseeked),t.addEventListener("ended",this.onvended);var r=this.config;this.levels&&r.autoStartLoad&&this.hls.startLoad(r.startPosition)}},{key:"onMediaDetaching",value:function(){var e=this.media;e&&e.ended&&(k.logger.log("MSE detaching and video ended, reset startPosition"),this.startPosition=this.lastCurrentTime=0);var t=this.levels;t&&t.forEach(function(e){e.details&&e.details.fragments.forEach(function(e){e.loadCounter=void 0,e.backtracked=void 0})}),e&&(e.removeEventListener("seeking",this.onvseeking),e.removeEventListener("seeked",this.onvseeked),e.removeEventListener("ended",this.onvended),this.onvseeking=this.onvseeked=this.onvended=null),this.media=this.mediaBuffer=null,this.loadedmetadata=!1,this.stopLoad()}},{key:"onMediaSeeking",value:function(){var e=this.media,t=e?e.currentTime:void 0,r=this.config;if(k.logger.log("media seeking to "+t.toFixed(3)),this.state===R.FRAG_LOADING){var i=this.mediaBuffer?this.mediaBuffer:e,a=f.default.bufferInfo(i,t,this.config.maxBufferHole),n=this.fragCurrent;if(0===a.len&&n){var s=r.maxFragLookUpTolerance,o=n.start-s,l=n.start+n.duration+s;tl?(n.loader&&(k.logger.log("seeking outside of buffer while fragment load in progress, cancel fragment load"),n.loader.abort()),this.fragCurrent=null,this.fragPrevious=null,this.state=R.IDLE):k.logger.log("seeking outside of buffer but within currently loaded fragment range")}}else this.state===R.ENDED&&(this.state=R.IDLE);e&&(this.lastCurrentTime=t),this.state!==R.FRAG_LOADING&&void 0!==this.fragLoadIdx&&(this.fragLoadIdx+=2*r.fragLoadingLoopThreshold),this.loadedmetadata||(this.nextLoadPosition=this.startPosition=t),this.tick()}},{key:"onMediaSeeked",value:function(){k.logger.log("media seeked to "+this.media.currentTime.toFixed(3)),this.tick()}},{key:"onMediaEnded",value:function(){k.logger.log("media ended"),this.startPosition=this.lastCurrentTime=0}},{key:"onManifestLoading",value:function(){k.logger.log("trigger BUFFER_RESET"),this.hls.trigger(v.default.BUFFER_RESET),this._bufferedFrags=[],this.stalled=!1,this.startPosition=this.lastCurrentTime=0}},{key:"onManifestParsed",value:function(e){var t,r=!1,i=!1;e.levels.forEach(function(e){(t=e.audioCodec)&&(t.indexOf("mp4a.40.2")!==-1&&(r=!0),t.indexOf("mp4a.40.5")!==-1&&(i=!0))}),this.audioCodecSwitch=r&&i,this.audioCodecSwitch&&k.logger.log("both AAC/HE-AAC audio found in levels; declaring level codec as HE-AAC"),this.levels=e.levels,this.startLevelLoaded=!1,this.startFragRequested=!1;var a=this.config;(a.autoStartLoad||this.forceStartLoad)&&this.hls.startLoad(a.startPosition)}},{key:"onLevelLoaded",value:function(e){var t=e.details,r=e.level,i=this.levels[r],a=t.totalduration,n=0;if(k.logger.log("level "+r+" loaded ["+t.startSN+","+t.endSN+"],duration:"+a),this.levelLastLoaded=r,t.live){var s=i.details;s&&t.fragments.length>0?(E.default.mergeDetails(s,t),n=t.fragments[0].start,this.liveSyncPosition=this.computeLivePosition(n,s),t.PTSKnown?k.logger.log("live playlist sliding:"+n.toFixed(3)):k.logger.log("live playlist - outdated PTS, unknown sliding")):(t.PTSKnown=!1,k.logger.log("live playlist - first load, unknown sliding"))}else t.PTSKnown=!1;if(i.details=t,this.hls.trigger(v.default.LEVEL_UPDATED,{details:t,level:r}),this.startFragRequested===!1){if(this.startPosition===-1||this.lastCurrentTime===-1){var o=t.startTimeOffset;isNaN(o)?t.live?(this.startPosition=this.computeLivePosition(n,t),k.logger.log("configure startPosition to "+this.startPosition)):this.startPosition=0:(o<0&&(k.logger.log("negative start time offset "+o+", count from end of last fragment"),o=n+a+o),k.logger.log("start time offset found in playlist, adjust startPosition to "+o),this.startPosition=o),this.lastCurrentTime=this.startPosition}this.nextLoadPosition=this.startPosition}this.state===R.WAITING_LEVEL&&(this.state=R.IDLE),this.tick()}},{key:"onKeyLoaded",value:function(){this.state===R.KEY_LOADING&&(this.state=R.IDLE,this.tick())}},{key:"onFragLoaded",value:function(e){var t=this.fragCurrent,r=e.frag;if(this.state===R.FRAG_LOADING&&t&&"main"===r.type&&r.level===t.level&&r.sn===t.sn){var i=e.stats,a=this.levels[t.level],n=a.details;if(k.logger.log("Loaded "+t.sn+" of ["+n.startSN+" ,"+n.endSN+"],level "+t.level),this.bitrateTest=!1,this.stats=i,r.bitrateTest===!0&&this.hls.nextLoadLevel)this.state=R.IDLE,this.startFragRequested=!1,i.tparsed=i.tbuffered=performance.now(),this.hls.trigger(v.default.FRAG_BUFFERED,{stats:i,frag:t,id:"main"}),this.tick();else if("initSegment"===r.sn)this.state=R.IDLE,i.tparsed=i.tbuffered=performance.now(),n.initSegment.data=e.payload,this.hls.trigger(v.default.FRAG_BUFFERED,{stats:i,frag:t,id:"main"}),this.tick();else{this.state=R.PARSING;var s=n.totalduration,o=t.level,l=t.sn,u=this.config.defaultAudioCodec||a.audioCodec;this.audioCodecSwap&&(k.logger.log("swapping playlist audio codec"),void 0===u&&(u=this.lastAudioCodec),u&&(u=u.indexOf("mp4a.40.5")!==-1?"mp4a.40.2":"mp4a.40.5")),this.pendingBuffering=!0,this.appended=!1,k.logger.log("Parsing "+l+" of ["+n.startSN+" ,"+n.endSN+"],level "+o+", cc "+t.cc);var d=this.demuxer;d||(d=this.demuxer=new h.default(this.hls,"main"));var f=this.media,c=f&&f.seeking,g=!c&&(n.PTSKnown||!n.live),p=n.initSegment?n.initSegment.data:[];d.push(e.payload,p,u,a.videoCodec,t,s,g,void 0)}}this.fragLoadError=0}},{key:"onFragParsingInitSegment",value:function(e){var t=this.fragCurrent,r=e.frag;if(t&&"main"===e.id&&r.sn===t.sn&&r.level===t.level&&this.state===R.PARSING){var i,a,n=e.tracks;if(n.audio&&this.altAudio&&delete n.audio,a=n.audio){var s=this.levels[this.level].audioCodec,o=navigator.userAgent.toLowerCase();s&&this.audioCodecSwap&&(k.logger.log("swapping playlist audio codec"),s=s.indexOf("mp4a.40.5")!==-1?"mp4a.40.2":"mp4a.40.5"),this.audioCodecSwitch&&1!==a.metadata.channelCount&&o.indexOf("firefox")===-1&&(s="mp4a.40.5"),o.indexOf("android")!==-1&&"audio/mpeg"!==a.container&&(s="mp4a.40.2",k.logger.log("Android: force audio codec to "+s)),a.levelCodec=s,a.id=e.id}a=n.video,a&&(a.levelCodec=this.levels[this.level].videoCodec,a.id=e.id),this.hls.trigger(v.default.BUFFER_CODECS,n);for(i in n){a=n[i],k.logger.log("main track:"+i+",container:"+a.container+",codecs[level/parsed]=["+a.levelCodec+"/"+a.codec+"]");var l=a.initSegment;l&&(this.appended=!0,this.pendingBuffering=!0,this.hls.trigger(v.default.BUFFER_APPENDING,{type:i,data:l,parent:"main",content:"initSegment"}))}this.tick()}}},{key:"onFragParsingData",value:function(e){var t=this,r=this.fragCurrent,i=e.frag;if(r&&"main"===e.id&&i.sn===r.sn&&i.level===r.level&&("audio"!==e.type||!this.altAudio)&&this.state===R.PARSING){var a=this.levels[this.level],n=r;if(isNaN(e.endPTS)&&(e.endPTS=e.startPTS+r.duration,e.endDTS=e.startDTS+r.duration),k.logger.log("Parsed "+e.type+",PTS:["+e.startPTS.toFixed(3)+","+e.endPTS.toFixed(3)+"],DTS:["+e.startDTS.toFixed(3)+"/"+e.endDTS.toFixed(3)+"],nb:"+e.nb+",dropped:"+(e.dropped||0)),"video"===e.type)if(n.dropped=e.dropped,n.dropped){if(!n.backtracked)return n.backtracked=!0,this.nextLoadPosition=e.startPTS,this.state=R.IDLE,void this.tick();k.logger.warn("Already backtracked on this fragment, appending with the gap")}else n.backtracked=!1;var s=E.default.updateFragPTSDTS(a.details,n.sn,e.startPTS,e.endPTS,e.startDTS,e.endDTS),o=this.hls;o.trigger(v.default.LEVEL_PTS_UPDATED,{details:a.details,level:this.level,drift:s,type:e.type,start:e.startPTS,end:e.endPTS}),[e.data1,e.data2].forEach(function(r){r&&r.length&&t.state===R.PARSING&&(t.appended=!0,t.pendingBuffering=!0,o.trigger(v.default.BUFFER_APPENDING,{type:e.type,data:r,parent:"main",content:"data"}))}),this.tick()}}},{key:"onFragParsed",value:function(e){var t=this.fragCurrent,r=e.frag;t&&"main"===e.id&&r.sn===t.sn&&r.level===t.level&&this.state===R.PARSING&&(this.stats.tparsed=performance.now(),this.state=R.PARSED,this._checkAppendedParsed())}},{key:"onAudioTrackSwitching",value:function(e){var t=!!e.url,r=e.id;if(!t){if(this.mediaBuffer!==this.media){k.logger.log("switching on main audio, use media.buffered to schedule main fragment loading"),this.mediaBuffer=this.media;var i=this.fragCurrent;i.loader&&(k.logger.log("switching to main audio track, cancel main fragment load"),i.loader.abort()),this.fragCurrent=null,this.fragPrevious=null,this.demuxer&&(this.demuxer.destroy(),this.demuxer=null),this.state=R.IDLE}var a=this.hls;a.trigger(v.default.BUFFER_FLUSHING,{startOffset:0,endOffset:Number.POSITIVE_INFINITY,type:"audio"}),a.trigger(v.default.AUDIO_TRACK_SWITCHED,{id:r}),this.altAudio=!1}}},{key:"onAudioTrackSwitched",value:function(e){var t=e.id,r=!!this.hls.audioTracks[t].url;if(r){var i=this.videoBuffer;i&&this.mediaBuffer!==i&&(k.logger.log("switching on alternate audio, use video.buffered to schedule main fragment loading"),this.mediaBuffer=i)}this.altAudio=r,this.tick()}},{key:"onBufferCreated",value:function(e){var t=e.tracks,r=void 0,i=void 0,a=!1;for(var n in t){var s=t[n];"main"===s.id?(i=n,r=s,"video"===n&&(this.videoBuffer=t[n].buffer)):a=!0}a&&r?(k.logger.log("alternate track found, use "+i+".buffered to schedule main fragment loading"),this.mediaBuffer=r.buffer):this.mediaBuffer=this.media}},{key:"onBufferAppended",value:function(e){if("main"===e.parent){var t=this.state;t!==R.PARSING&&t!==R.PARSED||(this.pendingBuffering=e.pending>0,this._checkAppendedParsed())}}},{key:"_checkAppendedParsed",value:function(){if(!(this.state!==R.PARSED||this.appended&&this.pendingBuffering)){var e=this.fragCurrent;if(e){var t=this.mediaBuffer?this.mediaBuffer:this.media;k.logger.log("main buffered : "+T.default.toString(t.buffered));var r=this._bufferedFrags.filter(function(e){return f.default.isBuffered(t,(e.startPTS+e.endPTS)/2)});r.push(e),this._bufferedFrags=r.sort(function(e,t){return e.startPTS-t.startPTS}),this.fragPrevious=e;var i=this.stats;i.tbuffered=performance.now(),this.fragLastKbps=Math.round(8*i.total/(i.tbuffered-i.tfirst)),this.hls.trigger(v.default.FRAG_BUFFERED,{stats:i,frag:e,id:"main"}),this.state=R.IDLE}this.tick()}}},{key:"onError",value:function(e){var t=e.frag||this.fragCurrent;if(!t||"main"===t.type){var r=this.media,i=r&&f.default.isBuffered(r,r.currentTime)&&f.default.isBuffered(r,r.currentTime+.5);switch(e.details){case _.ErrorDetails.FRAG_LOAD_ERROR:case _.ErrorDetails.FRAG_LOAD_TIMEOUT:case _.ErrorDetails.KEY_LOAD_ERROR:case _.ErrorDetails.KEY_LOAD_TIMEOUT:if(!e.fatal){var a=this.fragLoadError;a?a++:a=1;var n=this.config;if(a<=n.fragLoadingMaxRetry||i||t.autoLevel&&t.level){this.fragLoadError=a,t.loadCounter=0;var s=Math.min(Math.pow(2,a-1)*n.fragLoadingRetryDelay,n.fragLoadingMaxRetryTimeout);k.logger.warn("mediaController: frag loading failed, retry in "+s+" ms"),this.retryDate=performance.now()+s,this.loadedmetadata||(this.startFragRequested=!1,this.nextLoadPosition=this.startPosition),this.state=R.FRAG_LOADING_WAITING_RETRY}else k.logger.error("mediaController: "+e.details+" reaches max retry, redispatch as fatal ..."),e.fatal=!0,this.state=R.ERROR}break;case _.ErrorDetails.FRAG_LOOP_LOADING_ERROR:e.fatal||(i?(this._reduceMaxBufferLength(t.duration),this.state=R.IDLE):t.autoLevel&&0!==t.level||(e.fatal=!0,this.state=R.ERROR));break;case _.ErrorDetails.LEVEL_LOAD_ERROR:case _.ErrorDetails.LEVEL_LOAD_TIMEOUT:this.state!==R.ERROR&&(e.fatal?(this.state=R.ERROR,k.logger.warn("streamController: "+e.details+",switch to "+this.state+" state ...")):this.state===R.WAITING_LEVEL&&(this.state=R.IDLE));break;case _.ErrorDetails.BUFFER_FULL_ERROR:"main"!==e.parent||this.state!==R.PARSING&&this.state!==R.PARSED||(i?(this._reduceMaxBufferLength(this.config.maxBufferLength),this.state=R.IDLE):(k.logger.warn("buffer full error also media.currentTime is not buffered, flush everything"),this.fragCurrent=null,this.flushMainBuffer(0,Number.POSITIVE_INFINITY)))}}}},{key:"_reduceMaxBufferLength",value:function(e){var t=this.config;t.maxMaxBufferLength>=e&&(t.maxMaxBufferLength/=2,k.logger.warn("main:reduce max buffer length to "+t.maxMaxBufferLength+"s"),this.fragLoadIdx+=2*t.fragLoadingLoopThreshold)}},{key:"_checkBuffer",value:function(){var e=this.media;if(e&&e.readyState){var t=e.currentTime,r=this.mediaBuffer?this.mediaBuffer:e,i=r.buffered;if(!this.loadedmetadata&&i.length){this.loadedmetadata=!0;var a=e.seeking?t:this.startPosition,n=f.default.isBuffered(r,a);t===a&&n||(k.logger.log("target start position:"+a),n||(a=i.start(0),k.logger.log("target start position not buffered, seek to buffered.start(0) "+a)),k.logger.log("adjust currentTime from "+t+" to "+a),e.currentTime=a)}else if(this.immediateSwitch)this.immediateLevelSwitchEnd();else{var s=f.default.bufferInfo(e,t,0),o=!(e.paused||e.ended||0===e.buffered.length),l=t!==this.lastCurrentTime,u=this.config;if(l)this.stallReported&&(k.logger.warn("playback not stuck anymore @"+t+", after "+Math.round(performance.now()-this.stalled)+"ms"),this.stallReported=!1),this.stalled=void 0,this.nudgeRetry=0;else if(o){var d=performance.now(),c=this.hls;if(this.stalled){var h=d-this.stalled,g=s.len,p=this.nudgeRetry||0;if(g<=.5&&h>1e3*u.lowBufferWatchdogPeriod){this.stallReported||(this.stallReported=!0,k.logger.warn("playback stalling in low buffer @"+t),c.trigger(v.default.ERROR,{type:_.ErrorTypes.MEDIA_ERROR,details:_.ErrorDetails.BUFFER_STALLED_ERROR,fatal:!1,buffer:g}));var y=s.nextStart,m=y-t;if(y&&m0){this.nudgeRetry=++p;var E=p*u.nudgeOffset;k.logger.log("adjust currentTime from "+e.currentTime+" to next buffered @ "+y+" + nudge "+E),e.currentTime=y+E,this.stalled=void 0,c.trigger(v.default.ERROR,{type:_.ErrorTypes.MEDIA_ERROR,details:_.ErrorDetails.BUFFER_SEEK_OVER_HOLE,fatal:!1,hole:y+E-t})}}else if(g>.5&&h>1e3*u.highBufferWatchdogPeriod)if(this.stallReported||(this.stallReported=!0,k.logger.warn("playback stalling in high buffer @"+t),c.trigger(v.default.ERROR,{type:_.ErrorTypes.MEDIA_ERROR,details:_.ErrorDetails.BUFFER_STALLED_ERROR,fatal:!1,buffer:g})),this.stalled=void 0,this.nudgeRetry=++p,p"+e),this.hls.trigger(v.default.STREAM_STATE_TRANSITION,{previousState:t,nextState:e})}},get:function(){return this._state}},{key:"currentLevel",get:function(){var e=this.media;if(e){var t=this.getBufferedFrag(e.currentTime);if(t)return t.level}return-1}},{key:"nextBufferedFrag",get:function(){var e=this.media;return e?this.followingBufferedFrag(this.getBufferedFrag(e.currentTime)):null}},{key:"nextLevel",get:function(){var e=this.nextBufferedFrag;return e?e.level:-1}},{key:"liveSyncPosition",get:function(){return this._liveSyncPosition},set:function(e){this._liveSyncPosition=e}}]),t}(y.default);r.default=A},{24:24,30:30,31:31,32:32,34:34,35:35,45:45,50:50,51:51}],13:[function(e,t,r){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(r,"__esModule",{value:!0});var o=function(){function e(e,t){for(var r=0;r-1&&this.vttFragQueues[this.currentTrackId].length){var e=this.currentlyProcessing=this.vttFragQueues[this.currentTrackId].shift();this.hls.trigger(u.default.FRAG_LOADING,{frag:e})}}},{key:"onSubtitleFragProcessed",value:function(e){e.success&&this.vttFragSNsProcessed[e.frag.trackId].push(e.frag.sn),this.currentlyProcessing=null,this.nextFrag()}},{key:"onError",value:function(e){var t=e.frag;t&&"subtitle"!==t.type||this.currentlyProcessing&&(this.currentlyProcessing=null,this.nextFrag())}},{key:"onSubtitleTracksUpdated",value:function(e){var t=this;c.logger.log("subtitle tracks updated"),this.tracks=e.subtitleTracks,this.clearVttFragQueues(),this.vttFragSNsProcessed={},this.tracks.forEach(function(e){t.vttFragSNsProcessed[e.id]=[]})}},{key:"onSubtitleTrackSwitch",value:function(e){this.currentTrackId=e.id,this.clearVttFragQueues()}},{key:"onSubtitleTrackLoaded",value:function(e){var t=this.vttFragSNsProcessed[e.id],r=this.vttFragQueues[e.id],i=this.currentlyProcessing?this.currentlyProcessing.sn:-1,a=function(e){return t.indexOf(e.sn)>-1},n=function(e){return r.some(function(t){return t.sn===e.sn})};e.details.fragments.forEach(function(t){a(t)||t.sn===i||n(t)||(t.trackId=e.id,r.push(t))}),this.nextFrag()}}]),t}(f.default);r.default=h},{31:31,32:32,50:50}],14:[function(e,t,r){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(r,"__esModule",{value:!0});var o=function(){function e(e,t){for(var r=0;r=0&&e0;)e.removeCue(e.cues[0])}function l(e,t){return e&&e.label===t.name&&!(e.textTrack1||e.textTrack2)}function u(e,t,r,i){return Math.min(t,i)-Math.max(e,r)}Object.defineProperty(r,"__esModule",{value:!0});var d=function(){function e(e,t){for(var r=0;r=0&&(o[0]=Math.min(o[0],t),o[1]=Math.max(o[1],r),n=!0,l/(r-t)>.5))return}n||a.push([t,r]),this.Cues.newCue(this[e],t,r,i)}},{key:"onInitPtsFound",value:function(e){var t=this;void 0===this.initPTS&&(this.initPTS=e.initPTS),this.unparsedVttFrags.length&&(this.unparsedVttFrags.forEach(function(e){t.onFragLoaded(e)}),this.unparsedVttFrags=[])}},{key:"getExistingTrack",value:function(e){var t=this.media;if(t)for(var r=0;r>>8^255&p^99,e[h]=p,t[p]=h;var y=c[h],m=c[y],E=c[m],b=257*c[p]^16843008*p;i[h]=b<<24|b>>>8,a[h]=b<<16|b>>>16,n[h]=b<<8|b>>>24,s[h]=b,b=16843009*E^65537*m^257*y^16843008*h,l[p]=b<<24|b>>>8,u[p]=b<<16|b>>>16,d[p]=b<<8|b>>>24,f[p]=b,h?(h=y^c[c[c[E^y]]],g^=c[c[g]]):h=g=1}}},{key:"expandKey",value:function(e){for(var t=this.uint8ArrayToUint32Array_(e),r=!0,i=0;i>8|e>>>24}},{key:"decrypt",value:function(e,t,r){for(var i,a,n=this.keySize+6,s=this.invKeySchedule,o=this.invSBox,l=this.invSubMix,u=l[0],d=l[1],f=l[2],c=l[3],h=this.uint8ArrayToUint32Array_(r),g=h[0],v=h[1],p=h[2],y=h[3],m=new Int32Array(e),E=new Int32Array(m.length),b=void 0,T=void 0,_=void 0,k=void 0,R=void 0,A=void 0,S=void 0,L=void 0,w=void 0,D=void 0,O=void 0,I=void 0,P=this.networkToHostOrderSwap;t>>24]^d[A>>16&255]^f[S>>8&255]^c[255&L]^s[i],T=u[A>>>24]^d[S>>16&255]^f[L>>8&255]^c[255&R]^s[i+1],_=u[S>>>24]^d[L>>16&255]^f[R>>8&255]^c[255&A]^s[i+2],k=u[L>>>24]^d[R>>16&255]^f[A>>8&255]^c[255&S]^s[i+3],R=b,A=T,S=_,L=k,i+=4;b=o[R>>>24]<<24^o[A>>16&255]<<16^o[S>>8&255]<<8^o[255&L]^s[i],T=o[A>>>24]<<24^o[S>>16&255]<<16^o[L>>8&255]<<8^o[255&R]^s[i+1],_=o[S>>>24]<<24^o[L>>16&255]<<16^o[R>>8&255]<<8^o[255&A]^s[i+2],k=o[L>>>24]<<24^o[R>>16&255]<<16^o[A>>8&255]<<8^o[255&S]^s[i+3],i+=3,E[t]=P(b^g),E[t+1]=P(k^v),E[t+2]=P(_^p),E[t+3]=P(T^y),g=w,v=D,p=O,y=I,t+=4}return E.buffer}},{key:"destroy",value:function(){this.key=void 0,this.keySize=void 0,this.ksRows=void 0,this.sBox=void 0,this.invSBox=void 0,this.subMix=void 0,this.invSubMix=void 0,this.keySchedule=void 0,this.invKeySchedule=void 0,this.rcon=void 0}}]),e}();r.default=n},{}],18:[function(e,t,r){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(r,"__esModule",{value:!0});var n=function(){function e(e,t){for(var r=0;r>>5,(s-=h)>0&&c+h+s<=v);)for(g=m+f*u,p={unit:e.subarray(c+h,c+h+s),pts:g,dts:g},a.samples.push(p),a.len+=s,c+=s+h,f++;c>>6),(o=(60&t[r+2])>>>2)>h.length-1?void e.trigger(Event.ERROR,{type:a.ErrorTypes.MEDIA_ERROR,details:a.ErrorDetails.FRAG_PARSING_ERROR,fatal:!0,reason:"invalid ADTS sampling index:"+o}):(u=(1&t[r+2])<<2,u|=(192&t[r+3])>>>6,i.logger.log("manifest codec:"+n+",ADTS data:type:"+s+",sampleingIndex:"+o+"["+h[o]+"Hz],channelConfig:"+u),/firefox/i.test(f)?o>=6?(s=5,d=new Array(4),l=o-3):(s=2,d=new Array(2),l=o):f.indexOf("android")!==-1?(s=2,d=new Array(2),l=o):(s=5,d=new Array(4),n&&(n.indexOf("mp4a.40.29")!==-1||n.indexOf("mp4a.40.5")!==-1)||!n&&o>=6?l=o-3:((n&&n.indexOf("mp4a.40.2")!==-1&&o>=6&&1===u||!n&&1===u)&&(s=2,d=new Array(2)),l=o)),d[0]=s<<3,d[0]|=(14&o)>>1,d[1]|=(1&o)<<7,d[1]|=u<<3,5===s&&(d[1]|=(14&l)>>1,d[2]=(1&l)<<7,d[2]|=8,d[3]=0),{config:d,samplerate:h[o],channelCount:u,codec:"mp4a.40."+s,manifestCodec:c})}};t.exports=n},{30:30,50:50}],22:[function(e,t,r){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(r,"__esModule",{value:!0});var n=function(){function e(e,t){for(var r=0;r0&&null!=t&&null!=t.key&&"AES-128"===t.method){var g=this.decrypter;null==g&&(g=this.decrypter=new d.default(this.observer,this.config));var v,p=this;try{v=performance.now()}catch(e){v=Date.now()}g.decrypt(e,t.key.buffer,t.iv.buffer,function(e){var d;try{d=performance.now()}catch(e){d=Date.now()}p.observer.trigger(o.default.FRAG_DECRYPTED,{stats:{tstart:v,tdecrypt:d}}),p.pushDecrypted(new Uint8Array(e),t,new Uint8Array(r),i,a,n,s,l,u,f,c,h)})}else this.pushDecrypted(new Uint8Array(e),t,new Uint8Array(r),i,a,n,s,l,u,f,c,h)}},{key:"pushDecrypted",value:function(e,t,r,i,a,n,s,u,d,f,h,v){var y=this.demuxer;if(!y||s&&!this.probe(e)){var E=this.observer,T=this.typeSupported,_=this.config,k=[{demux:p.default,remux:m.default},{demux:c.default,remux:m.default},{demux:g.default,remux:b.default}];for(var R in k){var A=k[R],S=A.demux.probe;if(S(e)){var L=this.remuxer=new A.remux(E,_,T,this.vendor);y=new A.demux(E,L,_,T),this.probe=S;break}}if(!y)return void E.trigger(o.default.ERROR,{type:l.ErrorTypes.MEDIA_ERROR,details:l.ErrorDetails.FRAG_PARSING_ERROR,fatal:!0,reason:"no demux matching with content found"});this.demuxer=y}var w=this.remuxer;(s||u)&&(y.resetInitSegment(r,i,a,f),w.resetInitSegment()),s&&(y.resetTimeStamp(),w.resetTimeStamp(v)),"function"==typeof y.setDecryptData&&y.setDecryptData(t),y.append(e,n,d,h)}}]),e}();r.default=T},{18:18,20:20,27:27,29:29,30:30,32:32,42:42,43:43}],23:[function(e,t,r){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(r,"__esModule",{value:!0});var a=e(22),n=i(a),s=e(32),o=i(s),l=e(50),u=e(1),d=i(u),f=function(e){var t=new d.default;t.trigger=function(e){for(var r=arguments.length,i=Array(r>1?r-1:0),a=1;a1?r-1:0),a=1;a1?t-1:0),i=1;i1?t-1:0),i=1;ie?(this.word<<=e,this.bitsAvailable-=e):(e-=this.bitsAvailable,t=e>>3,e-=t>>3,this.bytesAvailable-=t,this.loadWord(),this.word<<=e,this.bitsAvailable-=e)}},{key:"readBits",value:function(e){var t=Math.min(this.bitsAvailable,e),r=this.word>>>32-t;return e>32&&n.logger.error("Cannot read more than 32 bits at a time"),this.bitsAvailable-=t,this.bitsAvailable>0?this.word<<=t:this.bytesAvailable>0&&this.loadWord(),t=e-t,t>0&&this.bitsAvailable?r<>>e))return this.word<<=e,this.bitsAvailable-=e,e;return this.loadWord(),e+this.skipLZ()}},{key:"skipUEG",value:function(){this.skipBits(1+this.skipLZ())}},{key:"skipEG",value:function(){this.skipBits(1+this.skipLZ())}},{key:"readUEG",value:function(){var e=this.skipLZ();return this.readBits(e+1)-1}},{key:"readEG",value:function(){var e=this.readUEG();return 1&e?1+e>>>1:-1*(e>>>1)}},{key:"readBoolean",value:function(){return 1===this.readBits(1)}},{key:"readUByte",value:function(){return this.readBits(8)}},{key:"readUShort",value:function(){return this.readBits(16)}},{key:"readUInt",value:function(){return this.readBits(32)}},{key:"skipScalingList",value:function(e){var t,r,i=8,a=8;for(t=0;t=8){var r=e.bin2str(t.subarray(4,8));return["moof","ftyp","styp"].indexOf(r)>=0}return!1}},{key:"bin2str",value:function(e){return String.fromCharCode.apply(null,e)}},{key:"findBox",value:function(t,r){var i,a,n,s,o,l=[];if(!r.length)return null;for(i=0;i1?i+a:t.byteLength,n===r[0]&&(1===r.length?l.push(t.subarray(i+8,s)):(o=e.findBox(t.subarray(i+8,s),r.slice(1)),o.length&&(l=l.concat(o)))),i=s;return l}},{key:"parseInitSegment",value:function(t){var r=[];return e.findBox(t,["moov","trak"]).forEach(function(t){var i=e.findBox(t,["tkhd"])[0];if(i){var a=i[0],n=0===a?12:20,s=i[n]<<24|i[n+1]<<16|i[n+2]<<8|i[n+3];s=s<0?4294967296+s:s;var o=e.findBox(t,["mdia","mdhd"])[0];if(o){a=o[0],n=0===a?12:20;var l=o[n]<<24|o[n+1]<<16|o[n+2]<<8|o[n+3],u=e.findBox(t,["mdia","hdlr"])[0];if(u){var d=e.bin2str(u.subarray(8,12)),f={soun:"audio",vide:"video"}[d];f&&(r[s]={timescale:l,type:f},r[f]={timescale:l,id:s})}}}}),r}},{key:"startDTS",value:function(t,r){var i,a,n;return i=e.findBox(r,["moof","traf"]),a=[].concat.apply([],i.map(function(r){return e.findBox(r,["tfhd"]).map(function(i){var a,n,s;return a=i[4]<<24|i[5]<<16|i[6]<<8|i[7],n=t[a].timescale||9e4,s=e.findBox(r,["tfdt"]).map(function(e){var t,r;return t=e[0],r=e[4]<<24|e[5]<<16|e[6]<<8|e[7],1===t&&(r*=Math.pow(2,32),r+=e[8]<<24|e[9]<<16|e[10]<<8|e[11]),r})[0],(s=s||1/0)/n})})),n=Math.min.apply(null,a),isFinite(n)?n:0}}]),e}();r.default=o},{32:32}],28:[function(e,t,r){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(r,"__esModule",{value:!0});var a=function(){function e(e,t){for(var r=0;r=e.length)return void r();if(!(e[t].unit.length<32)){var i=this.decrypter.isSync();if(this.decryptAacSample(e,t,r,i),!i)return}}}},{key:"getAvcEncryptedData",value:function(e){for(var t=16*Math.floor((e.length-48)/160)+16,r=new Int8Array(t),i=0,a=32;a<=e.length-16;a+=160,i+=16)r.set(e.subarray(a,a+16),i);return r}},{key:"getAvcDecryptedUnit",value:function(e,t){t=new Uint8Array(t);for(var r=0,i=32;i<=e.length-16;i+=160,r+=16)e.set(t.subarray(r,r+16),i);return e}},{key:"decryptAvcSample",value:function(e,t,r,i,a,n){var s=this.discardEPB(a.data),o=this.getAvcEncryptedData(s),l=this;this.decryptBuffer(o.buffer,function(o){a.data=l.getAvcDecryptedUnit(s,o),n||l.decryptAvcSamples(e,t,r+1,i)})}},{key:"decryptAvcSamples",value:function(e,t,r,i){for(;;t++,r=0){if(t>=e.length)return void i();for(var a=e[t].units;!(r>=a.length);r++){var n=a[r];if(!(n.length<=48||1!==n.type&&5!==n.type)){var s=this.decrypter.isSync();if(this.decryptAvcSample(e,t,r,i,n,s),!s)return}}}}}]),e}();r.default=o},{18:18}],29:[function(e,t,r){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(r,"__esModule",{value:!0});var n=function(){function e(e,t){for(var r=0;r>4>1){if((o=a+5+e[a+4])===a+188)continue}else o=a+4;switch(s){case m:n&&(_&&(l=L(_))&&w(l,!1),_={data:[],size:0}),_&&(_.data.push(e.subarray(o,a+188)),_.size+=a+188-o);break;case E:n&&(k&&(l=L(k))&&(p.isAAC?D(l):O(l)),k={data:[],size:0}),k&&(k.data.push(e.subarray(o,a+188)),k.size+=a+188-o);break;case b:n&&(R&&(l=L(R))&&I(l),R={data:[],size:0}),R&&(R.data.push(e.subarray(o,a+188)),R.size+=a+188-o);break;case 0:n&&(o+=e[o]+1),T=this._pmtId=A(e,o);break;case T:n&&(o+=e[o]+1);var P=S(e,o,this.typeSupported.mpeg===!0||this.typeSupported.mp3===!0,null!=this.sampleAes);m=P.avc,m>0&&(h.id=m),E=P.audio,E>0&&(p.id=E,p.isAAC=P.isAAC),b=P.id3,b>0&&(y.id=b),f&&!c&&(g.logger.log("reparse from beginning"),f=!1,a=-188),c=this.pmtParsed=!0;break;case 17:case 8191:break;default:f=!0}}else this.observer.trigger(u.default.ERROR,{type:v.ErrorTypes.MEDIA_ERROR,details:v.ErrorDetails.FRAG_PARSING_ERROR,fatal:!1,reason:"TS packet did not start with 0x47"});_&&(l=L(_))?(w(l,!0),h.pesData=null):h.pesData=_,k&&(l=L(k))?(p.isAAC?D(l):O(l),p.pesData=null):(k&&k.size&&g.logger.log("last AAC PES packet truncated,might overlap between fragments"),p.pesData=k),R&&(l=L(R))?(I(l),y.pesData=null):y.pesData=R,null==this.sampleAes?this.remuxer.remux(p,h,y,this._txtTrack,t,r,i):this.decryptAndRemux(p,h,y,this._txtTrack,t,r,i)}},{key:"decryptAndRemux",value:function(e,t,r,i,a,n,s){if(e.samples&&e.isAAC){var o=this;this.sampleAes.decryptAacSamples(e.samples,0,function(){o.decryptAndRemuxAvc(e,t,r,i,a,n,s)})}else this.decryptAndRemuxAvc(e,t,r,i,a,n,s)}},{key:"decryptAndRemuxAvc",value:function(e,t,r,i,a,n,s){if(t.samples){var o=this;this.sampleAes.decryptAvcSamples(t.samples,0,0,function(){o.remuxer.remux(e,t,r,i,a,n,s)})}else this.remuxer.remux(e,t,r,i,a,n,s)}},{key:"destroy",value:function(){this._initPTS=this._initDTS=void 0,this._duration=0}},{key:"_parsePAT",value:function(e,t){return(31&e[t+10])<<8|e[t+11]}},{key:"_parsePMT",value:function(e,t,r,i){var a,n,s,o,l={audio:-1,avc:-1,id3:-1,isAAC:!0};for(a=(15&e[t+1])<<8|e[t+2],n=t+3+a-4,s=(15&e[t+10])<<8|e[t+11],t+=12+s;t1;){var f=new Uint8Array(d[0].length+d[1].length);f.set(d[0]),f.set(d[1],d[0].length),d[0]=f,d.splice(1,1)}if(t=d[0],1===(t[0]<<16)+(t[1]<<8)+t[2]){if((i=(t[4]<<8)+t[5])&&i>e.size-6)return null;r=t[7],192&r&&(s=536870912*(14&t[9])+4194304*(255&t[10])+16384*(254&t[11])+128*(255&t[12])+(254&t[13])/2,
+s>4294967295&&(s-=8589934592),64&r?(o=536870912*(14&t[14])+4194304*(255&t[15])+16384*(254&t[16])+128*(255&t[17])+(254&t[18])/2,o>4294967295&&(o-=8589934592),s-o>54e5&&(g.logger.warn(Math.round((s-o)/9e4)+"s delta between PTS and DTS, align them"),s=o)):o=s),a=t[8],l=a+9,e.size-=l,n=new Uint8Array(e.size);for(var c=0,h=d.length;cv){l-=v;continue}t=t.subarray(l),v-=l,l=0}n.set(t,u),u+=v}return i&&(i-=a+3),{data:n,pts:s,dts:o,len:i}}return null}},{key:"pushAccesUnit",value:function(e,t){if(e.units.length&&e.frame){var r=t.samples,i=r.length;!this.config.forceKeyFrameOnDiscontinuity||e.key===!0||t.sps&&(i||this.contiguous)?(e.id=i,r.push(e)):t.dropped++}e.debug.length&&g.logger.log(e.pts+"/"+e.dts+":"+e.debug)}},{key:"_parseAVCPES",value:function(e,t){var r,i,a,n=this,s=this._avcTrack,o=this._parseAVCNALu(e.data),l=this.avcSample;e.data=null,o.forEach(function(t){switch(t.type){case 1:i=!0,l.frame=!0;var o=t.data;if(o.length>4){var u=new f.default(o).readSliceType();2!==u&&4!==u&&7!==u&&9!==u||(l.key=!0)}break;case 5:i=!0,l||(l=n.avcSample=n._createAVCSample(!0,e.pts,e.dts,"")),l.key=!0,l.frame=!0;break;case 6:i=!0,r=new f.default(n.discardEPB(t.data)),r.readUByte();for(var d=0,c=0,h=!1,g=0;!h&&r.bytesAvailable>1;){d=0;do{g=r.readUByte(),d+=g}while(255===g);c=0;do{g=r.readUByte(),c+=g}while(255===g);if(4===d&&0!==r.bytesAvailable){h=!0;if(181===r.readUByte()){if(49===r.readUShort()){if(1195456820===r.readUInt()){if(3===r.readUByte()){var v=r.readUByte(),p=r.readUByte(),y=31&v,m=[v,p];for(a=0;a0){if(t.pts>=e[r-1].pts)e.push(t);else for(var i=r-1;i>=0;i--)if(t.pts=0)i={data:e.subarray(c,s-u-1),type:n},f.push(i);else{var h=this._getLastNalUnit();if(h&&(d&&s<=4-d&&h.state&&(h.data=h.data.subarray(0,h.data.byteLength-d)),(r=s-u-1)>0)){var g=new Uint8Array(h.data.byteLength+r);g.set(h.data,0),g.set(e.subarray(0,r),h.data.byteLength),h.data=g}}s=0&&u>=0&&(i={data:e.subarray(c,o),type:n,state:u},f.push(i)),0===f.length){var v=this._getLastNalUnit();if(v){var p=new Uint8Array(v.data.byteLength+e.byteLength);p.set(v.data,0),p.set(e,v.data.byteLength),v.data=p}}return l.naluState=u,f}},{key:"discardEPB",value:function(e){for(var t,r,i=e.byteLength,a=[],n=1;n1&&(g.logger.log("AAC: align PTS for overlapping frames by "+Math.round((k-p)/90)),p=k)}for(;n+5>>5,(r-=s)>0&&n+s+r<=d);)for(l=p+a*i,f={unit:h.subarray(n+s,n+s+r),pts:l,dts:l},c.samples.push(f),c.len+=r,n+=r+s,a++;n0;)s+=t}},{key:"_onMpegFrame",value:function(e,t,r,i,a,n){var s=1152/r*1e3,o=n+a*s,l=this._audioTrack;l.config=[],l.channelCount=i,l.samplerate=r,l.duration=this._duration,l.samples.push({unit:e,pts:o,dts:o}),l.len+=e.length}},{key:"_onMpegNoise",value:function(e){g.logger.warn("mpeg audio has noise: "+e.length+" bytes")}},{key:"_parseMpeg",value:function(e,t,r,i,a){var n=[32,64,96,128,160,192,224,256,288,320,352,384,416,448,32,48,56,64,80,96,112,128,160,192,224,256,320,384,32,40,48,56,64,80,96,112,128,160,192,224,256,320,32,48,56,64,80,96,112,128,144,160,176,192,224,256,8,16,24,32,40,48,56,64,80,96,112,128,144,160],s=[44100,48e3,32e3,22050,24e3,16e3,11025,12e3,8e3];if(t+2>r)return-1;if(255===e[t]||224==(224&e[t+1])){if(t+24>r)return-1;var o=e[t+1]>>3&3,l=e[t+1]>>1&3,u=e[t+2]>>4&15,d=e[t+2]>>2&3,f=!!(2&e[t+2]);if(1!==o&&0!==u&&15!==u&&3!==d){var c=3===o?3-l:3===l?3:4,h=1e3*n[14*c+u-1],g=3===o?0:2===o?1:2,v=s[3*g+d],p=f?1:0,y=e[t+3]>>6==3?1:2,m=3===l?(3===o?12:6)*h/v+p<<2:(3===o?144:72)*h/v+p|0;return t+m>r?-1:(this._onMpegFrame&&this._onMpegFrame(e.subarray(t,t+m),h,v,y,i,a),m)}}for(var E=t+2;E=564&&71===e[0]&&71===e[188]&&71===e[376]}}]),e}();r.default=p},{21:21,25:25,28:28,30:30,32:32,50:50}],30:[function(e,t,r){"use strict";Object.defineProperty(r,"__esModule",{value:!0});r.ErrorTypes={NETWORK_ERROR:"networkError",MEDIA_ERROR:"mediaError",MUX_ERROR:"muxError",OTHER_ERROR:"otherError"},r.ErrorDetails={MANIFEST_LOAD_ERROR:"manifestLoadError",MANIFEST_LOAD_TIMEOUT:"manifestLoadTimeOut",MANIFEST_PARSING_ERROR:"manifestParsingError",MANIFEST_INCOMPATIBLE_CODECS_ERROR:"manifestIncompatibleCodecsError",LEVEL_LOAD_ERROR:"levelLoadError",LEVEL_LOAD_TIMEOUT:"levelLoadTimeOut",LEVEL_SWITCH_ERROR:"levelSwitchError",AUDIO_TRACK_LOAD_ERROR:"audioTrackLoadError",AUDIO_TRACK_LOAD_TIMEOUT:"audioTrackLoadTimeOut",FRAG_LOAD_ERROR:"fragLoadError",FRAG_LOOP_LOADING_ERROR:"fragLoopLoadingError",FRAG_LOAD_TIMEOUT:"fragLoadTimeOut",FRAG_DECRYPT_ERROR:"fragDecryptError",FRAG_PARSING_ERROR:"fragParsingError",REMUX_ALLOC_ERROR:"remuxAllocError",KEY_LOAD_ERROR:"keyLoadError",KEY_LOAD_TIMEOUT:"keyLoadTimeOut",BUFFER_ADD_CODEC_ERROR:"bufferAddCodecError",BUFFER_APPEND_ERROR:"bufferAppendError",BUFFER_APPENDING_ERROR:"bufferAppendingError",BUFFER_STALLED_ERROR:"bufferStalledError",BUFFER_FULL_ERROR:"bufferFullError",BUFFER_SEEK_OVER_HOLE:"bufferSeekOverHole",BUFFER_NUDGE_ON_STALL:"bufferNudgeOnStall",INTERNAL_EXCEPTION:"internalException",WEBVTT_EXCEPTION:"webVTTException"}},{}],31:[function(e,t,r){"use strict";function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(r,"__esModule",{value:!0});var a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},n=function(){function e(e,t){for(var r=0;r1?r-1:0),n=1;n=r.start(i)&&t<=r.end(i))return!0;return!1},bufferInfo:function(e,t,r){if(e){var i,a=e.buffered,n=[];for(i=0;id&&(l[u-1].end=e[o].end):l.push(e[o])}else l.push(e[o])}for(o=0,i=0,a=n=t;o=f&&t=0&&o