diff --git a/bower.json b/bower.json index e112f97523..554021a897 100644 --- a/bower.json +++ b/bower.json @@ -1,7 +1,7 @@ { "name": "ionic", - "version": "0.9.27", - "codename": "salamander", + "version": "1.0.0-beta.1", + "codename": "actinium", "homepage": "https://github.com/driftyco/ionic", "authors": [ "Max Lynch ", diff --git a/component.json b/component.json index f956d643fb..08d2aa4946 100644 --- a/component.json +++ b/component.json @@ -1,7 +1,7 @@ { "repo": "driftyco/ionic", "development": {}, - "version": "0.9.27", + "version": "1.0.0-beta.1", "styles": [ "dist/css/ionic.css" ], diff --git a/release/css/ionic.css b/release/css/ionic.css index c34f04f751..24f78d888c 100644 --- a/release/css/ionic.css +++ b/release/css/ionic.css @@ -2,7 +2,7 @@ * Copyright 2014 Drifty Co. * http://drifty.com/ * - * Ionic, v0.9.27 + * Ionic, v1.0.0-beta.1 * A powerful HTML5 mobile app framework. * http://ionicframework.com/ * @@ -16,7 +16,7 @@ * Copyright 2014 Drifty Co. * http://drifty.com/ * - * Ionic, v0.9.27 + * Ionic, v1.0.0-beta.1 * A powerful HTML5 mobile app framework. * http://ionicframework.com/ * @@ -26,7 +26,7 @@ * */ /*! - Ionicons, v#{$ionicons-version} + Ionicons, v1.4.1 Created by Ben Sperry for the Ionic Framework, http://ionicons.com/ https://twitter.com/benjsperry https://twitter.com/ionicframework MIT License: https://github.com/driftyco/ionicons @@ -1686,11 +1686,11 @@ * -------------------------------------------------- * Adapted from normalize.css and some reset.css. We don't care even one * bit about old IE, so we don't need any hacks for that in here. - * + * * There are probably other things we could remove here, as well. * * normalize.css v2.1.2 | MIT License | git.io/normalize - + * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/) * http://cssreset.com */ @@ -2116,6 +2116,9 @@ body.grade-b, body.grade-c { text-align: center; font-size: 30px; } .ionic-refresher-content .icon-pulling { + -webkit-animation-name: refresh-spin-back; + -moz-animation-name: refresh-spin-back; + animation-name: refresh-spin-back; -webkit-animation-duration: 200ms; -moz-animation-duration: 200ms; animation-duration: 200ms; @@ -2140,6 +2143,20 @@ body.grade-b, body.grade-c { 100% { -webkit-transform: rotate(-180deg); } } +@keyframes refresh-spin-back { + 0% { + transform: rotate(-180deg); } + + 100% { + transform: rotate(0); } } + +@-webkit-keyframes refresh-spin-back { + 0% { + -webkit-transform: rotate(-180deg); } + + 100% { + -webkit-transform: rotate(0); } } + .scroll-refresher.active .icon-pulling { display: block; } .scroll-refresher.active .icon-refreshing { @@ -2193,6 +2210,12 @@ ion-infinite-scroll.active .scroll-infinite { .has-subheader { top: 88px; } +.has-tabs-top { + top: 93px; } + +.has-header.has-subheader.has-tabs-top { + top: 137px; } + .has-footer { bottom: 44px; } @@ -2466,64 +2489,64 @@ a.subdued { padding-left: 8px; height: 28px; } .bar.bar-light { - background-color: white; border-color: #ddd; + background-color: white; background-image: linear-gradient(0deg, #ddd, #ddd 50%, transparent 50%); color: #444; } .bar.bar-light .title { color: #444; } .bar.bar-stable { - background-color: #f8f8f8; border-color: #b2b2b2; + background-color: #f8f8f8; background-image: linear-gradient(0deg, #b2b2b2, #b2b2b2 50%, transparent 50%); color: #444; } .bar.bar-stable .title { color: #444; } .bar.bar-positive { - background-color: #4a87ee; border-color: #145fd7; + background-color: #4a87ee; background-image: linear-gradient(0deg, #145fd7, #145fd7 50%, transparent 50%); color: #fff; } .bar.bar-positive .title { color: #fff; } .bar.bar-calm { - background-color: #43cee6; border-color: #1aacc3; + background-color: #43cee6; background-image: linear-gradient(0deg, #1aacc3, #1aacc3 50%, transparent 50%); color: #fff; } .bar.bar-calm .title { color: #fff; } .bar.bar-assertive { - background-color: #ef4e3a; border-color: #cc2311; + background-color: #ef4e3a; background-image: linear-gradient(0deg, #cc2311, #cc2311 50%, transparent 50%); color: #fff; } .bar.bar-assertive .title { color: #fff; } .bar.bar-balanced { - background-color: #66cc33; border-color: #498f24; + background-color: #66cc33; background-image: linear-gradient(0deg, #498f24, #498f24 50%, transparent 50%); color: #fff; } .bar.bar-balanced .title { color: #fff; } .bar.bar-energized { - background-color: #f0b840; border-color: #d39211; + background-color: #f0b840; background-image: linear-gradient(0deg, #d39211, #d39211 50%, transparent 50%); color: #fff; } .bar.bar-energized .title { color: #fff; } .bar.bar-royal { - background-color: #8a6de9; border-color: #552bdf; + background-color: #8a6de9; background-image: linear-gradient(0deg, #552bdf, #552bdf 50%, transparent 50%); color: #fff; } .bar.bar-royal .title { color: #fff; } .bar.bar-dark { - background-color: #444444; border-color: #111; + background-color: #444444; background-image: linear-gradient(0deg, #111, #111 50%, transparent 50%); color: #fff; } .bar.bar-dark .title { @@ -2580,200 +2603,200 @@ a.subdued { line-height: 32px; } .bar .button-bar + .button, .bar .button + .button-bar { margin-left: 5px; } - .bar .title + .button:last-child, .bar > .button + .button:last-child, .bar > .button.pull-right, .bar .title + .buttons { + .bar .title + .button:last-child, .bar > .button + .button:last-child, .bar > .button.pull-right, .bar .buttons.pull-right, .bar .title + .buttons { position: absolute; top: 5px; right: 5px; bottom: 5px; } .bar-light .button { - color: #444; + border-color: #ddd; background-color: white; - border-color: #ddd; } + color: #444; } .bar-light .button:hover { color: #444; text-decoration: none; } .bar-light .button.active { + border-color: #ccc; background-color: #fafafa; - box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); - border-color: #ccc; } + box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); } .bar-light .button.button-clear { - color: #444; - background: none; border-color: transparent; + background: none; box-shadow: none; + color: #444; font-size: 17px; } .bar-light .button.button-icon { - background: none; - border-color: transparent; } + border-color: transparent; + background: none; } .bar-stable .button { - color: #444; + border-color: #b2b2b2; background-color: #f8f8f8; - border-color: #b2b2b2; } + color: #444; } .bar-stable .button:hover { color: #444; text-decoration: none; } .bar-stable .button.active { + border-color: #a2a2a2; background-color: #e5e5e5; - box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); - border-color: #a2a2a2; } + box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); } .bar-stable .button.button-clear { - color: #444; - background: none; border-color: transparent; + background: none; box-shadow: none; + color: #444; font-size: 17px; } .bar-stable .button.button-icon { - background: none; - border-color: transparent; } + border-color: transparent; + background: none; } .bar-positive .button { - color: #fff; + border-color: #145fd7; background-color: #4a87ee; - border-color: #145fd7; } + color: #fff; } .bar-positive .button:hover { color: #fff; text-decoration: none; } .bar-positive .button.active { + border-color: #145fd7; background-color: #145fd7; - box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); - border-color: #145fd7; } + box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); } .bar-positive .button.button-clear { - color: #fff; - background: none; border-color: transparent; + background: none; box-shadow: none; + color: #fff; font-size: 17px; } .bar-positive .button.button-icon { - background: none; - border-color: transparent; } + border-color: transparent; + background: none; } .bar-calm .button { - color: #fff; + border-color: #1aacc3; background-color: #43cee6; - border-color: #1aacc3; } + color: #fff; } .bar-calm .button:hover { color: #fff; text-decoration: none; } .bar-calm .button.active { + border-color: #1aacc3; background-color: #1aacc3; - box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); - border-color: #1aacc3; } + box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); } .bar-calm .button.button-clear { - color: #fff; - background: none; border-color: transparent; + background: none; box-shadow: none; + color: #fff; font-size: 17px; } .bar-calm .button.button-icon { - background: none; - border-color: transparent; } + border-color: transparent; + background: none; } .bar-assertive .button { - color: #fff; + border-color: #cc2311; background-color: #ef4e3a; - border-color: #cc2311; } + color: #fff; } .bar-assertive .button:hover { color: #fff; text-decoration: none; } .bar-assertive .button.active { + border-color: #cc2311; background-color: #cc2311; - box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); - border-color: #cc2311; } + box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); } .bar-assertive .button.button-clear { - color: #fff; - background: none; border-color: transparent; + background: none; box-shadow: none; + color: #fff; font-size: 17px; } .bar-assertive .button.button-icon { - background: none; - border-color: transparent; } + border-color: transparent; + background: none; } .bar-balanced .button { - color: #fff; + border-color: #498f24; background-color: #66cc33; - border-color: #498f24; } + color: #fff; } .bar-balanced .button:hover { color: #fff; text-decoration: none; } .bar-balanced .button.active { + border-color: #498f24; background-color: #498f24; - box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); - border-color: #498f24; } + box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); } .bar-balanced .button.button-clear { - color: #fff; - background: none; border-color: transparent; + background: none; box-shadow: none; + color: #fff; font-size: 17px; } .bar-balanced .button.button-icon { - background: none; - border-color: transparent; } + border-color: transparent; + background: none; } .bar-energized .button { - color: #fff; + border-color: #d39211; background-color: #f0b840; - border-color: #d39211; } + color: #fff; } .bar-energized .button:hover { color: #fff; text-decoration: none; } .bar-energized .button.active { + border-color: #d39211; background-color: #d39211; - box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); - border-color: #d39211; } + box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); } .bar-energized .button.button-clear { - color: #fff; - background: none; border-color: transparent; + background: none; box-shadow: none; + color: #fff; font-size: 17px; } .bar-energized .button.button-icon { - background: none; - border-color: transparent; } + border-color: transparent; + background: none; } .bar-royal .button { - color: #fff; + border-color: #552bdf; background-color: #8a6de9; - border-color: #552bdf; } + color: #fff; } .bar-royal .button:hover { color: #fff; text-decoration: none; } .bar-royal .button.active { + border-color: #552bdf; background-color: #552bdf; - box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); - border-color: #552bdf; } + box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); } .bar-royal .button.button-clear { - color: #fff; - background: none; border-color: transparent; + background: none; box-shadow: none; + color: #fff; font-size: 17px; } .bar-royal .button.button-icon { - background: none; - border-color: transparent; } + border-color: transparent; + background: none; } .bar-dark .button { - color: #fff; + border-color: #111; background-color: #444444; - border-color: #111; } + color: #fff; } .bar-dark .button:hover { color: #fff; text-decoration: none; } .bar-dark .button.active { + border-color: #000; background-color: #262626; - box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); - border-color: #000; } + box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15); } .bar-dark .button.button-clear { - color: #fff; - background: none; border-color: transparent; + background: none; box-shadow: none; + color: #fff; font-size: 17px; } .bar-dark .button.button-icon { - background: none; - border-color: transparent; } + border-color: transparent; + background: none; } .bar-header { top: 0; @@ -2823,9 +2846,9 @@ a.subdued { -webkit-transform: translate3d(0, 0, 0); -moz-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); + border-color: #b2b2b2; background-color: #f8f8f8; background-image: linear-gradient(0deg, #b2b2b2, #b2b2b2 50%, transparent 50%); - border-color: #b2b2b2; color: #444; position: absolute; bottom: 0; @@ -2839,78 +2862,6 @@ a.subdued { .tabs .tab-item .badge { background-color: #444; color: #f8f8f8; } - .tabs.tabs-light { - background-color: #fff; - background-image: linear-gradient(0deg, #ddd, #ddd 50%, transparent 50%); - border-color: #ddd; - color: #444; } - .tabs.tabs-light .tab-item .badge { - background-color: #444; - color: #fff; } - .tabs.tabs-stable { - background-color: #f8f8f8; - background-image: linear-gradient(0deg, #b2b2b2, #b2b2b2 50%, transparent 50%); - border-color: #b2b2b2; - color: #444; } - .tabs.tabs-stable .tab-item .badge { - background-color: #444; - color: #f8f8f8; } - .tabs.tabs-positive { - background-color: #4a87ee; - background-image: linear-gradient(0deg, #145fd7, #145fd7 50%, transparent 50%); - border-color: #145fd7; - color: #fff; } - .tabs.tabs-positive .tab-item .badge { - background-color: #fff; - color: #4a87ee; } - .tabs.tabs-calm { - background-color: #43cee6; - background-image: linear-gradient(0deg, #1aacc3, #1aacc3 50%, transparent 50%); - border-color: #1aacc3; - color: #fff; } - .tabs.tabs-calm .tab-item .badge { - background-color: #fff; - color: #43cee6; } - .tabs.tabs-assertive { - background-color: #ef4e3a; - background-image: linear-gradient(0deg, #cc2311, #cc2311 50%, transparent 50%); - border-color: #cc2311; - color: #fff; } - .tabs.tabs-assertive .tab-item .badge { - background-color: #fff; - color: #ef4e3a; } - .tabs.tabs-balanced { - background-color: #66cc33; - background-image: linear-gradient(0deg, #498f24, #498f24 50%, transparent 50%); - border-color: #498f24; - color: #fff; } - .tabs.tabs-balanced .tab-item .badge { - background-color: #fff; - color: #66cc33; } - .tabs.tabs-energized { - background-color: #f0b840; - background-image: linear-gradient(0deg, #d39211, #d39211 50%, transparent 50%); - border-color: #d39211; - color: #fff; } - .tabs.tabs-energized .tab-item .badge { - background-color: #fff; - color: #f0b840; } - .tabs.tabs-royal { - background-color: #8a6de9; - background-image: linear-gradient(0deg, #552bdf, #552bdf 50%, transparent 50%); - border-color: #552bdf; - color: #fff; } - .tabs.tabs-royal .tab-item .badge { - background-color: #fff; - color: #8a6de9; } - .tabs.tabs-dark { - background-color: #444; - background-image: linear-gradient(0deg, #111, #111 50%, transparent 50%); - border-color: #111; - color: #fff; } - .tabs.tabs-dark .tab-item .badge { - background-color: #fff; - color: #444; } @media (min--moz-device-pixel-ratio: 1.5), (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5), (min-resolution: 144dpi), (min-resolution: 1.5dppx) { .tabs { padding-top: 2px; @@ -2920,7 +2871,90 @@ a.subdued { background-size: 100% 1px; background-repeat: no-repeat; } } -.tabs-top { +/* Allow parent element of tabs to define color, or just the tab itself */ +.tabs-light > .tabs, .tabs.tabs-light { + border-color: #ddd; + background-color: #fff; + background-image: linear-gradient(0deg, #ddd, #ddd 50%, transparent 50%); + color: #444; } + .tabs-light > .tabs .tab-item .badge, .tabs.tabs-light .tab-item .badge { + background-color: #444; + color: #fff; } + +.tabs-stable > .tabs, .tabs.tabs-stable { + border-color: #b2b2b2; + background-color: #f8f8f8; + background-image: linear-gradient(0deg, #b2b2b2, #b2b2b2 50%, transparent 50%); + color: #444; } + .tabs-stable > .tabs .tab-item .badge, .tabs.tabs-stable .tab-item .badge { + background-color: #444; + color: #f8f8f8; } + +.tabs-positive > .tabs, .tabs.tabs-positive { + border-color: #145fd7; + background-color: #4a87ee; + background-image: linear-gradient(0deg, #145fd7, #145fd7 50%, transparent 50%); + color: #fff; } + .tabs-positive > .tabs .tab-item .badge, .tabs.tabs-positive .tab-item .badge { + background-color: #fff; + color: #4a87ee; } + +.tabs-calm > .tabs, .tabs.tabs-calm { + border-color: #1aacc3; + background-color: #43cee6; + background-image: linear-gradient(0deg, #1aacc3, #1aacc3 50%, transparent 50%); + color: #fff; } + .tabs-calm > .tabs .tab-item .badge, .tabs.tabs-calm .tab-item .badge { + background-color: #fff; + color: #43cee6; } + +.tabs-assertive > .tabs, .tabs.tabs-assertive { + border-color: #cc2311; + background-color: #ef4e3a; + background-image: linear-gradient(0deg, #cc2311, #cc2311 50%, transparent 50%); + color: #fff; } + .tabs-assertive > .tabs .tab-item .badge, .tabs.tabs-assertive .tab-item .badge { + background-color: #fff; + color: #ef4e3a; } + +.tabs-balanced > .tabs, .tabs.tabs-balanced { + border-color: #498f24; + background-color: #66cc33; + background-image: linear-gradient(0deg, #498f24, #498f24 50%, transparent 50%); + color: #fff; } + .tabs-balanced > .tabs .tab-item .badge, .tabs.tabs-balanced .tab-item .badge { + background-color: #fff; + color: #66cc33; } + +.tabs-energized > .tabs, .tabs.tabs-energized { + border-color: #d39211; + background-color: #f0b840; + background-image: linear-gradient(0deg, #d39211, #d39211 50%, transparent 50%); + color: #fff; } + .tabs-energized > .tabs .tab-item .badge, .tabs.tabs-energized .tab-item .badge { + background-color: #fff; + color: #f0b840; } + +.tabs-royal > .tabs, .tabs.tabs-royal { + border-color: #552bdf; + background-color: #8a6de9; + background-image: linear-gradient(0deg, #552bdf, #552bdf 50%, transparent 50%); + color: #fff; } + .tabs-royal > .tabs .tab-item .badge, .tabs.tabs-royal .tab-item .badge { + background-color: #fff; + color: #8a6de9; } + +.tabs-dark > .tabs, .tabs.tabs-dark { + border-color: #111; + background-color: #444; + background-image: linear-gradient(0deg, #111, #111 50%, transparent 50%); + color: #fff; } + .tabs-dark > .tabs .tab-item .badge, .tabs.tabs-dark .tab-item .badge { + background-color: #fff; + color: #444; } + +/* Allow parent element to have tabs-top */ +.tabs-top > .tabs, .tabs.tabs-top { top: 44px; padding-top: 0; padding-bottom: 2px; @@ -2949,6 +2983,9 @@ a.subdued { .tab-item:hover { cursor: pointer; } +.tabs-item-hide, .tabs-item-hide > .tabs { + display: none; } + .tabs-icon-top .tab-item, .tabs-icon-bottom .tab-item { font-size: 12px; line-height: 14px; } @@ -2992,25 +3029,25 @@ a.subdued { /* Navigational tab */ /* Active state for tab */ -.tab-item.active { +.tab-item.tab-item-active { opacity: 1; } - .tab-item.active.tab-item-light { + .tab-item.tab-item-active.tab-item-light { color: #fff; } - .tab-item.active.tab-item-stable { + .tab-item.tab-item-active.tab-item-stable { color: #f8f8f8; } - .tab-item.active.tab-item-positive { + .tab-item.tab-item-active.tab-item-positive { color: #4a87ee; } - .tab-item.active.tab-item-calm { + .tab-item.tab-item-active.tab-item-calm { color: #43cee6; } - .tab-item.active.tab-item-assertive { + .tab-item.tab-item-active.tab-item-assertive { color: #ef4e3a; } - .tab-item.active.tab-item-balanced { + .tab-item.tab-item-active.tab-item-balanced { color: #66cc33; } - .tab-item.active.tab-item-energized { + .tab-item.tab-item-active.tab-item-energized { color: #f0b840; } - .tab-item.active.tab-item-royal { + .tab-item.tab-item-active.tab-item-royal { color: #8a6de9; } - .tab-item.active.tab-item-dark { + .tab-item.tab-item-active.tab-item-dark { color: #444; } .item.tabs { @@ -3103,7 +3140,6 @@ a.subdued { left: 20%; overflow: visible; min-height: 240px; - max-width: 768px; width: 60%; } .modal.ng-leave-active { bottom: 0; } } @@ -3186,6 +3222,13 @@ a.subdued { .popup-buttons .button:last-child { margin-right: 0px; } +.popup-open { + pointer-events: none; } + .popup-open.modal-open .modal { + pointer-events: none; } + .popup-open .popup-backdrop, .popup-open .popup { + pointer-events: auto; } + .popup-backdrop { -webkit-animation-name: fadeIn; -moz-animation-name: fadeIn; @@ -3208,6 +3251,9 @@ a.subdued { background-color: rgba(0, 0, 0, 0.4); } .loading-backdrop { + -webkit-transition: visibility 0s linear 0.3s; + -moz-transition: visibility 0s linear 0.3s; + transition: visibility 0s linear 0.3s; position: fixed; top: 0; left: 0; @@ -3220,13 +3266,8 @@ a.subdued { -moz-transition-delay: 0s; transition-delay: 0s; visibility: visible; } - -.loading-backdrop { - -webkit-transition: visibility 0s linear 0.3s; - -moz-transition: visibility 0s linear 0.3s; - transition: visibility 0s linear 0.3s; } - .loading-backdrop.active { - background-color: rgba(0, 0, 0, 0.7); } + .loading-backdrop.active.show-backdrop { + background-color: rgba(0, 0, 0, 0.7); } .loading { position: fixed; @@ -3247,12 +3288,9 @@ a.subdued { * -------------------------------------------------- */ .item { - color: #444; - background-color: #fff; border-color: #ddd; - -webkit-transition: margin-left 0.2s ease-in-out, margin-right 0.2s ease-in-out, left 0.2s ease-in-out; - -moz-transition: margin-left 0.2s ease-in-out, margin-right 0.2s ease-in-out, left 0.2s ease-in-out; - transition: margin-left 0.2s ease-in-out, margin-right 0.2s ease-in-out, left 0.2s ease-in-out; + background-color: #fff; + color: #444; position: relative; z-index: 2; display: block; @@ -3288,77 +3326,81 @@ a.subdued { position: absolute; top: 15px; right: 35px; } + .item.item-button-right .badge { + right: 65px; } .item.item-divider .badge { top: 7.5px; } .item .badge + .badge { margin-right: 5px; } .item.item-light { - color: #444; + border-color: #ddd; background-color: #fff; - border-color: #ddd; } + color: #444; } .item.item-stable { - color: #444; + border-color: #b2b2b2; background-color: #f8f8f8; - border-color: #b2b2b2; } + color: #444; } .item.item-positive { - color: #fff; + border-color: #145fd7; background-color: #4a87ee; - border-color: #145fd7; } + color: #fff; } .item.item-calm { - color: #fff; + border-color: #1aacc3; background-color: #43cee6; - border-color: #1aacc3; } + color: #fff; } .item.item-assertive { - color: #fff; + border-color: #cc2311; background-color: #ef4e3a; - border-color: #cc2311; } + color: #fff; } .item.item-balanced { - color: #fff; + border-color: #498f24; background-color: #66cc33; - border-color: #498f24; } + color: #fff; } .item.item-energized { - color: #fff; + border-color: #d39211; background-color: #f0b840; - border-color: #d39211; } + color: #fff; } .item.item-royal { - color: #fff; + border-color: #552bdf; background-color: #8a6de9; - border-color: #552bdf; } + color: #fff; } .item.item-dark { - color: #fff; + border-color: #111; background-color: #444; - border-color: #111; } + color: #fff; } + .item[ng-click]:hover { + cursor: pointer; } .item.active:not(.item-divider):not(.item-input):not(.item-input-inset), .item-complex.active .item-content { - background-color: #D9D9D9; - border-color: #ccc; } + border-color: #ccc; + background-color: #D9D9D9; } .item.active:not(.item-divider):not(.item-input):not(.item-input-inset).item-light, .item-complex.active .item-content.item-light { - background-color: #fafafa; - border-color: #ccc; } + border-color: #ccc; + background-color: #fafafa; } .item.active:not(.item-divider):not(.item-input):not(.item-input-inset).item-stable, .item-complex.active .item-content.item-stable { - background-color: #e5e5e5; - border-color: #a2a2a2; } + border-color: #a2a2a2; + background-color: #e5e5e5; } .item.active:not(.item-divider):not(.item-input):not(.item-input-inset).item-positive, .item-complex.active .item-content.item-positive { - background-color: #145fd7; - border-color: #145fd7; } + border-color: #145fd7; + background-color: #145fd7; } .item.active:not(.item-divider):not(.item-input):not(.item-input-inset).item-calm, .item-complex.active .item-content.item-calm { - background-color: #1aacc3; - border-color: #1aacc3; } + border-color: #1aacc3; + background-color: #1aacc3; } .item.active:not(.item-divider):not(.item-input):not(.item-input-inset).item-assertive, .item-complex.active .item-content.item-assertive { - background-color: #cc2311; - border-color: #cc2311; } + border-color: #cc2311; + background-color: #cc2311; } .item.active:not(.item-divider):not(.item-input):not(.item-input-inset).item-balanced, .item-complex.active .item-content.item-balanced { - background-color: #498f24; - border-color: #498f24; } + border-color: #498f24; + background-color: #498f24; } .item.active:not(.item-divider):not(.item-input):not(.item-input-inset).item-energized, .item-complex.active .item-content.item-energized { - background-color: #d39211; - border-color: #d39211; } + border-color: #d39211; + background-color: #d39211; } .item.active:not(.item-divider):not(.item-input):not(.item-input-inset).item-royal, .item-complex.active .item-content.item-royal { - background-color: #552bdf; - border-color: #552bdf; } + border-color: #552bdf; + background-color: #552bdf; } .item.active:not(.item-divider):not(.item-input):not(.item-input-inset).item-dark, .item-complex.active .item-content.item-dark { - background-color: #262626; - border-color: #000; } + border-color: #000; + background-color: #262626; } .item, .item h1, .item h2, .item h3, .item h4, .item h5, .item h6, .item p, .item-content, .item-content h1, .item-content h2, .item-content h3, .item-content h4, .item-content h5, .item-content h6, .item-content p { overflow: hidden; @@ -3384,14 +3426,6 @@ a.item { padding: 0; } .item-complex .item-content, .item-radio .item-content { - /** - * The content area of a complex list item. This area can - * Slide left and right and be dragged to support different - * UI interactions. - */ - -webkit-transition: all 0.1s ease-in-out; - -moz-transition: all 0.1s ease-in-out; - transition: all 0.1s ease-in-out; position: relative; z-index: 2; padding: 15px 40px 15px 15px; @@ -3545,40 +3579,38 @@ a.item-content { * By default, if an .item is created out of an or - * - * ``` - * ```js - * function MyController($scope, $ionicScrollDelegate) { - * $scope.scrollToTop = function() { - * $ionicScrollDelegate.scrollTop(); - * }; - * } - * ``` - */ -.factory('$ionicScrollDelegate', ['$rootScope', '$timeout', '$q', '$anchorScroll', '$location', '$document', function($rootScope, $timeout, $q, $anchorScroll, $location, $document) { - return { - /** - * @ngdoc method - * @name $ionicScrollDelegate#scrollTop - * @param {boolean=} shouldAnimate Whether the scroll should animate. - */ - scrollTop: function(animate) { - $rootScope.$broadcast('scroll.scrollTop', animate); - }, - /** - * @ngdoc method - * @name $ionicScrollDelegate#scrollBottom - * @param {boolean=} shouldAnimate Whether the scroll should animate. - */ - scrollBottom: function(animate) { - $rootScope.$broadcast('scroll.scrollBottom', animate); - }, - /** - * @ngdoc method - * @name $ionicScrollDelegate#scroll - * @param {number} left The x-value to scroll to. - * @param {number} top The y-value to scroll to. - * @param {boolean=} shouldAnimate Whether the scroll should animate. - */ - scrollTo: function(left, top, animate) { - $rootScope.$broadcast('scroll.scrollTo', left, top, animate); - }, - /** - * @ngdoc method - * @name $ionicScrollDelegate#anchorScroll - * @description Tell the scrollView to scroll to the element with an id - * matching window.location.hash. - * - * If no matching element is found, it will scroll to top. - * - * @param {boolean=} shouldAnimate Whether the scroll should animate. - */ - anchorScroll: function(animate) { - $rootScope.$broadcast('scroll.anchorScroll', animate); - }, - /** - * @ngdoc method - * @name $ionicScrollDelegate#resize - * @description Tell the scrollView to recalculate the size of its container. - */ - resize: function() { - $rootScope.$broadcast('scroll.resize'); - }, - /** - * @private - */ - tapScrollToTop: function(element, animate) { - var _this = this; - if (!angular.isDefined(animate)) { - animate = true; - } - - ionic.on('tap', function(e) { - var target = e.target; - //Don't scroll to top for a button click - if (ionic.DomUtil.getParentOrSelfWithClass(target, 'button')) { - return; - } - - var el = element[0]; - var bounds = el.getBoundingClientRect(); - - if(ionic.DomUtil.rectContains(e.gesture.touches[0].pageX, e.gesture.touches[0].pageY, bounds.left, bounds.top, bounds.left + bounds.width, bounds.top + 20)) { - _this.scrollTop(animate); - } - }, element[0]); - }, - - finishRefreshing: function($scope) { - $scope.$broadcast('scroll.refreshComplete'); - }, - - /** - * @private - * Attempt to get the current scroll view in scope (if any) - * - * Note: will not work in an isolated scope context. - */ - getScrollView: function($scope) { - return $scope.scrollView; - }, - - /** - * @private - * Register a scope and scroll view for scroll event handling. - * $scope {Scope} the scope to register and listen for events - */ - register: function($scope, $element, scrollView) { - - var scrollEl = $element[0]; - - function scrollViewResize() { - // Run the resize after this digest - return $timeout(function() { - scrollView.resize(); - }); - } - - $element.on('scroll', function(e) { - var detail = (e.originalEvent || e).detail || {}; - - $scope.$onScroll && $scope.$onScroll({ - event: e, - scrollTop: detail.scrollTop || 0, - scrollLeft: detail.scrollLeft || 0 - }); - - }); - - $scope.$parent.$on('scroll.resize', scrollViewResize); - - // Called to stop refreshing on the scroll view - $scope.$parent.$on('scroll.refreshComplete', function(e) { - scrollView.finishPullToRefresh(); - }); - - $scope.$parent.$on('scroll.anchorScroll', function(e, animate) { - scrollViewResize().then(function() { - var hash = $location.hash(); - var elm; - if (hash && (elm = document.getElementById(hash)) ) { - var scroll = ionic.DomUtil.getPositionInParent(elm, scrollEl); - scrollView.scrollTo(scroll.left, scroll.top, !!animate); - } else { - scrollView.scrollTo(0,0, !!animate); - } - }); - }); - - $scope.$parent.$on('scroll.scrollTo', function(e, left, top, animate) { - scrollViewResize().then(function() { - scrollView.scrollTo(left, top, !!animate); - }); - }); - $scope.$parent.$on('scroll.scrollTop', function(e, animate) { - scrollViewResize().then(function() { - scrollView.scrollTo(0, 0, !!animate); - }); - }); - $scope.$parent.$on('scroll.scrollBottom', function(e, animate) { - scrollViewResize().then(function() { - var sv = scrollView; - if (sv) { - var max = sv.getScrollMax(); - sv.scrollTo(max.left, max.top, !!animate); - } - }); - }); - } - }; -}]); - -})(ionic); - - -(function() { -'use strict'; - -angular.module('ionic.ui.service.sideMenuDelegate', []) - -.factory('$ionicSideMenuDelegate', ['$rootScope', '$timeout', '$q', function($rootScope, $timeout, $q) { - return { - getSideMenuController: function($scope) { - return $scope.sideMenuController; - }, - close: function($scope) { - if($scope.sideMenuController) { - $scope.sideMenuController.close(); - } - }, - toggleLeft: function($scope) { - if($scope.sideMenuController) { - $scope.sideMenuController.toggleLeft(); - } - }, - toggleRight: function($scope) { - if($scope.sideMenuController) { - $scope.sideMenuController.toggleRight(); - } - }, - openLeft: function($scope) { - if($scope.sideMenuController) { - $scope.sideMenuController.openPercentage(100); - } - }, - openRight: function($scope) { - if($scope.sideMenuController) { - $scope.sideMenuController.openPercentage(-100); - } - } - }; -}]); - -})(); - -(function() { -'use strict'; - -angular.module('ionic.ui.service.slideBoxDelegate', []) - -.factory('$ionicSlideBoxDelegate', ['$rootScope', '$timeout', function($rootScope, $timeout) { - return { - /** - * Trigger a slidebox to update and resize itself - */ - update: function(animate) { - $rootScope.$broadcast('slideBox.update'); - }, - - register: function($scope, $element) { - $scope.$parent.$on('slideBox.update', function(e) { - if(e.defaultPrevented) { - return; - } - $timeout(function() { - $scope.$parent.slideBoxController.setup(); - }); - e.preventDefault(); - }); - } - }; -}]); - -})(ionic); - (function() { 'use strict'; @@ -2251,124 +2107,144 @@ angular.module('ionic.ui.actionSheet', []) angular.module('ionic.ui.header', ['ngAnimate', 'ngSanitize']) -.directive('barHeader', ['$ionicScrollDelegate', function($ionicScrollDelegate) { - return { - restrict: 'C', - link: function($scope, $element, $attr) { - // We want to scroll to top when the top of this element is clicked - $ionicScrollDelegate.tapScrollToTop($element); - } - }; -}]) +.directive('ionNavBar', tapScrollToTopDirective()) +.directive('ionHeaderBar', tapScrollToTopDirective()) /** * @ngdoc directive * @name ionHeaderBar * @module ionic * @restrict E + * * @description - * While Ionic provides simple Header and Footer bars that can be created through - * HTML and CSS alone, Header bars specifically can be extended in order to - * provide dynamic layout features such as auto-title centering and animation. - * They are also used by the Views and Navigation Controller to animate a title - * on navigation and toggle a back button. + * Adds a fixed header bar above some content. * - * The main header bar feature provided is auto title centering. - * In this situation, the title text will center itself until either the - * left or right button content is too wide for the label to center. - * In that case, it will slide left or right until it can fit. - * You can also align the title left for a more Android-friendly header. - * - * Using two-way data binding, the header bar will automatically - * readjust the heading title alignment when the title or buttons change. - * - * @param {string} title The title use on the headerBar. - * @param {expression=} leftButtons Point to an array of buttons to put on the left of the bar. - * @param {expression=} rightButtons Point to an array of buttons to put on the right of the bar. - * @param {string=} type The type of the bar, for example 'bar-positive'. - * @param {string=} align Where to align the title. 'left', 'right', or 'center'. Defaults to 'center'. + * @param {string=} align-title Where to align the title. + * Avaialble: 'left', 'right', or 'center'. Defaults to 'center'. * * @usage * ```html - * + * + *
+ * + *
+ *

Title!

+ *
+ * + *
*
+ * + * Some content! + * * ``` - * */ -.directive('ionHeaderBar', ['$ionicScrollDelegate', function($ionicScrollDelegate) { - return { - restrict: 'E', - replace: true, - transclude: true, - template: '
\ -
\ - \ -
\ -

\ -
\ - \ -
\ -
', +.directive('ionHeaderBar', barDirective(true)) - scope: { - leftButtons: '=', - rightButtons: '=', - title: '@', - type: '@', - alignTitle: '@' - }, - link: function($scope, $element, $attr) { - var hb = new ionic.views.HeaderBar({ - el: $element[0], - alignTitle: $scope.alignTitle || 'center' - }); +/** + * @ngdoc directive + * @name ionFooterBar + * @module ionic + * @restrict E + * + * @description + * Adds a fixed footer bar below some content. + * + * @param {string=} align-title Where to align the title. + * Avaialble: 'left', 'right', or 'center'. Defaults to 'center'. + * + * @usage + * ```html + * + * Some content! + * + * + *
+ * + *
+ *

Title!

+ *
+ * + *
+ *
+ * ``` + */ +.directive('ionFooterBar', barDirective(false)); - $element.addClass($scope.type); +function tapScrollToTopDirective() { + return ['$ionicScrollDelegate', function($ionicScrollDelegate) { + return { + restrict: 'E', + link: function($scope, $element, $attr) { + ionic.on('tap', onTap, $element[0]); + $scope.$on('$destroy', function() { + ionic.off('tap', onTap, $element[0]); + }); - $scope.headerBarView = hb; + function onTap(e) { + if (ionic.DomUtil.getParentOrSelfWithClass(e.target, 'button', 4)) { + return; + } + var touch = e.gesture && e.gesture.touches[0] || e.detail.touches[0]; + var bounds = $element[0].getBoundingClientRect(); + if (ionic.DomUtil.rectContains( + touch.pageX, touch.pageY, + bounds.left, bounds.top - 20, + bounds.left + bounds.width, bounds.top + bounds.height + )) { + $ionicScrollDelegate.scrollTop(true); + } + } + } + }; + }]; +} - $scope.$watchCollection('leftButtons', function(val) { - // Resize the title since the buttons have changed - hb.align(); - }); - $scope.$watchCollection('rightButtons', function(val) { - // Resize the title since the buttons have changed - hb.align(); - }); +function barDirective(isHeader) { + return [function() { + return { + restrict: 'E', + compile: function($element, $attr) { + $element.addClass(isHeader ? 'bar bar-header' : 'bar bar-footer'); - $scope.$watch('title', function(val) { - // Resize the title since the title has changed - hb.align(); - }); - } - }; -}]) + return { pre: prelink }; + function prelink($scope, $element, $attr) { + var hb = new ionic.views.HeaderBar({ + el: $element[0], + alignTitle: $attr.alignTitle || 'center' + }); -.directive('ionFooterBar', function() { - return { - restrict: 'E', - replace: true, - transclude: true, - template: '
\ -
', + var el = $element[0]; + //just incase header is on rootscope + var parentScope = $scope.$parent || $scope; - scope: { - type: '@', - }, - - link: function($scope, $element, $attr) { - $element.addClass($scope.type); - } - }; -}); + if (isHeader) { + $scope.$watch(function() { return el.className; }, function(value) { + var isSubheader = value.indexOf('bar-subheader') !== -1; + parentScope.$hasHeader = !isSubheader; + parentScope.$hasSubheader = isSubheader; + }); + $scope.$on('$destroy', function() { + parentScope.$hasHeader = parentScope.$hasSubheader = null; + }); + } else { + $scope.$watch(function() { return el.className; }, function(value) { + var isSubfooter = value.indexOf('bar-subfooter') !== -1; + parentScope.$hasFooter = !isSubfooter; + parentScope.$hasSubfooter = isSubfooter; + }); + $scope.$on('$destroy', function() { + parentScope.$hasFooter = parentScope.$hasSubfooter = null; + }); + $scope.$watch('$hasTabs', function(val) { + $element.toggleClass('has-tabs', !!val); + }); + } + } + } + }; + }]; +} })(ionic); @@ -2428,7 +2304,7 @@ angular.module('ionic.ui.checkbox', []) (function() { 'use strict'; -angular.module('ionic.ui.content', ['ionic.ui.service', 'ionic.ui.scroll']) +angular.module('ionic.ui.content', ['ionic.ui.scroll']) /** * Panel is a simple 100% width and height, fixed panel. It's meant for content to be @@ -2438,7 +2314,6 @@ angular.module('ionic.ui.content', ['ionic.ui.service', 'ionic.ui.scroll']) * @ngdoc directive * @name ionPane * @module ionic - * @group page layout * @restrict E * * @description A simple container that fits content, with no side effects. Adds the 'pane' class to the element. @@ -2456,12 +2331,12 @@ angular.module('ionic.ui.content', ['ionic.ui.service', 'ionic.ui.scroll']) * @ngdoc directive * @name ionContent * @module ionic - * @group page layout - * @groupMainItem + * @delegate ionic.service:$ionicScrollDelegate + * @restrict E * * @description * The ionContent directive provides an easy to use content area that can be configured - * to use Ionic's custom Scroll View, or the built in overflow scorlling of the browser. + * to use Ionic's custom Scroll View, or the built in overflow scrolling of the browser. * * While we recommend using the custom Scroll features in Ionic in most cases, sometimes * (for performance reasons) only the browser's native overflow scrolling will suffice, @@ -2472,52 +2347,48 @@ angular.module('ionic.ui.content', ['ionic.ui.service', 'ionic.ui.scroll']) * directive, and infinite scrolling with the {@link ionic.directive:ionInfiniteScroll} * directive. * - * @restrict E + * @param {string=} delegate-handle The handle used to identify this scrollView + * with {@link ionic.service:$ionicScrollDelegate}. + * @param {boolean=} padding Whether to add padding to the content. + * of the content. Defaults to true on iOS, false on Android. * @param {boolean=} scroll Whether to allow scrolling of content. Defaults to true. * @param {boolean=} overflow-scroll Whether to use overflow-scrolling instead of * Ionic scroll. - * @param {boolean=} padding Whether to add padding to the content. - * @param {boolean=} has-header Whether to offset the content for a header bar. - * @param {boolean=} has-subheader Whether to offset the content for a subheader bar. - * @param {boolean=} has-footer Whether to offset the content for a footer bar. * @param {boolean=} has-bouncing Whether to allow scrolling to bounce past the edges * of the content. Defaults to true on iOS, false on Android. * @param {expression=} on-scroll Expression to evaluate when the content is scrolled. * @param {expression=} on-scroll-complete Expression to evaluate when a scroll action completes. */ .directive('ionContent', [ - '$parse', '$timeout', - '$ionicScrollDelegate', '$controller', '$ionicBind', -function($parse, $timeout, $ionicScrollDelegate, $controller, $ionicBind) { +function($timeout, $controller, $ionicBind) { return { restrict: 'E', - replace: true, - transclude: true, require: '^?ionNavView', scope: true, - template: - '
' + - '
' + - '
', - compile: function(element, attr, transclude) { - if(attr.hasHeader == "true") { element.addClass('has-header'); } - if(attr.hasSubheader == "true") { element.addClass('has-subheader'); } - if(attr.hasFooter == "true") { element.addClass('has-footer'); } - if(attr.hasTabs == "true") { element.addClass('has-tabs'); } - if(attr.padding == "true") { element.find('div').addClass('padding'); } + compile: function(element, attr) { + element.addClass('scroll-content'); - return { - //Prelink so it can compile before other directives compile. - //Then other directives can require ionicScrollCtrl - pre: prelink - }; + //We cannot transclude here because it breaks element.data() inheritance on compile + var innerElement = angular.element('
'); + innerElement.append(element.contents()); + element.append(innerElement); + return { pre: prelink }; function prelink($scope, $element, $attr, navViewCtrl) { - var clone, sc, scrollView, scrollCtrl, - scrollContent = angular.element($element[0].querySelector('.scroll')); + $scope.$watch(function() { + return ($scope.$hasHeader ? ' has-header' : '') + + ($scope.$hasSubheader ? ' has-subheader' : '') + + ($scope.$hasFooter ? ' has-footer' : '') + + ($scope.$hasSubfooter ? ' has-subfooter' : '') + + ($scope.$hasTabs ? ' has-tabs' : '') + + ($scope.$hasTabsTop ? ' has-tabs-top' : ''); + }, function(className, oldClassName) { + $element.removeClass(oldClassName); + $element.addClass(className); + }); $ionicBind($scope, $attr, { $onScroll: '&onScroll', @@ -2534,16 +2405,22 @@ function($parse, $timeout, $ionicScrollDelegate, $controller, $ionicBind) { scrollEventInterval: '@' }); + if (angular.isDefined($attr.padding)) { + $scope.$watch($attr.padding, function(newVal) { + innerElement.toggleClass('padding', !!newVal); + }); + } + if ($scope.scroll === "false") { //do nothing } else if(attr.overflowScroll === "true") { $element.addClass('overflow-scroll'); } else { - - scrollCtrl = $controller('$ionicScroll', { + $controller('$ionicScroll', { $scope: $scope, scrollViewOptions: { el: $element[0], + delegateHandle: attr.delegateHandle, bouncing: $scope.$eval($scope.hasBouncing), startX: $scope.$eval($scope.startX) || 0, startY: $scope.$eval($scope.startY) || 0, @@ -2560,33 +2437,8 @@ function($parse, $timeout, $ionicScrollDelegate, $controller, $ionicBind) { } } }); - //Publish scrollView to parent so children can access it - scrollView = $scope.$parent.scrollView = scrollCtrl.scrollView; - - $scope.$on('$viewContentLoaded', function(e, viewHistoryData) { - viewHistoryData || (viewHistoryData = {}); - var scroll = viewHistoryData.scrollValues; - if (scroll) { - $timeout(function() { - scrollView.scrollTo(+scroll.left || null, +scroll.top || null); - }, 0); - } - - //Save scroll onto viewHistoryData when scope is destroyed - $scope.$on('$destroy', function() { - viewHistoryData.scrollValues = scrollView.getValues(); - }); - }); - } - transclude($scope, function(clone) { - if (scrollCtrl) { - clone.data('$$ionicScrollController', scrollCtrl); - } - scrollContent.append(clone); - }); - } } }; @@ -2597,7 +2449,6 @@ function($parse, $timeout, $ionicScrollDelegate, $controller, $ionicBind) { * @name ionRefresher * @module ionic * @restrict E - * @group page layout * @parent ionic.directive:ionContent, ionic.directive:ionScroll * @description * Allows you to add pull-to-refresh to a scrollView. @@ -2608,19 +2459,8 @@ function($parse, $timeout, $ionicScrollDelegate, $controller, $ionicBind) { * When refreshing is complete, $broadcast the 'scroll.refreshComplete' event * from your controller. * - * @param {expression=} on-refresh Called when the user pulls down enough and lets go - * of the refresher. - * @param {expression=} on-pulling Called when the user starts to pull down - * on the refresher. - * @param {string=} pulling-icon The icon to display while the user is pulling down. - * Default: 'ion-arrow-down-c'. - * @param {string=} pulling-text The text to display while the user is pulling down. - * @param {string=} refreshing-icon The icon to display after user lets go of the - * refresher. - * @param {string=} refreshing-text The text to display after the user lets go of - * the refresher. - * * @usage + * * ```html * * \ -
\ +
\ \
\
\ -
\ - \ +
\ + \
\
\ \ @@ -2898,22 +2750,24 @@ angular.module('ionic.ui.list', ['ngAnimate']) $scope.deleteClick = function() { if($attr.onDelete) { // this item has an on-delete attribute - $scope.onDelete({ item: $scope.item }); + $scope.onDelete({ item: $scope.item, index: $scope.$parent.$index }); } else if($parentAttrs.onDelete) { // run the parent list's onDelete method // if it doesn't exist nothing will happen - $parentScope.onDelete({ item: $scope.item }); + $parentScope.onDelete({ item: $scope.item, index: $scope.$parent.$index }); } }; // Set which icons to use for deleting $scope.deleteIconClass = $scope.deleteIcon || $parentScope.deleteIcon || 'ion-minus-circled'; + $element.addClass('item-left-editable'); } } // set the reorder Icon Class only if the item or list set can-reorder="true" if(($attr.canReorder ? $scope.canReorder : $parentScope.canReorder) === "true") { $scope.reorderIconClass = $scope.reorderIcon || $parentScope.reorderIcon || 'ion-navicon'; + $element.addClass('item-right-editable'); } // Set the option buttons which can be revealed by swiping to the left @@ -2923,6 +2777,7 @@ angular.module('ionic.ui.list', ['ngAnimate']) if(typeof $scope.itemOptionButtons === "undefined") { $scope.itemOptionButtons = $parentScope.optionButtons(); } + $element.addClass('item-swipeable'); } } @@ -2996,7 +2851,7 @@ angular.module('ionic.ui.list', ['ngAnimate']) reorderIcon: '@' }, - template: '
', + template: '
', controller: ['$scope', '$attrs', function($scope, $attrs) { this.scope = $scope; @@ -3005,6 +2860,7 @@ angular.module('ionic.ui.list', ['ngAnimate']) link: function($scope, $element, $attr, ionicScrollCtrl) { $scope.listView = new ionic.views.ListView({ + canSwipe: $scope.canSwipe !== "false" && !!$scope.optionButtons(), el: $element[0], listEl: $element[0].children[0], scrollEl: ionicScrollCtrl && ionicScrollCtrl.element, @@ -3023,6 +2879,7 @@ angular.module('ionic.ui.list', ['ngAnimate']) var destroyShowReorderWatch = $scope.$watch('showReorder', function(val) { if(val) { $element[0].classList.add('item-options-hide'); + $scope.listView && $scope.listView.clearDragEffects(); } else if(val === false) { // false checking is because it could be undefined // if its undefined then we don't care to do anything @@ -3059,7 +2916,7 @@ angular.module('ionic.ui.loading', []) link: function($scope, $element){ $element.addClass($scope.animation || ''); }, - template: '
' + + template: '
' + '
' + '
' + '
' @@ -3090,50 +2947,485 @@ angular.module('ionic.ui.modal', []) })(); -(function() { -angular.module('ionic.ui.navAnimation', []) + +angular.module('ionic.ui.navBar', ['ionic.service.view', 'ngSanitize']) + +/** + * @ngdoc service + * @name $ionicNavBarDelegate + * @module ionic + * @description + * Delegate for controlling the {@link ionic.directive:ionNavBar} directive. + * + * @usage + * + * ```html + * + * + * + * + * + * ``` + * ```js + * function MyCtrl($scope, $ionicNavBarDelegate) { + * $scope.setNavTitle = function(title) { + * $ionicNavBarDelegate.setTitle(title); + * } + * } + * ``` + */ +.service('$ionicNavBarDelegate', delegateService([ + /** + * @ngdoc method + * @name $ionicNavBarDelegate#back + * @description Goes back in the view history. + * @param {DOMEvent=} event The event object (eg from a tap event) + */ + 'back', + /** + * @ngdoc method + * @name $ionicNavBarDelegate#align + * @description Aligns the title with the buttons in a given direction. + * @param {string=} direction The direction to the align the title text towards. + * Available: 'left', 'right', 'center'. Default: 'center'. + */ + 'align', + /** + * @ngdoc method + * @name $ionicNavBarDelegate#showBackButton + * @description + * Set whether the {@link ionic.directive:ionNavBackButton} should be shown + * (if it exists). + * @param {boolean} show Whether to show the back button. + */ + 'showBackButton', + /** + * @ngdoc method + * @name $ionicNavBarDelegate#showBar + * @description + * Set whether the {@link ionic.directive:ionNavBar} should be shown. + * @param {boolean} show Whether to show the bar. + */ + 'showBar', + /** + * @ngdoc method + * @name $ionicNavBarDelegate#setTitle + * @description + * Set the title for the {@link ionic.directive:ionNavBar}. + * @param {string} title The new title to show. + */ + 'setTitle', + /** + * @ngdoc method + * @name $ionicNavBarDelegate#changeTitle + * @description + * Change the title, transitioning the new title in and the old one out in a given direction. + * @param {string} title The new title to show. + * @param {string} direction The direction to transition the new title in. + * Available: 'forward', 'back'. + */ + 'changeTitle', + /** + * @ngdoc method + * @name $ionicNavBarDelegate#getTitle + * @returns {string} The current title of the navbar. + */ + 'getTitle', + /** + * @ngdoc method + * @name $ionicNavBarDelegate#getPreviousTitle + * @returns {string} The previous title of the navbar. + */ + 'getPreviousTitle' + /** + * @ngdoc method + * @name $ionicNavBarDelegate#$getByHandle + * @param {string} handle + * @returns `delegateInstance` A delegate instance that controls only the + * navBars with delegate-handle matching the given handle. + * + * Example: `$ionicNavBarDelegate.$getByHandle('myHandle').setTitle('newTitle')` + */ +])) + +.controller('$ionicNavBar', [ + '$scope', + '$element', + '$attrs', + '$ionicViewService', + '$animate', + '$compile', + '$ionicNavBarDelegate', +function($scope, $element, $attrs, $ionicViewService, $animate, $compile, $ionicNavBarDelegate) { + //Let the parent know about our controller too so that children of + //sibling content elements can know about us + $element.parent().data('$ionNavBarController', this); + + var deregisterInstance = $ionicNavBarDelegate._registerInstance(this, $attrs.delegateHandle); + + $scope.$on('$destroy', deregisterInstance); + + var self = this; + + this.leftButtonsElement = angular.element( + $element[0].querySelector('.buttons.left-buttons') + ); + this.rightButtonsElement = angular.element( + $element[0].querySelector('.buttons.right-buttons') + ); + + this.back = function(e) { + var backView = $ionicViewService.getBackView(); + backView && backView.go(); + e && (e.alreadyHandled = true); + return false; + }; + + this.align = function(direction) { + this._headerBarView.align(direction); + }; + + this.showBackButton = function(show) { + $scope.backButtonShown = !!show; + }; + + this.showBar = function(show) { + $scope.isInvisible = !show; + }; + + this.setTitle = function(title) { + $scope.oldTitle = $scope.title; + $scope.title = title || ''; + }; + + this.changeTitle = function(title, direction) { + if ($scope.title === title) { + return false; + } + this.setTitle(title); + $scope.isReverse = direction == 'back'; + $scope.shouldAnimate = !!direction; + + if (!$scope.shouldAnimate) { + //We're done! + this._headerBarView.align(); + } else { + this._animateTitles(); + } + return true; + }; + + this.getTitle = function() { + return $scope.title || ''; + }; + + this.getPreviousTitle = function() { + return $scope.oldTitle || ''; + }; + + /** + * Exposed for testing + */ + this._animateTitles = function() { + var oldTitleEl, newTitleEl, currentTitles; + + //If we have any title right now + //(or more than one, they could be transitioning on switch), + //replace the first one with an oldTitle element + currentTitles = $element[0].querySelectorAll('.title'); + if (currentTitles.length) { + oldTitleEl = $compile('

')($scope); + angular.element(currentTitles[0]).replaceWith(oldTitleEl); + } + //Compile new title + newTitleEl = $compile('

')($scope); + + //Animate in on next frame + ionic.requestAnimationFrame(function() { + + oldTitleEl && $animate.leave(angular.element(oldTitleEl)); + + var insert = oldTitleEl && angular.element(oldTitleEl) || null; + $animate.enter(newTitleEl, $element, insert, function() { + self._headerBarView.align(); + }); + + //Cleanup any old titles leftover (besides the one we already did replaceWith on) + angular.forEach(currentTitles, function(el) { + if (el && el.parentNode) { + //Use .remove() to cleanup things like .data() + angular.element(el).remove(); + } + }); + + //$apply so bindings fire + $scope.$digest(); + + //Stop flicker of new title on ios7 + ionic.requestAnimationFrame(function() { + newTitleEl[0].classList.remove('invisible'); + }); + }); + }; +}]) + /** * @ngdoc directive - * @name ionNavAnimation + * @name ionNavBar * @module ionic - * @restrict A - * @parent ionic.directive:ionNavView + * @delegate ionic.service:$ionicNavBarDelegate + * @restrict E * * @description - * When used under an {@link ionic.directive:ionNavView} and on an `` element, - * allows you to set the animation all clicks on that link within the navView use. + * If we have an {@link ionic.directive:ionNavView} directive, we can also create an + * ``, which will create a topbar that updates as the application state changes. + * + * We can add a back button by putting an {@link ionic.directive:ionNavBackButton} inside. + * + * We can add buttons depending on the currently visible view using + * {@link ionic.directive:ionNavButtons}. + * + * Assign an [animation class](/docs/components#animations) to the element to + * enable animated changing of titles (recommended: 'slide-left-right' or 'nav-title-slide-ios7') + * + * @usage + * + * ```html + * + * + * + * + * + * + * + * + * ``` + * + * @param {string=} delegate-handle The handle used to identify this navBar + * with {@link ionic.service:$ionicNavBarDelegate}. + * @param align-title {string=} Where to align the title of the navbar. + * Available: 'left', 'right', 'center'. Defaults to 'center'. + */ +.directive('ionNavBar', ['$ionicViewService', '$rootScope', '$animate', '$compile', +function($ionicViewService, $rootScope, $animate, $compile) { + + return { + restrict: 'E', + controller: '$ionicNavBar', + scope: true, + compile: function(tElement, tAttrs) { + //We cannot transclude here because it breaks element.data() inheritance on compile + tElement + .addClass('bar bar-header nav-bar') + .append( + '
' + + '
' + + '

' + + '
' + + '
' + ); + + return { pre: prelink }; + function prelink($scope, $element, $attr, navBarCtrl) { + navBarCtrl._headerBarView = new ionic.views.HeaderBar({ + el: $element[0], + alignTitle: $attr.alignTitle || 'center' + }); + + //defaults + $scope.backButtonShown = false; + $scope.shouldAnimate = true; + $scope.isReverse = false; + $scope.isInvisible = true; + $scope.$parent.$hasHeader = true; + + $scope.$on('$destroy', function() { + $scope.$parent.$hasHeader = false; + }); + + $scope.$watch(function() { + return ($scope.isReverse ? ' reverse' : '') + + ($scope.isInvisible ? ' invisible' : '') + + (!$scope.shouldAnimate ? ' no-animation' : ''); + }, function(className, oldClassName) { + $element.removeClass(oldClassName); + $element.addClass(className); + }); + + } + } + }; +}]) + +/** + * @ngdoc directive + * @name ionNavBackButton + * @module ionic + * @restrict E + * @parent ionNavBar + * @description + * Creates a back button inside an {@link ionic.directive:ionNavBar}. + * + * Will show up when the user is able to go back in the current navigation stack. + * + * By default, will go back when clicked. If you wish for more advanced behavior, see the + * examples below. + * + * @usage + * + * With default click action: + * + * ```html + * + * + * Back! + * + * + * ``` + * + * With custom click action, using {@link ionic.service:$ionicNavBarDelegate}: + * + * ```html + * + * + * Back + * + * + * ``` + * ```js + * function MyCtrl($scope, $ionicNavBarDelegate) { + * $scope.goBack = function() { + * $ionicNavBarDelegate.back(); + * }; + * } + * ``` + * + * Displaying the previous title on the back button, again using + * {@link ionic.service:$ionicNavBarDelegate}. + * + * ```html + * + * + * {% raw %}{{getPreviousTitle() || 'Back'}}{% endraw %} + * + * + * ``` + * ```js + * function MyCtrl($scope, $ionicNavBarDelegate) { + * $scope.getPreviousTitle = function() { + * return $ionicNavBarDelegate.getPreviousTitle(); + * }; + * } + * ``` + */ +.directive('ionNavBackButton', ['$ionicNgClick', function($ionicNgClick) { + return { + restrict: 'E', + require: '^ionNavBar', + compile: function(tElement, tAttrs) { + tElement.addClass('button back-button'); + return function($scope, $element, $attr, navBarCtrl) { + if (!$attr.ngClick) { + $scope.$navBack = navBarCtrl.back; + $ionicNgClick($scope, $element, '$navBack($event)'); + } + + //If the current viewstate does not allow a back button, + //always hide it. + var deregisterListener = $scope.$parent.$on( + '$viewHistory.historyChange', + function(e, data) { + $scope.hasBackButton = !!data.showBack; + } + ); + $scope.$on('$destroy', deregisterListener); + + //Make sure both that a backButton is allowed in the first place, + //and that it is shown by the current view. + $scope.$watch('!!(backButtonShown && hasBackButton)', function(show) { + $element.toggleClass('hide', !show); + }); + }; + } + }; +}]) + +/** + * @ngdoc directive + * @name ionNavButtons + * @module ionic + * @restrict E + * @parent ionNavView + * + * @description + * Use ionNavButtons to set the buttons on your {@link ionic.directive:ionNavBar} + * from within an {@link ionic.directive:ionView}. + * + * Any buttons you declare will be placed onto the navbar's corresponding side, + * and then destroyed when the user leaves their parent view. * * @usage * ```html + * + * * * + * + * + * * - *
- * Click me and #/some-page will transition in with the slide-in-up animation! - * + * Some super content here! * * * * ``` * - * @param {string} ion-nav-animation The animation to make the parent ionNavView change pages with when clicking this element. + * @param {string} side The side to place the buttons on in the parent + * {@link ionic.directive:ionNavBar}. Available: 'left' or 'right'. */ -.directive('ionNavAnimation', function() { +.directive('ionNavButtons', ['$compile', '$animate', function($compile, $animate) { return { - restrict: 'A', - require: '^?ionNavView', - link: function($scope, $element, $attrs, navViewCtrl) { - if (!navViewCtrl) { - return; - } - ionic.on('tap', function() { - navViewCtrl.setNextAnimation($attrs.ionNavAnimation); - }, $element[0]); + require: '^ionNavBar', + restrict: 'E', + compile: function($element, $attrs) { + var content = $element.contents().remove(); + return function($scope, $element, $attrs, navBarCtrl) { + var navElement = $attrs.side === 'right' ? + navBarCtrl.rightButtonsElement : + navBarCtrl.leftButtonsElement; + + //Put all of our inside buttons into their own div, + //so we can remove them all when this element dies - + //even if the buttons have changed through an ng-repeat or the like, + //we just remove their div parent and they are gone. + var buttons = angular.element('
').append(content); + + //Compile buttons inside content so they have access to everything + //something inside content does (eg parent ionicScroll) + $element.append(buttons); + $compile(buttons)($scope); + + //Append buttons to navbar + $animate.enter(buttons, navElement); + + //When our ion-nav-buttons container is destroyed, + //destroy everything in the navbar + $scope.$on('$destroy', function() { + $animate.leave(buttons); + }); + + // The original element is just a completely empty element. + // make it invisible just to be sure it doesn't change any layout + $element.css('display', 'none'); + }; } }; -}); -})(); - +}]); (function() { 'use strict'; @@ -3160,6 +3452,18 @@ angular.module('ionic.ui.popup', []) replace: true, transclude: true, scope: true, + template: + '', link: function($scope, $element, $attr) { $ionicBind($scope, $attr, { title: '@', @@ -3182,18 +3486,7 @@ angular.module('ionic.ui.popup', []) } $scope.$onButtonTap({button: button, event: event}); } - }, - template: '' + } }; }]); @@ -3338,11 +3631,14 @@ angular.module('ionic.ui.scroll', []) * @ngdoc directive * @name ionScroll * @module ionic + * @delegate ionic.service:$ionicScrollDelegate * @restrict E * * @description * Creates a scrollable container for all content inside. * + * @param {string=} delegate-handle The handle used to identify this scrollView + * with {@link ionic.service:$ionicScrollDelegate}. * @param {string=} direction Which way to scroll. 'x' or 'y'. Default 'y'. * @param {boolean=} paging Whether to scroll with paging. * @param {expression=} on-refresh Called on pull-to-refresh, triggered by an {@link ionic.directive:ionRefresher}. @@ -3350,41 +3646,43 @@ angular.module('ionic.ui.scroll', []) * @param {boolean=} scrollbar-x Whether to show the horizontal scrollbar. Default false. * @param {boolean=} scrollbar-x Whether to show the vertical scrollbar. Default true. */ -.directive('ionScroll', ['$parse', '$timeout', '$controller', function($parse, $timeout, $controller) { +.directive('ionScroll', [ + '$timeout', + '$controller', + '$ionicBind', +function($timeout, $controller, $ionicBind) { return { restrict: 'E', - replace: true, - template: '
', - transclude: true, - scope: { - direction: '@', - paging: '@', - onRefresh: '&', - onScroll: '&', - scroll: '@', - scrollbarX: '@', - scrollbarY: '@', - }, - + scope: true, controller: function() {}, + compile: function(element, attr) { + element.addClass('scroll-view'); - compile: function(element, attr, transclude) { - - return { - //Prelink so it can compile before other directives compile. - //Then other directives can require ionicScrollCtrl - pre: prelink - }; + //We cannot transclude here because it breaks element.data() inheritance on compile + var innerElement = angular.element('
'); + innerElement.append(element.contents()); + element.append(innerElement); + return { pre: prelink }; function prelink($scope, $element, $attr) { - var scrollView, scrollCtrl, - sc = $element[0].children[0]; + var scrollView, scrollCtrl; - if(attr.padding == "true") { - sc.classList.add('padding'); + $ionicBind($scope, $attr, { + direction: '@', + paging: '@', + $onScroll: '&onScroll', + scroll: '@', + scrollbarX: '@', + scrollbarY: '@', + }); + + if (angular.isDefined($attr.padding)) { + $scope.$watch($attr.padding, function(newVal) { + innerElement.toggleClass('padding', !!newVal); + }); } if($scope.$eval($scope.paging) === true) { - sc.classList.add('scroll-paging'); + innerElement.addClass('scroll-paging'); } if(!$scope.direction) { $scope.direction = 'y'; } @@ -3392,6 +3690,7 @@ angular.module('ionic.ui.scroll', []) var scrollViewOptions= { el: $element[0], + delegateHandle: $attr.delegateHandle, paging: isPaging, scrollbarX: $scope.$eval($scope.scrollbarX) !== false, scrollbarY: $scope.$eval($scope.scrollbarY) !== false, @@ -3438,33 +3737,97 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie }]) /** - * @ngdoc controller - * @name ionicSideMenus + * @ngdoc service + * @name $ionicSideMenuDelegate * @module ionic - * @group side menu * * @description - * Controller for the {@link ionic.directive:ionSideMenus} directive. - */ -/** - * @ngdoc method - * @name ionicSideMenus#toggleLeft - * @description Toggle the left side menu (if it exists). - */ -/** - * @ngdoc method - * @name ionicSideMenus#toggleRight - * @description Toggle the right side menu (if it exists). + * Delegate for controlling the {@link ionic.directive:ionSideMenus} directive. + * + * Methods called directly on the $ionicSideMenuDelegate service will control all side + * menus. Use the {@link ionic.service:$ionicSideMenuDelegate#$getByHandle $getByHandle} + * method to control specific ionSideMenus instances. + * + * @usage + * + * ```html + * + * + * + * Content! + * + * + * + * Left Menu! + * + * + * + * ``` + * ```js + * function MainCtrl($scope, $ionicSideMenuDelegate) { + * $scope.toggleLeftSideMenu = function() { + * $ionicSideMenuDelegate.toggleLeft(); + * }; + * } + * ``` */ +.service('$ionicSideMenuDelegate', delegateService([ + /** + * @ngdoc method + * @name $ionicSideMenuDelegate#toggleLeft + * @description Toggle the left side menu (if it exists). + * @param {boolean=} isOpen Whether to open or close the menu. + * Default: Toggles the menu. + */ + 'toggleLeft', + /** + * @ngdoc method + * @name $ionicSideMenuDelegate#toggleRight + * @description Toggle the right side menu (if it exists). + * @param {boolean=} isOpen Whether to open or close the menu. + * Default: Toggles the menu. + */ + 'toggleRight', + /** + * @ngdoc method + * @name $ionicSideMenuDelegate#isOpenLeft + * @returns {boolean} Whether the left menu is currently opened. + */ + 'isOpenLeft', + /** + * @ngdoc method + * @name $ionicSideMenuDelegate#isOpenRight + * @returns {boolean} Whether the right menu is currently opened. + */ + 'isOpenRight', + /** + * @ngdoc method + * @name $ionicSideMenuDelegate#canDragContent + * @param {boolean=} canDrag Set whether the content can or cannot be dragged to open + * side menus. + * @returns {boolean} Whether the content can be dragged to open side menus. + */ + 'canDragContent', + /** + * @ngdoc method + * @name $ionicSideMenuDelegate#$getByHandle + * @param {string} handle + * @returns `delegateInstance` A delegate instance that controls only the + * {@link ionic.directive:ionSideMenus} directives with `delegate-handle` matching + * the given handle. + * + * Example: `$ionicSideMenuDelegate.$getByHandle('my-handle').toggleLeft();` + */ +])) /** * @ngdoc directive * @name ionSideMenus * @module ionic + * @delegate ionic.service:$ionicSideMenuDelegate * @restrict E - * @group side menu - * @groupMainItem - * @controller ionicSideMenus * * @description * A container element for side menu(s) and the main content. Allows the left @@ -3479,14 +3842,14 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie * * @usage * To use side menus, add an `` parent element, - * an `` for the center content, + * an `` for the center content, * and one or more `` directives. * * ```html * * - * - * + * + * * * * @@ -3498,20 +3861,21 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie * * ``` * ```js - * function ContentController($scope) { + * function ContentController($scope, $ionicSideMenuDelegate) { * $scope.toggleLeft = function() { - * $scope.sideMenuController.toggleLeft(); + * $ionicSideMenuDelegate.toggleLeft(); * }; * } * ``` * - * @param {expression=} model The model to assign this side menu container's {@link ionic.controller:ionicSideMenus} controller to. By default, assigns to $scope.sideMenuController. + * @param {string=} delegate-handle The handle used to identify this side menu + * with {@link ionic.service:$ionicSideMenuDelegate}. * */ .directive('ionSideMenus', function() { return { restrict: 'ECA', - controller: ['$scope', '$attrs', '$parse', function($scope, $attrs, $parse) { + controller: ['$scope', '$attrs', '$ionicSideMenuDelegate', function($scope, $attrs, $ionicSideMenuDelegate) { var _this = this; angular.extend(this, ionic.controllers.SideMenuController.prototype); @@ -3521,9 +3885,20 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie right: { width: 275 } }); + this.canDragContent = function(canDrag) { + if (arguments.length) { + $scope.dragContent = !!canDrag; + } + return $scope.dragContent; + }; + $scope.sideMenuContentTranslateX = 0; - $parse($attrs.model || 'sideMenuController').assign($scope, this); + var deregisterInstance = $ionicSideMenuDelegate._registerInstance( + this, $attrs.delegateHandle + ); + + $scope.$on('$destroy', deregisterInstance); }], replace: true, transclude: true, @@ -3535,21 +3910,18 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie * @ngdoc directive * @name ionSideMenuContent * @module ionic - * @restrict A - * @group side menu + * @restrict E * @parent ionic.directive:ionSideMenus * * @description * A container for the main visible content, sibling to one or more * {@link ionic.directive:ionSideMenu} directives. * - * An attribute directive, recommended to be used as part of an `` element. - * * @usage * ```html - *
- *
+ * + * * ``` * For a complete side menu example, see the * {@link ionic.directive:ionSideMenus} documentation. @@ -3559,20 +3931,21 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie */ .directive('ionSideMenuContent', ['$timeout', '$ionicGesture', function($timeout, $ionicGesture) { return { - restrict: 'AC', + restrict: 'EA', //DEPRECATED 'A' require: '^ionSideMenus', scope: true, - compile: function(element, attr, transclude) { - return function($scope, $element, $attr, sideMenuCtrl) { + compile: function(element, attr) { + return { pre: prelink }; + function prelink($scope, $element, $attr, sideMenuCtrl) { - $element.addClass('menu-content'); + $element.addClass('menu-content pane'); if (angular.isDefined(attr.dragContent)) { $scope.$watch(attr.dragContent, function(value) { - $scope.dragContent = value; + sideMenuCtrl.canDragContent(value); }); } else { - $scope.dragContent = true; + sideMenuCtrl.canDragContent(true); } var defaultPrevented = false; @@ -3653,7 +4026,7 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie $ionicGesture.off(releaseGesture, 'release', dragReleaseFn); ionic.off('tap', contentTap, $element[0]); }); - }; + } } }; }]) @@ -3663,7 +4036,6 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie * @name ionSideMenu * @module ionic * @restrict E - * @group side menu * @parent ionic.directive:ionSideMenus * * @description @@ -3688,14 +4060,13 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie return { restrict: 'E', require: '^ionSideMenus', - replace: true, - transclude: true, scope: true, - template: '', - compile: function(element, attr, transclude) { + compile: function(element, attr) { angular.isUndefined(attr.isEnabled) && attr.$set('isEnabled', 'true'); angular.isUndefined(attr.width) && attr.$set('width', '275'); + element.addClass('menu menu-' + attr.side); + return function($scope, $element, $attr, sideMenuCtrl) { $scope.side = $attr.side || 'left'; @@ -3714,14 +4085,79 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie $scope.$watch($attr.isEnabled, function(val) { sideMenu.setIsEnabled(!!val); }); - - transclude($scope, function(clone) { - $element.append(clone); - }); }; } }; -}); +}) + +/** + * @ngdoc directive + * @name menuToggle + * @module ionic + * @restrict AC + * + * @description + * Toggle a side menu on the given side + * + * @usage + * Below is an example of a link within a nav bar. Tapping this link would + * automatically open the given side menu + * + * ```html + * + * + * + * + * ... + * + * ``` + */ +.directive('menuToggle', ['$ionicViewService', function($ionicViewService) { + return { + restrict: 'AC', + require: '^ionSideMenus', + link: function($scope, $element, $attr, sideMenuCtrl) { + var side = $scope.$eval($attr.menuToggle) || 'left'; + $element.bind('click', function(){ + if(side === 'left') { + sideMenuCtrl.toggleLeft(); + } else if(side === 'right') { + sideMenuCtrl.toggleRight(); + } + }); + } + }; +}]) + +/** + * @ngdoc directive + * @name menuClose + * @module ionic + * @restrict AC + * + * @description + * Closes a side menu which is currently opened. + * + * @usage + * Below is an example of a link within a side menu. Tapping this link would + * automatically close the currently opened menu + * + * ```html + * Home + * ``` + */ +.directive('menuClose', ['$ionicViewService', function($ionicViewService) { + return { + restrict: 'AC', + require: '^ionSideMenus', + link: function($scope, $element, $attr, sideMenuCtrl) { + $element.bind('click', function(){ + sideMenuCtrl.close(); + }); + } + }; +}]); + })(); (function() { @@ -3729,6 +4165,102 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie angular.module('ionic.ui.slideBox', []) +/** + * @ngdoc service + * @name $ionicSlideBoxDelegate + * @module ionic + * @description + * Delegate that controls the {@link ionic.directive:ionSlideBox} directive. + * + * Methods called directly on the $ionicSlideBoxDelegate service will control all side + * menus. Use the {@link ionic.service:$ionicSlideBoxDelegate#$getByHandle $getByHandle} + * method to control specific slide box instances. + * + * @usage + * + * ```html + * + * + * + *
+ * + *
+ *
+ * + *
+ * Slide 2! + *
+ *
+ *
+ * + * ``` + * ```js + * function MyCtrl($scope, $ionicSlideBoxDelegate) { + * $scope.nextSlide = function() { + * $ionicSlideBoxDelegate.next(); + * } + * } + * ``` + */ +.service('$ionicSlideBoxDelegate', delegateService([ + /** + * @ngdoc method + * @name $ionicSlideBoxDelegate#update + * @description + * Update the slidebox (for example if using Angular with ng-repeat, + * resize it for the elements inside). + */ + 'update', + /** + * @ngdoc method + * @name $ionicSlideBoxDelegate#slide + * @param {number} to The index to slide to. + * @param {number=} speed The number of milliseconds for the change to take. + */ + 'slide', + /** + * @ngdoc method + * @name $ionicSlideBoxDelegate#previous + * @description Go to the previous slide. Wraps around if at the beginning. + */ + 'previous', + /** + * @ngdoc method + * @name $ionicSlideBoxDelegate#next + * @description Go to the next slide. Wraps around if at the end. + */ + 'next', + /** + * @ngdoc method + * @name $ionicSlideBoxDelegate#stop + * @description Stop sliding. The slideBox will not move again until + * explicitly told to do so. + */ + 'stop', + /** + * @ngdoc method + * @name $ionicSlideBoxDelegate#currentIndex + * @returns number The index of the current slide. + */ + 'currentIndex', + /** + * @ngdoc method + * @name $ionicSlideBoxDelegate#slidesCount + * @returns number The number of slides there are currently. + */ + 'slidesCount' + /** + * @ngdoc method + * @name $ionicSlideBoxDelegate#$getByHandle + * @param {string} handle + * @returns `delegateInstance` A delegate instance that controls only the + * {@link ionic.directive:ionSlideBox} directives with `delegate-handle` matching + * the given handle. + * + * Example: `$ionicSlideBoxDelegate.$getByHandle('my-handle').stop();` + */ +])) + /** * The internal controller for the slide box controller. */ @@ -3737,8 +4269,8 @@ angular.module('ionic.ui.slideBox', []) * @ngdoc directive * @name ionSlideBox * @module ionic + * @delegate ionic.service:$ionicSlideBoxDelegate * @restrict E - * @controller ionicSlideBox * @description * The Slide Box is a multi-page container where each page can be swiped or dragged between: * @@ -3759,7 +4291,8 @@ angular.module('ionic.ui.slideBox', []) * * ``` * - * @param {expression=} model The model to assign this slide box container's {@link ionic.controller:ionicSlideBox} controller to. By default, assigns to $scope.slideBoxController. + * @param {string=} delegate-handle The handle used to identify this slideBox + * with {@link ionic.service:$ionicSlideBoxDelegate}. * @param {boolean=} does-continue Whether the slide box should automatically slide. * @param {number=} slide-interval How many milliseconds to wait to change slides (if does-continue is true). Defaults to 4000. * @param {boolean=} show-pager Whether a pager should be shown for this slide box. @@ -3767,7 +4300,11 @@ angular.module('ionic.ui.slideBox', []) * @param {expression=} on-slide-changed Expression called whenever the slide is changed. * @param {expression=} active-slide Model to bind the current slide to. */ -.directive('ionSlideBox', ['$timeout', '$compile', '$ionicSlideBoxDelegate', function($timeout, $compile, $ionicSlideBoxDelegate) { +.directive('ionSlideBox', [ + '$timeout', + '$compile', + '$ionicSlideBoxDelegate', +function($timeout, $compile, $ionicSlideBoxDelegate) { return { restrict: 'E', replace: true, @@ -3780,7 +4317,7 @@ angular.module('ionic.ui.slideBox', []) onSlideChanged: '&', activeSlide: '=?' }, - controller: ['$scope', '$element', '$attrs', '$parse', function($scope, $element, $attrs, $parse) { + controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { var _this = this; var continuous = $scope.$eval($scope.doesContinue) === true; @@ -3826,9 +4363,12 @@ angular.module('ionic.ui.slideBox', []) slider.slide(index); }); - $parse($attrs.model || 'slideBoxController').assign($scope.$parent, slider); + //Exposed for testing + this.__slider = slider; - $ionicSlideBoxDelegate.register($scope, $element); + var deregisterInstance = $ionicSlideBoxDelegate._registerInstance(slider, $attrs.delegateHandle); + + $scope.$on('$destroy', deregisterInstance); this.slidesCount = function() { return slider.slidesCount(); @@ -3908,32 +4448,80 @@ angular.module('ionic.ui.tabs', ['ionic.service.view']) }]) /** - * @ngdoc controller - * @group tab bar - * @name ionicTabs + * @ngdoc service + * @name $ionicTabsDelegate * @module ionic * * @description - * Controller for the {@link ionic.directive:ionTabs} directive. + * Delegate for controlling the {@link ionic.directive:ionTabs} directive. + * + * Methods called directly on the $ionicTabsDelegate service will control all ionTabs + * directives. Use the {@link ionic.service:$ionicTabsDelegate#$getByHandle $getByHandle} + * method to control specific ionTabs instances. + * + * @usage + * + * ```html + * + * + * + * + * Hello tab 1! + * + * + * Hello tab 2! + * + * + * + * ``` + * ```js + * function MyCtrl($scope, $ionicTabsDelegate) { + * $scope.selectTabWithIndex = function(index) { + * $ionicTabsDelegate.select(index); + * } + * } + * ``` */ +.service('$ionicTabsDelegate', delegateService([ + /** + * @ngdoc method + * @name $ionicTabsDelegate#select + * @description Select the tab matching the given index. + * + * @param {number} index Index of the tab to select. + * @param {boolean=} shouldChangeHistory Whether this selection should load this tab's + * view history (if it exists) and use it, or just load the default page. + * Default false. + * Hint: you probably want this to be true if you have an + * {@link ionic.directive:ionNavView} inside your tab. + */ + 'select', + /** + * @ngdoc method + * @name $ionicTabsDelegate#selectedIndex + * @returns `number` The index of the selected tab, or -1. + */ + 'selectedIndex' + /** + * @ngdoc method + * @name $ionicTabsDelegate#$getByHandle + * @param {string} handle + * @returns `delegateInstance` A delegate instance that controls only the + * {@link ionic.directive:ionTabs} directives with `delegate-handle` matching + * the given handle. + * + * Example: `$ionicTabsDelegate.$getByHandle('my-handle').select(0);` + */ +])) + .controller('ionicTabs', ['$scope', '$ionicViewService', '$element', function($scope, $ionicViewService, $element) { var _selectedTab = null; var self = this; self.tabs = []; - /** - * @ngdoc method - * @name ionicTabs#selectedTabIndex - * @returns `number` The index of the selected tab, or -1. - */ - self.selectedTabIndex = function() { + self.selectedIndex = function() { return self.tabs.indexOf(_selectedTab); }; - /** - * @ngdoc method - * @name ionicTabs#selectedTab - * @returns `ionTab` The selected tab or null if none selected. - */ self.selectedTab = function() { return _selectedTab; }; @@ -3974,17 +4562,6 @@ angular.module('ionic.ui.tabs', ['ionic.service.view']) } }; - /** - * @ngdoc method - * @name ionicTabs#select - * @description Select the given tab or tab index. - * - * @param {ionTab|number} tabOrIndex A tab object or index of a tab to select - * @param {boolean=} shouldChangeHistory Whether this selection should load this tab's view history - * (if it exists) and use it, or just loading the default page. Default false. - * Hint: you probably want this to be true if you have an - * {@link ionic.directive:ionNavView} inside your tab. - */ self.select = function(tab, shouldEmitEvent) { var tabIndex; if (angular.isNumber(tab)) { @@ -4033,20 +4610,24 @@ angular.module('ionic.ui.tabs', ['ionic.service.view']) * @ngdoc directive * @name ionTabs * @module ionic + * @delegate ionic.service:$ionicTabsDelegate * @restrict E - * @group tab bar - * @groupMainItem - * @controller ionicTabs * @codepen KbrzJ * * @description - * Powers a multi-tabbed interface with a Tab Bar and a set of "pages" that can be tabbed through. + * Powers a multi-tabbed interface with a Tab Bar and a set of "pages" that can be tabbed + * through. * - * See the {@link ionic.directive:ionTab} directive's documentation for more details. + * Assign any [tabs class](/docs/components#tabs) or + * [animation class](/docs/components#animation) to the element to define + * its look and feel. + * + * See the {@link ionic.directive:ionTab} directive's documentation for more details on + * individual tabs. * * @usage * ```html - * + * * * * @@ -4059,48 +4640,49 @@ angular.module('ionic.ui.tabs', ['ionic.service.view']) * * * + * * * ``` * - * @param {expression=} model The model to assign this tab bar's {@link ionic.controller:ionicTabs} controller to. By default, assigns to $scope.tabsController. - * @param {string=} animation The animation to use when changing between tab pages. - * @param {string=} tabs-style The class to apply to the tabs. Defaults to 'tabs-positive'. - * @param {string=} tabs-type Whether to put the tabs on the top or bottom. Defaults to 'tabs-bottom'. + * @param {string=} delegate-handle The handle used to identify these tabs + * with {@link ionic.service:$ionicTabsDelegate}. */ -.directive('ionTabs', ['$ionicViewService', '$ionicBind', '$parse', function($ionicViewService, $ionicBind, $parse) { +.directive('ionTabs', ['$ionicViewService', '$ionicTabsDelegate', function($ionicViewService, $ionicTabsDelegate) { return { restrict: 'E', - replace: true, scope: true, - transclude: true, controller: 'ionicTabs', - template: - '
' + - '
' + - '
' + - '
', - compile: function(element, attr, transclude) { - if(angular.isUndefined(attr.tabsType)) attr.$set('tabsType', 'tabs-positive'); + compile: function(element, attr) { + element.addClass('view'); + //We cannot transclude here because it breaks element.data() inheritance on compile + var innerElement = angular.element('
'); + innerElement.append(element.contents()); + element.append(innerElement); - return function link($scope, $element, $attr, tabsCtrl) { + return { pre: prelink }; + function prelink($scope, $element, $attr, tabsCtrl) { + var deregisterInstance = $ionicTabsDelegate._registerInstance( + tabsCtrl, $attr.delegateHandle + ); - $ionicBind($scope, $attr, { - $animation: '@animation', - $tabsStyle: '@tabsStyle', - $tabsType: '@tabsType' - }); - - $parse(attr.model || 'tabsController').assign($scope, tabsCtrl); + $scope.$on('$destroy', deregisterInstance); tabsCtrl.$scope = $scope; tabsCtrl.$element = $element; tabsCtrl.$tabsElement = angular.element($element[0].querySelector('.tabs')); - transclude($scope, function(clone) { - $element.append(clone); + var el = $element[0]; + $scope.$watch(function() { return el.className; }, function(value) { + var isTabsTop = value.indexOf('tabs-top') !== -1; + var isHidden = value.indexOf('tabs-item-hide') !== -1; + $scope.$hasTabs = !isTabsTop && !isHidden; + $scope.$hasTabsTop = isTabsTop && !isHidden; }); - }; + $scope.$on('$destroy', function() { + $scope.$hasTabs = $scope.$hasTabsTop = null; + }); + } } }; }]) @@ -4112,7 +4694,6 @@ function($scope, $ionicViewService, $rootScope, $element) { /** * @ngdoc directive - * @group tab bar * @name ionTab * @module ionic * @restrict E @@ -4123,8 +4704,6 @@ function($scope, $ionicViewService, $rootScope, $element) { * * Each ionTab has its own view history. * - * Whenever a tab is shown or hidden, it will broadcast a 'tab.shown' or 'tab.hidden' event. - * * @usage * ```html * ') .append( element.contents().remove() ); @@ -4175,6 +4759,9 @@ function($rootScope, $animate, $ionicBind, $compile, $ionicViewService) { tabsCtrl = ctrls[0], tabCtrl = ctrls[1]; + //Remove title attribute so browser-tooltip does not apear + $element[0].removeAttribute('title'); + $ionicBind($scope, $attr, { animate: '=', onSelect: '&', @@ -4213,9 +4800,6 @@ function($rootScope, $animate, $ionicBind, $compile, $ionicViewService) { tabsCtrl.$tabsElement.append($compile(tabNavElement)($scope)); $scope.$watch('$tabSelected', function(value) { - if (!value) { - $scope.$broadcast('tab.hidden', $scope); - } childScope && childScope.$destroy(); childScope = null; childElement && $animate.leave(childElement); @@ -4225,7 +4809,6 @@ function($rootScope, $animate, $ionicBind, $compile, $ionicViewService) { childElement = tabContent.clone(); $animate.enter(childElement, tabsCtrl.$element); $compile(childElement)(childScope); - $scope.$broadcast('tab.shown', $scope); } }); @@ -4246,7 +4829,7 @@ function($rootScope, $animate, $ionicBind, $compile, $ionicViewService) { replace: true, require: ['^ionTabs', '^ionTab'], template: - '' + '{{badge}}' + '' + @@ -4266,6 +4849,9 @@ function($rootScope, $animate, $ionicBind, $compile, $ionicViewService) { var tabsCtrl = ctrls[0], tabCtrl = ctrls[1]; + //Remove title attribute so browser-tooltip does not apear + $element[0].removeAttribute('title'); + $scope.selectTab = function(e) { e.preventDefault(); tabsCtrl.select(tabCtrl.$scope, true); @@ -4408,14 +4994,14 @@ angular.module('ionic.ui.touch', []) }); }); - ionic.on('tap', onTap, element[0]); + ionic.on("release", onTap, element[0]); // Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click // something else nearby. element.onclick = function(event) { }; scope.$on('$destroy', function () { - ionic.off('tap', onTap, element[0]); + ionic.off("release", onTap, element[0]); }); }; }]) @@ -4446,203 +5032,12 @@ angular.module('ionic.ui.touch', []) angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gesture', 'ngSanitize']) -/** - * @ngdoc directive - * @name ionNavBar - * @module ionic - * @restrict E - * - * @usage - * If have an {@link ionic.directive:ionNavView} directive, we can also create an - * , which will create a topbar that updates as the application state changes. - * We can also add some styles and set up animations: - * - * ```html - * - * - * - * - * - * - * - * ``` - * - * @param {string=} back-button-type The type of the back button's icon. Available: 'button-icon' or just 'button'. - * @param {string=} back-button-icon The icon to use for the back button. For example, 'ion-arrow-left-c'. - * @param {string=} back-button-label The label to use for the back button. For example, 'Back'. - * @param animation {string=} The animation used to transition between titles. - * @param type {string=} The className for the navbar. For example, 'bar-positive'. - * @param align {string=} Where to align the title of the navbar. Available: 'left', 'right', 'center'. Defaults to 'center'. - */ -.directive('ionNavBar', ['$ionicViewService', '$rootScope', '$animate', '$compile', - function( $ionicViewService, $rootScope, $animate, $compile) { - - return { - restrict: 'E', - replace: true, - scope: { - animation: '@', - type: '@', - backType: '@backButtonType', - backLabel: '@backButtonLabel', - backIcon: '@backButtonIcon', - alignTitle: '@' - }, - controller: function() {}, - template: - '', - compile: function(tElement, tAttrs) { - - return function link($scope, $element, $attr) { - //defaults - $scope.backButtonEnabled = false; - $scope.animateEnabled = true; - $scope.isReverse = false; - $scope.isInvisible = true; - - $scope.navBarClass = function() { - return ($scope.type ? ' ' + $scope.type : '') + - ($scope.isReverse ? ' reverse' : '') + - ($scope.isInvisible ? ' invisible' : '') + - (!$scope.animationDisabled && $scope.animation ? ' ' + $scope.animation : ''); - }; - - // Initialize our header bar view which will handle - // resizing and aligning our title labels - var hb = new ionic.views.HeaderBar({ - el: $element[0], - alignTitle: $scope.alignTitle || 'center' - }); - $scope.headerBarView = hb; - - //Navbar events - $scope.$on('viewState.viewEnter', function(e, data) { - updateHeaderData(data); - }); - $scope.$on('viewState.showNavBar', function(e, showNavBar) { - $scope.isInvisible = !showNavBar; - }); - - // All of these these are emitted from children of a sibling scope, - // so we listen on parent so we can catch them as they bubble up - var unregisterEventListeners = [ - $scope.$parent.$on('$viewHistory.historyChange', function(e, data) { - $scope.backButtonEnabled = !!data.showBack; - }), - $scope.$parent.$on('viewState.leftButtonsChanged', function(e, data) { - $scope.leftButtons = data; - }), - $scope.$parent.$on('viewState.rightButtonsChanged', function(e, data) { - $scope.rightButtons = data; - }), - $scope.$parent.$on('viewState.showBackButton', function(e, data) { - $scope.backButtonEnabled = !!data; - }), - $scope.$parent.$on('viewState.titleUpdated', function(e, data) { - $scope.title = data && data.title || ''; - }) - ]; - $scope.$on('$destroy', function() { - for (var i=0; i')($scope); - angular.element(currentTitles[0]).replaceWith(oldTitleEl); - } - //Compile new title - newTitleEl = $compile('

')($scope); - - //Animate in one frame - ionic.requestAnimationFrame(function() { - - oldTitleEl && $animate.leave(angular.element(oldTitleEl)); - - var insert = oldTitleEl && angular.element(oldTitleEl) || null; - $animate.enter(newTitleEl, $element, insert, function() { - hb.align(); - }); - - //Cleanup any old titles leftover (besides the one we already did replaceWith on) - angular.forEach(currentTitles, function(el) { - if (el && el.parentNode) { - //Use .remove() to cleanup things like .data() - angular.element(el).remove(); - } - }); - - //$apply so bindings fire - $scope.$digest(); - - //Stop flicker of new title on ios7 - ionic.requestAnimationFrame(function() { - newTitleEl[0].classList.remove('invisible'); - }); - }); - } - }; - } - }; -}]) - /** * @ngdoc directive * @name ionView * @module ionic * @restrict E - * @parent ionNavBar + * @parent ionNavView * * @description * A container for content, used to tell a parent {@link ionic.directive:ionNavBar} @@ -4653,7 +5048,7 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu * * ```html * - * + * * * * Hello! @@ -4662,97 +5057,52 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu * * ``` * - * @param {expression=} left-buttons The leftButtons to display on the parent {@link ionic.directive:ionNavBar}. - * @param {expression=} right-buttons The rightButtons to display on the parent {@link ionic.directive:ionNavBar}. * @param {string=} title The title to display on the parent {@link ionic.directive:ionNavBar}. - * @param {boolean=} hideBackButton Whether to hide the back button on the parent {@link ionic.directive:ionNavBar}. - * @param {boolean=} hideNavBar Whether to hide the parent {@link ionic.directive:ionNavBar}. + * @param {boolean=} hideBackButton Whether to hide the back button on the parent + * {@link ionic.directive:ionNavBar} by default. + * @param {boolean=} hideNavBar Whether to hide the parent + * {@link ionic.directive:ionNavBar} by default. */ .directive('ionView', ['$ionicViewService', '$rootScope', '$animate', function( $ionicViewService, $rootScope, $animate) { return { restrict: 'EA', priority: 1000, - scope: { - leftButtons: '=', - rightButtons: '=', - title: '@', - hideBackButton: '@', - hideNavBar: '@', - }, - + require: '^?ionNavBar', compile: function(tElement, tAttrs, transclude) { tElement.addClass('pane'); tElement[0].removeAttribute('title'); - return function link($scope, $element, $attr) { - - $rootScope.$broadcast('viewState.viewEnter', { - title: $scope.title, - navDirection: $scope.$navDirection || $scope.$parent.$navDirection - }); - - // Should we hide a back button when this tab is shown - $scope.hideBackButton = $scope.$eval($scope.hideBackButton); - if($scope.hideBackButton) { - $rootScope.$broadcast('viewState.showBackButton', false); + return function link($scope, $element, $attr, navBarCtrl) { + if (!navBarCtrl) { + return; } + var initialTitle = $attr.title; + navBarCtrl.changeTitle(initialTitle, $scope.$navDirection); - // Should the nav bar be hidden for this view or not? - $rootScope.$broadcast('viewState.showNavBar', ($scope.hideNavBar !== 'true') ); - - // watch for changes in the left buttons - $scope.$watch('leftButtons', function(value) { - $scope.$emit('viewState.leftButtonsChanged', $scope.leftButtons); + // watch for changes in the title, don't set initial value as changeTitle does that + $attr.$observe('title', function(val, oldVal) { + if (val !== initialTitle) { + navBarCtrl.setTitle(val); + } }); - $scope.$watch('rightButtons', function(val) { - $scope.$emit('viewState.rightButtonsChanged', $scope.rightButtons); + $scope.$watch($attr.hideBackButton, function(value) { + // Should we hide a back button when this tab is shown + navBarCtrl.showBackButton(!value); }); - // watch for changes in the title - $scope.$watch('title', function(val) { - $scope.$emit('viewState.titleUpdated', $scope); + $scope.$watch($attr.hideNavBar, function(value) { + // Should the nav bar be hidden for this view or not? + navBarCtrl.showBar(!value); }); + }; } }; }]) -/** -* @private -*/ -.directive('ionNavBackButton', ['$ionicViewService', '$rootScope', - function($ionicViewService, $rootScope) { - - function goBack(e) { - var backView = $ionicViewService.getBackView(); - backView && backView.go(); - e.alreadyHandled = true; - return false; - } - - return { - restrict: 'E', - scope: { - type: '=', - label: '=', - icon: '=' - }, - replace: true, - template: - '', - link: function($scope) { - $scope.goBack = goBack; - } - }; -}]) - /** * @ngdoc directive * @name ionNavView @@ -4787,8 +5137,11 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu * {@link ionic.directive:ionNavBar} directive which will render a header bar that updates as we * navigate through the navigation stack. * + * You can any [animation class](/docs/components#animation) on the navView to have its pages slide. + * Recommended for page transitions: 'slide-left-right', 'slide-left-right-ios7', 'slide-in-up'. + * * ```html - * + * * * * @@ -4843,8 +5196,6 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu * @param {string=} name A view name. The name should be unique amongst the other views in the * same state. You can have views of the same name that live in different states. For more * information, see ui-router's [ui-view documentation](http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.directive:ui-view). - * @param {string=} animation The animation to use for views underneath this ionNavView. - * Defaults to 'slide-left-right'. */ .directive('ionNavView', ['$ionicViewService', '$state', '$compile', '$controller', '$animate', function( $ionicViewService, $state, $compile, $controller, $animate) { @@ -4857,10 +5208,7 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu terminal: true, priority: 2000, transclude: true, - controller: ['$scope', function($scope) { - this.setNextAnimation = function(anim) { - $scope.$nextAnimation = anim; - }; + controller: [function(){ }], compile: function (element, attr, transclude) { return function(scope, element, attr, navViewCtrl) { @@ -4953,10 +5301,45 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu } }; return directive; +}]) + + +/** + * @ngdoc directive + * @name navClear + * @module ionic + * @restrict AC + * + * @description + * Disables any transition animations between views, along with removing the back + * button which would normally show on the next view. This directive is useful for + * links within a sideMenu. + * + * @usage + * Below is an example of a link within a side menu. Tapping this link would disable + * any animations which would normally occur between views. + * + * ```html + *
Home + * ``` + */ +.directive('navClear', ['$ionicViewService', function($ionicViewService) { + return { + restrict: 'AC', + link: function($scope, $element, $attr) { + $element.bind('click', function(){ + $ionicViewService.nextViewOptions({ + disableAnimate: true, + disableBack: true + }); + }); + } + }; }]); })(); +/* (function() { 'use strict'; @@ -4979,8 +5362,9 @@ angular.module('ionic.ui.virtRepeat', []) }; }); })(ionic); +*/ - +/* (function() { 'use strict'; @@ -5015,7 +5399,6 @@ function isTagNameInList(element, list){ // Utility to find the viewport/content elements given the start element: function findViewportAndContent(startElement){ - /*jshint eqeqeq:false, curly:false */ var root = $rootElement[0]; var e, n; // Somewhere between the grandparent and the root node @@ -5105,13 +5488,13 @@ function computeRowHeight(element){ angular.module('ionic.ui.virtualRepeat', []) -/** - * A replacement for ng-repeat that supports virtual lists. - * This is not a 1 to 1 replacement for ng-repeat. However, in situations - * where you have huge lists, this repeater will work with our virtual - * scrolling to only render items that are showing or will be showing - * if a scroll is made. - */ +// +// A replacement for ng-repeat that supports virtual lists. +// This is not a 1 to 1 replacement for ng-repeat. However, in situations +// where you have huge lists, this repeater will work with our virtual +// scrolling to only render items that are showing or will be showing +// if a scroll is made. +// .directive('ionVirtualRepeat', ['$log', function($log) { return { require: ['?ngModel, ^virtualList'], @@ -5308,46 +5691,335 @@ angular.module('ionic.ui.virtualRepeat', []) }]); })(ionic); - -(function() { -'use strict'; +*/ angular.module('ionic.ui.scroll') +/** + * @ngdoc service + * @name $ionicScrollDelegate + * @module ionic + * @description + * Delegate for controlling scrollViews (created by + * {@link ionic.directive:ionContent} and + * {@link ionic.directive:ionScroll} directives). + * + * Methods called directly on the $ionicScrollDelegate service will control all scroll + * views. Use the {@link ionic.service:$ionicScrollDelegate#$getByHandle $getByHandle} + * method to control specific scrollViews. + * + * @usage + * + * ```html + * + * + * + * + * + * ``` + * ```js + * function MainCtrl($scope, $ionicScrollDelegate) { + * $scope.scrollTop = function() { + * $ionicScrollDelegate.scrollTop(); + * }; + * } + * ``` + * + * Example of advanced usage, with two scroll areas using `delegate-handle` + * for fine control. + * + * ```html + * + * + * + * + * + * + * + * + * ``` + * ```js + * function MainCtrl($scope, $ionicScrollDelegate) { + * $scope.scrollMainToTop = function() { + * $ionicScrollDelegate.$getByHandle('mainScroll').scrollTop(); + * }; + * $scope.scrollSmallToTop = function() { + * $ionicScrollDelegate.$getByHandle('small').scrollTop(); + * }; + * } + * ``` + */ + +.service('$ionicScrollDelegate', delegateService([ + /** + * @ngdoc method + * @name $ionicScrollDelegate#resize + * @description Tell the scrollView to recalculate the size of its container. + */ + 'resize', + /** + * @ngdoc method + * @name $ionicScrollDelegate#scrollTop + * @param {boolean=} shouldAnimate Whether the scroll should animate. + */ + 'scrollTop', + /** + * @ngdoc method + * @name $ionicScrollDelegate#scrollBottom + * @param {boolean=} shouldAnimate Whether the scroll should animate. + */ + 'scrollBottom', + /** + * @ngdoc method + * @name $ionicScrollDelegate#scrollTo + * @param {number} left The x-value to scroll to. + * @param {number} top The y-value to scroll to. + * @param {boolean=} shouldAnimate Whether the scroll should animate. + */ + 'scrollTo', + /** + * @ngdoc method + * @name $ionicScrollDelegate#anchorScroll + * @description Tell the scrollView to scroll to the element with an id + * matching window.location.hash. + * + * If no matching element is found, it will scroll to top. + * + * @param {boolean=} shouldAnimate Whether the scroll should animate. + */ + 'anchorScroll', + /** + * @ngdoc method + * @name $ionicScrollDelegate#rememberScrollPosition + * @description + * Will make it so, when this scrollView is destroyed (user leaves the page), + * the last scroll position the page was on will be saved, indexed by the + * given id. + * + * Note: for pages associated with a view under an ion-nav-view, + * rememberScrollPosition automatically saves their scroll. + * + * Related methods: scrollToRememberedPosition, forgetScrollPosition (below). + * + * In the following example, the scroll position of the ion-scroll element + * will persist, even when the user changes the toggle switch. + * + * ```html + * + * + *
+ * + * {{i}} + * + *
+ *
+ * ``` + * ```js + * function ScrollCtrl($scope, $ionicScrollDelegate) { + * var delegate = $ionicScrollDelegate.$getByHandle('myScroll'); + * + * // Put any unique ID here. The point of this is: every time the controller is recreated + * // we want to load the correct remembered scroll values. + * delegate.rememberScrollPosition('my-scroll-id'); + * delegate.scrollToRememberedPosition(); + * $scope.items = []; + * for (var i=0; i<100; i++) { + * $scope.items.push(i); + * } + * } + * ``` + * + * @param {string} id The id to remember the scroll position of this + * scrollView by. + */ + 'rememberScrollPosition', + /** + * @ngdoc method + * @name $ionicScrollDelegate#forgetScrollPosition + * @description + * Stop remembering the scroll position for this scrollView. + */ + 'forgetScrollPosition', + /** + * @ngdoc method + * @name $ionicScrollDelegate#scrollToRememberedPosition + * @description + * If this scrollView has an id associated with its scroll position, + * (through calling rememberScrollPosition), and that position is remembered, + * load the position and scroll to it. + * @param {boolean=} shouldAnimate Whether to animate the scroll. + */ + 'scrollToRememberedPosition' + /** + * @ngdoc method + * @name $ionicScrollDelegate#$getByHandle + * @param {string} handle + * @returns `delegateInstance` A delegate instance that controls only the + * scrollViews with `delegate-handle` matching the given handle. + * + * Example: `$ionicScrollDelegate.$getByHandle('my-handle').scrollTop();` + */ +])) + /** * @private */ -.controller('$ionicScroll', ['$scope', 'scrollViewOptions', '$timeout', '$ionicScrollDelegate', '$window', function($scope, scrollViewOptions, $timeout, $ionicScrollDelegate, $window) { +.factory('$$scrollValueCache', function() { + return {}; +}) + +.controller('$ionicScroll', [ + '$scope', + 'scrollViewOptions', + '$timeout', + '$window', + '$$scrollValueCache', + '$location', + '$rootScope', + '$document', + '$ionicScrollDelegate', +function($scope, scrollViewOptions, $timeout, $window, $$scrollValueCache, $location, $rootScope, $document, $ionicScrollDelegate) { var self = this; + this._scrollViewOptions = scrollViewOptions; //for testing + var element = this.element = scrollViewOptions.el; + var $element = this.$element = angular.element(element); var scrollView = this.scrollView = new ionic.views.Scroll(scrollViewOptions); + //Attach self to element as a controller so other directives can require this controller + //through `require: '$ionicScroll' + //Also attach to parent so that sibling elements can require this + ($element.parent().length ? $element.parent() : $element) + .data('$$ionicScrollController', this); + + var deregisterInstance = $ionicScrollDelegate._registerInstance( + this, scrollViewOptions.delegateHandle + ); + if (!angular.isDefined(scrollViewOptions.bouncing)) { ionic.Platform.ready(function() { scrollView.options.bouncing = !ionic.Platform.isAndroid(); }); } - var $element = this.$element = angular.element(element); + var resize = angular.bind(scrollView, scrollView.resize); + ionic.on('resize', resize, $window); - //Attach self to element as a controller so other directives can require this controller - //through `require: '$ionicScroll' - $element.data('$$ionicScrollController', this); + // set by rootScope listener if needed + var backListenDone = angular.noop; - //Register delegate for event handling - $ionicScrollDelegate.register($scope, $element, scrollView); - - $window.addEventListener('resize', resize); $scope.$on('$destroy', function() { + deregisterInstance(); + ionic.off('resize', resize, $window); $window.removeEventListener('resize', resize); + backListenDone(); + if (self._rememberScrollId) { + $$scrollValueCache[self._rememberScrollId] = scrollView.getValues(); + } }); - function resize() { - scrollView.resize(); - } - this.setRefresher = function(refresherScope, refresherElement) { + $element.on('scroll', function(e) { + var detail = (e.originalEvent || e).detail || {}; + $scope.$onScroll && $scope.$onScroll({ + event: e, + scrollTop: detail.scrollTop || 0, + scrollLeft: detail.scrollLeft || 0 + }); + }); + + $scope.$on('$viewContentLoaded', function(e, historyData) { + //only the top-most scroll area under a view should remember that view's + //scroll position + if (e.defaultPrevented) { return; } + e.preventDefault(); + + var viewId = historyData && historyData.viewId; + if (viewId) { + self.rememberScrollPosition(viewId); + self.scrollToRememberedPosition(); + + backListenDone = $rootScope.$on('$viewHistory.viewBack', function(e, fromViewId, toViewId) { + //When going back from this view, forget its saved scroll position + if (viewId === fromViewId) { + self.forgetScrollPosition(); + } + }); + } + }); + + $timeout(function() { + scrollView.run(); + }); + + this._rememberScrollId = null; + + this.resize = function() { + return $timeout(resize); + }; + + this.scrollTop = function(shouldAnimate) { + this.resize().then(function() { + scrollView.scrollTo(0, 0, !!shouldAnimate); + }); + }; + + this.scrollBottom = function(shouldAnimate) { + this.resize().then(function() { + var max = scrollView.getScrollMax(); + scrollView.scrollTo(max.left, max.top, !!shouldAnimate); + }); + }; + + this.scrollTo = function(left, top, shouldAnimate) { + this.resize().then(function() { + scrollView.scrollTo(left, top, !!shouldAnimate); + }); + }; + + this.anchorScroll = function(shouldAnimate) { + this.resize().then(function() { + var hash = $location.hash(); + var elm = hash && $document[0].getElementById(hash); + if (hash && elm) { + var scroll = ionic.DomUtil.getPositionInParent(elm, self.$element); + scrollView.scrollTo(scroll.left, scroll.top, !!shouldAnimate); + } else { + scrollView.scrollTo(0,0, !!shouldAnimate); + } + }); + }; + + this.rememberScrollPosition = function(id) { + if (!id) { + throw new Error("Must supply an id to remember the scroll by!"); + } + this._rememberScrollId = id; + }; + this.forgetScrollPosition = function() { + delete $$scrollValueCache[this._rememberScrollId]; + this._rememberScrollId = null; + }; + this.scrollToRememberedPosition = function(shouldAnimate) { + var values = $$scrollValueCache[this._rememberScrollId]; + if (values) { + this.resize().then(function() { + scrollView.scrollTo(+values.left, +values.top, shouldAnimate); + }); + } + }; + + + + /** + * @private + */ + this._setRefresher = function(refresherScope, refresherElement) { var refresher = this.refresher = refresherElement; var refresherHeight = self.refresher.clientHeight || 0; scrollView.activatePullToRefresh(refresherHeight, function() { @@ -5361,10 +6033,7 @@ angular.module('ionic.ui.scroll') refresherScope.$onRefresh(); }); }; - - $timeout(function() { - scrollView.run(); - }); }]); -})(); + +})(); \ No newline at end of file diff --git a/release/js/ionic-angular.min.js b/release/js/ionic-angular.min.js index 221e34346b..61cb8b4d26 100644 --- a/release/js/ionic-angular.min.js +++ b/release/js/ionic-angular.min.js @@ -2,7 +2,7 @@ * Copyright 2014 Drifty Co. * http://drifty.com/ * - * Ionic, v0.9.27 + * Ionic, v1.0.0-beta.1 * A powerful HTML5 mobile app framework. * http://ionicframework.com/ * @@ -12,5 +12,5 @@ * */ -function $LocationDecorator(e,t){return e.__hash=e.hash,e.hash=function(n){return angular.isDefined(n)&&t(function(){var e=document.querySelector(".scroll-content");e&&(e.scrollTop=0)},0,!1),e.__hash(n)},e}angular.module("ionic.service",["ionic.service.bind","ionic.service.platform","ionic.service.actionSheet","ionic.service.gesture","ionic.service.loading","ionic.service.modal","ionic.service.popup","ionic.service.templateLoad","ionic.service.view","ionic.decorator.location"]),angular.module("ionic.ui.service",["ionic.ui.service.scrollDelegate","ionic.ui.service.slideBoxDelegate","ionic.ui.service.sideMenuDelegate"]),angular.module("ionic.ui",["ionic.ui.content","ionic.ui.scroll","ionic.ui.tabs","ionic.ui.viewState","ionic.ui.header","ionic.ui.sideMenu","ionic.ui.slideBox","ionic.ui.list","ionic.ui.checkbox","ionic.ui.toggle","ionic.ui.radio","ionic.ui.touch","ionic.ui.popup"]),angular.module("ionic",["ionic.service","ionic.ui.service","ionic.ui","ngAnimate","ngSanitize","ui.router"]),angular.element.prototype.addClass=function(e){var t,n,i,o,r,a;if(e&&"ng-scope"!=e&&"ng-isolate-scope"!=e)for(t=0;t')(c),s=angular.element(l[0].querySelector(".action-sheet-wrapper")),u=function(e){s.removeClass("action-sheet-up"),e&&o(function(){r.cancel()},200),i.removeClass(l,"active",function(){c.$destroy()}),t[0].body.classList.remove("action-sheet-open"),c.$deregisterBackButton&&c.$deregisterBackButton()};c.$deregisterBackButton=a.registerBackButtonAction(function(){u()},300),c.cancel=function(){u(!0)},c.buttonClicked=function(e){(r.buttonClicked&&r.buttonClicked(e))===!0&&u(!1)},c.destructiveButtonClicked=function(){(r.destructiveButtonClicked&&r.destructiveButtonClicked())===!0&&u(!1)},t[0].body.appendChild(l[0]),t[0].body.classList.add("action-sheet-open");var d=new ionic.views.ActionSheet({el:l[0]});return c.sheet=d,i.addClass(l,"active"),o(function(){s.addClass("action-sheet-up")},20),d}}}]),angular.module("ionic.service.bind",[]).factory("$ionicBind",["$parse","$interpolate",function(e,t){var n=/^\s*([@=&])(\??)\s*(\w*)\s*$/;return function(i,o,r){angular.forEach(r||{},function(r,a){var c,l,s=r.match(n)||[],u=s[3]||a,d=s[1];switch(d){case"@":if(!o[u])return;o.$observe(u,function(e){i[a]=e}),o[u]&&(i[a]=t(o[u])(i));break;case"=":if(!o[u])return;l=i.$watch(o[u],function(e){i[a]=e}),i.$on("$destroy",l);break;case"&":if(o[u]&&o[u].match(RegExp(a+"(.*?)")))throw new Error('& expression binding "'+a+'" looks like it will recursively call "'+o[u]+'" and cause a stack overflow! Please choose a different scopeName.');c=e(o[u]),i[a]=function(e){return c(i,e)}}})}}]),angular.module("ionic.service.gesture",[]).factory("$ionicGesture",[function(){return{on:function(e,t,n){return window.ionic.onGesture(e,t,n[0])},off:function(e,t,n){return window.ionic.offGesture(e,t,n)}}}]),angular.module("ionic.service.loading",["ionic.ui.loading"]).factory("$ionicLoading",["$rootScope","$document","$compile",function(e,t,n){return{show:function(i){var o={content:"",animation:"fade-in",showBackdrop:!0,maxWidth:200,showDelay:0};i=angular.extend(o,i);var r=e.$new(!0);angular.extend(r,i);var a=angular.element(t[0].querySelector(".loading-backdrop"));a.length&&a.remove();var c=n(""+i.content+"")(r);t[0].body.appendChild(c[0]);var l=new ionic.views.Loading({el:c[0],maxWidth:i.maxWidth,showDelay:i.showDelay});return l.show(),r.loading=l,l}}}]),angular.module("ionic.service.modal",["ionic.service.templateLoad","ionic.service.platform","ionic.ui.modal"]).factory("$ionicModal",["$rootScope","$document","$compile","$timeout","$ionicPlatform","$ionicTemplateLoader",function(e,t,n,i,o,r){var a=ionic.views.Modal.inherit({initialize:function(e){ionic.views.Modal.prototype.initialize.call(this,e),this.animation=e.animation||"slide-in-up"},show:function(){var e=this,n=angular.element(e.modalEl);e.el.classList.remove("hide"),t[0].body.classList.add("modal-open"),e._isShown=!0,e.el.parentElement||(n.addClass(e.animation),t[0].body.appendChild(e.el)),n.addClass("ng-enter active").removeClass("ng-leave ng-leave-active"),i(function(){n.addClass("ng-enter-active"),e.scope.$parent&&e.scope.$parent.$broadcast("modal.shown"),e.el.classList.add("active")},20),e._deregisterBackButton=o.registerBackButtonAction(function(){e.hide()},200),ionic.views.Modal.prototype.show.call(e)},hide:function(){var e=this;e._isShown=!1;var n=angular.element(e.modalEl);e.el.classList.remove("active"),n.addClass("ng-leave"),i(function(){n.addClass("ng-leave-active").removeClass("ng-enter ng-enter-active active")},20),i(function(){t[0].body.classList.remove("modal-open"),e.el.classList.add("hide")},350),ionic.views.Modal.prototype.hide.call(e),e.scope.$parent&&e.scope.$parent.$broadcast("modal.hidden"),e._deregisterBackButton&&e._deregisterBackButton()},remove:function(){var e=this;e.hide(),e.scope.$parent&&e.scope.$parent.$broadcast("modal.removed"),i(function(){e.scope.$destroy(),e.el&&e.el.parentElement&&e.el.parentElement.removeChild(e.el)},750)},isShown:function(){return!!this._isShown}}),c=function(t,i){var o=i.scope&&i.scope.$new()||e.$new(!0),r=n(""+t+"")(o);i.el=r[0],i.modalEl=i.el.querySelector(".modal");var c=new a(i);return c.scope=o,i.scope||(o.modal=c),c};return{fromTemplate:function(e,t){var n=c(e,t||{});return n},fromTemplateUrl:function(e,t,n){var i;return angular.isFunction(t)&&(i=t,t=n),r.load(e).then(function(e){var n=c(e,t||{});return i&&i(n),n})}}}]),function(e){"use strict";angular.module("ionic.service.platform",[]).provider("$ionicPlatform",function(){return{$get:["$q","$rootScope",function(t,n){return{onHardwareBackButton:function(t){e.Platform.ready(function(){document.addEventListener("backbutton",t,!1)})},offHardwareBackButton:function(t){e.Platform.ready(function(){document.removeEventListener("backbutton",t)})},registerBackButtonAction:function(t,i,o){var r=this;r._hasBackButtonHandler||(n.$backButtonActions={},r.onHardwareBackButton(r.hardwareBackButtonClick),r._hasBackButtonHandler=!0);var a={id:o?o:e.Utils.nextUid(),priority:i?i:0,fn:t};return n.$backButtonActions[a.id]=a,function(){delete n.$backButtonActions[a.id]}},hardwareBackButtonClick:function(e){var t,i;for(i in n.$backButtonActions)(!t||n.$backButtonActions[i].priority>=t.priority)&&(t=n.$backButtonActions[i]);return t?(t.fn(e),t):void 0},is:function(t){return e.Platform.is(t)},ready:function(n){var i=t.defer();return e.Platform.ready(function(){i.resolve(),n()}),i.promise}}}]}})}(ionic),function(e){"use strict";angular.module("ionic.service.popup",["ionic.service.templateLoad"]).factory("$ionicPopup",["$rootScope","$q","$document","$compile","$timeout","$ionicTemplateLoader",function(t,n,i,o,r,a){var c={stackPushDelay:50},l=function(e){e.el.style.marginLeft=-e.el.offsetWidth/2+"px",e.el.style.marginTop=-e.el.offsetHeight/2+"px"},s=function(e){var t=e.el.querySelector(".popup-body");t&&""==t.innerHTML.trim()&&(t.style.display="none")},u=function(t){e.requestAnimationFrame(function(){s(t),l(t),t.el.classList.remove("popup-hidden"),t.el.classList.add("popup-showing"),t.el.classList.add("active")})},d=function(t){e.requestAnimationFrame(function(){t.el.classList.remove("popup-hidden"),t.el.classList.add("popup-showing"),t.el.classList.add("active")})},f=function(t){e.requestAnimationFrame(function(){t.el.classList.remove("active"),t.el.classList.add("popup-hidden")})},v=function(e){e.el.offsetWidth,e.el.classList.remove("active"),e.el.classList.add("popup-hidden"),r(function(){e.el.remove()},400)},p=[],g=null,h=function(){var e=o("")(t.$new(!0));i[0].body.appendChild(e[0]),g=e},m=function(){g.remove()},$=function(e){var t=p[p.length-1];p.push(e),1==p.length&&h(),t?(f(t),r(function(){u(e)},c.stackPushDelay)):u(e)},b=function(){var e=p.pop(),t=p[p.length-1];v(e),t?d(t):m()},w=function(e,t){var n={el:e[0],scope:t};return t.popup=n,n},y=function(e,t){return''+(t||"")+""},k=function(e,r){var c=n.defer(),l={title:"",animation:"fade-in"};e=angular.extend(l,e);var s=e.scope&&e.scope.$new()||t.$new(!0);if(angular.extend(s,e),s.onClose=function(e,t){b(s.popup),r.resolve(t)},e.templateUrl)a.load(e.templateUrl).then(function(t){var n=y(e,t),r=o(n)(s);i[0].body.appendChild(r[0]),c.resolve(w(r,s))},function(e){c.reject(e)});else{var u=y(e,e.content),d=o(u)(s);i[0].body.appendChild(d[0]),c.resolve(w(d,s))}return c.promise};return{showPopup:function(e){var t=n.defer();return k(e,t).then(function(t){$(t,e)},function(e){console.error("Unable to load popup:",e)}),t.promise},show:function(e){return this.showPopup(e)},alert:function(e){return this.showPopup({content:e.content||"",title:e.title||"",buttons:[{text:e.okText||"OK",type:e.okType||"button-positive",onTap:function(){return!0}}]})},confirm:function(e){return this.showPopup({content:e.content||"",title:e.title||"",buttons:[{text:e.cancelText||"Cancel",type:e.cancelType||"button-default",onTap:function(e){e.preventDefault()}},{text:e.okText||"OK",type:e.okType||"button-positive",onTap:function(){return!0}}]})},prompt:function(e){var n=t.$new(!0);return n.data={},this.showPopup({content:e.content||'',title:e.title||"",subTitle:e.subTitle||"",scope:n,buttons:[{text:e.cancelText||"Cancel",type:e.cancelType||"button-default",onTap:function(e){e.preventDefault()}},{text:e.okText||"OK",type:e.okType||"button-positive",onTap:function(){return n.data.response}}]})}}}])}(ionic),angular.module("ionic.service.templateLoad",[]).factory("$ionicTemplateLoader",["$q","$http","$templateCache",function(e,t,n){return{load:function(e){return t.get(e,{cache:n}).then(function(e){return e.data&&e.data.trim()})}}}]),angular.module("ionic.service.view",["ui.router","ionic.service.platform"]).run(["$rootScope","$state","$location","$document","$animate","$ionicPlatform",function(e,t,n,i,o,r){function a(t){return e.$viewHistory.backView?e.$viewHistory.backView.go():ionic.Platform.exitApp(),t.preventDefault(),!1}e.$viewHistory={histories:{root:{historyId:"root",parentHistoryId:null,stack:[],cursor:-1}},views:{},backView:null,forwardView:null,currentView:null,disabledRegistrableTagNames:[]},e.$on("viewState.changeHistory",function(i,o){if(o){var r=o.historyId?e.$viewHistory.histories[o.historyId]:null;if(r&&r.cursor>-1&&r.cursor-1&&c.stack.length>0&&c.cursor=u.index;p--)v.stack[p].destroy(),v.stack.splice(p)}}else d.navAction="initialView";o.views[d.viewId]=this.createView({viewId:d.viewId,index:c.stack.length,historyId:c.historyId,backViewId:l&&l.viewId?l.viewId:null,forwardViewId:null,stateId:a,stateName:this.getCurrentStateName(),stateParams:this.getCurrentStateParams(),url:n.url(),scrollValues:null}),c.stack.push(o.views[d.viewId])}return this.setNavViews(d.viewId),c.cursor=o.currentView.index,d},setNavViews:function(t){var n=e.$viewHistory;n.currentView=this._getViewById(t),n.backView=this._getBackView(n.currentView),n.forwardView=this._getForwardView(n.currentView),e.$broadcast("$viewHistory.historyChange",{showBack:n.backView&&n.backView.historyId===n.currentView.historyId})},registerHistory:function(e){e.$historyId=ionic.Utils.nextUid()},createView:function(e){var t=new c;return t.initialize(e)},getCurrentView:function(){return e.$viewHistory.currentView},getBackView:function(){return e.$viewHistory.backView},getForwardView:function(){return e.$viewHistory.forwardView},getNavDirection:function(){return e.$viewHistory.navDirection},getCurrentStateName:function(){return t&&t.current?t.current.name:null},isCurrentStateNavView:function(e){return t&&t.current&&t.current.views&&t.current.views[e]?!0:!1},getCurrentStateParams:function(){var e;if(t&&t.params)for(var n in t.params)t.params.hasOwnProperty(n)&&(e=e||{},e[n]=t.params[n]);return e},getCurrentStateId:function(){var e;if(t&&t.current&&t.current.name){if(e=t.current.name,t.params)for(var n in t.params)t.params.hasOwnProperty(n)&&t.params[n]&&(e+="_"+n+"="+t.params[n]);return e}return ionic.Utils.nextUid()},goToHistoryRoot:function(t){if(t){var n=e.$viewHistory.histories[t];if(n&&n.stack.length){if(e.$viewHistory.currentView&&e.$viewHistory.currentView.viewId===n.stack[0].viewId)return;e.$viewHistory.forcedNav={viewId:n.stack[0].viewId,navAction:"moveBack",navDirection:"back"},n.stack[0].go()}}},_getViewById:function(t){return t?e.$viewHistory.views[t]:null},_getBackView:function(e){return e?this._getViewById(e.backViewId):null},_getForwardView:function(e){return e?this._getViewById(e.forwardViewId):null},_getHistoryById:function(t){return t?e.$viewHistory.histories[t]:null},_getHistory:function(t){var n=this._getParentHistoryObj(t);return e.$viewHistory.histories[n.historyId]||(e.$viewHistory.histories[n.historyId]={historyId:n.historyId,parentHistoryId:this._getParentHistoryObj(n.scope.$parent).historyId,stack:[],cursor:-1}),e.$viewHistory.histories[n.historyId]},_getParentHistoryObj:function(t){for(var n=t;n;){if(n.hasOwnProperty("$historyId"))return{historyId:n.$historyId,scope:n};n=n.$parent}return{historyId:"root",scope:e}},getRenderer:function(e,t,n){function i(e){for(var t="";!t&&e;)t=e.getAttribute("animation"),e=e.parentElement;return t}function o(){s&&e[0].classList.add(s),"back"===r.navDirection?e[0].classList.add("reverse"):e[0].classList.remove("reverse")}var r,c,l=this,s=angular.isDefined(n.$nextAnimation)?n.$nextAnimation:i(e[0]);return n.$nextAnimation=void 0,function(t){return{enter:function(n){return c&&t?(o(),n.addClass("ng-enter"),document.body.classList.add("disable-pointer-events"),void a.enter(n,e,null,function(){document.body.classList.remove("disable-pointer-events"),s&&e[0].classList.remove(s)})):void e.append(n)},leave:function(){var n=e.contents();return c&&t?(o(),void a.leave(n,function(){n.remove()})):void n.remove()},register:function(e){return r=l.register(n,e),c=null!==s&&null!==r.navDirection,r}}}},disableRegisterByTagName:function(t){e.$viewHistory.disabledRegistrableTagNames.push(t.toUpperCase())},isTagNameRegistrable:function(t){var n,i,o=e.$viewHistory.disabledRegistrableTagNames;for(n=0;n
{{titleText}}
'}}])}(),function(e){"use strict";angular.module("ionic.ui.header",["ngAnimate","ngSanitize"]).directive("barHeader",["$ionicScrollDelegate",function(e){return{restrict:"C",link:function(t,n){e.tapScrollToTop(n)}}}]).directive("ionHeaderBar",["$ionicScrollDelegate",function(){return{restrict:"E",replace:!0,transclude:!0,template:'

',scope:{leftButtons:"=",rightButtons:"=",title:"@",type:"@",alignTitle:"@"},link:function(t,n){var i=new e.views.HeaderBar({el:n[0],alignTitle:t.alignTitle||"center"});n.addClass(t.type),t.headerBarView=i,t.$watchCollection("leftButtons",function(){i.align()}),t.$watchCollection("rightButtons",function(){i.align()}),t.$watch("title",function(){i.align()})}}}]).directive("ionFooterBar",function(){return{restrict:"E",replace:!0,transclude:!0,template:'
',scope:{type:"@"},link:function(e,t){t.addClass(e.type)}}})}(ionic),function(){"use strict";angular.module("ionic.ui.checkbox",[]).directive("ionCheckbox",function(){return{restrict:"E",replace:!0,require:"?ngModel",scope:{ngModel:"=?",ngValue:"=?",ngChecked:"=?",ngChange:"&"},transclude:!0,template:'
',compile:function(e,t){var n=e.find("input");t.name&&n.attr("name",t.name),t.ngChecked&&n.attr("ng-checked","ngChecked"),t.ngTrueValue&&n.attr("ng-true-value",t.ngTrueValue),t.ngFalseValue&&n.attr("ng-false-value",t.ngFalseValue)}}})}(),function(){"use strict";angular.module("ionic.ui.content",["ionic.ui.service","ionic.ui.scroll"]).directive("ionPane",function(){return{restrict:"E",link:function(e,t){t.addClass("pane")}}}).directive("ionContent",["$parse","$timeout","$ionicScrollDelegate","$controller","$ionicBind",function(e,t,n,i,o){return{restrict:"E",replace:!0,transclude:!0,require:"^?ionNavView",scope:!0,template:'
',compile:function(e,n,r){function a(e,a,c){var l,s,u=angular.element(a[0].querySelector(".scroll"));o(e,c,{$onScroll:"&onScroll",$onScrollComplete:"&onScrollComplete",hasBouncing:"@",scroll:"@",padding:"@",hasScrollX:"@",hasScrollY:"@",scrollbarX:"@",scrollbarY:"@",startX:"@",startY:"@",scrollEventInterval:"@"}),"false"===e.scroll||("true"===n.overflowScroll?a.addClass("overflow-scroll"):(s=i("$ionicScroll",{$scope:e,scrollViewOptions:{el:a[0],bouncing:e.$eval(e.hasBouncing),startX:e.$eval(e.startX)||0,startY:e.$eval(e.startY)||0,scrollbarX:e.$eval(e.scrollbarX)!==!1,scrollbarY:e.$eval(e.scrollbarY)!==!1,scrollingX:e.$eval(e.hasScrollX)===!0,scrollingY:e.$eval(e.hasScrollY)!==!1,scrollEventInterval:parseInt(e.scrollEventInterval,10)||20,scrollingComplete:function(){e.$onScrollComplete({scrollTop:this.__scrollTop,scrollLeft:this.__scrollLeft})}}}),l=e.$parent.scrollView=s.scrollView,e.$on("$viewContentLoaded",function(n,i){i||(i={});var o=i.scrollValues;o&&t(function(){l.scrollTo(+o.left||null,+o.top||null)},0),e.$on("$destroy",function(){i.scrollValues=l.getValues()})}))),r(e,function(e){s&&e.data("$$ionicScrollController",s),u.append(e)})}return"true"==n.hasHeader&&e.addClass("has-header"),"true"==n.hasSubheader&&e.addClass("has-subheader"),"true"==n.hasFooter&&e.addClass("has-footer"),"true"==n.hasTabs&&e.addClass("has-tabs"),"true"==n.padding&&e.find("div").addClass("padding"),{pre:a}}}}]).directive("ionRefresher",["$ionicBind",function(e){return{restrict:"E",replace:!0,require:"^$ionicScroll",template:'
',compile:function(t,n){return angular.isUndefined(n.pullingIcon)&&n.$set("pullingIcon","ion-arrow-down-c"),angular.isUndefined(n.refreshingIcon)&&n.$set("refreshingIcon","ion-loading-d"),function(t,n,i,o){e(t,i,{pullingIcon:"@",pullingText:"@",refreshingIcon:"@",refreshingText:"@",$onRefresh:"&onRefresh",$onPulling:"&onPulling"}),o.setRefresher(t,n[0]),t.$on("scroll.refreshComplete",function(){n[0].classList.remove("active"),o.scrollView.finishPullToRefresh()})}}}}]).directive("ionInfiniteScroll",["$timeout",function(e){return{restrict:"E",require:["^$ionicScroll","ionInfiniteScroll"],template:'
',scope:!0,controller:["$scope","$attrs",function(e,t){this.isLoading=!1,this.scrollView=null,this.getMaxScroll=function(){var e=t.distance||"1%";return e.indexOf("%")>-1?this.scrollView.getScrollMax().top*(1-parseInt(e,10)/100):this.scrollView.getScrollMax().top-parseInt(e,10)}}],link:function(t,n,i,o){var r=o[0],a=o[1],c=a.scrollView=r.scrollView;t.icon=function(){return angular.isDefined(i.icon)?i.icon:"ion-loading-d"},t.$on("scroll.infiniteScrollComplete",function(){n[0].classList.remove("active"),e(function(){c.resize()},0,!1),a.isLoading=!1}),r.$element.on("scroll",ionic.animationFrameThrottle(function(){!a.isLoading&&c.getValues().top>=a.getMaxScroll()&&(n[0].classList.add("active"),a.isLoading=!0,t.$parent.$apply(i.onInfinite||""))}))}}}])}(),function(){"use strict";angular.module("ionic.ui.list",["ngAnimate"]).directive("ionItem",["$timeout","$parse",function(){return{restrict:"E",require:"?^ionList",replace:!0,transclude:!0,scope:{item:"=",itemType:"@",canDelete:"@",canReorder:"@",canSwipe:"@",onDelete:"&",optionButtons:"&",deleteIcon:"@",reorderIcon:"@"},template:'
',link:function(e,t,n,i){if(i){var o=i.scope,r=i.attrs;n.$observe("href",function(t){t&&(e.href=t.trim())}),e.itemType||(e.itemType=o.itemType),t.addClass(e.itemType||o.itemType),e.itemClass=e.itemType,"false"!==(n.canDelete?e.canDelete:o.canDelete)&&(n.onDelete||r.onDelete)&&(e.deleteClick=function(){n.onDelete?e.onDelete({item:e.item}):r.onDelete&&o.onDelete({item:e.item})},e.deleteIconClass=e.deleteIcon||o.deleteIcon||"ion-minus-circled"),"true"===(n.canReorder?e.canReorder:o.canReorder)&&(e.reorderIconClass=e.reorderIcon||o.reorderIcon||"ion-navicon"),"false"!==(n.canSwipe?e.canSwipe:o.canSwipe)&&(e.itemOptionButtons=e.optionButtons(),"undefined"==typeof e.itemOptionButtons&&(e.itemOptionButtons=o.optionButtons()))}}}}]).directive("ionList",["$timeout",function(e){return{restrict:"E",replace:!0,transclude:!0,require:"^?$ionicScroll",scope:{itemType:"@",canDelete:"@",canReorder:"@",canSwipe:"@",showDelete:"=",showReorder:"=",onDelete:"&",onReorder:"&",optionButtons:"&",deleteIcon:"@",reorderIcon:"@"},template:"
",controller:["$scope","$attrs",function(e,t){this.scope=e,this.attrs=t}],link:function(t,n,i,o){t.listView=new ionic.views.ListView({el:n[0],listEl:n[0].children[0],scrollEl:o&&o.element,scrollView:o&&o.scrollView,onReorder:function(e,n,i){t.$apply(function(){t.onReorder({el:e,start:n,end:i})})}}),i.animation&&n[0].classList.add(i.animation);var r=t.$watch("showReorder",function(t){t?n[0].classList.add("item-options-hide"):t===!1&&e(function(){n[0].classList.remove("item-options-hide")},250)});t.$on("$destroy",function(){r()})}}}])}(),function(){"use strict";angular.module("ionic.ui.loading",[]).directive("ionLoading",function(){return{restrict:"E",replace:!0,transclude:!0,link:function(e,t){t.addClass(e.animation||"")},template:'
'}})}(),function(){"use strict";angular.module("ionic.ui.modal",[]).directive("ionModal",[function(){return{restrict:"E",transclude:!0,replace:!0,template:''}}])}(),function(){angular.module("ionic.ui.navAnimation",[]).directive("ionNavAnimation",function(){return{restrict:"A",require:"^?ionNavView",link:function(e,t,n,i){i&&ionic.on("tap",function(){i.setNextAnimation(n.ionNavAnimation)},t[0])}}})}(),function(){"use strict";angular.module("ionic.ui.popup",[]).directive("ionPopupBackdrop",function(){return{restrict:"E",replace:!0,template:''}}).directive("ionPopup",["$ionicBind",function(e){return{restrict:"E",replace:!0,transclude:!0,scope:!0,link:function(t,n,i){e(t,i,{title:"@",buttons:"=",$onButtonTap:"&onButtonTap",$onClose:"&onClose"}),t._buttonTapped=function(e,n){var i=e.onTap&&e.onTap(n); -return n.defaultPrevented?t.$onClose({button:e,result:!1,event:n}):i?t.$onClose({button:e,result:i,event:n}):void t.$onButtonTap({button:e,event:n})}},template:''}}])}(),function(e){"use strict";angular.module("ionic.ui.radio",[]).directive("ionRadio",function(){return{restrict:"E",replace:!0,require:"?ngModel",scope:{ngModel:"=?",ngValue:"=?",ngChange:"&",icon:"@"},transclude:!0,template:'',compile:function(e,t){t.name&&e.children().eq(0).attr("name",t.name),t.icon&&e.children().eq(2).removeClass("ion-checkmark").addClass(t.icon)}}}).directive("ionRadioButtons",function(){return{restrict:"E",replace:!0,require:"?ngModel",scope:{value:"@"},transclude:!0,template:'
',controller:["$scope","$element",function(e,t){this.select=function(e){for(var n,i=t.children(),o=0;o
',transclude:!0,scope:{direction:"@",paging:"@",onRefresh:"&",onScroll:"&",scroll:"@",scrollbarX:"@",scrollbarY:"@"},controller:function(){},compile:function(e,t){function i(e,i){var o,r,a=i[0].children[0];"true"==t.padding&&a.classList.add("padding"),e.$eval(e.paging)===!0&&a.classList.add("scroll-paging"),e.direction||(e.direction="y");var c=e.$eval(e.paging)===!0,l={el:i[0],paging:c,scrollbarX:e.$eval(e.scrollbarX)!==!1,scrollbarY:e.$eval(e.scrollbarY)!==!1,scrollingX:e.direction.indexOf("x")>=0,scrollingY:e.direction.indexOf("y")>=0};c&&(l.speedMultiplier=.8,l.bouncing=!1),r=n("$ionicScroll",{$scope:e,scrollViewOptions:l}),o=e.$parent.scrollView=r.scrollView}return{pre:i}}}}])}(),function(){"use strict";angular.module("ionic.ui.sideMenu",["ionic.service.gesture","ionic.service.view"]).run(["$ionicViewService",function(e){e.disableRegisterByTagName("ion-side-menus")}]).directive("ionSideMenus",function(){return{restrict:"ECA",controller:["$scope","$attrs","$parse",function(e,t,n){angular.extend(this,ionic.controllers.SideMenuController.prototype),ionic.controllers.SideMenuController.call(this,{left:{width:275},right:{width:275}}),e.sideMenuContentTranslateX=0,n(t.model||"sideMenuController").assign(e,this)}],replace:!0,transclude:!0,template:'
'}}).directive("ionSideMenuContent",["$timeout","$ionicGesture",function(e,t){return{restrict:"AC",require:"^ionSideMenus",scope:!0,compile:function(n,i){return function(n,o,r,a){function c(e){0!==a.getOpenAmount()&&(a.close(),e.gesture.srcEvent.preventDefault())}o.addClass("menu-content"),angular.isDefined(i.dragContent)?n.$watch(i.dragContent,function(e){n.dragContent=e}):n.dragContent=!0;var l=!1,s=!1;ionic.on("tap",c,o[0]);var u=function(e){if(n.dragContent){if(l||e.gesture.srcEvent.defaultPrevented)return;s=!0,a._handleDrag(e),e.gesture.srcEvent.preventDefault()}},d=function(e){s&&e.gesture.srcEvent.preventDefault()},f=t.on("dragright",u,o),v=t.on("dragleft",u,o),p=t.on("dragup",d,o),g=t.on("dragdown",d,o),h=function(e){s=!1,l||a._endDrag(e),l=!1},m=t.on("release",h,o);a.setContent({onDrag:function(){},endDrag:function(){},getTranslateX:function(){return n.sideMenuContentTranslateX||0},setTranslateX:ionic.animationFrameThrottle(function(t){o[0].style[ionic.CSS.TRANSFORM]="translate3d("+t+"px, 0, 0)",e(function(){n.sideMenuContentTranslateX=t})}),enableAnimation:function(){n.animationEnabled=!0,o[0].classList.add("menu-animated")},disableAnimation:function(){n.animationEnabled=!1,o[0].classList.remove("menu-animated")}}),n.$on("$destroy",function(){t.off(v,"dragleft",u),t.off(f,"dragright",u),t.off(p,"dragup",u),t.off(g,"dragdown",u),t.off(m,"release",h),ionic.off("tap",c,o[0])})}}}}]).directive("ionSideMenu",function(){return{restrict:"E",require:"^ionSideMenus",replace:!0,transclude:!0,scope:!0,template:'',compile:function(e,t,n){return angular.isUndefined(t.isEnabled)&&t.$set("isEnabled","true"),angular.isUndefined(t.width)&&t.$set("width","275"),function(e,t,i,o){e.side=i.side||"left";var r=o[e.side]=new ionic.views.SideMenu({width:275,el:t[0],isEnabled:!0});e.$watch(i.width,function(e){var t=+e;t&&t==e&&r.setWidth(+e)}),e.$watch(i.isEnabled,function(e){r.setIsEnabled(!!e)}),n(e,function(e){t.append(e)})}}}})}(),function(){"use strict";angular.module("ionic.ui.slideBox",[]).directive("ionSlideBox",["$timeout","$compile","$ionicSlideBoxDelegate",function(e,t,n){return{restrict:"E",replace:!0,transclude:!0,scope:{doesContinue:"@",slideInterval:"@",showPager:"@",disableScroll:"@",onSlideChanged:"&",activeSlide:"=?"},controller:["$scope","$element","$attrs","$parse",function(t,i,o,r){var a=t.$eval(t.doesContinue)===!0,c=a?t.$eval(t.slideInterval)||4e3:0,l=new ionic.views.Slider({el:i[0],auto:c,disableScroll:t.$eval(t.disableScroll)===!0||!1,continuous:a,startSlide:t.activeSlide,slidesChanged:function(){t.currentSlide=l.currentIndex(),e(function(){})},callback:function(n){t.currentSlide=n,t.onSlideChanged({index:t.currentSlide}),t.$parent.$broadcast("slideBox.slideChanged",n),t.activeSlide=n,e(function(){})}});t.$watch("activeSlide",function(e){angular.isDefined(e)&&l.slide(e)}),t.$on("slideBox.nextSlide",function(){l.next()}),t.$on("slideBox.prevSlide",function(){l.prev()}),t.$on("slideBox.setSlide",function(e,t){l.slide(t)}),r(o.model||"slideBoxController").assign(t.$parent,l),n.register(t,i),this.slidesCount=function(){return l.slidesCount()},e(function(){l.load()})}],template:'
',link:function(e,n){if(e.$eval(e.showPager)!==!1){var i=e.$new(),o=angular.element("");n.append(o),t(o)(i)}}}}]).directive("ionSlide",function(){return{restrict:"E",require:"^ionSlideBox",compile:function(e){return e.addClass("slider-slide"),function(){}}}}).directive("ionPager",function(){return{restrict:"E",replace:!0,require:"^ionSlideBox",template:'
',link:function(e,t,n,i){var o=function(e){for(var n=t[0].children,i=n.length,o=0;i>o;o++)o==e?n[o].classList.add("active"):n[o].classList.remove("active")};e.numSlides=function(){return new Array(i.slidesCount())},e.$watch("currentSlide",function(e){o(e)})}}})}(),angular.module("ionic.ui.tabs",["ionic.service.view"]).run(["$ionicViewService",function(e){e.disableRegisterByTagName("ion-tabs")}]).controller("ionicTabs",["$scope","$ionicViewService","$element",function(e,t){var n=null,i=this;i.tabs=[],i.selectedTabIndex=function(){return i.tabs.indexOf(n)},i.selectedTab=function(){return n},i.add=function(e){t.registerHistory(e),i.tabs.push(e),1===i.tabs.length&&i.select(e)},i.remove=function(e){var t=i.tabs.indexOf(e);if(-1!==t){if(e.$tabSelected)if(i.deselect(e),1===i.tabs.length);else{var n=t===i.tabs.length-1?t-1:t+1;i.select(i.tabs[n])}i.tabs.splice(t,1)}},i.deselect=function(e){e.$tabSelected&&(n=null,e.$tabSelected=!1,(e.onDeselect||angular.noop)())},i.select=function(o,r){var a;if(angular.isNumber(o)?(a=o,o=i.tabs[a]):a=i.tabs.indexOf(o),!o||-1==a)throw new Error('Cannot select tab "'+a+'"!');if(n&&n.$historyId==o.$historyId)r&&t.goToHistoryRoot(o.$historyId);else if(angular.forEach(i.tabs,function(e){i.deselect(e)}),n=o,o.$tabSelected=!0,(o.onSelect||angular.noop)(),r){var c={type:"tab",tabIndex:a,historyId:o.$historyId,navViewName:o.navViewName,hasNavView:!!o.navViewName,title:o.title,url:o.href,uiSref:o.uiSref};e.$emit("viewState.changeHistory",c)}}}]).directive("ionTabs",["$ionicViewService","$ionicBind","$parse",function(e,t,n){return{restrict:"E",replace:!0,scope:!0,transclude:!0,controller:"ionicTabs",template:'
',compile:function(e,i,o){return angular.isUndefined(i.tabsType)&&i.$set("tabsType","tabs-positive"),function(e,r,a,c){t(e,a,{$animation:"@animation",$tabsStyle:"@tabsStyle",$tabsType:"@tabsType"}),n(i.model||"tabsController").assign(e,c),c.$scope=e,c.$element=r,c.$tabsElement=angular.element(r[0].querySelector(".tabs")),o(e,function(e){r.append(e)})}}}}]).controller("ionicTab",["$scope","$ionicViewService","$rootScope","$element",function(e){this.$scope=e}]).directive("ionTab",["$rootScope","$animate","$ionicBind","$compile","$ionicViewService",function(e,t,n,i,o){function r(e,t){return angular.isDefined(t)?" "+e+'="'+t+'"':""}return{restrict:"E",require:["^ionTabs","ionTab"],replace:!0,controller:"ionicTab",scope:!0,compile:function(e,a){var c=e[0].querySelector("ion-nav-view")||e[0].querySelector("data-ion-nav-view"),l=c&&c.getAttribute("name"),s=angular.element('
').append(e.contents().remove());return function(e,c,u,d){function f(){o.isCurrentStateNavView(e.navViewName)&&tabsCtrl.select(e)}var v,p,g;tabsCtrl=d[0],tabCtrl=d[1],n(e,u,{animate:"=",onSelect:"&",onDeselect:"&",title:"@",uiSref:"@",href:"@"}),tabsCtrl.add(e),e.$on("$destroy",function(){tabsCtrl.remove(e),g.isolateScope().$destroy(),g.remove()}),l&&(e.navViewName=l,e.$on("$stateChangeSuccess",f),f()),g=angular.element(""),g.data("$ionTabsController",tabsCtrl),g.data("$ionTabController",tabCtrl),tabsCtrl.$tabsElement.append(i(g)(e)),e.$watch("$tabSelected",function(n){n||e.$broadcast("tab.hidden",e),v&&v.$destroy(),v=null,p&&t.leave(p),p=null,n&&(v=e.$new(),p=s.clone(),t.enter(p,tabsCtrl.$element),i(p)(v),e.$broadcast("tab.shown",e))})}}}}]).directive("ionTabNav",["$ionicNgClick",function(e){return{restrict:"E",replace:!0,require:["^ionTabs","^ionTab"],template:'{{badge}}',scope:{title:"@",icon:"@",iconOn:"@",iconOff:"@",badge:"=",badgeStyle:"@"},compile:function(){return function(t,n,i,o){var r=o[0],a=o[1];t.selectTab=function(e){e.preventDefault(),r.select(a.$scope,!0)},i.ngClick||e(t,n,"selectTab($event)"),t.getIconOn=function(){return t.iconOn||t.icon},t.getIconOff=function(){return t.iconOff||t.icon},t.isTabActive=function(){return r.selectedTab()===a.$scope}}}}}]),function(e){"use strict";angular.module("ionic.ui.toggle",[]).directive("ionToggle",["$ionicGesture","$timeout",function(){return{restrict:"E",replace:!0,require:"?ngModel",scope:{ngModel:"=?",ngValue:"=?",ngChecked:"=?",ngChange:"&",ngDisabled:"=?"},transclude:!0,template:'
',compile:function(t,n){var i=t.find("input");return n.name&&i.attr("name",n.name),n.ngChecked&&i.attr("ng-checked","ngChecked"),n.ngTrueValue&&i.attr("ng-true-value",n.ngTrueValue),n.ngFalseValue&&i.attr("ng-false-value",n.ngFalseValue),function(t,n){var i,o,r,a;i=n[0].getElementsByTagName("label")[0],o=i.children[0],r=i.children[1],a=r.children[0];var c=angular.element(o).controller("ngModel");t.toggle=new e.views.Toggle({el:i,track:r,checkbox:o,handle:a,onChange:function(){c.$setViewValue(o.checked?!0:!1),t.$apply()}}),t.$on("$destroy",function(){t.toggle.destroy()})}}}}])}(window.ionic),function(e,t){"use strict";e.module("ionic.ui.touch",[]).config(["$provide",function(e){e.decorator("ngClickDirective",["$delegate",function(e){return e.shift(),e}])}]).factory("$ionicNgClick",["$parse",function(e){function n(e){t.tapElement(e.target,e)}return function(i,o,r){var a=e(r);o.on("click",function(e){i.$apply(function(){a(i,{$event:e})})}),t.on("tap",n,o[0]),o.onclick=function(){},i.$on("$destroy",function(){t.off("tap",n,o[0])})}}]).directive("ngClick",["$ionicNgClick",function(e){return function(t,n,i){e(t,n,i.ngClick)}}]).directive("ionStopEvent",function(){function e(e){e.stopPropagation()}return{restrict:"A",link:function(t,n,i){n.bind(i.ionStopEvent,e)}}})}(window.angular,window.ionic),function(){"use strict";angular.module("ionic.ui.viewState",["ionic.service.view","ionic.service.gesture","ngSanitize"]).directive("ionNavBar",["$ionicViewService","$rootScope","$animate","$compile",function(e,t,n,i){return{restrict:"E",replace:!0,scope:{animation:"@",type:"@",backType:"@backButtonType",backLabel:"@backButtonLabel",backIcon:"@backButtonIcon",alignTitle:"@"},controller:function(){},template:'',compile:function(){return function(e,t){function o(t){angular.isDefined(t.hideBackButton)&&(e.backButtonEnabled=!!t.hideBackButton),e.isReverse="back"==t.navDirection,e.animateEnabled=!(!t.navDirection||t.animate===!1),e.leftButtons=t.leftButtons,e.rightButtons=t.rightButtons,e.oldTitle=e.title,e.title=t&&t.title||"",e.oldTitle!==e.title&&(e.animateEnabled?r():a.align())}function r(){var o,r,c;c=t[0].querySelectorAll(".title"),c.length&&(o=i('

')(e),angular.element(c[0]).replaceWith(o)),r=i('

')(e),ionic.requestAnimationFrame(function(){o&&n.leave(angular.element(o));var i=o&&angular.element(o)||null;n.enter(r,t,i,function(){a.align()}),angular.forEach(c,function(e){e&&e.parentNode&&angular.element(e).remove()}),e.$digest(),ionic.requestAnimationFrame(function(){r[0].classList.remove("invisible")})})}e.backButtonEnabled=!1,e.animateEnabled=!0,e.isReverse=!1,e.isInvisible=!0,e.navBarClass=function(){return(e.type?" "+e.type:"")+(e.isReverse?" reverse":"")+(e.isInvisible?" invisible":"")+(!e.animationDisabled&&e.animation?" "+e.animation:"")};var a=new ionic.views.HeaderBar({el:t[0],alignTitle:e.alignTitle||"center"});e.headerBarView=a,e.$on("viewState.viewEnter",function(e,t){o(t)}),e.$on("viewState.showNavBar",function(t,n){e.isInvisible=!n});var c=[e.$parent.$on("$viewHistory.historyChange",function(t,n){e.backButtonEnabled=!!n.showBack}),e.$parent.$on("viewState.leftButtonsChanged",function(t,n){e.leftButtons=n}),e.$parent.$on("viewState.rightButtonsChanged",function(t,n){e.rightButtons=n}),e.$parent.$on("viewState.showBackButton",function(t,n){e.backButtonEnabled=!!n}),e.$parent.$on("viewState.titleUpdated",function(t,n){e.title=n&&n.title||""})];e.$on("$destroy",function(){for(var e=0;e {{label}}',link:function(e){e.goBack=t}}}]).directive("ionNavView",["$ionicViewService","$state","$compile","$controller","$animate",function(e,t,n,i,o){var r=!1,a={restrict:"E",terminal:!0,priority:2e3,transclude:!0,controller:["$scope",function(e){this.setNextAnimation=function(t){e.$nextAnimation=t}}],compile:function(c,l,s){return function(c,l,u){function d(r){o.enabled()===!1&&(r=!1);var a=t.$current&&t.$current.locals[p];if(a!==v){var s=e.getRenderer(l,u,c);if(f&&(f.$destroy(),f=null),!a)return v=null,$.state=null,l.append(h);var d=angular.element("
").html(a.$template).contents(),m=s().register(d);s(r).leave(),v=a,$.state=a.$$state,s(r).enter(d);var b=n(d);if(f=c.$new(),f.$navDirection=m.navDirection,a.$$controller){a.$scope=f;var w=i(a.$$controller,a);l.children().data("$ngControllerController",w)}b(f);var y=e._getViewById(m.viewId)||{};f.$broadcast("$viewContentLoaded",y),g&&f.$eval(g),d=null}}var f,v,p=u[a.name]||u.name||"",g=u.onload||"",h=s(c);l.append(h);var m=l.parent().inheritedData("$uiView");p.indexOf("@")<0&&(p=p+"@"+(m?m.state.name:""));var $={name:p,state:null};l.data("$uiView",$);var b=function(){if(!r){r=!0;try{d(!0)}catch(e){throw r=!1,e}r=!1}};c.$on("$stateChangeSuccess",b),c.$on("$viewContentLoading",b),d(!1)}}};return a}])}(),function(){"use strict";angular.module("ionic.ui.virtRepeat",[]).directive("ionVirtRepeat",function(){return{require:["?ngModel","^virtualList"],transclude:"element",priority:1e3,terminal:!0,compile:function(){return function(e,t,n,i){var o=i[1];o.listView.renderViewport=function(){}}}}})}(ionic),function(){"use strict";function e(e){var t=e.match(/^\s*([\$\w]+)\s+in\s+(\S*)\s*$/);if(!t)throw new Error("Expected sfVirtualRepeat in form of '_item_ in _collection_' but got '"+e+"'.");return{value:t[1],collection:t[2]}}function t(e){var t={overflow:"auto"},n=window.getComputedStyle?window.getComputedStyle(e[0]):e[0].currentStyle,i=n&&n.getPropertyValue("max-height"),o=n&&n.getPropertyValue("height");i&&"0px"!==i?t.maxHeight=i:t.height=o&&"0px"!==o?o:window.innerHeight,e.css(t)}function n(e){var t={margin:0,padding:0,border:0,"box-sizing":"border-box"};e.css(t)}function i(e){var t=window.getComputedStyle?window.getComputedStyle(e):e.currentStyle,n=t&&t.getPropertyValue("max-height"),i=t&&t.getPropertyValue("height");if(i&&"0px"!==i&&"auto"!==i)$log.info('Row height is "%s" from css height',i);else if(n&&"0px"!==n&&"none"!==n)i=n,$log.info('Row height is "%s" from css max-height',i);else{if(!e.clientHeight)throw new Error("Unable to compute height of row");i=e.clientHeight+"px",$log.info('Row height is "%s" from client height',i)}return angular.element(e).css("height",i),parseInt(i,10)}angular.module("ionic.ui.virtualRepeat",[]).directive("ionVirtualRepeat",["$log",function(o){return{require:["?ngModel, ^virtualList"],transclude:"element",priority:1e3,terminal:!0,compile:function(r,a){var c=e(a.sfVirtualRepeat);return function(e,r,a,l){function s(e,t,n){var i=n.$new();return i[c.value]=t[e],i.$index=e,i.$first=0===e,i.$last=e===t.length-1,i.$middle=!(i.$first||i.$last),i.$watch(function(){i[c.value]=t[e]}),i}function u(e,t,n,i,o){var r,a,c,l=document.createDocumentFragment(),u=[];for(a=e;a!==t;a++)c=s(a,n,i),r=linker(c,angular.noop),u.push(r),l.appendChild(r[0]);return o.after(l),u}function d(){var e=clip(y.firstActive,y.firstVisible-y.lowWater,y.firstVisible-y.highWater),t=clip(y.firstActive+y.active,y.firstVisible+y.visible+y.lowWater,y.firstVisible+y.visible+y.highWater);y.firstActive=Math.max(0,e),y.active=Math.min(t,y.total)-y.firstActive}function f(t){$&&e.$apply(function(){y.firstVisible=Math.floor(t.target.scrollTop/$),y.visible=Math.ceil(w.viewport[0].clientHeight/$),o.log("scroll to row %o",y.firstVisible),b=t.target.scrollTop+t.target.clientHeight>=t.target.scrollHeight,d(),o.log(" state is now %o",y),o.log(" sticky = %o",b)})}function v(e){var t=e.$eval(c.collection);return t.length!==y.total&&(y.total=t.length,d()),{start:y.firstActive,active:y.active,len:t.length}}function p(e,t){var n,i,o=Array.prototype[e];for(i=0;t>i;i++)n=o.call(m),n.scope().$destroy(),n.remove()}function g(e,t,n){var a,l=t.start+t.active,s=n.$eval(c.collection);if(e===t)o.info("initial listen"),a=u(e.start,l,s,n,r),m=a,m.length&&($=i(a[0][0]));else{var d=e.start+e.active,f=e.start>=t.start,v=f?e.start-t.start:t.start-e.start,g=d>=l?d-l:l-d,h=v<(f?t.active:e.active);if(o.info("change by %o,%o rows %s",v,g,f?"forward":"backward"),h){if(f?(o.info("need to remove from the top"),p("shift",v)):v&&(o.info("need to add at the top"),a=u(e.start,t.start,s,n,r),m=a.concat(m)),l>d)o.info("need to remove from the bottom"),p("pop",l-d);else if(g){var y=m[m.length-1];o.info("need to add to the bottom"),a=u(l,d,s,n,y),m=m.concat(a)}}else o.info("non-contiguous change"),p("pop",m.length),m=u(e.start,d,s,n,r);!$&&m.length&&($=i(m[0][0])),w.content.css({"padding-top":e.start*$+"px"})}w.content.css({height:e.len*$+"px"}),b&&(w.viewport[0].scrollTop=w.viewport[0].clientHeight+w.viewport[0].scrollHeight)}var h=l[1],m=[],$=0,b=!1,w=h.element,y="ngModel"in a?e.$eval(a.ngModel):{};y.firstActive=0,y.firstVisible=0,y.visible=0,y.active=0,y.total=0,y.lowWater=y.lowWater||100,y.highWater=y.highWater||300,n(w.content),t(w.viewport),w.bind("momentumScrolled",f),e.$on("$destroy",function(){w.unbind("momentumScrolled",f)}),e.$watch(v,g,!0)}}}}])}(ionic),function(){"use strict";angular.module("ionic.ui.scroll").controller("$ionicScroll",["$scope","scrollViewOptions","$timeout","$ionicScrollDelegate","$window",function(e,t,n,i,o){function r(){l.resize()}var a=this,c=this.element=t.el,l=this.scrollView=new ionic.views.Scroll(t);angular.isDefined(t.bouncing)||ionic.Platform.ready(function(){l.options.bouncing=!ionic.Platform.isAndroid()});var s=this.$element=angular.element(c);s.data("$$ionicScrollController",this),i.register(e,s,l),o.addEventListener("resize",r),e.$on("$destroy",function(){o.removeEventListener("resize",r)}),this.setRefresher=function(e,t){var n=this.refresher=t,i=a.refresher.clientHeight||0;l.activatePullToRefresh(i,function(){n.classList.add("active"),e.$onPulling()},function(){n.classList.remove("refreshing"),n.classList.remove("active")},function(){n.classList.add("refreshing"),e.$onRefresh()})},n(function(){l.run()})}])}(); \ No newline at end of file +!function(){function e(e){return["$log",function(t){function n(e){this.handle=e}var i=this,o=this._instances=[];this._registerInstance=function(e,t){return t||(t=ionic.Utils.nextUid()),e.$$delegateHandle=t,o.push(e),function(){var t=o.indexOf(e);-1!==t&&o.splice(t,1)}},this.$getByHandle=function(e){return e?new n(e):i},e.forEach(function(e){function r(e,t,n){var i,o;return e.forEach(function(e,r){o=e[t].apply(e,n),0===r&&(i=o)}),i}n.prototype[e]=function(){var n=this.handle,i=o.filter(function(e){return e.$$delegateHandle===n});return i.length?r(i,e,arguments):t.warn('Delegate for handle "'+this.handle+'" could not find a','corresponding element with delegate-handle="'+this.handle+'"!',e,"was not called!")},i[e]=function(){return r(o,e,arguments)}})}]}angular.module("ionic.service",["ionic.service.bind","ionic.service.platform","ionic.service.actionSheet","ionic.service.gesture","ionic.service.loading","ionic.service.modal","ionic.service.popup","ionic.service.templateLoad","ionic.service.view","ionic.decorator.location"]),angular.module("ionic.ui",["ionic.ui.checkbox","ionic.ui.content","ionic.ui.header","ionic.ui.list","ionic.ui.navBar","ionic.ui.popup","ionic.ui.radio","ionic.ui.scroll","ionic.ui.sideMenu","ionic.ui.slideBox","ionic.ui.tabs","ionic.ui.toggle","ionic.ui.touch","ionic.ui.viewState"]),angular.module("ionic",["ionic.service","ionic.ui","ngAnimate","ngSanitize","ui.router"]),angular.element.prototype.addClass=function(e){var t,n,i,o,r,a;if(e&&"ng-scope"!=e&&"ng-isolate-scope"!=e)for(t=0;t')(c),l=angular.element(s[0].querySelector(".action-sheet-wrapper")),u=function(e){l.removeClass("action-sheet-up"),e&&o(function(){r.cancel()},200),i.removeClass(s,"active",function(){c.$destroy()}),t[0].body.classList.remove("action-sheet-open"),c.$deregisterBackButton&&c.$deregisterBackButton()};c.$deregisterBackButton=a.registerBackButtonAction(function(){u()},300),c.cancel=function(){u(!0)},c.buttonClicked=function(e){(r.buttonClicked&&r.buttonClicked(e))===!0&&u(!1)},c.destructiveButtonClicked=function(){(r.destructiveButtonClicked&&r.destructiveButtonClicked())===!0&&u(!1)},t[0].body.appendChild(s[0]),t[0].body.classList.add("action-sheet-open");var d=new ionic.views.ActionSheet({el:s[0]});return c.sheet=d,i.addClass(s,"active"),o(function(){l.addClass("action-sheet-up")},20),d}}}]),angular.module("ionic.service.bind",[]).factory("$ionicBind",["$parse","$interpolate",function(e,t){var n=/^\s*([@=&])(\??)\s*(\w*)\s*$/;return function(i,o,r){angular.forEach(r||{},function(r,a){var c,s,l=r.match(n)||[],u=l[3]||a,d=l[1];switch(d){case"@":if(!o[u])return;o.$observe(u,function(e){i[a]=e}),o[u]&&(i[a]=t(o[u])(i));break;case"=":if(!o[u])return;s=i.$watch(o[u],function(e){i[a]=e}),i.$on("$destroy",s);break;case"&":if(o[u]&&o[u].match(RegExp(a+"(.*?)")))throw new Error('& expression binding "'+a+'" looks like it will recursively call "'+o[u]+'" and cause a stack overflow! Please choose a different scopeName.');c=e(o[u]),i[a]=function(e){return c(i,e)}}})}}]),angular.module("ionic.service.gesture",[]).factory("$ionicGesture",[function(){return{on:function(e,t,n){return window.ionic.onGesture(e,t,n[0])},off:function(e,t,n){return window.ionic.offGesture(e,t,n)}}}]),angular.module("ionic.service.loading",["ionic.ui.loading"]).factory("$ionicLoading",["$rootScope","$document","$compile",function(e,t,n){return{show:function(i){var o={content:"",animation:"fade-in",showBackdrop:!0,maxWidth:200,showDelay:0};i=angular.extend(o,i);var r=e.$new(!0);angular.extend(r,i);var a=angular.element(t[0].querySelector(".loading-backdrop"));a.length&&a.remove();var c=n(""+i.content+"")(r);t[0].body.appendChild(c[0]);var s=new ionic.views.Loading({el:c[0],maxWidth:i.maxWidth,showDelay:i.showDelay});return s.show(),r.loading=s,s}}}]),angular.module("ionic.service.modal",["ionic.service.templateLoad","ionic.service.platform","ionic.ui.modal"]).factory("$ionicModal",["$rootScope","$document","$compile","$timeout","$ionicPlatform","$ionicTemplateLoader",function(e,t,n,i,o,r){var a=ionic.views.Modal.inherit({initialize:function(e){ionic.views.Modal.prototype.initialize.call(this,e),this.animation=e.animation||"slide-in-up"},show:function(){var e=this,n=angular.element(e.modalEl);e.el.classList.remove("hide"),t[0].body.classList.add("modal-open"),e._isShown=!0,e.el.parentElement||(n.addClass(e.animation),t[0].body.appendChild(e.el)),n.addClass("ng-enter active").removeClass("ng-leave ng-leave-active"),i(function(){n.addClass("ng-enter-active"),e.scope.$parent&&e.scope.$parent.$broadcast("modal.shown"),e.el.classList.add("active")},20),e._deregisterBackButton=o.registerBackButtonAction(function(){e.hide()},200),ionic.views.Modal.prototype.show.call(e)},hide:function(){var e=this;e._isShown=!1;var n=angular.element(e.modalEl);e.el.classList.remove("active"),n.addClass("ng-leave"),i(function(){n.addClass("ng-leave-active").removeClass("ng-enter ng-enter-active active")},20),i(function(){t[0].body.classList.remove("modal-open"),e.el.classList.add("hide")},350),ionic.views.Modal.prototype.hide.call(e),e.scope.$parent&&e.scope.$parent.$broadcast("modal.hidden"),e._deregisterBackButton&&e._deregisterBackButton()},remove:function(){var e=this;e.hide(),e.scope.$parent&&e.scope.$parent.$broadcast("modal.removed"),i(function(){e.scope.$destroy(),e.el&&e.el.parentElement&&e.el.parentElement.removeChild(e.el)},750)},isShown:function(){return!!this._isShown}}),c=function(t,i){var o=i.scope&&i.scope.$new()||e.$new(!0),r=n(""+t+"")(o);i.el=r[0],i.modalEl=i.el.querySelector(".modal");var c=new a(i);return c.scope=o,i.scope||(o.modal=c),c};return{fromTemplate:function(e,t){var n=c(e,t||{});return n},fromTemplateUrl:function(e,t,n){var i;return angular.isFunction(t)&&(i=t,t=n),r.load(e).then(function(e){var n=c(e,t||{});return i&&i(n),n})}}}]),function(e){"use strict";angular.module("ionic.service.platform",[]).provider("$ionicPlatform",function(){return{$get:["$q","$rootScope",function(t,n){return{onHardwareBackButton:function(t){e.Platform.ready(function(){document.addEventListener("backbutton",t,!1)})},offHardwareBackButton:function(t){e.Platform.ready(function(){document.removeEventListener("backbutton",t)})},registerBackButtonAction:function(t,i,o){var r=this;r._hasBackButtonHandler||(n.$backButtonActions={},r.onHardwareBackButton(r.hardwareBackButtonClick),r._hasBackButtonHandler=!0);var a={id:o?o:e.Utils.nextUid(),priority:i?i:0,fn:t};return n.$backButtonActions[a.id]=a,function(){delete n.$backButtonActions[a.id]}},hardwareBackButtonClick:function(e){var t,i;for(i in n.$backButtonActions)(!t||n.$backButtonActions[i].priority>=t.priority)&&(t=n.$backButtonActions[i]);return t?(t.fn(e),t):void 0},is:function(t){return e.Platform.is(t)},ready:function(n){var i=t.defer();return e.Platform.ready(function(){i.resolve(),n()}),i.promise}}}]}})}(ionic),function(e){"use strict";angular.module("ionic.service.popup",["ionic.service.templateLoad"]).factory("$ionicPopup",["$rootScope","$q","$document","$compile","$timeout","$ionicTemplateLoader",function(t,n,i,o,r,a){var c={stackPushDelay:50},s=function(e){e.el.style.marginLeft=-e.el.offsetWidth/2+"px",e.el.style.marginTop=-e.el.offsetHeight/2+"px"},l=function(e){var t=e.el.querySelector(".popup-body");t&&""==t.innerHTML.trim()&&(t.style.display="none")},u=function(e){var t,n;t=e.el.querySelectorAll("button"),n=t[t.length-1],n&&n.focus()},d=function(t){e.requestAnimationFrame(function(){l(t),s(t),t.el.classList.remove("popup-hidden"),t.el.classList.add("popup-showing"),t.el.classList.add("active"),u(t)})},f=function(t){e.requestAnimationFrame(function(){t.el.classList.remove("popup-hidden"),t.el.classList.add("popup-showing"),t.el.classList.add("active"),u(t)})},v=function(t){e.requestAnimationFrame(function(){t.el.classList.remove("active"),t.el.classList.add("popup-hidden")})},p=function(e){e.el.offsetWidth,e.el.classList.remove("active"),e.el.classList.add("popup-hidden"),r(function(){e.el.remove()},400)},g=[],h=null,m=function(){var e=o("")(t.$new(!0));i[0].body.appendChild(e[0]),h=e,i[0].body.classList.add("popup-open")},$=function(){h.remove(),r(function(){i[0].body.classList.remove("popup-open")},300)},b=function(e){var t=g[g.length-1];g.push(e),1==g.length&&m(),t?(v(t),r(function(){d(e)},c.stackPushDelay)):d(e)},w=function(){var e=g.pop(),t=g[g.length-1];p(e),t?f(t):$()},y=function(e,t){var n={el:e[0],scope:t,close:function(){w(this)}};return t.popup=n,n},k=function(e,t){return''+(t||"")+""},S=function(e,r){var c=n.defer(),s={title:"",animation:"fade-in"};e=angular.extend(s,e);var l=e.scope&&e.scope.$new()||t.$new(!0);if(angular.extend(l,e),l.onClose=function(e,t){w(l.popup),r.resolve(t)},e.templateUrl)a.load(e.templateUrl).then(function(t){var n=k(e,t),r=o(n)(l);i[0].body.appendChild(r[0]),c.resolve(y(r,l))},function(e){c.reject(e)});else{var u=k(e,e.content),d=o(u)(l);i[0].body.appendChild(d[0]),c.resolve(y(d,l))}return c.promise};return{showPopup:function(e){var t=n.defer();return S(e,t).then(function(n){t.notify(n),b(n,e)},function(){}),t.promise},show:function(e){return this.showPopup(e)},alert:function(e){return this.showPopup({content:e.content||"",title:e.title||"",buttons:[{text:e.okText||"OK",type:e.okType||"button-positive",onTap:function(){return!0}}]})},confirm:function(e){return this.showPopup({content:e.content||"",title:e.title||"",buttons:[{text:e.cancelText||"Cancel",type:e.cancelType||"button-default",onTap:function(e){e.preventDefault()}},{text:e.okText||"OK",type:e.okType||"button-positive",onTap:function(){return!0}}]})},prompt:function(e){var n=t.$new(!0);return n.data={},this.showPopup({content:e.content||'',title:e.title||"",subTitle:e.subTitle||"",scope:n,buttons:[{text:e.cancelText||"Cancel",type:e.cancelType||"button-default",onTap:function(e){e.preventDefault()}},{text:e.okText||"OK",type:e.okType||"button-positive",onTap:function(){return n.data.response}}]})}}}])}(ionic),angular.module("ionic.service.templateLoad",[]).factory("$ionicTemplateLoader",["$q","$http","$templateCache",function(e,t,n){return{load:function(e){return t.get(e,{cache:n}).then(function(e){return e.data&&e.data.trim()})}}}]),angular.module("ionic.service.view",["ui.router","ionic.service.platform"]).run(["$rootScope","$state","$location","$document","$animate","$ionicPlatform",function(e,t,n,i,o,r){function a(t){return e.$viewHistory.backView?e.$viewHistory.backView.go():ionic.Platform.exitApp(),t.preventDefault(),!1}e.$viewHistory={histories:{root:{historyId:"root",parentHistoryId:null,stack:[],cursor:-1}},views:{},backView:null,forwardView:null,currentView:null,disabledRegistrableTagNames:[]},e.$on("viewState.changeHistory",function(i,o){if(o){var r=o.historyId?e.$viewHistory.histories[o.historyId]:null;if(r&&r.cursor>-1&&r.cursor-1&&c.stack.length>0&&c.cursor=u.index;g--)p.stack[g].destroy(),p.stack.splice(g)}}else f.navAction="initialView";o.views[f.viewId]=this.createView({viewId:f.viewId,index:c.stack.length,historyId:c.historyId,backViewId:s&&s.viewId?s.viewId:null,forwardViewId:null,stateId:a,stateName:this.getCurrentStateName(),stateParams:this.getCurrentStateParams(),url:n.url()}),"moveBack"==f.navAction&&e.$emit("$viewHistory.viewBack",s.viewId,f.viewId),c.stack.push(o.views[f.viewId])}return d&&(d.disableAnimate&&(f.navDirection=null),d.disableBack&&(o.views[f.viewId].backViewId=null),this.nextViewOptions(null)),this.setNavViews(f.viewId),c.cursor=o.currentView.index,f},setNavViews:function(t){var n=e.$viewHistory;n.currentView=this._getViewById(t),n.backView=this._getBackView(n.currentView),n.forwardView=this._getForwardView(n.currentView),e.$broadcast("$viewHistory.historyChange",{showBack:n.backView&&n.backView.historyId===n.currentView.historyId})},registerHistory:function(e){e.$historyId=ionic.Utils.nextUid()},createView:function(e){var t=new c;return t.initialize(e)},getCurrentView:function(){return e.$viewHistory.currentView},getBackView:function(){return e.$viewHistory.backView},getForwardView:function(){return e.$viewHistory.forwardView},getNavDirection:function(){return e.$viewHistory.navDirection},getCurrentStateName:function(){return t&&t.current?t.current.name:null},isCurrentStateNavView:function(e){return t&&t.current&&t.current.views&&t.current.views[e]?!0:!1},getCurrentStateParams:function(){var e;if(t&&t.params)for(var n in t.params)t.params.hasOwnProperty(n)&&(e=e||{},e[n]=t.params[n]);return e},getCurrentStateId:function(){var e;if(t&&t.current&&t.current.name){if(e=t.current.name,t.params)for(var n in t.params)t.params.hasOwnProperty(n)&&t.params[n]&&(e+="_"+n+"="+t.params[n]);return e}return ionic.Utils.nextUid()},goToHistoryRoot:function(t){if(t){var n=e.$viewHistory.histories[t];if(n&&n.stack.length){if(e.$viewHistory.currentView&&e.$viewHistory.currentView.viewId===n.stack[0].viewId)return;e.$viewHistory.forcedNav={viewId:n.stack[0].viewId,navAction:"moveBack",navDirection:"back"},n.stack[0].go()}}},_getViewById:function(t){return t?e.$viewHistory.views[t]:null},_getBackView:function(e){return e?this._getViewById(e.backViewId):null},_getForwardView:function(e){return e?this._getViewById(e.forwardViewId):null},_getHistoryById:function(t){return t?e.$viewHistory.histories[t]:null},_getHistory:function(t){var n=this._getParentHistoryObj(t);return e.$viewHistory.histories[n.historyId]||(e.$viewHistory.histories[n.historyId]={historyId:n.historyId,parentHistoryId:this._getParentHistoryObj(n.scope.$parent).historyId,stack:[],cursor:-1}),e.$viewHistory.histories[n.historyId]},_getParentHistoryObj:function(t){for(var n=t;n;){if(n.hasOwnProperty("$historyId"))return{historyId:n.$historyId,scope:n};n=n.$parent}return{historyId:"root",scope:e}},nextViewOptions:function(e){return arguments.length?void(this._nextOpts=e):this._nextOpts},getRenderer:function(e,t,n){function i(e){for(var t="";!t&&e;)t=e.getAttribute("animation"),e=e.parentElement;return t}function o(){l&&e[0].classList.add(l),"back"===r.navDirection?e[0].classList.add("reverse"):e[0].classList.remove("reverse")}var r,c,s=this,l=angular.isDefined(n.$nextAnimation)?n.$nextAnimation:i(e[0]);return n.$nextAnimation=void 0,function(t){return{enter:function(n){return c&&t?(o(),n.addClass("ng-enter"),document.body.classList.add("disable-pointer-events"),void a.enter(n,e,null,function(){document.body.classList.remove("disable-pointer-events"),l&&e[0].classList.remove(l)})):void e.append(n)},leave:function(){var n=e.contents();return c&&t?(o(),void a.leave(n,function(){n.remove()})):void n.remove()},register:function(e){return r=s.register(n,e),c=null!==l&&null!==r.navDirection,r}}}},disableRegisterByTagName:function(t){e.$viewHistory.disabledRegistrableTagNames.push(t.toUpperCase())},isTagNameRegistrable:function(t){var n,i,o=e.$viewHistory.disabledRegistrableTagNames;for(n=0;n
{{titleText}}
'}}])}(),function(e){"use strict";function t(){return["$ionicScrollDelegate",function(t){return{restrict:"E",link:function(n,i){function o(n){if(!e.DomUtil.getParentOrSelfWithClass(n.target,"button",4)){var o=n.gesture&&n.gesture.touches[0]||n.detail.touches[0],r=i[0].getBoundingClientRect();e.DomUtil.rectContains(o.pageX,o.pageY,r.left,r.top-20,r.left+r.width,r.top+r.height)&&t.scrollTop(!0)}}e.on("tap",o,i[0]),n.$on("$destroy",function(){e.off("tap",o,i[0])})}}}]}function n(t){return[function(){return{restrict:"E",compile:function(n){function i(n,i,o){var r=(new e.views.HeaderBar({el:i[0],alignTitle:o.alignTitle||"center"}),i[0]),a=n.$parent||n;t?(n.$watch(function(){return r.className},function(e){var t=-1!==e.indexOf("bar-subheader");a.$hasHeader=!t,a.$hasSubheader=t}),n.$on("$destroy",function(){a.$hasHeader=a.$hasSubheader=null})):(n.$watch(function(){return r.className},function(e){var t=-1!==e.indexOf("bar-subfooter");a.$hasFooter=!t,a.$hasSubfooter=t}),n.$on("$destroy",function(){a.$hasFooter=a.$hasSubfooter=null}),n.$watch("$hasTabs",function(e){i.toggleClass("has-tabs",!!e)}))}return n.addClass(t?"bar bar-header":"bar bar-footer"),{pre:i}}}}]}angular.module("ionic.ui.header",["ngAnimate","ngSanitize"]).directive("ionNavBar",t()).directive("ionHeaderBar",t()).directive("ionHeaderBar",n(!0)).directive("ionFooterBar",n(!1))}(ionic),function(){"use strict";angular.module("ionic.ui.checkbox",[]).directive("ionCheckbox",function(){return{restrict:"E",replace:!0,require:"?ngModel",scope:{ngModel:"=?",ngValue:"=?",ngChecked:"=?",ngChange:"&"},transclude:!0,template:'
',compile:function(e,t){var n=e.find("input");t.name&&n.attr("name",t.name),t.ngChecked&&n.attr("ng-checked","ngChecked"),t.ngTrueValue&&n.attr("ng-true-value",t.ngTrueValue),t.ngFalseValue&&n.attr("ng-false-value",t.ngFalseValue)}}})}(),function(){"use strict";angular.module("ionic.ui.content",["ionic.ui.scroll"]).directive("ionPane",function(){return{restrict:"E",link:function(e,t){t.addClass("pane")}}}).directive("ionContent",["$timeout","$controller","$ionicBind",function(e,t,n){return{restrict:"E",require:"^?ionNavView",scope:!0,compile:function(e,i){function o(e,o,a){e.$watch(function(){return(e.$hasHeader?" has-header":"")+(e.$hasSubheader?" has-subheader":"")+(e.$hasFooter?" has-footer":"")+(e.$hasSubfooter?" has-subfooter":"")+(e.$hasTabs?" has-tabs":"")+(e.$hasTabsTop?" has-tabs-top":"")},function(e,t){o.removeClass(t),o.addClass(e)}),n(e,a,{$onScroll:"&onScroll",$onScrollComplete:"&onScrollComplete",hasBouncing:"@",scroll:"@",padding:"@",hasScrollX:"@",hasScrollY:"@",scrollbarX:"@",scrollbarY:"@",startX:"@",startY:"@",scrollEventInterval:"@"}),angular.isDefined(a.padding)&&e.$watch(a.padding,function(e){r.toggleClass("padding",!!e)}),"false"===e.scroll||("true"===i.overflowScroll?o.addClass("overflow-scroll"):t("$ionicScroll",{$scope:e,scrollViewOptions:{el:o[0],delegateHandle:i.delegateHandle,bouncing:e.$eval(e.hasBouncing),startX:e.$eval(e.startX)||0,startY:e.$eval(e.startY)||0,scrollbarX:e.$eval(e.scrollbarX)!==!1,scrollbarY:e.$eval(e.scrollbarY)!==!1,scrollingX:e.$eval(e.hasScrollX)===!0,scrollingY:e.$eval(e.hasScrollY)!==!1,scrollEventInterval:parseInt(e.scrollEventInterval,10)||20,scrollingComplete:function(){e.$onScrollComplete({scrollTop:this.__scrollTop,scrollLeft:this.__scrollLeft})}}}))}e.addClass("scroll-content");var r=angular.element('
');return r.append(e.contents()),e.append(r),{pre:o}}}}]).directive("ionRefresher",["$ionicBind",function(e){return{restrict:"E",replace:!0,require:"^$ionicScroll",template:'
',compile:function(t,n){return angular.isUndefined(n.pullingIcon)&&n.$set("pullingIcon","ion-arrow-down-c"),angular.isUndefined(n.refreshingIcon)&&n.$set("refreshingIcon","ion-loading-d"),function(t,n,i,o){e(t,i,{pullingIcon:"@",pullingText:"@",refreshingIcon:"@",refreshingText:"@",$onRefresh:"&onRefresh",$onPulling:"&onPulling"}),o._setRefresher(t,n[0]),t.$on("scroll.refreshComplete",function(){n[0].classList.remove("active"),o.scrollView.finishPullToRefresh()})}}}}]).directive("ionInfiniteScroll",["$timeout",function(e){return{restrict:"E",require:["^$ionicScroll","ionInfiniteScroll"],template:'
',scope:!0,controller:["$scope","$attrs",function(e,t){this.isLoading=!1,this.scrollView=null,this.getMaxScroll=function(){var e=t.distance||"1%";return e.indexOf("%")>-1?this.scrollView.getScrollMax().top*(1-parseInt(e,10)/100):this.scrollView.getScrollMax().top-parseInt(e,10)}}],link:function(t,n,i,o){var r=o[0],a=o[1],c=a.scrollView=r.scrollView;t.icon=function(){return angular.isDefined(i.icon)?i.icon:"ion-loading-d"},t.$on("scroll.infiniteScrollComplete",function(){n[0].classList.remove("active"),e(function(){c.resize()},0,!1),a.isLoading=!1}),r.$element.on("scroll",ionic.animationFrameThrottle(function(){!a.isLoading&&c.getValues().top>=a.getMaxScroll()&&(n[0].classList.add("active"),a.isLoading=!0,t.$parent.$apply(i.onInfinite||""))}))}}}])}(),function(){"use strict";angular.module("ionic.ui.list",["ngAnimate"]).directive("ionItem",["$timeout","$parse",function(){return{restrict:"E",require:"?^ionList",replace:!0,transclude:!0,scope:{item:"=",itemType:"@",canDelete:"@",canReorder:"@",canSwipe:"@",onDelete:"&",optionButtons:"&",deleteIcon:"@",reorderIcon:"@"},template:'
',link:function(e,t,n,i){if(i){var o=i.scope,r=i.attrs;n.$observe("href",function(t){t&&(e.href=t.trim())}),e.itemType||(e.itemType=o.itemType),t.addClass(e.itemType||o.itemType),e.itemClass=e.itemType,"false"!==(n.canDelete?e.canDelete:o.canDelete)&&(n.onDelete||r.onDelete)&&(e.deleteClick=function(){n.onDelete?e.onDelete({item:e.item,index:e.$parent.$index}):r.onDelete&&o.onDelete({item:e.item,index:e.$parent.$index})},e.deleteIconClass=e.deleteIcon||o.deleteIcon||"ion-minus-circled",t.addClass("item-left-editable")),"true"===(n.canReorder?e.canReorder:o.canReorder)&&(e.reorderIconClass=e.reorderIcon||o.reorderIcon||"ion-navicon",t.addClass("item-right-editable")),"false"!==(n.canSwipe?e.canSwipe:o.canSwipe)&&(e.itemOptionButtons=e.optionButtons(),"undefined"==typeof e.itemOptionButtons&&(e.itemOptionButtons=o.optionButtons()),t.addClass("item-swipeable"))}}}}]).directive("ionList",["$timeout",function(e){return{restrict:"E",replace:!0,transclude:!0,require:"^?$ionicScroll",scope:{itemType:"@",canDelete:"@",canReorder:"@",canSwipe:"@",showDelete:"=",showReorder:"=",onDelete:"&",onReorder:"&",optionButtons:"&",deleteIcon:"@",reorderIcon:"@"},template:"
",controller:["$scope","$attrs",function(e,t){this.scope=e,this.attrs=t}],link:function(t,n,i,o){t.listView=new ionic.views.ListView({canSwipe:"false"!==t.canSwipe&&!!t.optionButtons(),el:n[0],listEl:n[0].children[0],scrollEl:o&&o.element,scrollView:o&&o.scrollView,onReorder:function(e,n,i){t.$apply(function(){t.onReorder({el:e,start:n,end:i})})}}),i.animation&&n[0].classList.add(i.animation);var r=t.$watch("showReorder",function(i){i?(n[0].classList.add("item-options-hide"),t.listView&&t.listView.clearDragEffects()):i===!1&&e(function(){n[0].classList.remove("item-options-hide")},250)});t.$on("$destroy",function(){r()})}}}])}(),function(){"use strict";angular.module("ionic.ui.loading",[]).directive("ionLoading",function(){return{restrict:"E",replace:!0,transclude:!0,link:function(e,t){t.addClass(e.animation||"")},template:'
'}})}(),function(){"use strict";angular.module("ionic.ui.modal",[]).directive("ionModal",[function(){return{restrict:"E",transclude:!0,replace:!0,template:''}}])}(),angular.module("ionic.ui.navBar",["ionic.service.view","ngSanitize"]).service("$ionicNavBarDelegate",e(["back","align","showBackButton","showBar","setTitle","changeTitle","getTitle","getPreviousTitle"])).controller("$ionicNavBar",["$scope","$element","$attrs","$ionicViewService","$animate","$compile","$ionicNavBarDelegate",function(e,t,n,i,o,r,a){t.parent().data("$ionNavBarController",this);var c=a._registerInstance(this,n.delegateHandle);e.$on("$destroy",c);var s=this;this.leftButtonsElement=angular.element(t[0].querySelector(".buttons.left-buttons")),this.rightButtonsElement=angular.element(t[0].querySelector(".buttons.right-buttons")),this.back=function(e){var t=i.getBackView();return t&&t.go(),e&&(e.alreadyHandled=!0),!1},this.align=function(e){this._headerBarView.align(e)},this.showBackButton=function(t){e.backButtonShown=!!t},this.showBar=function(t){e.isInvisible=!t},this.setTitle=function(t){e.oldTitle=e.title,e.title=t||""},this.changeTitle=function(t,n){return e.title===t?!1:(this.setTitle(t),e.isReverse="back"==n,e.shouldAnimate=!!n,e.shouldAnimate?this._animateTitles():this._headerBarView.align(),!0)},this.getTitle=function(){return e.title||""},this.getPreviousTitle=function(){return e.oldTitle||""},this._animateTitles=function(){var n,i,a;a=t[0].querySelectorAll(".title"),a.length&&(n=r('

')(e),angular.element(a[0]).replaceWith(n)),i=r('

')(e),ionic.requestAnimationFrame(function(){n&&o.leave(angular.element(n));var r=n&&angular.element(n)||null;o.enter(i,t,r,function(){s._headerBarView.align()}),angular.forEach(a,function(e){e&&e.parentNode&&angular.element(e).remove()}),e.$digest(),ionic.requestAnimationFrame(function(){i[0].classList.remove("invisible")})})}}]).directive("ionNavBar",["$ionicViewService","$rootScope","$animate","$compile",function(){return{restrict:"E",controller:"$ionicNavBar",scope:!0,compile:function(e){function t(e,t,n,i){i._headerBarView=new ionic.views.HeaderBar({el:t[0],alignTitle:n.alignTitle||"center"}),e.backButtonShown=!1,e.shouldAnimate=!0,e.isReverse=!1,e.isInvisible=!0,e.$parent.$hasHeader=!0,e.$on("$destroy",function(){e.$parent.$hasHeader=!1}),e.$watch(function(){return(e.isReverse?" reverse":"")+(e.isInvisible?" invisible":"")+(e.shouldAnimate?"":" no-animation")},function(e,n){t.removeClass(n),t.addClass(e)})}return e.addClass("bar bar-header nav-bar").append('

'),{pre:t} +}}}]).directive("ionNavBackButton",["$ionicNgClick",function(e){return{restrict:"E",require:"^ionNavBar",compile:function(t){return t.addClass("button back-button"),function(t,n,i,o){i.ngClick||(t.$navBack=o.back,e(t,n,"$navBack($event)"));var r=t.$parent.$on("$viewHistory.historyChange",function(e,n){t.hasBackButton=!!n.showBack});t.$on("$destroy",r),t.$watch("!!(backButtonShown && hasBackButton)",function(e){n.toggleClass("hide",!e)})}}}}]).directive("ionNavButtons",["$compile","$animate",function(e,t){return{require:"^ionNavBar",restrict:"E",compile:function(n){var i=n.contents().remove();return function(n,o,r,a){var c="right"===r.side?a.rightButtonsElement:a.leftButtonsElement,s=angular.element("
").append(i);o.append(s),e(s)(n),t.enter(s,c),n.$on("$destroy",function(){t.leave(s)}),o.css("display","none")}}}}]),function(){"use strict";angular.module("ionic.ui.popup",[]).directive("ionPopupBackdrop",function(){return{restrict:"E",replace:!0,template:''}}).directive("ionPopup",["$ionicBind",function(e){return{restrict:"E",replace:!0,transclude:!0,scope:!0,template:'',link:function(t,n,i){e(t,i,{title:"@",buttons:"=",$onButtonTap:"&onButtonTap",$onClose:"&onClose"}),t._buttonTapped=function(e,n){var i=e.onTap&&e.onTap(n);return n.defaultPrevented?t.$onClose({button:e,result:!1,event:n}):i?t.$onClose({button:e,result:i,event:n}):void t.$onButtonTap({button:e,event:n})}}}}])}(),function(e){"use strict";angular.module("ionic.ui.radio",[]).directive("ionRadio",function(){return{restrict:"E",replace:!0,require:"?ngModel",scope:{ngModel:"=?",ngValue:"=?",ngChange:"&",icon:"@"},transclude:!0,template:'',compile:function(e,t){t.name&&e.children().eq(0).attr("name",t.name),t.icon&&e.children().eq(2).removeClass("ion-checkmark").addClass(t.icon)}}}).directive("ionRadioButtons",function(){return{restrict:"E",replace:!0,require:"?ngModel",scope:{value:"@"},transclude:!0,template:'
',controller:["$scope","$element",function(e,t){this.select=function(e){for(var n,i=t.children(),o=0;o=0,scrollingY:e.direction.indexOf("y")>=0};s&&(l.speedMultiplier=.8,l.bouncing=!1),c=t("$ionicScroll",{$scope:e,scrollViewOptions:l}),a=e.$parent.scrollView=c.scrollView}e.addClass("scroll-view");var o=angular.element('
');return o.append(e.contents()),e.append(o),{pre:i}}}}])}(),function(){"use strict";angular.module("ionic.ui.sideMenu",["ionic.service.gesture","ionic.service.view"]).run(["$ionicViewService",function(e){e.disableRegisterByTagName("ion-side-menus")}]).service("$ionicSideMenuDelegate",e(["toggleLeft","toggleRight","isOpenLeft","isOpenRight","canDragContent"])).directive("ionSideMenus",function(){return{restrict:"ECA",controller:["$scope","$attrs","$ionicSideMenuDelegate",function(e,t,n){angular.extend(this,ionic.controllers.SideMenuController.prototype),ionic.controllers.SideMenuController.call(this,{left:{width:275},right:{width:275}}),this.canDragContent=function(t){return arguments.length&&(e.dragContent=!!t),e.dragContent},e.sideMenuContentTranslateX=0;var i=n._registerInstance(this,t.delegateHandle);e.$on("$destroy",i)}],replace:!0,transclude:!0,template:'
'}}).directive("ionSideMenuContent",["$timeout","$ionicGesture",function(e,t){return{restrict:"EA",require:"^ionSideMenus",scope:!0,compile:function(n,i){function o(n,o,r,a){function c(e){0!==a.getOpenAmount()&&(a.close(),e.gesture.srcEvent.preventDefault())}o.addClass("menu-content pane"),angular.isDefined(i.dragContent)?n.$watch(i.dragContent,function(e){a.canDragContent(e)}):a.canDragContent(!0);var s=!1,l=!1;ionic.on("tap",c,o[0]);var u=function(e){if(n.dragContent){if(s||e.gesture.srcEvent.defaultPrevented)return;l=!0,a._handleDrag(e),e.gesture.srcEvent.preventDefault()}},d=function(e){l&&e.gesture.srcEvent.preventDefault()},f=t.on("dragright",u,o),v=t.on("dragleft",u,o),p=t.on("dragup",d,o),g=t.on("dragdown",d,o),h=function(e){l=!1,s||a._endDrag(e),s=!1},m=t.on("release",h,o);a.setContent({onDrag:function(){},endDrag:function(){},getTranslateX:function(){return n.sideMenuContentTranslateX||0},setTranslateX:ionic.animationFrameThrottle(function(t){o[0].style[ionic.CSS.TRANSFORM]="translate3d("+t+"px, 0, 0)",e(function(){n.sideMenuContentTranslateX=t})}),enableAnimation:function(){n.animationEnabled=!0,o[0].classList.add("menu-animated")},disableAnimation:function(){n.animationEnabled=!1,o[0].classList.remove("menu-animated")}}),n.$on("$destroy",function(){t.off(v,"dragleft",u),t.off(f,"dragright",u),t.off(p,"dragup",u),t.off(g,"dragdown",u),t.off(m,"release",h),ionic.off("tap",c,o[0])})}return{pre:o}}}}]).directive("ionSideMenu",function(){return{restrict:"E",require:"^ionSideMenus",scope:!0,compile:function(e,t){return angular.isUndefined(t.isEnabled)&&t.$set("isEnabled","true"),angular.isUndefined(t.width)&&t.$set("width","275"),e.addClass("menu menu-"+t.side),function(e,t,n,i){e.side=n.side||"left";var o=i[e.side]=new ionic.views.SideMenu({width:275,el:t[0],isEnabled:!0});e.$watch(n.width,function(e){var t=+e;t&&t==e&&o.setWidth(+e)}),e.$watch(n.isEnabled,function(e){o.setIsEnabled(!!e)})}}}}).directive("menuToggle",["$ionicViewService",function(){return{restrict:"AC",require:"^ionSideMenus",link:function(e,t,n,i){var o=e.$eval(n.menuToggle)||"left";t.bind("click",function(){"left"===o?i.toggleLeft():"right"===o&&i.toggleRight()})}}}]).directive("menuClose",["$ionicViewService",function(){return{restrict:"AC",require:"^ionSideMenus",link:function(e,t,n,i){t.bind("click",function(){i.close()})}}}])}(),function(){"use strict";angular.module("ionic.ui.slideBox",[]).service("$ionicSlideBoxDelegate",e(["update","slide","previous","next","stop","currentIndex","slidesCount"])).directive("ionSlideBox",["$timeout","$compile","$ionicSlideBoxDelegate",function(e,t,n){return{restrict:"E",replace:!0,transclude:!0,scope:{doesContinue:"@",slideInterval:"@",showPager:"@",disableScroll:"@",onSlideChanged:"&",activeSlide:"=?"},controller:["$scope","$element","$attrs",function(t,i,o){var r=t.$eval(t.doesContinue)===!0,a=r?t.$eval(t.slideInterval)||4e3:0,c=new ionic.views.Slider({el:i[0],auto:a,disableScroll:t.$eval(t.disableScroll)===!0||!1,continuous:r,startSlide:t.activeSlide,slidesChanged:function(){t.currentSlide=c.currentIndex(),e(function(){})},callback:function(n){t.currentSlide=n,t.onSlideChanged({index:t.currentSlide}),t.$parent.$broadcast("slideBox.slideChanged",n),t.activeSlide=n,e(function(){})}});t.$watch("activeSlide",function(e){angular.isDefined(e)&&c.slide(e)}),t.$on("slideBox.nextSlide",function(){c.next()}),t.$on("slideBox.prevSlide",function(){c.prev()}),t.$on("slideBox.setSlide",function(e,t){c.slide(t)}),this.__slider=c;var s=n._registerInstance(c,o.delegateHandle);t.$on("$destroy",s),this.slidesCount=function(){return c.slidesCount()},e(function(){c.load()})}],template:'
',link:function(e,n){if(e.$eval(e.showPager)!==!1){var i=e.$new(),o=angular.element("");n.append(o),t(o)(i)}}}}]).directive("ionSlide",function(){return{restrict:"E",require:"^ionSlideBox",compile:function(e){return e.addClass("slider-slide"),function(){}}}}).directive("ionPager",function(){return{restrict:"E",replace:!0,require:"^ionSlideBox",template:'
',link:function(e,t,n,i){var o=function(e){for(var n=t[0].children,i=n.length,o=0;i>o;o++)o==e?n[o].classList.add("active"):n[o].classList.remove("active")};e.numSlides=function(){return new Array(i.slidesCount())},e.$watch("currentSlide",function(e){o(e)})}}})}(),angular.module("ionic.ui.tabs",["ionic.service.view"]).run(["$ionicViewService",function(e){e.disableRegisterByTagName("ion-tabs")}]).service("$ionicTabsDelegate",e(["select","selectedIndex"])).controller("ionicTabs",["$scope","$ionicViewService","$element",function(e,t){var n=null,i=this;i.tabs=[],i.selectedIndex=function(){return i.tabs.indexOf(n)},i.selectedTab=function(){return n},i.add=function(e){t.registerHistory(e),i.tabs.push(e),1===i.tabs.length&&i.select(e)},i.remove=function(e){var t=i.tabs.indexOf(e);if(-1!==t){if(e.$tabSelected)if(i.deselect(e),1===i.tabs.length);else{var n=t===i.tabs.length-1?t-1:t+1;i.select(i.tabs[n])}i.tabs.splice(t,1)}},i.deselect=function(e){e.$tabSelected&&(n=null,e.$tabSelected=!1,(e.onDeselect||angular.noop)())},i.select=function(o,r){var a;if(angular.isNumber(o)?(a=o,o=i.tabs[a]):a=i.tabs.indexOf(o),!o||-1==a)throw new Error('Cannot select tab "'+a+'"!');if(n&&n.$historyId==o.$historyId)r&&t.goToHistoryRoot(o.$historyId);else if(angular.forEach(i.tabs,function(e){i.deselect(e)}),n=o,o.$tabSelected=!0,(o.onSelect||angular.noop)(),r){var c={type:"tab",tabIndex:a,historyId:o.$historyId,navViewName:o.navViewName,hasNavView:!!o.navViewName,title:o.title,url:o.href,uiSref:o.uiSref};e.$emit("viewState.changeHistory",c)}}}]).directive("ionTabs",["$ionicViewService","$ionicTabsDelegate",function(e,t){return{restrict:"E",scope:!0,controller:"ionicTabs",compile:function(e){function n(e,n,i,o){var r=t._registerInstance(o,i.delegateHandle);e.$on("$destroy",r),o.$scope=e,o.$element=n,o.$tabsElement=angular.element(n[0].querySelector(".tabs"));var a=n[0];e.$watch(function(){return a.className},function(t){var n=-1!==t.indexOf("tabs-top"),i=-1!==t.indexOf("tabs-item-hide");e.$hasTabs=!n&&!i,e.$hasTabsTop=n&&!i}),e.$on("$destroy",function(){e.$hasTabs=e.$hasTabsTop=null})}e.addClass("view");var i=angular.element('
');return i.append(e.contents()),e.append(i),{pre:n}}}}]).controller("ionicTab",["$scope","$ionicViewService","$rootScope","$element",function(e){this.$scope=e}]).directive("ionTab",["$rootScope","$animate","$ionicBind","$compile","$ionicViewService",function(e,t,n,i,o){function r(e,t){return angular.isDefined(t)?" "+e+'="'+t+'"':""}return{restrict:"E",require:["^ionTabs","ionTab"],replace:!0,controller:"ionicTab",scope:!0,compile:function(e,a){var c=e[0].querySelector("ion-nav-view")||e[0].querySelector("data-ion-nav-view"),s=c&&c.getAttribute("name"),l=(angular.element(e[0].querySelector("ion-tab-nav")||e[0].querySelector("data-ion-tab-nav")).remove(),angular.element('
').append(e.contents().remove()));return function(e,c,u,d){function f(){o.isCurrentStateNavView(e.navViewName)&&tabsCtrl.select(e)}var v,p,g;tabsCtrl=d[0],tabCtrl=d[1],c[0].removeAttribute("title"),n(e,u,{animate:"=",onSelect:"&",onDeselect:"&",title:"@",uiSref:"@",href:"@"}),tabsCtrl.add(e),e.$on("$destroy",function(){tabsCtrl.remove(e),g.isolateScope().$destroy(),g.remove()}),s&&(e.navViewName=s,e.$on("$stateChangeSuccess",f),f()),g=angular.element(""),g.data("$ionTabsController",tabsCtrl),g.data("$ionTabController",tabCtrl),tabsCtrl.$tabsElement.append(i(g)(e)),e.$watch("$tabSelected",function(n){v&&v.$destroy(),v=null,p&&t.leave(p),p=null,n&&(v=e.$new(),p=l.clone(),t.enter(p,tabsCtrl.$element),i(p)(v))})}}}}]).directive("ionTabNav",["$ionicNgClick",function(e){return{restrict:"E",replace:!0,require:["^ionTabs","^ionTab"],template:'{{badge}}',scope:{title:"@",icon:"@",iconOn:"@",iconOff:"@",badge:"=",badgeStyle:"@"},compile:function(){return function(t,n,i,o){var r=o[0],a=o[1];n[0].removeAttribute("title"),t.selectTab=function(e){e.preventDefault(),r.select(a.$scope,!0)},i.ngClick||e(t,n,"selectTab($event)"),t.getIconOn=function(){return t.iconOn||t.icon},t.getIconOff=function(){return t.iconOff||t.icon},t.isTabActive=function(){return r.selectedTab()===a.$scope}}}}}]),function(e){"use strict";angular.module("ionic.ui.toggle",[]).directive("ionToggle",["$ionicGesture","$timeout",function(){return{restrict:"E",replace:!0,require:"?ngModel",scope:{ngModel:"=?",ngValue:"=?",ngChecked:"=?",ngChange:"&",ngDisabled:"=?"},transclude:!0,template:'
',compile:function(t,n){var i=t.find("input");return n.name&&i.attr("name",n.name),n.ngChecked&&i.attr("ng-checked","ngChecked"),n.ngTrueValue&&i.attr("ng-true-value",n.ngTrueValue),n.ngFalseValue&&i.attr("ng-false-value",n.ngFalseValue),function(t,n){var i,o,r,a;i=n[0].getElementsByTagName("label")[0],o=i.children[0],r=i.children[1],a=r.children[0];var c=angular.element(o).controller("ngModel");t.toggle=new e.views.Toggle({el:i,track:r,checkbox:o,handle:a,onChange:function(){c.$setViewValue(o.checked?!0:!1),t.$apply()}}),t.$on("$destroy",function(){t.toggle.destroy()})}}}}])}(window.ionic),function(e,t){"use strict";e.module("ionic.ui.touch",[]).config(["$provide",function(e){e.decorator("ngClickDirective",["$delegate",function(e){return e.shift(),e}])}]).factory("$ionicNgClick",["$parse",function(e){function n(e){t.tapElement(e.target,e)}return function(i,o,r){var a=e(r);o.on("click",function(e){i.$apply(function(){a(i,{$event:e})})}),t.on("release",n,o[0]),o.onclick=function(){},i.$on("$destroy",function(){t.off("release",n,o[0])})}}]).directive("ngClick",["$ionicNgClick",function(e){return function(t,n,i){e(t,n,i.ngClick)}}]).directive("ionStopEvent",function(){function e(e){e.stopPropagation()}return{restrict:"A",link:function(t,n,i){n.bind(i.ionStopEvent,e)}}})}(window.angular,window.ionic),function(){"use strict";angular.module("ionic.ui.viewState",["ionic.service.view","ionic.service.gesture","ngSanitize"]).directive("ionView",["$ionicViewService","$rootScope","$animate",function(){return{restrict:"EA",priority:1e3,require:"^?ionNavBar",compile:function(e){return e.addClass("pane"),e[0].removeAttribute("title"),function(e,t,n,i){if(i){var o=n.title;i.changeTitle(o,e.$navDirection),n.$observe("title",function(e){e!==o&&i.setTitle(e)}),e.$watch(n.hideBackButton,function(e){i.showBackButton(!e)}),e.$watch(n.hideNavBar,function(e){i.showBar(!e)})}}}}}]).directive("ionNavView",["$ionicViewService","$state","$compile","$controller","$animate",function(e,t,n,i,o){var r=!1,a={restrict:"E",terminal:!0,priority:2e3,transclude:!0,controller:[function(){}],compile:function(c,s,l){return function(c,s,u){function d(r){o.enabled()===!1&&(r=!1);var a=t.$current&&t.$current.locals[p];if(a!==v){var l=e.getRenderer(s,u,c);if(f&&(f.$destroy(),f=null),!a)return v=null,$.state=null,s.append(h);var d=angular.element("
").html(a.$template).contents(),m=l().register(d);l(r).leave(),v=a,$.state=a.$$state,l(r).enter(d);var b=n(d);if(f=c.$new(),f.$navDirection=m.navDirection,a.$$controller){a.$scope=f;var w=i(a.$$controller,a);s.children().data("$ngControllerController",w)}b(f);var y=e._getViewById(m.viewId)||{};f.$broadcast("$viewContentLoaded",y),g&&f.$eval(g),d=null}}var f,v,p=u[a.name]||u.name||"",g=u.onload||"",h=l(c);s.append(h);var m=s.parent().inheritedData("$uiView");p.indexOf("@")<0&&(p=p+"@"+(m?m.state.name:""));var $={name:p,state:null};s.data("$uiView",$);var b=function(){if(!r){r=!0;try{d(!0)}catch(e){throw r=!1,e}r=!1}};c.$on("$stateChangeSuccess",b),c.$on("$viewContentLoading",b),d(!1)}}};return a}]).directive("navClear",["$ionicViewService",function(e){return{restrict:"AC",link:function(t,n){n.bind("click",function(){e.nextViewOptions({disableAnimate:!0,disableBack:!0})})}}}])}(),angular.module("ionic.ui.scroll").service("$ionicScrollDelegate",e(["resize","scrollTop","scrollBottom","scrollTo","anchorScroll","rememberScrollPosition","forgetScrollPosition","scrollToRememberedPosition"])).factory("$$scrollValueCache",function(){return{}}).controller("$ionicScroll",["$scope","scrollViewOptions","$timeout","$window","$$scrollValueCache","$location","$rootScope","$document","$ionicScrollDelegate",function(e,t,n,i,o,r,a,c,s){var l=this;this._scrollViewOptions=t;var u=this.element=t.el,d=this.$element=angular.element(u),f=this.scrollView=new ionic.views.Scroll(t);(d.parent().length?d.parent():d).data("$$ionicScrollController",this);var v=s._registerInstance(this,t.delegateHandle);angular.isDefined(t.bouncing)||ionic.Platform.ready(function(){f.options.bouncing=!ionic.Platform.isAndroid()});var p=angular.bind(f,f.resize);ionic.on("resize",p,i);var g=angular.noop;e.$on("$destroy",function(){v(),ionic.off("resize",p,i),i.removeEventListener("resize",p),g(),l._rememberScrollId&&(o[l._rememberScrollId]=f.getValues())}),d.on("scroll",function(t){var n=(t.originalEvent||t).detail||{};e.$onScroll&&e.$onScroll({event:t,scrollTop:n.scrollTop||0,scrollLeft:n.scrollLeft||0})}),e.$on("$viewContentLoaded",function(e,t){if(!e.defaultPrevented){e.preventDefault();var n=t&&t.viewId;n&&(l.rememberScrollPosition(n),l.scrollToRememberedPosition(),g=a.$on("$viewHistory.viewBack",function(e,t){n===t&&l.forgetScrollPosition()}))}}),n(function(){f.run()}),this._rememberScrollId=null,this.resize=function(){return n(p)},this.scrollTop=function(e){this.resize().then(function(){f.scrollTo(0,0,!!e)})},this.scrollBottom=function(e){this.resize().then(function(){var t=f.getScrollMax();f.scrollTo(t.left,t.top,!!e)})},this.scrollTo=function(e,t,n){this.resize().then(function(){f.scrollTo(e,t,!!n)})},this.anchorScroll=function(e){this.resize().then(function(){var t=r.hash(),n=t&&c[0].getElementById(t);if(t&&n){var i=ionic.DomUtil.getPositionInParent(n,l.$element);f.scrollTo(i.left,i.top,!!e)}else f.scrollTo(0,0,!!e)})},this.rememberScrollPosition=function(e){if(!e)throw new Error("Must supply an id to remember the scroll by!");this._rememberScrollId=e},this.forgetScrollPosition=function(){delete o[this._rememberScrollId],this._rememberScrollId=null},this.scrollToRememberedPosition=function(e){var t=o[this._rememberScrollId];t&&this.resize().then(function(){f.scrollTo(+t.left,+t.top,e)})},this._setRefresher=function(e,t){var n=this.refresher=t,i=l.refresher.clientHeight||0;f.activatePullToRefresh(i,function(){n.classList.add("active"),e.$onPulling()},function(){n.classList.remove("refreshing"),n.classList.remove("active")},function(){n.classList.add("refreshing"),e.$onRefresh()})}}])}(); \ No newline at end of file diff --git a/release/js/ionic.bundle.js b/release/js/ionic.bundle.js index a5e9eae5df..67e0abc9b5 100644 --- a/release/js/ionic.bundle.js +++ b/release/js/ionic.bundle.js @@ -8,7 +8,7 @@ * Copyright 2014 Drifty Co. * http://drifty.com/ * - * Ionic, v0.9.27 + * Ionic, v1.0.0-beta.1 * A powerful HTML5 mobile app framework. * http://ionicframework.com/ * @@ -18,13 +18,14 @@ * */ +(function() { // Create namespaces // window.ionic = { controllers: {}, views: {}, - version: '{{ VERSION }}' + version: '1.0.0-beta.1' }; (function(ionic) { @@ -141,16 +142,19 @@ window.ionic = { }; })(ionic); -(function(ionic) { +(function(window, document, ionic) { - var readyCallbacks = [], - domReady = function() { + var readyCallbacks = []; + var isDomReady = false; + + function domReady() { + isDomReady = true; for(var x=0; x startCoordinates.x + HIT_RADIUS || - c.x < startCoordinates.x - HIT_RADIUS || - c.y > startCoordinates.y + HIT_RADIUS || - c.y < startCoordinates.y - HIT_RADIUS); + // Quick check for 0,0 which could be simulated mouse click for form submission + if(c.x === 0 && c.y === 0) { + return false; + } + + return (c.x > startCoordinates.x + 2 || + c.x < startCoordinates.x - 2 || + c.y > startCoordinates.y + 2 || + c.y < startCoordinates.y - 2); } function recordCoordinates(event) { @@ -2488,23 +2498,19 @@ window.ionic = { gesture.originalEvent.changedTouches[0]) || touches[0].originalEvent || touches[0]; - if(e) return { x: e.clientX, y: e.clientY }; + if(e) return { x: e.clientX || e.pageX, y: e.clientY || e.pageY }; } return { x:0, y:0 }; } + var clickPreventTimerId; function removeClickPrevent(e) { - setTimeout(function(){ + clearTimeout(clickPreventTimerId); + clickPreventTimerId = setTimeout(function(){ var tap = isRecentTap(e); if(tap) delete tapCoordinates[tap.id]; + startCoordinates = {}; }, REMOVE_PREVENT_DELAY); - - setTimeout(function(){ - for(var hitKey in hitElements) { - hitElements[hitKey] && hitElements[hitKey].classList.remove('active'); - delete hitElements[hitKey]; - } - }, 150); } function stopEvent(e){ @@ -2516,8 +2522,7 @@ window.ionic = { function blurActive() { var ele = document.activeElement; if(ele && (ele.tagName === "INPUT" || - ele.tagName === "TEXTAREA" || - ele.tagName === "SELECT")) { + ele.tagName === "TEXTAREA")) { // using a timeout to prevent funky scrolling while a keyboard hides setTimeout(function(){ ele.blur(); @@ -2527,46 +2532,143 @@ window.ionic = { function recordStartCoordinates(e) { startCoordinates = getCoordinates(e); - - var x, ele = e.target; - for(x=0; x<5; x++) { - if(!ele || ele.tagName === 'LABEL') break; - if( ele.classList.contains('item') || ele.classList.contains('button') ) { - hitElements[hitCounts] = ele; - hitCounts = (hitCounts > 24 ? 0 : hitCounts + 1); - ionic.requestAnimationFrame(function(){ - ele.classList.add('active'); - }); - break; - } - ele = ele.parentElement; - } } var tapCoordinates = {}; // used to remember coordinates to ignore if they happen again quickly var startCoordinates = {}; // used to remember where the coordinates of the start of the tap var CLICK_PREVENT_DURATION = 1500; // max milliseconds ghostclicks in the same area should be prevented - var REMOVE_PREVENT_DELAY = 375; // delay after a touchend/mouseup before removing the ghostclick prevent + var REMOVE_PREVENT_DELAY = 380; // delay after a touchend/mouseup before removing the ghostclick prevent var HIT_RADIUS = 15; - var hitElements = {}; - var hitCounts = 0; - // set global click handler and check if the event should stop or not - document.addEventListener('click', preventGhostClick, true); + ionic.Platform.ready(function(){ - // global tap event listener polyfill for HTML elements that were "tapped" by the user - ionic.on("tap", tapPolyfill, document); + if(ionic.Platform.grade === 'c') { + // low performing phones should have a longer ghostclick prevent + REMOVE_PREVENT_DELAY = 800; + } - // listeners used to remove ghostclick prevention - document.addEventListener('touchend', removeClickPrevent, false); - document.addEventListener('mouseup', removeClickPrevent, false); + // set global click handler and check if the event should stop or not + document.addEventListener('click', preventGhostClick, true); - // in the case the user touched the screen, then scrolled, it shouldn't fire the click - document.addEventListener('touchstart', recordStartCoordinates, false); - document.addEventListener('mousedown', recordStartCoordinates, false); + // global release event listener polyfill for HTML elements that were tapped or held + ionic.on("release", tapPolyfill, document); + + // listeners used to remove ghostclick prevention + document.addEventListener('touchend', removeClickPrevent, false); + document.addEventListener('mouseup', removeClickPrevent, false); + + // in the case the user touched the screen, then scrolled, it shouldn't fire the click + document.addEventListener('touchstart', recordStartCoordinates, false); + document.addEventListener('mousedown', recordStartCoordinates, false); + }); })(this, document, ionic); +(function(document, ionic) { + 'use strict'; + + var queueElements = {}; // elements that should get an active state in XX milliseconds + var activeElements = {}; // elements that are currently active + var keyId = 0; // a counter for unique keys for the above ojects + + ionic.activator = { + + start: function(e) { + // when an element is touched/clicked, it climbs up a few + // parents to see if it is an .item or .button element + ionic.requestAnimationFrame(function(){ + var ele = e.target; + var eleToActivate; + + for(var x=0; x<4; x++) { + if(!ele) break; + if(eleToActivate && ele.classList.contains('item')) { + eleToActivate = ele; + break; + } + if( ele.tagName == 'A' || ele.tagName == 'BUTTON' || ele.getAttribute('ng-click') ) { + eleToActivate = ele; + } + if( ele.classList.contains('button') ) { + eleToActivate = ele; + break; + } + ele = ele.parentElement; + } + + if(eleToActivate) { + // queue that this element should be set to active + queueElements[keyId] = eleToActivate; + + // in XX milliseconds, set the queued elements to active + // add listeners to clear all queued/active elements onMove + if(e.type === 'touchstart') { + document.body.removeEventListener('mousedown', ionic.activator.start); + document.body.addEventListener('touchmove', clear, false); + setTimeout(activateElements, 85); + } else { + document.body.addEventListener('mousemove', clear, false); + ionic.requestAnimationFrame(activateElements); + } + + keyId = (keyId > 19 ? 0 : keyId + 1); + } + + }); + } + }; + + function activateElements() { + // activate all elements in the queue + for(var key in queueElements) { + if(queueElements[key]) { + queueElements[key].classList.add('active'); + activeElements[key] = queueElements[key]; + } + } + queueElements = {}; + } + + function deactivateElements() { + for(var key in activeElements) { + if(activeElements[key]) { + activeElements[key].classList.remove('active'); + delete activeElements[key]; + } + } + } + + function onEnd(e) { + // clear out any active/queued elements after XX milliseconds + setTimeout(clear, 200); + } + + function clear() { + // clear out any elements that are queued to be set to active + queueElements = {}; + + // in the next frame, remove the active class from all active elements + ionic.requestAnimationFrame(deactivateElements); + + // remove onMove listeners that clear out active elements + document.body.removeEventListener('mousemove', clear); + document.body.removeEventListener('touchmove', clear); + } + + // use window.onload because this doesn't need to run immediately + window.addEventListener('load', function(){ + // start an active element + document.body.addEventListener('touchstart', ionic.activator.start, false); + document.body.addEventListener('mousedown', ionic.activator.start, false); + + // clear all active elements after XX milliseconds + document.body.addEventListener('touchend', onEnd, false); + document.body.addEventListener('mouseup', onEnd, false); + document.body.addEventListener('touchcancel', onEnd, false); + }, false); + +})(document, ionic); + (function(ionic) { /* for nextUid() function below */ @@ -2779,12 +2881,12 @@ function androidKeyboardFix() { //If the height changes, and it's less than before, we have a keyboard open } else if (rememberedDeviceHeight !== window.innerHeight && window.innerHeight < rememberedDeviceHeight) { - document.body.classList.add('hide-footer'); + document.body.classList.add('footer-hide'); //Wait for next frame so document.activeElement is set ionic.requestAnimationFrame(handleKeyboardChange); } else { //Otherwise we have a keyboard close or a *really* weird resize - document.body.classList.remove('hide-footer'); + document.body.classList.remove('footer-hide'); } function handleKeyboardChange() { @@ -2856,7 +2958,7 @@ var IS_EMBEDDED_OBJECT_REGEX = /object|embed/i; // Create namespaces if (!global.core) { - global.core = { effect : {} }; + var core = global.core = { effect : {} }; } else if (!core.effect) { core.effect = {}; @@ -3442,8 +3544,9 @@ ionic.views.Scroll = ionic.views.View.inherit({ function shouldIgnorePress(e) { // Don't react if initial down happens on a form element return e.target.tagName.match(IS_INPUT_LIKE_REGEX) || - e.target.isContentEditable || - e.target.tagName.match(IS_EMBEDDED_OBJECT_REGEX); + e.target.isContentEditable || + e.target.tagName.match(IS_EMBEDDED_OBJECT_REGEX) || + e.target.dataset.preventScroll; } @@ -3508,8 +3611,18 @@ ionic.views.Scroll = ionic.views.View.inherit({ mousedown = false; }, false); + var wheelShowBarFn = ionic.debounce(function() { + self.__fadeScrollbars('in'); + }, 500, true); + + var wheelHideBarFn = ionic.debounce(function() { + self.__fadeScrollbars('out'); + }, 100, false); + document.addEventListener("mousewheel", function(e) { + wheelShowBarFn(); self.scrollBy(e.wheelDeltaX/self.options.wheelDampen, -e.wheelDeltaY/self.options.wheelDampen); + wheelHideBarFn(); }); } }, @@ -3564,9 +3677,6 @@ ionic.views.Scroll = ionic.views.View.inherit({ __resizeScrollbars: function() { var self = this; - // Bring the scrollbars in to show the content change - self.__fadeScrollbars('in'); - // Update horiz bar if(self.__indicatorX) { var width = Math.max(Math.round(self.__clientWidth * self.__clientWidth / (self.__contentWidth)), 20); @@ -4181,8 +4291,6 @@ ionic.views.Scroll = ionic.views.View.inherit({ var self = this; - self.__fadeScrollbars('in'); - // Reset interruptedAnimation flag self.__interruptedAnimation = true; @@ -4425,6 +4533,7 @@ ionic.views.Scroll = ionic.views.View.inherit({ self.__isDragging = (self.__enableScrollX || self.__enableScrollY) && (distanceX >= minimumTrackingForDrag || distanceY >= minimumTrackingForDrag); if (self.__isDragging) { self.__interruptedAnimation = false; + self.__fadeScrollbars('in'); } } @@ -4927,15 +5036,6 @@ ionic.views.Scroll = ionic.views.View.inherit({ (function(ionic) { 'use strict'; - /** - * @ngdoc controller - * @name ionicBar - * @module ionic - * @group page layout - * @description - * Controller for the {@link ionic.directive:ionHeaderBar} and - * {@link ionic.directive:ionFooterBar} directives. - */ ionic.views.HeaderBar = ionic.views.View.inherit({ initialize: function(opts) { this.el = opts.el; @@ -4947,16 +5047,6 @@ ionic.views.Scroll = ionic.views.View.inherit({ this.align(); }, - /** - * @ngdoc method - * @name ionicBar#align - * @description - * Aligns the title text with the buttons in the bar - * so that the title size is maximized and aligned correctly - * as much as possible. - * @param {string=} direction Which direction to align the title towards. - * Available: 'left', 'right', 'center'. Default: 'center'. - */ align: function(align) { align || (align = this.alignTitle); @@ -5040,7 +5130,7 @@ ionic.views.Scroll = ionic.views.View.inherit({ var ITEM_OPTIONS_CLASS = 'item-options'; var ITEM_PLACEHOLDER_CLASS = 'item-placeholder'; var ITEM_REORDERING_CLASS = 'item-reordering'; - var ITEM_DRAG_CLASS = 'item-drag'; + var ITEM_REORDER_BTN_CLASS = 'item-reorder'; var DragOp = function() {}; DragOp.prototype = { @@ -5049,6 +5139,9 @@ ionic.views.Scroll = ionic.views.View.inherit({ drag: function(e) { }, end: function(e) { + }, + isSameItem: function(item) { + return false; } }; @@ -5060,6 +5153,7 @@ ionic.views.Scroll = ionic.views.View.inherit({ }; SlideDrag.prototype = new DragOp(); + SlideDrag.prototype.start = function(e) { var content, buttons, offsetX, buttonsWidth; @@ -5097,6 +5191,27 @@ ionic.views.Scroll = ionic.views.View.inherit({ }; }; + /** + * Check if this is the same item that was previously dragged. + */ + SlideDrag.prototype.isSameItem = function(op) { + if(op._lastDrag && this._currentDrag) { + return this._currentDrag.content == op._lastDrag.content; + } + return false; + }; + + SlideDrag.prototype.clean = function(e) { + var lastDrag = this._lastDrag; + + if(!lastDrag) return; + + ionic.requestAnimationFrame(function() { + lastDrag.content.style[ionic.CSS.TRANSITION] = ''; + lastDrag.content.style[ionic.CSS.TRANSFORM] = 'translate3d(0, 0, 0)'; + }); + }; + SlideDrag.prototype.drag = ionic.animationFrameThrottle(function(e) { var buttonsWidth; @@ -5157,21 +5272,7 @@ ionic.views.Scroll = ionic.views.View.inherit({ } - // var content = this._currentDrag.content; - - // var onRestingAnimationEnd = function(e) { - // if(e.propertyName == '-webkit-transform') { - // if(content) content.classList.remove(ITEM_SLIDING_CLASS); - // } - // e.target.removeEventListener('webkitTransitionEnd', onRestingAnimationEnd); - // }; - ionic.requestAnimationFrame(function() { - // var currentX = parseFloat(_this._currentDrag.content.style[ionic.CSS.TRANSFORM].replace('translate3d(', '').split(',')[0]) || 0; - // if(currentX !== restingPoint) { - // _this._currentDrag.content.classList.add(ITEM_SLIDING_CLASS); - // _this._currentDrag.content.addEventListener('webkitTransitionEnd', onRestingAnimationEnd); - // } if(restingPoint === 0) { _this._currentDrag.content.style[ionic.CSS.TRANSFORM] = ''; } else { @@ -5181,9 +5282,9 @@ ionic.views.Scroll = ionic.views.View.inherit({ // Kill the current drag + _this._lastDrag = _this._currentDrag; _this._currentDrag = null; - // We are done, notify caller doneCallback && doneCallback(); }); @@ -5337,7 +5438,8 @@ ionic.views.Scroll = ionic.views.View.inherit({ opts = ionic.extend({ onReorder: function(el, oldIndex, newIndex) {}, virtualRemoveThreshold: -200, - virtualAddThreshold: 200 + virtualAddThreshold: 200, + canSwipe: false }, opts); ionic.extend(this, opts); @@ -5352,10 +5454,6 @@ ionic.views.Scroll = ionic.views.View.inherit({ this.onRefreshOpening = opts.onRefreshOpening || function() {}; this.onRefreshHolding = opts.onRefreshHolding || function() {}; - window.ionic.onGesture('touch', function(e) { - _this._handleTouch(e); - }, this.el); - window.ionic.onGesture('release', function(e) { _this._handleEndDrag(e); }, this.el); @@ -5433,10 +5531,22 @@ ionic.views.Scroll = ionic.views.View.inherit({ } }, + /** + * Clear any active drag effects on the list. + */ + clearDragEffects: function() { + if(this._lastDragOp) { + this._lastDragOp.clean && this._lastDragOp.clean(); + this._lastDragOp = null; + } + }, + _initDrag: function() { //ionic.views.ListView.__super__._initDrag.call(this); - //this._isDragging = false; + // Store the last one + this._lastDragOp = this._dragOp; + this._dragOp = null; }, @@ -5455,10 +5565,14 @@ ionic.views.Scroll = ionic.views.View.inherit({ _startDrag: function(e) { var _this = this; + var didStart = false; + this._isDragging = false; + var lastDragOp = this._lastDragOp; + // Check if this is a reorder drag - if(ionic.DomUtil.getParentOrSelfWithClass(e.target, ITEM_DRAG_CLASS) && (e.gesture.direction == 'up' || e.gesture.direction == 'down')) { + if(ionic.DomUtil.getParentOrSelfWithClass(e.target, ITEM_REORDER_BTN_CLASS) && (e.gesture.direction == 'up' || e.gesture.direction == 'down')) { var item = this._getItem(e.target); if(item) { @@ -5472,20 +5586,25 @@ ionic.views.Scroll = ionic.views.View.inherit({ }); this._dragOp.start(e); e.preventDefault(); - return; } } // Or check if this is a swipe to the side drag else if(!this._didDragUpOrDown && (e.gesture.direction == 'left' || e.gesture.direction == 'right') && Math.abs(e.gesture.deltaX) > 5) { - this._dragOp = new SlideDrag({ el: this.el }); - this._dragOp.start(e); - e.preventDefault(); - return; + + // Make sure this is an item with buttons + var item = this._getItem(e.target); + if(item && item.querySelector('.item-options')) { + this._dragOp = new SlideDrag({ el: this.el }); + this._dragOp.start(e); + e.preventDefault(); + } } - // We aren't handling it, so pass it up the chain - //ionic.views.ListView.__super__._startDrag.call(this, e); + // If we had a last drag operation and this is a new one on a different item, clean that last one + if(lastDragOp && this._dragOp && !this._dragOp.isSameItem(lastDragOp) && e.defaultPrevented) { + lastDragOp.clean && lastDragOp.clean(); + } }, @@ -5499,13 +5618,6 @@ ionic.views.Scroll = ionic.views.View.inherit({ return; } - // Cancel touch timeout - clearTimeout(this._touchTimeout); - var items = _this.el.querySelectorAll('.item'); - for(var i = 0, l = items.length; i < l; i++) { - items[i].classList.remove('active'); - } - this._dragOp.end(e, function() { _this._initDrag(); }); @@ -5517,17 +5629,14 @@ ionic.views.Scroll = ionic.views.View.inherit({ _handleDrag: function(e) { var _this = this, content, buttons; + if (!this.canSwipe) { + return; + } + if(Math.abs(e.gesture.deltaY) > 5) { this._didDragUpOrDown = true; } - // If the user has a touch timeout to highlight an element, clear it if we - // get sufficient draggage - if(Math.abs(e.gesture.deltaX) > 10 || Math.abs(e.gesture.deltaY) > 10) { - clearTimeout(this._touchTimeout); - } - - clearTimeout(this._touchTimeout); // If we get a drag event, make sure we aren't in another drag, then check if we should // start one if(!this.isDragging && !this._dragOp) { @@ -5542,25 +5651,7 @@ ionic.views.Scroll = ionic.views.View.inherit({ e.gesture.srcEvent.preventDefault(); this._dragOp.drag(e); - }, - - /** - * Handle the touch event to show the active state on an item if necessary. - */ - _handleTouch: function(e) { - var _this = this; - - var item = ionic.DomUtil.getParentOrSelfWithClass(e.target, ITEM_CLASS); - if(!item) { return; } - - this._touchTimeout = setTimeout(function() { - var items = _this.el.querySelectorAll('.item'); - for(var i = 0, l = items.length; i < l; i++) { - items[i].classList.remove('active'); - } - item.classList.add('active'); - }, 250); - }, + } }); @@ -5584,7 +5675,7 @@ ionic.views.Scroll = ionic.views.View.inherit({ this.showDelay = opts.showDelay || 0; - this._loadingBox = this.el.querySelector('.loading'); + this._loadingBox = this.el.querySelector('.loading') || this.el; }, show: function() { var _this = this; @@ -5613,6 +5704,11 @@ ionic.views.Scroll = ionic.views.View.inherit({ window.clearTimeout(this._showDelayTimeout); this.el.classList.remove('active'); + }, + setContent: function(html) { + if (this._loadingBox) { + this._loadingBox.innerHTML = html || ''; + } } }); @@ -5794,14 +5890,6 @@ ionic.views.Scroll = ionic.views.View.inherit({ * */ -/** - * @ngdoc controller - * @name ionicSlideBox - * @module ionic - * @description - * Controller for the {@link ionic.directive:ionSlideBox} directive. - */ - (function(ionic) { 'use strict'; @@ -6257,16 +6345,13 @@ ionic.views.Slider = ionic.views.View.inherit({ } // Public API + this.update = function() { + setTimeout(setup); + }; this.setup = function() { setup(); }; - /** - * @ngdoc method - * @name ionicSlideBox#slide - * @param {number} to The index to slide to. - * @param {number=} speed The number of milliseconds for the change to take. - */ this.slide = function(to, speed) { // cancel slideshow stop(); @@ -6274,23 +6359,13 @@ ionic.views.Slider = ionic.views.View.inherit({ slide(to, speed); }; - /** - * @ngdoc method - * @name ionicSlideBox#prev - * @description Go to the previous slide. Wraps around if at the beginning. - */ - this.prev = function() { + this.prev = this.previous = function() { // cancel slideshow stop(); prev(); }; - /** - * @ngdoc method - * @name ionicSlideBox#next - * @description Go to the next slide. Wraps around if at the end. - */ this.next = function() { // cancel slideshow stop(); @@ -6298,32 +6373,16 @@ ionic.views.Slider = ionic.views.View.inherit({ next(); }; - /** - * @ngdoc method - * @name ionicSlideBox#stop - * @description Stop sliding. The slideBox will not move again until - * explicitly told to do so. - */ this.stop = function() { // cancel slideshow stop(); }; - /** - * @ngdoc method - * @name ionicSlideBox#currentIndex - * @returns number The index of the current slide. - */ this.currentIndex = function() { // return current index position return index; }; - /** - * @ngdoc method - * @name ionicSlideBox#slidesCount - * @returns number The number of slides there are currently. - */ this.slidesCount = function() { // return total number of slides return length; @@ -7002,13 +7061,24 @@ ionic.controllers.NavController = ionic.controllers.ViewController.inherit({ }; }, + isOpenLeft: function() { + return this.getOpenAmount() > 0; + }, + + isOpenRight: function() { + return this.getOpenAmount() < 0; + }, + /** * Toggle the left menu to open 100% */ - toggleLeft: function() { - this.content.enableAnimation(); + toggleLeft: function(shouldOpen) { var openAmount = this.getOpenAmount(); - if(openAmount > 0) { + if (arguments.length === 0) { + shouldOpen = openAmount <= 0; + } + this.content.enableAnimation(); + if(!shouldOpen) { this.openPercentage(0); } else { this.openPercentage(100); @@ -7018,10 +7088,13 @@ ionic.controllers.NavController = ionic.controllers.ViewController.inherit({ /** * Toggle the right menu to open 100% */ - toggleRight: function() { - this.content.enableAnimation(); + toggleRight: function(shouldOpen) { var openAmount = this.getOpenAmount(); - if(openAmount < 0) { + if (arguments.length === 0) { + shouldOpen = openAmount >= 0; + } + this.content.enableAnimation(); + if(!shouldOpen) { this.openPercentage(0); } else { this.openPercentage(-100); @@ -7388,6 +7461,7 @@ ionic.controllers.TabBarController = ionic.controllers.ViewController.inherit({ })(window.ionic); +})(); /*! * ionic.bundle.js is a concatenation of: * ionic.js, angular.js, angular-animate.js, @@ -32103,7 +32177,7 @@ angular.module('ui.router.compat') * Copyright 2014 Drifty Co. * http://drifty.com/ * - * Ionic, v0.9.27 + * Ionic, v1.0.0-beta.1 * A powerful HTML5 mobile app framework. * http://ionicframework.com/ * @@ -32113,6 +32187,7 @@ angular.module('ui.router.compat') * */ +(function() { /** * Create a wrapping module to ease having to include too many * modules. @@ -32138,33 +32213,25 @@ angular.module('ionic.service', [ 'ionic.decorator.location' ]); -// UI specific services and delegates -angular.module('ionic.ui.service', [ - 'ionic.ui.service.scrollDelegate', - 'ionic.ui.service.slideBoxDelegate', - 'ionic.ui.service.sideMenuDelegate', -]); - angular.module('ionic.ui', [ - 'ionic.ui.content', - 'ionic.ui.scroll', - 'ionic.ui.tabs', - 'ionic.ui.viewState', - 'ionic.ui.header', - 'ionic.ui.sideMenu', - 'ionic.ui.slideBox', - 'ionic.ui.list', - 'ionic.ui.checkbox', - 'ionic.ui.toggle', - 'ionic.ui.radio', - 'ionic.ui.touch', - 'ionic.ui.popup' - ]); - + 'ionic.ui.checkbox', + 'ionic.ui.content', + 'ionic.ui.header', + 'ionic.ui.list', + 'ionic.ui.navBar', + 'ionic.ui.popup', + 'ionic.ui.radio', + 'ionic.ui.scroll', + 'ionic.ui.sideMenu', + 'ionic.ui.slideBox', + 'ionic.ui.tabs', + 'ionic.ui.toggle', + 'ionic.ui.touch', + 'ionic.ui.viewState' +]); angular.module('ionic', [ 'ionic.service', - 'ionic.ui.service', 'ionic.ui', // Angular deps @@ -32228,6 +32295,86 @@ angular.element.prototype.removeClass = function(cssClasses) { return this; }; + +function delegateService(methodNames) { + return ['$log', function($log) { + var delegate = this; + + var instances = this._instances = []; + this._registerInstance = function(instance, handle) { + handle || (handle = ionic.Utils.nextUid()); + + instance.$$delegateHandle = handle; + instances.push(instance); + + return function deregister() { + var index = instances.indexOf(instance); + if (index !== -1) { + instances.splice(index, 1); + } + }; + }; + + this.$getByHandle = function(handle) { + if (!handle) { + return delegate; + } + return new InstanceForHandle(handle); + }; + + /* + * Creates a new object that will have all the methodNames given, + * and call them on the given the controller instance matching given + * handle. + * The reason we don't just let $getByHandle return the controller instance + * itself is that the controller instance might not exist yet. + * + * We want people to be able to do + * `var instance = $ionicScrollDelegate.$getByHandle('foo')` on controller + * instantiation, but on controller instantiation a child directive + * may not have been compiled yet! + * + * So this is our way of solving this problem: we create an object + * that will only try to fetch the controller with given handle + * once the methods are actually called. + */ + function InstanceForHandle(handle) { + this.handle = handle; + } + methodNames.forEach(function(methodName) { + InstanceForHandle.prototype[methodName] = function() { + var handle = this.handle; + var instancesToUse = instances.filter(function(instance) { + return instance.$$delegateHandle === handle; + }); + if (!instancesToUse.length) { + return $log.warn( + 'Delegate for handle "'+this.handle+'" could not find a', + 'corresponding element with delegate-handle="'+this.handle+'"!', + methodName, 'was not called!'); + } + return callMethod(instancesToUse, methodName, arguments); + }; + delegate[methodName] = function() { + return callMethod(instances, methodName, arguments); + }; + + function callMethod(instancesToUse, methodName, args) { + var finalResult; + var result; + instancesToUse.forEach(function(instance, index) { + result = instance[methodName].apply(instance, args); + //Make it so the first result is the one returned + if (index === 0) { + finalResult = result; + } + }); + return finalResult; + } + }); + }]; +} + angular.module('ionic.service.actionSheet', ['ionic.service.templateLoad', 'ionic.service.platform', 'ionic.ui.actionSheet', 'ngAnimate']) /** @@ -32506,6 +32653,7 @@ angular.module('ionic.service.loading', ['ionic.ui.loading']) * @returns {object} A shown loader with the following methods: * - `hide()` - Hides the loader. * - `show()` - Shows the loader. + * - `setContent(string)` - Sets the html content of the loader. */ show: function(opts) { var defaults = { @@ -32553,7 +32701,6 @@ angular.module('ionic.service.modal', ['ionic.service.templateLoad', 'ionic.serv * @ngdoc service * @name $ionicModal * @module ionic - * @controller ionicModal * @description * The Modal is a content pane that can go over the user's main view * temporarily. Usually used for making a choice or editing an item. @@ -32784,7 +32931,6 @@ angular.module('ionic.service.platform', []) * @ngdoc service * @name $ionicPlatform * @module ionic - * @group utilities * @description * An angular abstraction of {@link ionic.utility:ionic.Platform}. * @@ -32970,8 +33116,10 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad']) console.log('Tapped!', res); }, function(err) { console.log('Err:', err); - }, function(msg) { - console.log('message:', msg); + }, function(popup) { + // If you need to access the popup directly, do it in the notify method + // This is also where you can programatically close the popup: + // popup.close(); }); // A confirm dialog @@ -33023,7 +33171,7 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad']) }); ``` - + */ .factory('$ionicPopup', ['$rootScope', '$q', '$document', '$compile', '$timeout', '$ionicTemplateLoader', function($rootScope, $q, $document, $compile, $timeout, $ionicTemplateLoader) { @@ -33048,6 +33196,15 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad']) } }; + var focusLastButton = function(popup) { + var buttons, lastButton; + buttons = popup.el.querySelectorAll('button'); + lastButton = buttons[buttons.length-1]; + if(lastButton) { + lastButton.focus(); + } + } + // Show a single popup var showSinglePopup = function(popup, opts) { var _this = this; @@ -33058,6 +33215,8 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad']) popup.el.classList.remove('popup-hidden'); popup.el.classList.add('popup-showing'); popup.el.classList.add('active'); + + focusLastButton(popup); }); }; @@ -33067,6 +33226,7 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad']) popup.el.classList.remove('popup-hidden'); popup.el.classList.add('popup-showing'); popup.el.classList.add('active'); + focusLastButton(popup); }); }; @@ -33104,11 +33264,15 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad']) var el = $compile('')($rootScope.$new(true)); $document[0].body.appendChild(el[0]); backdropEl = el; + $document[0].body.classList.add('popup-open'); }; // Remove the backdrop element var removeBackdrop = function() { backdropEl.remove(); + $timeout(function(){ + $document[0].body.classList.remove('popup-open'); + }, 300); }; // Push the new popup onto the stack with the given data and scope. @@ -33155,7 +33319,10 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad']) var constructPopupOnScope = function(element, scope) { var popup = { el: element[0], - scope: scope + scope: scope, + close: function() { + popAndRemove(this); + } }; scope.popup = popup; @@ -33164,8 +33331,8 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad']) } var buildPopupTemplate = function(opts, content) { - return '' - + (content || '') + + return '' + + (content || '') + ''; }; @@ -33221,18 +33388,25 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad']) }; + // Public API return { + /** + * @private + */ showPopup: function(data) { var q = $q.defer(); createPopup(data, q).then(function(popup, scope) { + // Send the popup back + q.notify(popup); + // We constructed the popup, push it on the stack and show it pushAndShow(popup, data); }, function(err) { - console.error('Unable to load popup:', err); + void 0; }); return q.promise; @@ -33243,7 +33417,8 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad']) * @name $ionicPopup#show * @description show a complex popup. This is the master show function for all popups * @param {data} object The options for showing a popup, of the form: - * + * @returns {Promise} an Angular promise which resolves when the user enters the correct data, and also + * sends the constructed popup in the notify function (for programatic closing, as shown in the example above). * ``` * { * content: '', // String. The content of the popup @@ -33251,7 +33426,7 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad']) * subTitle: '', // String (optional). The sub-title of the popup * templateUrl: '', // URL String (optional). The URL of a template to load as the content (instead of the `content` field) * scope: null, // Scope (optional). A scope to apply to the popup content (for using ng-model in a template, for example) - * buttons: + * buttons: * [ * { * text: 'Cancel', @@ -33274,7 +33449,7 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad']) * } * } * ] - * + * * } * ``` */ @@ -33291,7 +33466,7 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad']) * * ```javascript * $ionicPopup.alert({ - * title: 'Hey!;, + * title: 'Hey!', * content: 'Don\'t do that!' * }).then(function(res) { * // Accepted @@ -33384,7 +33559,7 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad']) * @ngdoc method * @name $ionicPopup#prompt * @description show a simple prompt dialog. - * + * * ```javascript * $ionicPopup.prompt({ * title: 'Password Check', @@ -33437,7 +33612,7 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad']) ] }); } - + }; }]); @@ -33585,6 +33760,7 @@ angular.module('ionic.service.view', ['ui.router', 'ionic.service.platform']) currentView = viewHistory.currentView, backView = viewHistory.backView, forwardView = viewHistory.forwardView, + nextViewOptions = this.nextViewOptions(), rsp = { viewId: null, navAction: null, @@ -33618,7 +33794,7 @@ angular.module('ionic.service.view', ['ui.router', 'ionic.service.platform']) // they went back one, set the old current view as a forward view rsp.viewId = backView.viewId; rsp.navAction = 'moveBack'; - currentView.scrollValues = {}; //when going back, erase scrollValues + rsp.viewId = backView.viewId; if(backView.historyId === currentView.historyId) { // went back in the same history rsp.navDirection = 'back'; @@ -33692,13 +33868,23 @@ angular.module('ionic.service.view', ['ui.router', 'ionic.service.platform']) stateName: this.getCurrentStateName(), stateParams: this.getCurrentStateParams(), url: $location.url(), - scrollValues: null }); + if (rsp.navAction == 'moveBack') { + //moveBack(from, to); + $rootScope.$emit('$viewHistory.viewBack', currentView.viewId, rsp.viewId); + } + // add the new view to this history's stack hist.stack.push(viewHistory.views[rsp.viewId]); } + if(nextViewOptions) { + if(nextViewOptions.disableAnimate) rsp.navDirection = null; + if(nextViewOptions.disableBack) viewHistory.views[rsp.viewId].backViewId = null; + this.nextViewOptions(null); + } + this.setNavViews(rsp.viewId); hist.cursor = viewHistory.currentView.index; @@ -33848,6 +34034,14 @@ angular.module('ionic.service.view', ['ui.router', 'ionic.service.platform']) return { historyId: 'root', scope: $rootScope }; }, + nextViewOptions: function(opts) { + if(arguments.length) { + this._nextOpts = opts; + } else { + return this._nextOpts; + } + }, + getRenderer: function(navViewElement, navViewAttrs, navViewScope) { var service = this; var registerData; @@ -34003,293 +34197,29 @@ angular.module('ionic.decorator.location', []) * @private */ .config(['$provide', function($provide) { + function $LocationDecorator($location, $timeout) { + + $location.__hash = $location.hash; + //Fix: when window.location.hash is set, the scrollable area + //found nearest to body's scrollTop is set to scroll to an element + //with that ID. + $location.hash = function(value) { + if (angular.isDefined(value)) { + $timeout(function() { + var scroll = document.querySelector('.scroll-content'); + if (scroll) + scroll.scrollTop = 0; + }, 0, false); + } + return $location.__hash(value); + }; + + return $location; + } + $provide.decorator('$location', ['$delegate', '$timeout', $LocationDecorator]); }]); -function $LocationDecorator($location, $timeout) { - - $location.__hash = $location.hash; - //Fix: when window.location.hash is set, the scrollable area - //found nearest to body's scrollTop is set to scroll to an element - //with that ID. - $location.hash = function(value) { - if (angular.isDefined(value)) { - $timeout(function() { - var scroll = document.querySelector('.scroll-content'); - if (scroll) - scroll.scrollTop = 0; - }, 0, false); - } - return $location.__hash(value); - }; - - return $location; -} - -(function() { -'use strict'; - -angular.module('ionic.ui.service.scrollDelegate', []) - -/** - * @ngdoc service - * @name $ionicScrollDelegate - * @module ionic - * @group page layout - * @description - * Allows you to have some control over a scrollable area (created by an - * {@link ionic.directive:ionContent} or {@link ionic.directive:ionScroll} - * directive). - * - * Inject it into a controller, and its methods will send messages to the nearest scrollView and all of its children. - * - * @usage - * ```html - * - * - * - * ``` - * ```js - * function MyController($scope, $ionicScrollDelegate) { - * $scope.scrollToTop = function() { - * $ionicScrollDelegate.scrollTop(); - * }; - * } - * ``` - */ -.factory('$ionicScrollDelegate', ['$rootScope', '$timeout', '$q', '$anchorScroll', '$location', '$document', function($rootScope, $timeout, $q, $anchorScroll, $location, $document) { - return { - /** - * @ngdoc method - * @name $ionicScrollDelegate#scrollTop - * @param {boolean=} shouldAnimate Whether the scroll should animate. - */ - scrollTop: function(animate) { - $rootScope.$broadcast('scroll.scrollTop', animate); - }, - /** - * @ngdoc method - * @name $ionicScrollDelegate#scrollBottom - * @param {boolean=} shouldAnimate Whether the scroll should animate. - */ - scrollBottom: function(animate) { - $rootScope.$broadcast('scroll.scrollBottom', animate); - }, - /** - * @ngdoc method - * @name $ionicScrollDelegate#scroll - * @param {number} left The x-value to scroll to. - * @param {number} top The y-value to scroll to. - * @param {boolean=} shouldAnimate Whether the scroll should animate. - */ - scrollTo: function(left, top, animate) { - $rootScope.$broadcast('scroll.scrollTo', left, top, animate); - }, - /** - * @ngdoc method - * @name $ionicScrollDelegate#anchorScroll - * @description Tell the scrollView to scroll to the element with an id - * matching window.location.hash. - * - * If no matching element is found, it will scroll to top. - * - * @param {boolean=} shouldAnimate Whether the scroll should animate. - */ - anchorScroll: function(animate) { - $rootScope.$broadcast('scroll.anchorScroll', animate); - }, - /** - * @ngdoc method - * @name $ionicScrollDelegate#resize - * @description Tell the scrollView to recalculate the size of its container. - */ - resize: function() { - $rootScope.$broadcast('scroll.resize'); - }, - /** - * @private - */ - tapScrollToTop: function(element, animate) { - var _this = this; - if (!angular.isDefined(animate)) { - animate = true; - } - - ionic.on('tap', function(e) { - var target = e.target; - //Don't scroll to top for a button click - if (ionic.DomUtil.getParentOrSelfWithClass(target, 'button')) { - return; - } - - var el = element[0]; - var bounds = el.getBoundingClientRect(); - - if(ionic.DomUtil.rectContains(e.gesture.touches[0].pageX, e.gesture.touches[0].pageY, bounds.left, bounds.top, bounds.left + bounds.width, bounds.top + 20)) { - _this.scrollTop(animate); - } - }, element[0]); - }, - - finishRefreshing: function($scope) { - $scope.$broadcast('scroll.refreshComplete'); - }, - - /** - * @private - * Attempt to get the current scroll view in scope (if any) - * - * Note: will not work in an isolated scope context. - */ - getScrollView: function($scope) { - return $scope.scrollView; - }, - - /** - * @private - * Register a scope and scroll view for scroll event handling. - * $scope {Scope} the scope to register and listen for events - */ - register: function($scope, $element, scrollView) { - - var scrollEl = $element[0]; - - function scrollViewResize() { - // Run the resize after this digest - return $timeout(function() { - scrollView.resize(); - }); - } - - $element.on('scroll', function(e) { - var detail = (e.originalEvent || e).detail || {}; - - $scope.$onScroll && $scope.$onScroll({ - event: e, - scrollTop: detail.scrollTop || 0, - scrollLeft: detail.scrollLeft || 0 - }); - - }); - - $scope.$parent.$on('scroll.resize', scrollViewResize); - - // Called to stop refreshing on the scroll view - $scope.$parent.$on('scroll.refreshComplete', function(e) { - scrollView.finishPullToRefresh(); - }); - - $scope.$parent.$on('scroll.anchorScroll', function(e, animate) { - scrollViewResize().then(function() { - var hash = $location.hash(); - var elm; - if (hash && (elm = document.getElementById(hash)) ) { - var scroll = ionic.DomUtil.getPositionInParent(elm, scrollEl); - scrollView.scrollTo(scroll.left, scroll.top, !!animate); - } else { - scrollView.scrollTo(0,0, !!animate); - } - }); - }); - - $scope.$parent.$on('scroll.scrollTo', function(e, left, top, animate) { - scrollViewResize().then(function() { - scrollView.scrollTo(left, top, !!animate); - }); - }); - $scope.$parent.$on('scroll.scrollTop', function(e, animate) { - scrollViewResize().then(function() { - scrollView.scrollTo(0, 0, !!animate); - }); - }); - $scope.$parent.$on('scroll.scrollBottom', function(e, animate) { - scrollViewResize().then(function() { - var sv = scrollView; - if (sv) { - var max = sv.getScrollMax(); - sv.scrollTo(max.left, max.top, !!animate); - } - }); - }); - } - }; -}]); - -})(ionic); - - -(function() { -'use strict'; - -angular.module('ionic.ui.service.sideMenuDelegate', []) - -.factory('$ionicSideMenuDelegate', ['$rootScope', '$timeout', '$q', function($rootScope, $timeout, $q) { - return { - getSideMenuController: function($scope) { - return $scope.sideMenuController; - }, - close: function($scope) { - if($scope.sideMenuController) { - $scope.sideMenuController.close(); - } - }, - toggleLeft: function($scope) { - if($scope.sideMenuController) { - $scope.sideMenuController.toggleLeft(); - } - }, - toggleRight: function($scope) { - if($scope.sideMenuController) { - $scope.sideMenuController.toggleRight(); - } - }, - openLeft: function($scope) { - if($scope.sideMenuController) { - $scope.sideMenuController.openPercentage(100); - } - }, - openRight: function($scope) { - if($scope.sideMenuController) { - $scope.sideMenuController.openPercentage(-100); - } - } - }; -}]); - -})(); - -(function() { -'use strict'; - -angular.module('ionic.ui.service.slideBoxDelegate', []) - -.factory('$ionicSlideBoxDelegate', ['$rootScope', '$timeout', function($rootScope, $timeout) { - return { - /** - * Trigger a slidebox to update and resize itself - */ - update: function(animate) { - $rootScope.$broadcast('slideBox.update'); - }, - - register: function($scope, $element) { - $scope.$parent.$on('slideBox.update', function(e) { - if(e.defaultPrevented) { - return; - } - $timeout(function() { - $scope.$parent.slideBoxController.setup(); - }); - e.preventDefault(); - }); - } - }; -}]); - -})(ionic); - (function() { 'use strict'; @@ -34352,124 +34282,144 @@ angular.module('ionic.ui.actionSheet', []) angular.module('ionic.ui.header', ['ngAnimate', 'ngSanitize']) -.directive('barHeader', ['$ionicScrollDelegate', function($ionicScrollDelegate) { - return { - restrict: 'C', - link: function($scope, $element, $attr) { - // We want to scroll to top when the top of this element is clicked - $ionicScrollDelegate.tapScrollToTop($element); - } - }; -}]) +.directive('ionNavBar', tapScrollToTopDirective()) +.directive('ionHeaderBar', tapScrollToTopDirective()) /** * @ngdoc directive * @name ionHeaderBar * @module ionic * @restrict E + * * @description - * While Ionic provides simple Header and Footer bars that can be created through - * HTML and CSS alone, Header bars specifically can be extended in order to - * provide dynamic layout features such as auto-title centering and animation. - * They are also used by the Views and Navigation Controller to animate a title - * on navigation and toggle a back button. + * Adds a fixed header bar above some content. * - * The main header bar feature provided is auto title centering. - * In this situation, the title text will center itself until either the - * left or right button content is too wide for the label to center. - * In that case, it will slide left or right until it can fit. - * You can also align the title left for a more Android-friendly header. - * - * Using two-way data binding, the header bar will automatically - * readjust the heading title alignment when the title or buttons change. - * - * @param {string} title The title use on the headerBar. - * @param {expression=} leftButtons Point to an array of buttons to put on the left of the bar. - * @param {expression=} rightButtons Point to an array of buttons to put on the right of the bar. - * @param {string=} type The type of the bar, for example 'bar-positive'. - * @param {string=} align Where to align the title. 'left', 'right', or 'center'. Defaults to 'center'. + * @param {string=} align-title Where to align the title. + * Avaialble: 'left', 'right', or 'center'. Defaults to 'center'. * * @usage * ```html - * + * + *
+ * + *
+ *

Title!

+ *
+ * + *
*
+ * + * Some content! + * * ``` - * */ -.directive('ionHeaderBar', ['$ionicScrollDelegate', function($ionicScrollDelegate) { - return { - restrict: 'E', - replace: true, - transclude: true, - template: '
\ -
\ - \ -
\ -

\ -
\ - \ -
\ -
', +.directive('ionHeaderBar', barDirective(true)) - scope: { - leftButtons: '=', - rightButtons: '=', - title: '@', - type: '@', - alignTitle: '@' - }, - link: function($scope, $element, $attr) { - var hb = new ionic.views.HeaderBar({ - el: $element[0], - alignTitle: $scope.alignTitle || 'center' - }); +/** + * @ngdoc directive + * @name ionFooterBar + * @module ionic + * @restrict E + * + * @description + * Adds a fixed footer bar below some content. + * + * @param {string=} align-title Where to align the title. + * Avaialble: 'left', 'right', or 'center'. Defaults to 'center'. + * + * @usage + * ```html + * + * Some content! + * + * + *
+ * + *
+ *

Title!

+ *
+ * + *
+ *
+ * ``` + */ +.directive('ionFooterBar', barDirective(false)); - $element.addClass($scope.type); +function tapScrollToTopDirective() { + return ['$ionicScrollDelegate', function($ionicScrollDelegate) { + return { + restrict: 'E', + link: function($scope, $element, $attr) { + ionic.on('tap', onTap, $element[0]); + $scope.$on('$destroy', function() { + ionic.off('tap', onTap, $element[0]); + }); - $scope.headerBarView = hb; + function onTap(e) { + if (ionic.DomUtil.getParentOrSelfWithClass(e.target, 'button', 4)) { + return; + } + var touch = e.gesture && e.gesture.touches[0] || e.detail.touches[0]; + var bounds = $element[0].getBoundingClientRect(); + if (ionic.DomUtil.rectContains( + touch.pageX, touch.pageY, + bounds.left, bounds.top - 20, + bounds.left + bounds.width, bounds.top + bounds.height + )) { + $ionicScrollDelegate.scrollTop(true); + } + } + } + }; + }]; +} - $scope.$watchCollection('leftButtons', function(val) { - // Resize the title since the buttons have changed - hb.align(); - }); - $scope.$watchCollection('rightButtons', function(val) { - // Resize the title since the buttons have changed - hb.align(); - }); +function barDirective(isHeader) { + return [function() { + return { + restrict: 'E', + compile: function($element, $attr) { + $element.addClass(isHeader ? 'bar bar-header' : 'bar bar-footer'); - $scope.$watch('title', function(val) { - // Resize the title since the title has changed - hb.align(); - }); - } - }; -}]) + return { pre: prelink }; + function prelink($scope, $element, $attr) { + var hb = new ionic.views.HeaderBar({ + el: $element[0], + alignTitle: $attr.alignTitle || 'center' + }); -.directive('ionFooterBar', function() { - return { - restrict: 'E', - replace: true, - transclude: true, - template: '
\ -
', + var el = $element[0]; + //just incase header is on rootscope + var parentScope = $scope.$parent || $scope; - scope: { - type: '@', - }, - - link: function($scope, $element, $attr) { - $element.addClass($scope.type); - } - }; -}); + if (isHeader) { + $scope.$watch(function() { return el.className; }, function(value) { + var isSubheader = value.indexOf('bar-subheader') !== -1; + parentScope.$hasHeader = !isSubheader; + parentScope.$hasSubheader = isSubheader; + }); + $scope.$on('$destroy', function() { + parentScope.$hasHeader = parentScope.$hasSubheader = null; + }); + } else { + $scope.$watch(function() { return el.className; }, function(value) { + var isSubfooter = value.indexOf('bar-subfooter') !== -1; + parentScope.$hasFooter = !isSubfooter; + parentScope.$hasSubfooter = isSubfooter; + }); + $scope.$on('$destroy', function() { + parentScope.$hasFooter = parentScope.$hasSubfooter = null; + }); + $scope.$watch('$hasTabs', function(val) { + $element.toggleClass('has-tabs', !!val); + }); + } + } + } + }; + }]; +} })(ionic); @@ -34529,7 +34479,7 @@ angular.module('ionic.ui.checkbox', []) (function() { 'use strict'; -angular.module('ionic.ui.content', ['ionic.ui.service', 'ionic.ui.scroll']) +angular.module('ionic.ui.content', ['ionic.ui.scroll']) /** * Panel is a simple 100% width and height, fixed panel. It's meant for content to be @@ -34539,7 +34489,6 @@ angular.module('ionic.ui.content', ['ionic.ui.service', 'ionic.ui.scroll']) * @ngdoc directive * @name ionPane * @module ionic - * @group page layout * @restrict E * * @description A simple container that fits content, with no side effects. Adds the 'pane' class to the element. @@ -34557,12 +34506,12 @@ angular.module('ionic.ui.content', ['ionic.ui.service', 'ionic.ui.scroll']) * @ngdoc directive * @name ionContent * @module ionic - * @group page layout - * @groupMainItem + * @delegate ionic.service:$ionicScrollDelegate + * @restrict E * * @description * The ionContent directive provides an easy to use content area that can be configured - * to use Ionic's custom Scroll View, or the built in overflow scorlling of the browser. + * to use Ionic's custom Scroll View, or the built in overflow scrolling of the browser. * * While we recommend using the custom Scroll features in Ionic in most cases, sometimes * (for performance reasons) only the browser's native overflow scrolling will suffice, @@ -34573,52 +34522,48 @@ angular.module('ionic.ui.content', ['ionic.ui.service', 'ionic.ui.scroll']) * directive, and infinite scrolling with the {@link ionic.directive:ionInfiniteScroll} * directive. * - * @restrict E + * @param {string=} delegate-handle The handle used to identify this scrollView + * with {@link ionic.service:$ionicScrollDelegate}. + * @param {boolean=} padding Whether to add padding to the content. + * of the content. Defaults to true on iOS, false on Android. * @param {boolean=} scroll Whether to allow scrolling of content. Defaults to true. * @param {boolean=} overflow-scroll Whether to use overflow-scrolling instead of * Ionic scroll. - * @param {boolean=} padding Whether to add padding to the content. - * @param {boolean=} has-header Whether to offset the content for a header bar. - * @param {boolean=} has-subheader Whether to offset the content for a subheader bar. - * @param {boolean=} has-footer Whether to offset the content for a footer bar. * @param {boolean=} has-bouncing Whether to allow scrolling to bounce past the edges * of the content. Defaults to true on iOS, false on Android. * @param {expression=} on-scroll Expression to evaluate when the content is scrolled. * @param {expression=} on-scroll-complete Expression to evaluate when a scroll action completes. */ .directive('ionContent', [ - '$parse', '$timeout', - '$ionicScrollDelegate', '$controller', '$ionicBind', -function($parse, $timeout, $ionicScrollDelegate, $controller, $ionicBind) { +function($timeout, $controller, $ionicBind) { return { restrict: 'E', - replace: true, - transclude: true, require: '^?ionNavView', scope: true, - template: - '
' + - '
' + - '
', - compile: function(element, attr, transclude) { - if(attr.hasHeader == "true") { element.addClass('has-header'); } - if(attr.hasSubheader == "true") { element.addClass('has-subheader'); } - if(attr.hasFooter == "true") { element.addClass('has-footer'); } - if(attr.hasTabs == "true") { element.addClass('has-tabs'); } - if(attr.padding == "true") { element.find('div').addClass('padding'); } + compile: function(element, attr) { + element.addClass('scroll-content'); - return { - //Prelink so it can compile before other directives compile. - //Then other directives can require ionicScrollCtrl - pre: prelink - }; + //We cannot transclude here because it breaks element.data() inheritance on compile + var innerElement = angular.element('
'); + innerElement.append(element.contents()); + element.append(innerElement); + return { pre: prelink }; function prelink($scope, $element, $attr, navViewCtrl) { - var clone, sc, scrollView, scrollCtrl, - scrollContent = angular.element($element[0].querySelector('.scroll')); + $scope.$watch(function() { + return ($scope.$hasHeader ? ' has-header' : '') + + ($scope.$hasSubheader ? ' has-subheader' : '') + + ($scope.$hasFooter ? ' has-footer' : '') + + ($scope.$hasSubfooter ? ' has-subfooter' : '') + + ($scope.$hasTabs ? ' has-tabs' : '') + + ($scope.$hasTabsTop ? ' has-tabs-top' : ''); + }, function(className, oldClassName) { + $element.removeClass(oldClassName); + $element.addClass(className); + }); $ionicBind($scope, $attr, { $onScroll: '&onScroll', @@ -34635,16 +34580,22 @@ function($parse, $timeout, $ionicScrollDelegate, $controller, $ionicBind) { scrollEventInterval: '@' }); + if (angular.isDefined($attr.padding)) { + $scope.$watch($attr.padding, function(newVal) { + innerElement.toggleClass('padding', !!newVal); + }); + } + if ($scope.scroll === "false") { //do nothing } else if(attr.overflowScroll === "true") { $element.addClass('overflow-scroll'); } else { - - scrollCtrl = $controller('$ionicScroll', { + $controller('$ionicScroll', { $scope: $scope, scrollViewOptions: { el: $element[0], + delegateHandle: attr.delegateHandle, bouncing: $scope.$eval($scope.hasBouncing), startX: $scope.$eval($scope.startX) || 0, startY: $scope.$eval($scope.startY) || 0, @@ -34661,33 +34612,8 @@ function($parse, $timeout, $ionicScrollDelegate, $controller, $ionicBind) { } } }); - //Publish scrollView to parent so children can access it - scrollView = $scope.$parent.scrollView = scrollCtrl.scrollView; - - $scope.$on('$viewContentLoaded', function(e, viewHistoryData) { - viewHistoryData || (viewHistoryData = {}); - var scroll = viewHistoryData.scrollValues; - if (scroll) { - $timeout(function() { - scrollView.scrollTo(+scroll.left || null, +scroll.top || null); - }, 0); - } - - //Save scroll onto viewHistoryData when scope is destroyed - $scope.$on('$destroy', function() { - viewHistoryData.scrollValues = scrollView.getValues(); - }); - }); - } - transclude($scope, function(clone) { - if (scrollCtrl) { - clone.data('$$ionicScrollController', scrollCtrl); - } - scrollContent.append(clone); - }); - } } }; @@ -34698,7 +34624,6 @@ function($parse, $timeout, $ionicScrollDelegate, $controller, $ionicBind) { * @name ionRefresher * @module ionic * @restrict E - * @group page layout * @parent ionic.directive:ionContent, ionic.directive:ionScroll * @description * Allows you to add pull-to-refresh to a scrollView. @@ -34709,19 +34634,8 @@ function($parse, $timeout, $ionicScrollDelegate, $controller, $ionicBind) { * When refreshing is complete, $broadcast the 'scroll.refreshComplete' event * from your controller. * - * @param {expression=} on-refresh Called when the user pulls down enough and lets go - * of the refresher. - * @param {expression=} on-pulling Called when the user starts to pull down - * on the refresher. - * @param {string=} pulling-icon The icon to display while the user is pulling down. - * Default: 'ion-arrow-down-c'. - * @param {string=} pulling-text The text to display while the user is pulling down. - * @param {string=} refreshing-icon The icon to display after user lets go of the - * refresher. - * @param {string=} refreshing-text The text to display after the user lets go of - * the refresher. - * * @usage + * * ```html * * \ -
\ +
\ \
\ \ -
\ - \ +
\ + \
\
\ \ @@ -34999,22 +34925,24 @@ angular.module('ionic.ui.list', ['ngAnimate']) $scope.deleteClick = function() { if($attr.onDelete) { // this item has an on-delete attribute - $scope.onDelete({ item: $scope.item }); + $scope.onDelete({ item: $scope.item, index: $scope.$parent.$index }); } else if($parentAttrs.onDelete) { // run the parent list's onDelete method // if it doesn't exist nothing will happen - $parentScope.onDelete({ item: $scope.item }); + $parentScope.onDelete({ item: $scope.item, index: $scope.$parent.$index }); } }; // Set which icons to use for deleting $scope.deleteIconClass = $scope.deleteIcon || $parentScope.deleteIcon || 'ion-minus-circled'; + $element.addClass('item-left-editable'); } } // set the reorder Icon Class only if the item or list set can-reorder="true" if(($attr.canReorder ? $scope.canReorder : $parentScope.canReorder) === "true") { $scope.reorderIconClass = $scope.reorderIcon || $parentScope.reorderIcon || 'ion-navicon'; + $element.addClass('item-right-editable'); } // Set the option buttons which can be revealed by swiping to the left @@ -35024,6 +34952,7 @@ angular.module('ionic.ui.list', ['ngAnimate']) if(typeof $scope.itemOptionButtons === "undefined") { $scope.itemOptionButtons = $parentScope.optionButtons(); } + $element.addClass('item-swipeable'); } } @@ -35097,7 +35026,7 @@ angular.module('ionic.ui.list', ['ngAnimate']) reorderIcon: '@' }, - template: '
', + template: '
', controller: ['$scope', '$attrs', function($scope, $attrs) { this.scope = $scope; @@ -35106,6 +35035,7 @@ angular.module('ionic.ui.list', ['ngAnimate']) link: function($scope, $element, $attr, ionicScrollCtrl) { $scope.listView = new ionic.views.ListView({ + canSwipe: $scope.canSwipe !== "false" && !!$scope.optionButtons(), el: $element[0], listEl: $element[0].children[0], scrollEl: ionicScrollCtrl && ionicScrollCtrl.element, @@ -35124,6 +35054,7 @@ angular.module('ionic.ui.list', ['ngAnimate']) var destroyShowReorderWatch = $scope.$watch('showReorder', function(val) { if(val) { $element[0].classList.add('item-options-hide'); + $scope.listView && $scope.listView.clearDragEffects(); } else if(val === false) { // false checking is because it could be undefined // if its undefined then we don't care to do anything @@ -35160,7 +35091,7 @@ angular.module('ionic.ui.loading', []) link: function($scope, $element){ $element.addClass($scope.animation || ''); }, - template: '
' + + template: '
' + '
' + '
' + '
' @@ -35191,50 +35122,485 @@ angular.module('ionic.ui.modal', []) })(); -(function() { -angular.module('ionic.ui.navAnimation', []) + +angular.module('ionic.ui.navBar', ['ionic.service.view', 'ngSanitize']) + +/** + * @ngdoc service + * @name $ionicNavBarDelegate + * @module ionic + * @description + * Delegate for controlling the {@link ionic.directive:ionNavBar} directive. + * + * @usage + * + * ```html + * + * + * + * + * + * ``` + * ```js + * function MyCtrl($scope, $ionicNavBarDelegate) { + * $scope.setNavTitle = function(title) { + * $ionicNavBarDelegate.setTitle(title); + * } + * } + * ``` + */ +.service('$ionicNavBarDelegate', delegateService([ + /** + * @ngdoc method + * @name $ionicNavBarDelegate#back + * @description Goes back in the view history. + * @param {DOMEvent=} event The event object (eg from a tap event) + */ + 'back', + /** + * @ngdoc method + * @name $ionicNavBarDelegate#align + * @description Aligns the title with the buttons in a given direction. + * @param {string=} direction The direction to the align the title text towards. + * Available: 'left', 'right', 'center'. Default: 'center'. + */ + 'align', + /** + * @ngdoc method + * @name $ionicNavBarDelegate#showBackButton + * @description + * Set whether the {@link ionic.directive:ionNavBackButton} should be shown + * (if it exists). + * @param {boolean} show Whether to show the back button. + */ + 'showBackButton', + /** + * @ngdoc method + * @name $ionicNavBarDelegate#showBar + * @description + * Set whether the {@link ionic.directive:ionNavBar} should be shown. + * @param {boolean} show Whether to show the bar. + */ + 'showBar', + /** + * @ngdoc method + * @name $ionicNavBarDelegate#setTitle + * @description + * Set the title for the {@link ionic.directive:ionNavBar}. + * @param {string} title The new title to show. + */ + 'setTitle', + /** + * @ngdoc method + * @name $ionicNavBarDelegate#changeTitle + * @description + * Change the title, transitioning the new title in and the old one out in a given direction. + * @param {string} title The new title to show. + * @param {string} direction The direction to transition the new title in. + * Available: 'forward', 'back'. + */ + 'changeTitle', + /** + * @ngdoc method + * @name $ionicNavBarDelegate#getTitle + * @returns {string} The current title of the navbar. + */ + 'getTitle', + /** + * @ngdoc method + * @name $ionicNavBarDelegate#getPreviousTitle + * @returns {string} The previous title of the navbar. + */ + 'getPreviousTitle' + /** + * @ngdoc method + * @name $ionicNavBarDelegate#$getByHandle + * @param {string} handle + * @returns `delegateInstance` A delegate instance that controls only the + * navBars with delegate-handle matching the given handle. + * + * Example: `$ionicNavBarDelegate.$getByHandle('myHandle').setTitle('newTitle')` + */ +])) + +.controller('$ionicNavBar', [ + '$scope', + '$element', + '$attrs', + '$ionicViewService', + '$animate', + '$compile', + '$ionicNavBarDelegate', +function($scope, $element, $attrs, $ionicViewService, $animate, $compile, $ionicNavBarDelegate) { + //Let the parent know about our controller too so that children of + //sibling content elements can know about us + $element.parent().data('$ionNavBarController', this); + + var deregisterInstance = $ionicNavBarDelegate._registerInstance(this, $attrs.delegateHandle); + + $scope.$on('$destroy', deregisterInstance); + + var self = this; + + this.leftButtonsElement = angular.element( + $element[0].querySelector('.buttons.left-buttons') + ); + this.rightButtonsElement = angular.element( + $element[0].querySelector('.buttons.right-buttons') + ); + + this.back = function(e) { + var backView = $ionicViewService.getBackView(); + backView && backView.go(); + e && (e.alreadyHandled = true); + return false; + }; + + this.align = function(direction) { + this._headerBarView.align(direction); + }; + + this.showBackButton = function(show) { + $scope.backButtonShown = !!show; + }; + + this.showBar = function(show) { + $scope.isInvisible = !show; + }; + + this.setTitle = function(title) { + $scope.oldTitle = $scope.title; + $scope.title = title || ''; + }; + + this.changeTitle = function(title, direction) { + if ($scope.title === title) { + return false; + } + this.setTitle(title); + $scope.isReverse = direction == 'back'; + $scope.shouldAnimate = !!direction; + + if (!$scope.shouldAnimate) { + //We're done! + this._headerBarView.align(); + } else { + this._animateTitles(); + } + return true; + }; + + this.getTitle = function() { + return $scope.title || ''; + }; + + this.getPreviousTitle = function() { + return $scope.oldTitle || ''; + }; + + /** + * Exposed for testing + */ + this._animateTitles = function() { + var oldTitleEl, newTitleEl, currentTitles; + + //If we have any title right now + //(or more than one, they could be transitioning on switch), + //replace the first one with an oldTitle element + currentTitles = $element[0].querySelectorAll('.title'); + if (currentTitles.length) { + oldTitleEl = $compile('

')($scope); + angular.element(currentTitles[0]).replaceWith(oldTitleEl); + } + //Compile new title + newTitleEl = $compile('

')($scope); + + //Animate in on next frame + ionic.requestAnimationFrame(function() { + + oldTitleEl && $animate.leave(angular.element(oldTitleEl)); + + var insert = oldTitleEl && angular.element(oldTitleEl) || null; + $animate.enter(newTitleEl, $element, insert, function() { + self._headerBarView.align(); + }); + + //Cleanup any old titles leftover (besides the one we already did replaceWith on) + angular.forEach(currentTitles, function(el) { + if (el && el.parentNode) { + //Use .remove() to cleanup things like .data() + angular.element(el).remove(); + } + }); + + //$apply so bindings fire + $scope.$digest(); + + //Stop flicker of new title on ios7 + ionic.requestAnimationFrame(function() { + newTitleEl[0].classList.remove('invisible'); + }); + }); + }; +}]) + /** * @ngdoc directive - * @name ionNavAnimation + * @name ionNavBar * @module ionic - * @restrict A - * @parent ionic.directive:ionNavView + * @delegate ionic.service:$ionicNavBarDelegate + * @restrict E * * @description - * When used under an {@link ionic.directive:ionNavView} and on an `` element, - * allows you to set the animation all clicks on that link within the navView use. + * If we have an {@link ionic.directive:ionNavView} directive, we can also create an + * ``, which will create a topbar that updates as the application state changes. + * + * We can add a back button by putting an {@link ionic.directive:ionNavBackButton} inside. + * + * We can add buttons depending on the currently visible view using + * {@link ionic.directive:ionNavButtons}. + * + * Assign an [animation class](/docs/components#animations) to the element to + * enable animated changing of titles (recommended: 'slide-left-right' or 'nav-title-slide-ios7') + * + * @usage + * + * ```html + * + * + * + * + * + * + * + * + * ``` + * + * @param {string=} delegate-handle The handle used to identify this navBar + * with {@link ionic.service:$ionicNavBarDelegate}. + * @param align-title {string=} Where to align the title of the navbar. + * Available: 'left', 'right', 'center'. Defaults to 'center'. + */ +.directive('ionNavBar', ['$ionicViewService', '$rootScope', '$animate', '$compile', +function($ionicViewService, $rootScope, $animate, $compile) { + + return { + restrict: 'E', + controller: '$ionicNavBar', + scope: true, + compile: function(tElement, tAttrs) { + //We cannot transclude here because it breaks element.data() inheritance on compile + tElement + .addClass('bar bar-header nav-bar') + .append( + '
' + + '
' + + '

' + + '
' + + '
' + ); + + return { pre: prelink }; + function prelink($scope, $element, $attr, navBarCtrl) { + navBarCtrl._headerBarView = new ionic.views.HeaderBar({ + el: $element[0], + alignTitle: $attr.alignTitle || 'center' + }); + + //defaults + $scope.backButtonShown = false; + $scope.shouldAnimate = true; + $scope.isReverse = false; + $scope.isInvisible = true; + $scope.$parent.$hasHeader = true; + + $scope.$on('$destroy', function() { + $scope.$parent.$hasHeader = false; + }); + + $scope.$watch(function() { + return ($scope.isReverse ? ' reverse' : '') + + ($scope.isInvisible ? ' invisible' : '') + + (!$scope.shouldAnimate ? ' no-animation' : ''); + }, function(className, oldClassName) { + $element.removeClass(oldClassName); + $element.addClass(className); + }); + + } + } + }; +}]) + +/** + * @ngdoc directive + * @name ionNavBackButton + * @module ionic + * @restrict E + * @parent ionNavBar + * @description + * Creates a back button inside an {@link ionic.directive:ionNavBar}. + * + * Will show up when the user is able to go back in the current navigation stack. + * + * By default, will go back when clicked. If you wish for more advanced behavior, see the + * examples below. + * + * @usage + * + * With default click action: + * + * ```html + * + * + * Back! + * + * + * ``` + * + * With custom click action, using {@link ionic.service:$ionicNavBarDelegate}: + * + * ```html + * + * + * Back + * + * + * ``` + * ```js + * function MyCtrl($scope, $ionicNavBarDelegate) { + * $scope.goBack = function() { + * $ionicNavBarDelegate.back(); + * }; + * } + * ``` + * + * Displaying the previous title on the back button, again using + * {@link ionic.service:$ionicNavBarDelegate}. + * + * ```html + * + * + * {% raw %}{{getPreviousTitle() || 'Back'}}{% endraw %} + * + * + * ``` + * ```js + * function MyCtrl($scope, $ionicNavBarDelegate) { + * $scope.getPreviousTitle = function() { + * return $ionicNavBarDelegate.getPreviousTitle(); + * }; + * } + * ``` + */ +.directive('ionNavBackButton', ['$ionicNgClick', function($ionicNgClick) { + return { + restrict: 'E', + require: '^ionNavBar', + compile: function(tElement, tAttrs) { + tElement.addClass('button back-button'); + return function($scope, $element, $attr, navBarCtrl) { + if (!$attr.ngClick) { + $scope.$navBack = navBarCtrl.back; + $ionicNgClick($scope, $element, '$navBack($event)'); + } + + //If the current viewstate does not allow a back button, + //always hide it. + var deregisterListener = $scope.$parent.$on( + '$viewHistory.historyChange', + function(e, data) { + $scope.hasBackButton = !!data.showBack; + } + ); + $scope.$on('$destroy', deregisterListener); + + //Make sure both that a backButton is allowed in the first place, + //and that it is shown by the current view. + $scope.$watch('!!(backButtonShown && hasBackButton)', function(show) { + $element.toggleClass('hide', !show); + }); + }; + } + }; +}]) + +/** + * @ngdoc directive + * @name ionNavButtons + * @module ionic + * @restrict E + * @parent ionNavView + * + * @description + * Use ionNavButtons to set the buttons on your {@link ionic.directive:ionNavBar} + * from within an {@link ionic.directive:ionView}. + * + * Any buttons you declare will be placed onto the navbar's corresponding side, + * and then destroyed when the user leaves their parent view. * * @usage * ```html + * + * * * + * + * + * * - *
- * Click me and #/some-page will transition in with the slide-in-up animation! - * + * Some super content here! * * * * ``` * - * @param {string} ion-nav-animation The animation to make the parent ionNavView change pages with when clicking this element. + * @param {string} side The side to place the buttons on in the parent + * {@link ionic.directive:ionNavBar}. Available: 'left' or 'right'. */ -.directive('ionNavAnimation', function() { +.directive('ionNavButtons', ['$compile', '$animate', function($compile, $animate) { return { - restrict: 'A', - require: '^?ionNavView', - link: function($scope, $element, $attrs, navViewCtrl) { - if (!navViewCtrl) { - return; - } - ionic.on('tap', function() { - navViewCtrl.setNextAnimation($attrs.ionNavAnimation); - }, $element[0]); + require: '^ionNavBar', + restrict: 'E', + compile: function($element, $attrs) { + var content = $element.contents().remove(); + return function($scope, $element, $attrs, navBarCtrl) { + var navElement = $attrs.side === 'right' ? + navBarCtrl.rightButtonsElement : + navBarCtrl.leftButtonsElement; + + //Put all of our inside buttons into their own div, + //so we can remove them all when this element dies - + //even if the buttons have changed through an ng-repeat or the like, + //we just remove their div parent and they are gone. + var buttons = angular.element('
').append(content); + + //Compile buttons inside content so they have access to everything + //something inside content does (eg parent ionicScroll) + $element.append(buttons); + $compile(buttons)($scope); + + //Append buttons to navbar + $animate.enter(buttons, navElement); + + //When our ion-nav-buttons container is destroyed, + //destroy everything in the navbar + $scope.$on('$destroy', function() { + $animate.leave(buttons); + }); + + // The original element is just a completely empty element. + // make it invisible just to be sure it doesn't change any layout + $element.css('display', 'none'); + }; } }; -}); -})(); - +}]); (function() { 'use strict'; @@ -35261,6 +35627,18 @@ angular.module('ionic.ui.popup', []) replace: true, transclude: true, scope: true, + template: + '', link: function($scope, $element, $attr) { $ionicBind($scope, $attr, { title: '@', @@ -35283,18 +35661,7 @@ angular.module('ionic.ui.popup', []) } $scope.$onButtonTap({button: button, event: event}); } - }, - template: '' + } }; }]); @@ -35439,11 +35806,14 @@ angular.module('ionic.ui.scroll', []) * @ngdoc directive * @name ionScroll * @module ionic + * @delegate ionic.service:$ionicScrollDelegate * @restrict E * * @description * Creates a scrollable container for all content inside. * + * @param {string=} delegate-handle The handle used to identify this scrollView + * with {@link ionic.service:$ionicScrollDelegate}. * @param {string=} direction Which way to scroll. 'x' or 'y'. Default 'y'. * @param {boolean=} paging Whether to scroll with paging. * @param {expression=} on-refresh Called on pull-to-refresh, triggered by an {@link ionic.directive:ionRefresher}. @@ -35451,41 +35821,43 @@ angular.module('ionic.ui.scroll', []) * @param {boolean=} scrollbar-x Whether to show the horizontal scrollbar. Default false. * @param {boolean=} scrollbar-x Whether to show the vertical scrollbar. Default true. */ -.directive('ionScroll', ['$parse', '$timeout', '$controller', function($parse, $timeout, $controller) { +.directive('ionScroll', [ + '$timeout', + '$controller', + '$ionicBind', +function($timeout, $controller, $ionicBind) { return { restrict: 'E', - replace: true, - template: '
', - transclude: true, - scope: { - direction: '@', - paging: '@', - onRefresh: '&', - onScroll: '&', - scroll: '@', - scrollbarX: '@', - scrollbarY: '@', - }, - + scope: true, controller: function() {}, + compile: function(element, attr) { + element.addClass('scroll-view'); - compile: function(element, attr, transclude) { - - return { - //Prelink so it can compile before other directives compile. - //Then other directives can require ionicScrollCtrl - pre: prelink - }; + //We cannot transclude here because it breaks element.data() inheritance on compile + var innerElement = angular.element('
'); + innerElement.append(element.contents()); + element.append(innerElement); + return { pre: prelink }; function prelink($scope, $element, $attr) { - var scrollView, scrollCtrl, - sc = $element[0].children[0]; + var scrollView, scrollCtrl; - if(attr.padding == "true") { - sc.classList.add('padding'); + $ionicBind($scope, $attr, { + direction: '@', + paging: '@', + $onScroll: '&onScroll', + scroll: '@', + scrollbarX: '@', + scrollbarY: '@', + }); + + if (angular.isDefined($attr.padding)) { + $scope.$watch($attr.padding, function(newVal) { + innerElement.toggleClass('padding', !!newVal); + }); } if($scope.$eval($scope.paging) === true) { - sc.classList.add('scroll-paging'); + innerElement.addClass('scroll-paging'); } if(!$scope.direction) { $scope.direction = 'y'; } @@ -35493,6 +35865,7 @@ angular.module('ionic.ui.scroll', []) var scrollViewOptions= { el: $element[0], + delegateHandle: $attr.delegateHandle, paging: isPaging, scrollbarX: $scope.$eval($scope.scrollbarX) !== false, scrollbarY: $scope.$eval($scope.scrollbarY) !== false, @@ -35539,33 +35912,97 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie }]) /** - * @ngdoc controller - * @name ionicSideMenus + * @ngdoc service + * @name $ionicSideMenuDelegate * @module ionic - * @group side menu * * @description - * Controller for the {@link ionic.directive:ionSideMenus} directive. - */ -/** - * @ngdoc method - * @name ionicSideMenus#toggleLeft - * @description Toggle the left side menu (if it exists). - */ -/** - * @ngdoc method - * @name ionicSideMenus#toggleRight - * @description Toggle the right side menu (if it exists). + * Delegate for controlling the {@link ionic.directive:ionSideMenus} directive. + * + * Methods called directly on the $ionicSideMenuDelegate service will control all side + * menus. Use the {@link ionic.service:$ionicSideMenuDelegate#$getByHandle $getByHandle} + * method to control specific ionSideMenus instances. + * + * @usage + * + * ```html + * + * + * + * Content! + * + * + * + * Left Menu! + * + * + * + * ``` + * ```js + * function MainCtrl($scope, $ionicSideMenuDelegate) { + * $scope.toggleLeftSideMenu = function() { + * $ionicSideMenuDelegate.toggleLeft(); + * }; + * } + * ``` */ +.service('$ionicSideMenuDelegate', delegateService([ + /** + * @ngdoc method + * @name $ionicSideMenuDelegate#toggleLeft + * @description Toggle the left side menu (if it exists). + * @param {boolean=} isOpen Whether to open or close the menu. + * Default: Toggles the menu. + */ + 'toggleLeft', + /** + * @ngdoc method + * @name $ionicSideMenuDelegate#toggleRight + * @description Toggle the right side menu (if it exists). + * @param {boolean=} isOpen Whether to open or close the menu. + * Default: Toggles the menu. + */ + 'toggleRight', + /** + * @ngdoc method + * @name $ionicSideMenuDelegate#isOpenLeft + * @returns {boolean} Whether the left menu is currently opened. + */ + 'isOpenLeft', + /** + * @ngdoc method + * @name $ionicSideMenuDelegate#isOpenRight + * @returns {boolean} Whether the right menu is currently opened. + */ + 'isOpenRight', + /** + * @ngdoc method + * @name $ionicSideMenuDelegate#canDragContent + * @param {boolean=} canDrag Set whether the content can or cannot be dragged to open + * side menus. + * @returns {boolean} Whether the content can be dragged to open side menus. + */ + 'canDragContent', + /** + * @ngdoc method + * @name $ionicSideMenuDelegate#$getByHandle + * @param {string} handle + * @returns `delegateInstance` A delegate instance that controls only the + * {@link ionic.directive:ionSideMenus} directives with `delegate-handle` matching + * the given handle. + * + * Example: `$ionicSideMenuDelegate.$getByHandle('my-handle').toggleLeft();` + */ +])) /** * @ngdoc directive * @name ionSideMenus * @module ionic + * @delegate ionic.service:$ionicSideMenuDelegate * @restrict E - * @group side menu - * @groupMainItem - * @controller ionicSideMenus * * @description * A container element for side menu(s) and the main content. Allows the left @@ -35580,14 +36017,14 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie * * @usage * To use side menus, add an `` parent element, - * an `` for the center content, + * an `` for the center content, * and one or more `` directives. * * ```html * * - * - * + * + * * * * @@ -35599,20 +36036,21 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie * * ``` * ```js - * function ContentController($scope) { + * function ContentController($scope, $ionicSideMenuDelegate) { * $scope.toggleLeft = function() { - * $scope.sideMenuController.toggleLeft(); + * $ionicSideMenuDelegate.toggleLeft(); * }; * } * ``` * - * @param {expression=} model The model to assign this side menu container's {@link ionic.controller:ionicSideMenus} controller to. By default, assigns to $scope.sideMenuController. + * @param {string=} delegate-handle The handle used to identify this side menu + * with {@link ionic.service:$ionicSideMenuDelegate}. * */ .directive('ionSideMenus', function() { return { restrict: 'ECA', - controller: ['$scope', '$attrs', '$parse', function($scope, $attrs, $parse) { + controller: ['$scope', '$attrs', '$ionicSideMenuDelegate', function($scope, $attrs, $ionicSideMenuDelegate) { var _this = this; angular.extend(this, ionic.controllers.SideMenuController.prototype); @@ -35622,9 +36060,20 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie right: { width: 275 } }); + this.canDragContent = function(canDrag) { + if (arguments.length) { + $scope.dragContent = !!canDrag; + } + return $scope.dragContent; + }; + $scope.sideMenuContentTranslateX = 0; - $parse($attrs.model || 'sideMenuController').assign($scope, this); + var deregisterInstance = $ionicSideMenuDelegate._registerInstance( + this, $attrs.delegateHandle + ); + + $scope.$on('$destroy', deregisterInstance); }], replace: true, transclude: true, @@ -35636,21 +36085,18 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie * @ngdoc directive * @name ionSideMenuContent * @module ionic - * @restrict A - * @group side menu + * @restrict E * @parent ionic.directive:ionSideMenus * * @description * A container for the main visible content, sibling to one or more * {@link ionic.directive:ionSideMenu} directives. * - * An attribute directive, recommended to be used as part of an `` element. - * * @usage * ```html - *
- *
+ * + * * ``` * For a complete side menu example, see the * {@link ionic.directive:ionSideMenus} documentation. @@ -35660,20 +36106,21 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie */ .directive('ionSideMenuContent', ['$timeout', '$ionicGesture', function($timeout, $ionicGesture) { return { - restrict: 'AC', + restrict: 'EA', //DEPRECATED 'A' require: '^ionSideMenus', scope: true, - compile: function(element, attr, transclude) { - return function($scope, $element, $attr, sideMenuCtrl) { + compile: function(element, attr) { + return { pre: prelink }; + function prelink($scope, $element, $attr, sideMenuCtrl) { - $element.addClass('menu-content'); + $element.addClass('menu-content pane'); if (angular.isDefined(attr.dragContent)) { $scope.$watch(attr.dragContent, function(value) { - $scope.dragContent = value; + sideMenuCtrl.canDragContent(value); }); } else { - $scope.dragContent = true; + sideMenuCtrl.canDragContent(true); } var defaultPrevented = false; @@ -35754,7 +36201,7 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie $ionicGesture.off(releaseGesture, 'release', dragReleaseFn); ionic.off('tap', contentTap, $element[0]); }); - }; + } } }; }]) @@ -35764,7 +36211,6 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie * @name ionSideMenu * @module ionic * @restrict E - * @group side menu * @parent ionic.directive:ionSideMenus * * @description @@ -35789,14 +36235,13 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie return { restrict: 'E', require: '^ionSideMenus', - replace: true, - transclude: true, scope: true, - template: '', - compile: function(element, attr, transclude) { + compile: function(element, attr) { angular.isUndefined(attr.isEnabled) && attr.$set('isEnabled', 'true'); angular.isUndefined(attr.width) && attr.$set('width', '275'); + element.addClass('menu menu-' + attr.side); + return function($scope, $element, $attr, sideMenuCtrl) { $scope.side = $attr.side || 'left'; @@ -35815,14 +36260,79 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie $scope.$watch($attr.isEnabled, function(val) { sideMenu.setIsEnabled(!!val); }); - - transclude($scope, function(clone) { - $element.append(clone); - }); }; } }; -}); +}) + +/** + * @ngdoc directive + * @name menuToggle + * @module ionic + * @restrict AC + * + * @description + * Toggle a side menu on the given side + * + * @usage + * Below is an example of a link within a nav bar. Tapping this link would + * automatically open the given side menu + * + * ```html + * + * + * + * + * ... + * + * ``` + */ +.directive('menuToggle', ['$ionicViewService', function($ionicViewService) { + return { + restrict: 'AC', + require: '^ionSideMenus', + link: function($scope, $element, $attr, sideMenuCtrl) { + var side = $scope.$eval($attr.menuToggle) || 'left'; + $element.bind('click', function(){ + if(side === 'left') { + sideMenuCtrl.toggleLeft(); + } else if(side === 'right') { + sideMenuCtrl.toggleRight(); + } + }); + } + }; +}]) + +/** + * @ngdoc directive + * @name menuClose + * @module ionic + * @restrict AC + * + * @description + * Closes a side menu which is currently opened. + * + * @usage + * Below is an example of a link within a side menu. Tapping this link would + * automatically close the currently opened menu + * + * ```html + * Home + * ``` + */ +.directive('menuClose', ['$ionicViewService', function($ionicViewService) { + return { + restrict: 'AC', + require: '^ionSideMenus', + link: function($scope, $element, $attr, sideMenuCtrl) { + $element.bind('click', function(){ + sideMenuCtrl.close(); + }); + } + }; +}]); + })(); (function() { @@ -35830,6 +36340,102 @@ angular.module('ionic.ui.sideMenu', ['ionic.service.gesture', 'ionic.service.vie angular.module('ionic.ui.slideBox', []) +/** + * @ngdoc service + * @name $ionicSlideBoxDelegate + * @module ionic + * @description + * Delegate that controls the {@link ionic.directive:ionSlideBox} directive. + * + * Methods called directly on the $ionicSlideBoxDelegate service will control all side + * menus. Use the {@link ionic.service:$ionicSlideBoxDelegate#$getByHandle $getByHandle} + * method to control specific slide box instances. + * + * @usage + * + * ```html + * + * + * + *
+ * + *
+ *
+ * + *
+ * Slide 2! + *
+ *
+ *
+ * + * ``` + * ```js + * function MyCtrl($scope, $ionicSlideBoxDelegate) { + * $scope.nextSlide = function() { + * $ionicSlideBoxDelegate.next(); + * } + * } + * ``` + */ +.service('$ionicSlideBoxDelegate', delegateService([ + /** + * @ngdoc method + * @name $ionicSlideBoxDelegate#update + * @description + * Update the slidebox (for example if using Angular with ng-repeat, + * resize it for the elements inside). + */ + 'update', + /** + * @ngdoc method + * @name $ionicSlideBoxDelegate#slide + * @param {number} to The index to slide to. + * @param {number=} speed The number of milliseconds for the change to take. + */ + 'slide', + /** + * @ngdoc method + * @name $ionicSlideBoxDelegate#previous + * @description Go to the previous slide. Wraps around if at the beginning. + */ + 'previous', + /** + * @ngdoc method + * @name $ionicSlideBoxDelegate#next + * @description Go to the next slide. Wraps around if at the end. + */ + 'next', + /** + * @ngdoc method + * @name $ionicSlideBoxDelegate#stop + * @description Stop sliding. The slideBox will not move again until + * explicitly told to do so. + */ + 'stop', + /** + * @ngdoc method + * @name $ionicSlideBoxDelegate#currentIndex + * @returns number The index of the current slide. + */ + 'currentIndex', + /** + * @ngdoc method + * @name $ionicSlideBoxDelegate#slidesCount + * @returns number The number of slides there are currently. + */ + 'slidesCount' + /** + * @ngdoc method + * @name $ionicSlideBoxDelegate#$getByHandle + * @param {string} handle + * @returns `delegateInstance` A delegate instance that controls only the + * {@link ionic.directive:ionSlideBox} directives with `delegate-handle` matching + * the given handle. + * + * Example: `$ionicSlideBoxDelegate.$getByHandle('my-handle').stop();` + */ +])) + /** * The internal controller for the slide box controller. */ @@ -35838,8 +36444,8 @@ angular.module('ionic.ui.slideBox', []) * @ngdoc directive * @name ionSlideBox * @module ionic + * @delegate ionic.service:$ionicSlideBoxDelegate * @restrict E - * @controller ionicSlideBox * @description * The Slide Box is a multi-page container where each page can be swiped or dragged between: * @@ -35860,7 +36466,8 @@ angular.module('ionic.ui.slideBox', []) * * ``` * - * @param {expression=} model The model to assign this slide box container's {@link ionic.controller:ionicSlideBox} controller to. By default, assigns to $scope.slideBoxController. + * @param {string=} delegate-handle The handle used to identify this slideBox + * with {@link ionic.service:$ionicSlideBoxDelegate}. * @param {boolean=} does-continue Whether the slide box should automatically slide. * @param {number=} slide-interval How many milliseconds to wait to change slides (if does-continue is true). Defaults to 4000. * @param {boolean=} show-pager Whether a pager should be shown for this slide box. @@ -35868,7 +36475,11 @@ angular.module('ionic.ui.slideBox', []) * @param {expression=} on-slide-changed Expression called whenever the slide is changed. * @param {expression=} active-slide Model to bind the current slide to. */ -.directive('ionSlideBox', ['$timeout', '$compile', '$ionicSlideBoxDelegate', function($timeout, $compile, $ionicSlideBoxDelegate) { +.directive('ionSlideBox', [ + '$timeout', + '$compile', + '$ionicSlideBoxDelegate', +function($timeout, $compile, $ionicSlideBoxDelegate) { return { restrict: 'E', replace: true, @@ -35881,7 +36492,7 @@ angular.module('ionic.ui.slideBox', []) onSlideChanged: '&', activeSlide: '=?' }, - controller: ['$scope', '$element', '$attrs', '$parse', function($scope, $element, $attrs, $parse) { + controller: ['$scope', '$element', '$attrs', function($scope, $element, $attrs) { var _this = this; var continuous = $scope.$eval($scope.doesContinue) === true; @@ -35927,9 +36538,12 @@ angular.module('ionic.ui.slideBox', []) slider.slide(index); }); - $parse($attrs.model || 'slideBoxController').assign($scope.$parent, slider); + //Exposed for testing + this.__slider = slider; - $ionicSlideBoxDelegate.register($scope, $element); + var deregisterInstance = $ionicSlideBoxDelegate._registerInstance(slider, $attrs.delegateHandle); + + $scope.$on('$destroy', deregisterInstance); this.slidesCount = function() { return slider.slidesCount(); @@ -36009,32 +36623,80 @@ angular.module('ionic.ui.tabs', ['ionic.service.view']) }]) /** - * @ngdoc controller - * @group tab bar - * @name ionicTabs + * @ngdoc service + * @name $ionicTabsDelegate * @module ionic * * @description - * Controller for the {@link ionic.directive:ionTabs} directive. + * Delegate for controlling the {@link ionic.directive:ionTabs} directive. + * + * Methods called directly on the $ionicTabsDelegate service will control all ionTabs + * directives. Use the {@link ionic.service:$ionicTabsDelegate#$getByHandle $getByHandle} + * method to control specific ionTabs instances. + * + * @usage + * + * ```html + * + * + * + * + * Hello tab 1! + * + * + * Hello tab 2! + * + * + * + * ``` + * ```js + * function MyCtrl($scope, $ionicTabsDelegate) { + * $scope.selectTabWithIndex = function(index) { + * $ionicTabsDelegate.select(index); + * } + * } + * ``` */ +.service('$ionicTabsDelegate', delegateService([ + /** + * @ngdoc method + * @name $ionicTabsDelegate#select + * @description Select the tab matching the given index. + * + * @param {number} index Index of the tab to select. + * @param {boolean=} shouldChangeHistory Whether this selection should load this tab's + * view history (if it exists) and use it, or just load the default page. + * Default false. + * Hint: you probably want this to be true if you have an + * {@link ionic.directive:ionNavView} inside your tab. + */ + 'select', + /** + * @ngdoc method + * @name $ionicTabsDelegate#selectedIndex + * @returns `number` The index of the selected tab, or -1. + */ + 'selectedIndex' + /** + * @ngdoc method + * @name $ionicTabsDelegate#$getByHandle + * @param {string} handle + * @returns `delegateInstance` A delegate instance that controls only the + * {@link ionic.directive:ionTabs} directives with `delegate-handle` matching + * the given handle. + * + * Example: `$ionicTabsDelegate.$getByHandle('my-handle').select(0);` + */ +])) + .controller('ionicTabs', ['$scope', '$ionicViewService', '$element', function($scope, $ionicViewService, $element) { var _selectedTab = null; var self = this; self.tabs = []; - /** - * @ngdoc method - * @name ionicTabs#selectedTabIndex - * @returns `number` The index of the selected tab, or -1. - */ - self.selectedTabIndex = function() { + self.selectedIndex = function() { return self.tabs.indexOf(_selectedTab); }; - /** - * @ngdoc method - * @name ionicTabs#selectedTab - * @returns `ionTab` The selected tab or null if none selected. - */ self.selectedTab = function() { return _selectedTab; }; @@ -36075,17 +36737,6 @@ angular.module('ionic.ui.tabs', ['ionic.service.view']) } }; - /** - * @ngdoc method - * @name ionicTabs#select - * @description Select the given tab or tab index. - * - * @param {ionTab|number} tabOrIndex A tab object or index of a tab to select - * @param {boolean=} shouldChangeHistory Whether this selection should load this tab's view history - * (if it exists) and use it, or just loading the default page. Default false. - * Hint: you probably want this to be true if you have an - * {@link ionic.directive:ionNavView} inside your tab. - */ self.select = function(tab, shouldEmitEvent) { var tabIndex; if (angular.isNumber(tab)) { @@ -36134,20 +36785,24 @@ angular.module('ionic.ui.tabs', ['ionic.service.view']) * @ngdoc directive * @name ionTabs * @module ionic + * @delegate ionic.service:$ionicTabsDelegate * @restrict E - * @group tab bar - * @groupMainItem - * @controller ionicTabs * @codepen KbrzJ * * @description - * Powers a multi-tabbed interface with a Tab Bar and a set of "pages" that can be tabbed through. + * Powers a multi-tabbed interface with a Tab Bar and a set of "pages" that can be tabbed + * through. * - * See the {@link ionic.directive:ionTab} directive's documentation for more details. + * Assign any [tabs class](/docs/components#tabs) or + * [animation class](/docs/components#animation) to the element to define + * its look and feel. + * + * See the {@link ionic.directive:ionTab} directive's documentation for more details on + * individual tabs. * * @usage * ```html - * + * * * * @@ -36160,48 +36815,49 @@ angular.module('ionic.ui.tabs', ['ionic.service.view']) * * * + * * * ``` * - * @param {expression=} model The model to assign this tab bar's {@link ionic.controller:ionicTabs} controller to. By default, assigns to $scope.tabsController. - * @param {string=} animation The animation to use when changing between tab pages. - * @param {string=} tabs-style The class to apply to the tabs. Defaults to 'tabs-positive'. - * @param {string=} tabs-type Whether to put the tabs on the top or bottom. Defaults to 'tabs-bottom'. + * @param {string=} delegate-handle The handle used to identify these tabs + * with {@link ionic.service:$ionicTabsDelegate}. */ -.directive('ionTabs', ['$ionicViewService', '$ionicBind', '$parse', function($ionicViewService, $ionicBind, $parse) { +.directive('ionTabs', ['$ionicViewService', '$ionicTabsDelegate', function($ionicViewService, $ionicTabsDelegate) { return { restrict: 'E', - replace: true, scope: true, - transclude: true, controller: 'ionicTabs', - template: - '
' + - '
' + - '
' + - '
', - compile: function(element, attr, transclude) { - if(angular.isUndefined(attr.tabsType)) attr.$set('tabsType', 'tabs-positive'); + compile: function(element, attr) { + element.addClass('view'); + //We cannot transclude here because it breaks element.data() inheritance on compile + var innerElement = angular.element('
'); + innerElement.append(element.contents()); + element.append(innerElement); - return function link($scope, $element, $attr, tabsCtrl) { + return { pre: prelink }; + function prelink($scope, $element, $attr, tabsCtrl) { + var deregisterInstance = $ionicTabsDelegate._registerInstance( + tabsCtrl, $attr.delegateHandle + ); - $ionicBind($scope, $attr, { - $animation: '@animation', - $tabsStyle: '@tabsStyle', - $tabsType: '@tabsType' - }); - - $parse(attr.model || 'tabsController').assign($scope, tabsCtrl); + $scope.$on('$destroy', deregisterInstance); tabsCtrl.$scope = $scope; tabsCtrl.$element = $element; tabsCtrl.$tabsElement = angular.element($element[0].querySelector('.tabs')); - transclude($scope, function(clone) { - $element.append(clone); + var el = $element[0]; + $scope.$watch(function() { return el.className; }, function(value) { + var isTabsTop = value.indexOf('tabs-top') !== -1; + var isHidden = value.indexOf('tabs-item-hide') !== -1; + $scope.$hasTabs = !isTabsTop && !isHidden; + $scope.$hasTabsTop = isTabsTop && !isHidden; }); - }; + $scope.$on('$destroy', function() { + $scope.$hasTabs = $scope.$hasTabsTop = null; + }); + } } }; }]) @@ -36213,7 +36869,6 @@ function($scope, $ionicViewService, $rootScope, $element) { /** * @ngdoc directive - * @group tab bar * @name ionTab * @module ionic * @restrict E @@ -36224,8 +36879,6 @@ function($scope, $ionicViewService, $rootScope, $element) { * * Each ionTab has its own view history. * - * Whenever a tab is shown or hidden, it will broadcast a 'tab.shown' or 'tab.hidden' event. - * * @usage * ```html * ') .append( element.contents().remove() ); @@ -36276,6 +36934,9 @@ function($rootScope, $animate, $ionicBind, $compile, $ionicViewService) { tabsCtrl = ctrls[0], tabCtrl = ctrls[1]; + //Remove title attribute so browser-tooltip does not apear + $element[0].removeAttribute('title'); + $ionicBind($scope, $attr, { animate: '=', onSelect: '&', @@ -36314,9 +36975,6 @@ function($rootScope, $animate, $ionicBind, $compile, $ionicViewService) { tabsCtrl.$tabsElement.append($compile(tabNavElement)($scope)); $scope.$watch('$tabSelected', function(value) { - if (!value) { - $scope.$broadcast('tab.hidden', $scope); - } childScope && childScope.$destroy(); childScope = null; childElement && $animate.leave(childElement); @@ -36326,7 +36984,6 @@ function($rootScope, $animate, $ionicBind, $compile, $ionicViewService) { childElement = tabContent.clone(); $animate.enter(childElement, tabsCtrl.$element); $compile(childElement)(childScope); - $scope.$broadcast('tab.shown', $scope); } }); @@ -36347,7 +37004,7 @@ function($rootScope, $animate, $ionicBind, $compile, $ionicViewService) { replace: true, require: ['^ionTabs', '^ionTab'], template: - '' + '{{badge}}' + '' + @@ -36367,6 +37024,9 @@ function($rootScope, $animate, $ionicBind, $compile, $ionicViewService) { var tabsCtrl = ctrls[0], tabCtrl = ctrls[1]; + //Remove title attribute so browser-tooltip does not apear + $element[0].removeAttribute('title'); + $scope.selectTab = function(e) { e.preventDefault(); tabsCtrl.select(tabCtrl.$scope, true); @@ -36509,14 +37169,14 @@ angular.module('ionic.ui.touch', []) }); }); - ionic.on('tap', onTap, element[0]); + ionic.on("release", onTap, element[0]); // Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click // something else nearby. element.onclick = function(event) { }; scope.$on('$destroy', function () { - ionic.off('tap', onTap, element[0]); + ionic.off("release", onTap, element[0]); }); }; }]) @@ -36547,203 +37207,12 @@ angular.module('ionic.ui.touch', []) angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gesture', 'ngSanitize']) -/** - * @ngdoc directive - * @name ionNavBar - * @module ionic - * @restrict E - * - * @usage - * If have an {@link ionic.directive:ionNavView} directive, we can also create an - * , which will create a topbar that updates as the application state changes. - * We can also add some styles and set up animations: - * - * ```html - * - * - * - * - * - * - * - * ``` - * - * @param {string=} back-button-type The type of the back button's icon. Available: 'button-icon' or just 'button'. - * @param {string=} back-button-icon The icon to use for the back button. For example, 'ion-arrow-left-c'. - * @param {string=} back-button-label The label to use for the back button. For example, 'Back'. - * @param animation {string=} The animation used to transition between titles. - * @param type {string=} The className for the navbar. For example, 'bar-positive'. - * @param align {string=} Where to align the title of the navbar. Available: 'left', 'right', 'center'. Defaults to 'center'. - */ -.directive('ionNavBar', ['$ionicViewService', '$rootScope', '$animate', '$compile', - function( $ionicViewService, $rootScope, $animate, $compile) { - - return { - restrict: 'E', - replace: true, - scope: { - animation: '@', - type: '@', - backType: '@backButtonType', - backLabel: '@backButtonLabel', - backIcon: '@backButtonIcon', - alignTitle: '@' - }, - controller: function() {}, - template: - '', - compile: function(tElement, tAttrs) { - - return function link($scope, $element, $attr) { - //defaults - $scope.backButtonEnabled = false; - $scope.animateEnabled = true; - $scope.isReverse = false; - $scope.isInvisible = true; - - $scope.navBarClass = function() { - return ($scope.type ? ' ' + $scope.type : '') + - ($scope.isReverse ? ' reverse' : '') + - ($scope.isInvisible ? ' invisible' : '') + - (!$scope.animationDisabled && $scope.animation ? ' ' + $scope.animation : ''); - }; - - // Initialize our header bar view which will handle - // resizing and aligning our title labels - var hb = new ionic.views.HeaderBar({ - el: $element[0], - alignTitle: $scope.alignTitle || 'center' - }); - $scope.headerBarView = hb; - - //Navbar events - $scope.$on('viewState.viewEnter', function(e, data) { - updateHeaderData(data); - }); - $scope.$on('viewState.showNavBar', function(e, showNavBar) { - $scope.isInvisible = !showNavBar; - }); - - // All of these these are emitted from children of a sibling scope, - // so we listen on parent so we can catch them as they bubble up - var unregisterEventListeners = [ - $scope.$parent.$on('$viewHistory.historyChange', function(e, data) { - $scope.backButtonEnabled = !!data.showBack; - }), - $scope.$parent.$on('viewState.leftButtonsChanged', function(e, data) { - $scope.leftButtons = data; - }), - $scope.$parent.$on('viewState.rightButtonsChanged', function(e, data) { - $scope.rightButtons = data; - }), - $scope.$parent.$on('viewState.showBackButton', function(e, data) { - $scope.backButtonEnabled = !!data; - }), - $scope.$parent.$on('viewState.titleUpdated', function(e, data) { - $scope.title = data && data.title || ''; - }) - ]; - $scope.$on('$destroy', function() { - for (var i=0; i')($scope); - angular.element(currentTitles[0]).replaceWith(oldTitleEl); - } - //Compile new title - newTitleEl = $compile('

')($scope); - - //Animate in one frame - ionic.requestAnimationFrame(function() { - - oldTitleEl && $animate.leave(angular.element(oldTitleEl)); - - var insert = oldTitleEl && angular.element(oldTitleEl) || null; - $animate.enter(newTitleEl, $element, insert, function() { - hb.align(); - }); - - //Cleanup any old titles leftover (besides the one we already did replaceWith on) - angular.forEach(currentTitles, function(el) { - if (el && el.parentNode) { - //Use .remove() to cleanup things like .data() - angular.element(el).remove(); - } - }); - - //$apply so bindings fire - $scope.$digest(); - - //Stop flicker of new title on ios7 - ionic.requestAnimationFrame(function() { - newTitleEl[0].classList.remove('invisible'); - }); - }); - } - }; - } - }; -}]) - /** * @ngdoc directive * @name ionView * @module ionic * @restrict E - * @parent ionNavBar + * @parent ionNavView * * @description * A container for content, used to tell a parent {@link ionic.directive:ionNavBar} @@ -36754,7 +37223,7 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu * * ```html * - * + * * * * Hello! @@ -36763,97 +37232,52 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu * * ``` * - * @param {expression=} left-buttons The leftButtons to display on the parent {@link ionic.directive:ionNavBar}. - * @param {expression=} right-buttons The rightButtons to display on the parent {@link ionic.directive:ionNavBar}. * @param {string=} title The title to display on the parent {@link ionic.directive:ionNavBar}. - * @param {boolean=} hideBackButton Whether to hide the back button on the parent {@link ionic.directive:ionNavBar}. - * @param {boolean=} hideNavBar Whether to hide the parent {@link ionic.directive:ionNavBar}. + * @param {boolean=} hideBackButton Whether to hide the back button on the parent + * {@link ionic.directive:ionNavBar} by default. + * @param {boolean=} hideNavBar Whether to hide the parent + * {@link ionic.directive:ionNavBar} by default. */ .directive('ionView', ['$ionicViewService', '$rootScope', '$animate', function( $ionicViewService, $rootScope, $animate) { return { restrict: 'EA', priority: 1000, - scope: { - leftButtons: '=', - rightButtons: '=', - title: '@', - hideBackButton: '@', - hideNavBar: '@', - }, - + require: '^?ionNavBar', compile: function(tElement, tAttrs, transclude) { tElement.addClass('pane'); tElement[0].removeAttribute('title'); - return function link($scope, $element, $attr) { - - $rootScope.$broadcast('viewState.viewEnter', { - title: $scope.title, - navDirection: $scope.$navDirection || $scope.$parent.$navDirection - }); - - // Should we hide a back button when this tab is shown - $scope.hideBackButton = $scope.$eval($scope.hideBackButton); - if($scope.hideBackButton) { - $rootScope.$broadcast('viewState.showBackButton', false); + return function link($scope, $element, $attr, navBarCtrl) { + if (!navBarCtrl) { + return; } + var initialTitle = $attr.title; + navBarCtrl.changeTitle(initialTitle, $scope.$navDirection); - // Should the nav bar be hidden for this view or not? - $rootScope.$broadcast('viewState.showNavBar', ($scope.hideNavBar !== 'true') ); - - // watch for changes in the left buttons - $scope.$watch('leftButtons', function(value) { - $scope.$emit('viewState.leftButtonsChanged', $scope.leftButtons); + // watch for changes in the title, don't set initial value as changeTitle does that + $attr.$observe('title', function(val, oldVal) { + if (val !== initialTitle) { + navBarCtrl.setTitle(val); + } }); - $scope.$watch('rightButtons', function(val) { - $scope.$emit('viewState.rightButtonsChanged', $scope.rightButtons); + $scope.$watch($attr.hideBackButton, function(value) { + // Should we hide a back button when this tab is shown + navBarCtrl.showBackButton(!value); }); - // watch for changes in the title - $scope.$watch('title', function(val) { - $scope.$emit('viewState.titleUpdated', $scope); + $scope.$watch($attr.hideNavBar, function(value) { + // Should the nav bar be hidden for this view or not? + navBarCtrl.showBar(!value); }); + }; } }; }]) -/** -* @private -*/ -.directive('ionNavBackButton', ['$ionicViewService', '$rootScope', - function($ionicViewService, $rootScope) { - - function goBack(e) { - var backView = $ionicViewService.getBackView(); - backView && backView.go(); - e.alreadyHandled = true; - return false; - } - - return { - restrict: 'E', - scope: { - type: '=', - label: '=', - icon: '=' - }, - replace: true, - template: - '', - link: function($scope) { - $scope.goBack = goBack; - } - }; -}]) - /** * @ngdoc directive * @name ionNavView @@ -36888,8 +37312,11 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu * {@link ionic.directive:ionNavBar} directive which will render a header bar that updates as we * navigate through the navigation stack. * + * You can any [animation class](/docs/components#animation) on the navView to have its pages slide. + * Recommended for page transitions: 'slide-left-right', 'slide-left-right-ios7', 'slide-in-up'. + * * ```html - * + * * * * @@ -36944,8 +37371,6 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu * @param {string=} name A view name. The name should be unique amongst the other views in the * same state. You can have views of the same name that live in different states. For more * information, see ui-router's [ui-view documentation](http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.directive:ui-view). - * @param {string=} animation The animation to use for views underneath this ionNavView. - * Defaults to 'slide-left-right'. */ .directive('ionNavView', ['$ionicViewService', '$state', '$compile', '$controller', '$animate', function( $ionicViewService, $state, $compile, $controller, $animate) { @@ -36958,10 +37383,7 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu terminal: true, priority: 2000, transclude: true, - controller: ['$scope', function($scope) { - this.setNextAnimation = function(anim) { - $scope.$nextAnimation = anim; - }; + controller: [function(){ }], compile: function (element, attr, transclude) { return function(scope, element, attr, navViewCtrl) { @@ -37054,10 +37476,45 @@ angular.module('ionic.ui.viewState', ['ionic.service.view', 'ionic.service.gestu } }; return directive; +}]) + + +/** + * @ngdoc directive + * @name navClear + * @module ionic + * @restrict AC + * + * @description + * Disables any transition animations between views, along with removing the back + * button which would normally show on the next view. This directive is useful for + * links within a sideMenu. + * + * @usage + * Below is an example of a link within a side menu. Tapping this link would disable + * any animations which would normally occur between views. + * + * ```html + *
Home + * ``` + */ +.directive('navClear', ['$ionicViewService', function($ionicViewService) { + return { + restrict: 'AC', + link: function($scope, $element, $attr) { + $element.bind('click', function(){ + $ionicViewService.nextViewOptions({ + disableAnimate: true, + disableBack: true + }); + }); + } + }; }]); })(); +/* (function() { 'use strict'; @@ -37080,8 +37537,9 @@ angular.module('ionic.ui.virtRepeat', []) }; }); })(ionic); +*/ - +/* (function() { 'use strict'; @@ -37116,7 +37574,6 @@ function isTagNameInList(element, list){ // Utility to find the viewport/content elements given the start element: function findViewportAndContent(startElement){ - /*jshint eqeqeq:false, curly:false */ var root = $rootElement[0]; var e, n; // Somewhere between the grandparent and the root node @@ -37206,13 +37663,13 @@ function computeRowHeight(element){ angular.module('ionic.ui.virtualRepeat', []) -/** - * A replacement for ng-repeat that supports virtual lists. - * This is not a 1 to 1 replacement for ng-repeat. However, in situations - * where you have huge lists, this repeater will work with our virtual - * scrolling to only render items that are showing or will be showing - * if a scroll is made. - */ +// +// A replacement for ng-repeat that supports virtual lists. +// This is not a 1 to 1 replacement for ng-repeat. However, in situations +// where you have huge lists, this repeater will work with our virtual +// scrolling to only render items that are showing or will be showing +// if a scroll is made. +// .directive('ionVirtualRepeat', ['$log', function($log) { return { require: ['?ngModel, ^virtualList'], @@ -37409,46 +37866,335 @@ angular.module('ionic.ui.virtualRepeat', []) }]); })(ionic); - -(function() { -'use strict'; +*/ angular.module('ionic.ui.scroll') +/** + * @ngdoc service + * @name $ionicScrollDelegate + * @module ionic + * @description + * Delegate for controlling scrollViews (created by + * {@link ionic.directive:ionContent} and + * {@link ionic.directive:ionScroll} directives). + * + * Methods called directly on the $ionicScrollDelegate service will control all scroll + * views. Use the {@link ionic.service:$ionicScrollDelegate#$getByHandle $getByHandle} + * method to control specific scrollViews. + * + * @usage + * + * ```html + * + * + * + * + * + * ``` + * ```js + * function MainCtrl($scope, $ionicScrollDelegate) { + * $scope.scrollTop = function() { + * $ionicScrollDelegate.scrollTop(); + * }; + * } + * ``` + * + * Example of advanced usage, with two scroll areas using `delegate-handle` + * for fine control. + * + * ```html + * + * + * + * + * + * + * + * + * ``` + * ```js + * function MainCtrl($scope, $ionicScrollDelegate) { + * $scope.scrollMainToTop = function() { + * $ionicScrollDelegate.$getByHandle('mainScroll').scrollTop(); + * }; + * $scope.scrollSmallToTop = function() { + * $ionicScrollDelegate.$getByHandle('small').scrollTop(); + * }; + * } + * ``` + */ + +.service('$ionicScrollDelegate', delegateService([ + /** + * @ngdoc method + * @name $ionicScrollDelegate#resize + * @description Tell the scrollView to recalculate the size of its container. + */ + 'resize', + /** + * @ngdoc method + * @name $ionicScrollDelegate#scrollTop + * @param {boolean=} shouldAnimate Whether the scroll should animate. + */ + 'scrollTop', + /** + * @ngdoc method + * @name $ionicScrollDelegate#scrollBottom + * @param {boolean=} shouldAnimate Whether the scroll should animate. + */ + 'scrollBottom', + /** + * @ngdoc method + * @name $ionicScrollDelegate#scrollTo + * @param {number} left The x-value to scroll to. + * @param {number} top The y-value to scroll to. + * @param {boolean=} shouldAnimate Whether the scroll should animate. + */ + 'scrollTo', + /** + * @ngdoc method + * @name $ionicScrollDelegate#anchorScroll + * @description Tell the scrollView to scroll to the element with an id + * matching window.location.hash. + * + * If no matching element is found, it will scroll to top. + * + * @param {boolean=} shouldAnimate Whether the scroll should animate. + */ + 'anchorScroll', + /** + * @ngdoc method + * @name $ionicScrollDelegate#rememberScrollPosition + * @description + * Will make it so, when this scrollView is destroyed (user leaves the page), + * the last scroll position the page was on will be saved, indexed by the + * given id. + * + * Note: for pages associated with a view under an ion-nav-view, + * rememberScrollPosition automatically saves their scroll. + * + * Related methods: scrollToRememberedPosition, forgetScrollPosition (below). + * + * In the following example, the scroll position of the ion-scroll element + * will persist, even when the user changes the toggle switch. + * + * ```html + * + * + *
+ * + * {{i}} + * + *
+ *
+ * ``` + * ```js + * function ScrollCtrl($scope, $ionicScrollDelegate) { + * var delegate = $ionicScrollDelegate.$getByHandle('myScroll'); + * + * // Put any unique ID here. The point of this is: every time the controller is recreated + * // we want to load the correct remembered scroll values. + * delegate.rememberScrollPosition('my-scroll-id'); + * delegate.scrollToRememberedPosition(); + * $scope.items = []; + * for (var i=0; i<100; i++) { + * $scope.items.push(i); + * } + * } + * ``` + * + * @param {string} id The id to remember the scroll position of this + * scrollView by. + */ + 'rememberScrollPosition', + /** + * @ngdoc method + * @name $ionicScrollDelegate#forgetScrollPosition + * @description + * Stop remembering the scroll position for this scrollView. + */ + 'forgetScrollPosition', + /** + * @ngdoc method + * @name $ionicScrollDelegate#scrollToRememberedPosition + * @description + * If this scrollView has an id associated with its scroll position, + * (through calling rememberScrollPosition), and that position is remembered, + * load the position and scroll to it. + * @param {boolean=} shouldAnimate Whether to animate the scroll. + */ + 'scrollToRememberedPosition' + /** + * @ngdoc method + * @name $ionicScrollDelegate#$getByHandle + * @param {string} handle + * @returns `delegateInstance` A delegate instance that controls only the + * scrollViews with `delegate-handle` matching the given handle. + * + * Example: `$ionicScrollDelegate.$getByHandle('my-handle').scrollTop();` + */ +])) + /** * @private */ -.controller('$ionicScroll', ['$scope', 'scrollViewOptions', '$timeout', '$ionicScrollDelegate', '$window', function($scope, scrollViewOptions, $timeout, $ionicScrollDelegate, $window) { +.factory('$$scrollValueCache', function() { + return {}; +}) + +.controller('$ionicScroll', [ + '$scope', + 'scrollViewOptions', + '$timeout', + '$window', + '$$scrollValueCache', + '$location', + '$rootScope', + '$document', + '$ionicScrollDelegate', +function($scope, scrollViewOptions, $timeout, $window, $$scrollValueCache, $location, $rootScope, $document, $ionicScrollDelegate) { var self = this; + this._scrollViewOptions = scrollViewOptions; //for testing + var element = this.element = scrollViewOptions.el; + var $element = this.$element = angular.element(element); var scrollView = this.scrollView = new ionic.views.Scroll(scrollViewOptions); + //Attach self to element as a controller so other directives can require this controller + //through `require: '$ionicScroll' + //Also attach to parent so that sibling elements can require this + ($element.parent().length ? $element.parent() : $element) + .data('$$ionicScrollController', this); + + var deregisterInstance = $ionicScrollDelegate._registerInstance( + this, scrollViewOptions.delegateHandle + ); + if (!angular.isDefined(scrollViewOptions.bouncing)) { ionic.Platform.ready(function() { scrollView.options.bouncing = !ionic.Platform.isAndroid(); }); } - var $element = this.$element = angular.element(element); + var resize = angular.bind(scrollView, scrollView.resize); + ionic.on('resize', resize, $window); - //Attach self to element as a controller so other directives can require this controller - //through `require: '$ionicScroll' - $element.data('$$ionicScrollController', this); + // set by rootScope listener if needed + var backListenDone = angular.noop; - //Register delegate for event handling - $ionicScrollDelegate.register($scope, $element, scrollView); - - $window.addEventListener('resize', resize); $scope.$on('$destroy', function() { + deregisterInstance(); + ionic.off('resize', resize, $window); $window.removeEventListener('resize', resize); + backListenDone(); + if (self._rememberScrollId) { + $$scrollValueCache[self._rememberScrollId] = scrollView.getValues(); + } }); - function resize() { - scrollView.resize(); - } - this.setRefresher = function(refresherScope, refresherElement) { + $element.on('scroll', function(e) { + var detail = (e.originalEvent || e).detail || {}; + $scope.$onScroll && $scope.$onScroll({ + event: e, + scrollTop: detail.scrollTop || 0, + scrollLeft: detail.scrollLeft || 0 + }); + }); + + $scope.$on('$viewContentLoaded', function(e, historyData) { + //only the top-most scroll area under a view should remember that view's + //scroll position + if (e.defaultPrevented) { return; } + e.preventDefault(); + + var viewId = historyData && historyData.viewId; + if (viewId) { + self.rememberScrollPosition(viewId); + self.scrollToRememberedPosition(); + + backListenDone = $rootScope.$on('$viewHistory.viewBack', function(e, fromViewId, toViewId) { + //When going back from this view, forget its saved scroll position + if (viewId === fromViewId) { + self.forgetScrollPosition(); + } + }); + } + }); + + $timeout(function() { + scrollView.run(); + }); + + this._rememberScrollId = null; + + this.resize = function() { + return $timeout(resize); + }; + + this.scrollTop = function(shouldAnimate) { + this.resize().then(function() { + scrollView.scrollTo(0, 0, !!shouldAnimate); + }); + }; + + this.scrollBottom = function(shouldAnimate) { + this.resize().then(function() { + var max = scrollView.getScrollMax(); + scrollView.scrollTo(max.left, max.top, !!shouldAnimate); + }); + }; + + this.scrollTo = function(left, top, shouldAnimate) { + this.resize().then(function() { + scrollView.scrollTo(left, top, !!shouldAnimate); + }); + }; + + this.anchorScroll = function(shouldAnimate) { + this.resize().then(function() { + var hash = $location.hash(); + var elm = hash && $document[0].getElementById(hash); + if (hash && elm) { + var scroll = ionic.DomUtil.getPositionInParent(elm, self.$element); + scrollView.scrollTo(scroll.left, scroll.top, !!shouldAnimate); + } else { + scrollView.scrollTo(0,0, !!shouldAnimate); + } + }); + }; + + this.rememberScrollPosition = function(id) { + if (!id) { + throw new Error("Must supply an id to remember the scroll by!"); + } + this._rememberScrollId = id; + }; + this.forgetScrollPosition = function() { + delete $$scrollValueCache[this._rememberScrollId]; + this._rememberScrollId = null; + }; + this.scrollToRememberedPosition = function(shouldAnimate) { + var values = $$scrollValueCache[this._rememberScrollId]; + if (values) { + this.resize().then(function() { + scrollView.scrollTo(+values.left, +values.top, shouldAnimate); + }); + } + }; + + + + /** + * @private + */ + this._setRefresher = function(refresherScope, refresherElement) { var refresher = this.refresher = refresherElement; var refresherHeight = self.refresher.clientHeight || 0; scrollView.activatePullToRefresh(refresherHeight, function() { @@ -37462,10 +38208,7 @@ angular.module('ionic.ui.scroll') refresherScope.$onRefresh(); }); }; - - $timeout(function() { - scrollView.run(); - }); }]); -})(); + +})(); \ No newline at end of file diff --git a/release/js/ionic.bundle.min.js b/release/js/ionic.bundle.min.js index 52a95611df..2aab130d30 100644 --- a/release/js/ionic.bundle.min.js +++ b/release/js/ionic.bundle.min.js @@ -8,7 +8,7 @@ * Copyright 2014 Drifty Co. * http://drifty.com/ * - * Ionic, v0.9.27 + * Ionic, v1.0.0-beta.1 * A powerful HTML5 mobile app framework. * http://ionicframework.com/ * @@ -18,9 +18,9 @@ * */ -window.ionic={controllers:{},views:{},version:"{{ VERSION }}"},function(t){function e(t){return t*t*t}function i(t){return 3*t*t*(1-t)}function n(t){return 3*t*(1-t)*(1-t)}function r(t){return(1-t)*(1-t)*(1-t)}var o=function(t,e){return t||(t=0),e||(e=0),{x:t,y:e}};t.Animator={getQuadraticBezier:function(t,s,a,l,c){var h=new o;return h.x=s.x*e(t)+a.x*i(t)+l.x*n(t)+c.x*r(t),h.y=s.y*e(t)+a.y*i(t)+l.y*n(t)+c.y*r(t),h},getCubicBezier:function(t,e,i,n,r){epsilon=1e3/60/r/4;var o=function(e){var n=1-e;return 3*n*n*e*t+3*n*e*e*i+e*e*e},s=function(t){var i=1-t;return 3*i*i*t*e+3*i*t*t*n+t*t*t},a=function(e){var n=1-e;return 3*(2*(e-1)*e+n*n)*t+3*(-e*e*e+2*n*e)*i};return function(t){var e,i,n,r,l,c,h=t;for(n=h,c=0;8>c;c++){if(r=o(n)-h,Math.abs(r)n)return s(e);if(n>i)return s(i);for(;i>e;){if(r=o(n),Math.abs(r-h)r?e=n:i=n,n=.5*(i-e)+e}return s(n)}},animate:function(t){return{leave:function(){var e=function(){t.classList.remove("leave"),t.classList.remove("leave-active"),t.removeEventListener("webkitTransitionEnd",e),t.removeEventListener("transitionEnd",e)};return t.addEventListener("webkitTransitionEnd",e),t.addEventListener("transitionEnd",e),t.classList.add("leave"),t.classList.add("leave-active"),this},enter:function(){var e=function(){t.classList.remove("enter"),t.classList.remove("enter-active"),t.removeEventListener("webkitTransitionEnd",e),t.removeEventListener("transitionEnd",e)};return t.addEventListener("webkitTransitionEnd",e),t.addEventListener("transitionEnd",e),t.classList.add("enter"),t.classList.add("enter-active"),this}}}}}(ionic),function(t){var e=[],i=function(){for(var n=0;nr;r++)if(i=n[r],i.nodeName&&i.nodeName.toLowerCase()==e){if(i==t)return o;o++}return Array.prototype.slice.call(t.parentNode.children).indexOf(t)},swapNodes:function(t,e){e.parentNode.insertBefore(t,e)},getParentWithClass:function(t,e){for(;t.parentNode;){if(t.parentNode.classList&&t.parentNode.classList.contains(e))return t.parentNode;t=t.parentNode}return null},getParentOrSelfWithClass:function(t,e){for(;t;){if(t.classList&&t.classList.contains(e))return t;t=t.parentNode}return null},rectContains:function(t,e,i,n,r,o){return i>t||t>r?!1:n>e||e>o?!1:!0}},t.requestAnimationFrame=t.DomUtil.requestAnimationFrame,t.animationFrameThrottle=t.DomUtil.animationFrameThrottle}(window.ionic),function(t){window.CustomEvent||!function(){var t;t=function(t,e){var i;e=e||{bubbles:!1,cancelable:!1,detail:void 0};try{i=document.createEvent("CustomEvent"),i.initCustomEvent(t,e.bubbles,e.cancelable,e.detail)}catch(n){i=document.createEvent("Event");for(var r in e)i[r]=e[r];i.initEvent(t,e.bubbles,e.cancelable)}return i},t.prototype=window.Event.prototype,window.CustomEvent=t}(),t.EventController={VIRTUALIZED_EVENTS:["tap","swipe","swiperight","swipeleft","drag","hold","release"],trigger:function(t,e,i,n){var r=new CustomEvent(t,{detail:e,bubbles:!!i,cancelable:!!n});e&&e.target&&e.target.dispatchEvent(r)||window.dispatchEvent(r)},on:function(e,i,n){for(var r=n||window,o=0,s=this.VIRTUALIZED_EVENTS.length;s>o;o++)if(e==this.VIRTUALIZED_EVENTS[o]){var a=new t.Gesture(n);return a.on(e,i),a}r.addEventListener(e,i)},off:function(t,e,i){i.removeEventListener(t,e)},onGesture:function(e,i,n){var r=new t.Gesture(n);return r.on(e,i),r},offGesture:function(t,e,i){t.off(e,i)},handlePopState:function(){}},t.on=function(){t.EventController.on.apply(t.EventController,arguments)},t.off=function(){t.EventController.off.apply(t.EventController,arguments)},t.trigger=t.EventController.trigger,t.onGesture=function(){return t.EventController.onGesture.apply(t.EventController.onGesture,arguments)},t.offGesture=function(){return t.EventController.offGesture.apply(t.EventController.offGesture,arguments)}}(window.ionic),function(t){function e(){if(!t.Gestures.READY){t.Gestures.event.determineEventTypes();for(var e in t.Gestures.gestures)t.Gestures.gestures.hasOwnProperty(e)&&t.Gestures.detection.register(t.Gestures.gestures[e]);t.Gestures.event.onTouch(t.Gestures.DOCUMENT,t.Gestures.EVENT_MOVE,t.Gestures.detection.detect),t.Gestures.event.onTouch(t.Gestures.DOCUMENT,t.Gestures.EVENT_END,t.Gestures.detection.detect),t.Gestures.READY=!0}}t.Gesture=function(e,i){return new t.Gestures.Instance(e,i||{})},t.Gestures={},t.Gestures.defaults={stop_browser_behavior:"disable-user-behavior"},t.Gestures.HAS_POINTEREVENTS=window.navigator.pointerEnabled||window.navigator.msPointerEnabled,t.Gestures.HAS_TOUCHEVENTS="ontouchstart"in window,t.Gestures.MOBILE_REGEX=/mobile|tablet|ip(ad|hone|od)|android|silk/i,t.Gestures.NO_MOUSEEVENTS=t.Gestures.HAS_TOUCHEVENTS&&window.navigator.userAgent.match(t.Gestures.MOBILE_REGEX),t.Gestures.EVENT_TYPES={},t.Gestures.DIRECTION_DOWN="down",t.Gestures.DIRECTION_LEFT="left",t.Gestures.DIRECTION_UP="up",t.Gestures.DIRECTION_RIGHT="right",t.Gestures.POINTER_MOUSE="mouse",t.Gestures.POINTER_TOUCH="touch",t.Gestures.POINTER_PEN="pen",t.Gestures.EVENT_START="start",t.Gestures.EVENT_MOVE="move",t.Gestures.EVENT_END="end",t.Gestures.DOCUMENT=window.document,t.Gestures.plugins={},t.Gestures.READY=!1,t.Gestures.Instance=function(i,n){var r=this;if(null!==i)return e(),this.element=i,this.enabled=!0,this.options=t.Gestures.utils.extend(t.Gestures.utils.extend({},t.Gestures.defaults),n||{}),this.options.stop_browser_behavior&&t.Gestures.utils.stopDefaultBrowserBehavior(this.element,this.options.stop_browser_behavior),t.Gestures.event.onTouch(i,t.Gestures.EVENT_START,function(e){r.enabled&&t.Gestures.detection.startDetect(r,e)}),this},t.Gestures.Instance.prototype={on:function(t,e){for(var i=t.split(" "),n=0;n0&&o==t.Gestures.EVENT_END?o=t.Gestures.EVENT_MOVE:h||(o=t.Gestures.EVENT_END),(h||null===i)&&(i=l),s.call(t.Gestures.detection,a.collectEventData(e,o,a.getTouchList(i,o),l)),t.Gestures.HAS_POINTEREVENTS&&o==t.Gestures.EVENT_END&&(h=t.Gestures.PointerEvent.updatePointer(o,l))),h||(i=null,n=!1,r=!1,t.Gestures.PointerEvent.reset())}})},determineEventTypes:function(){var e;e=t.Gestures.HAS_POINTEREVENTS?t.Gestures.PointerEvent.getEvents():t.Gestures.NO_MOUSEEVENTS?["touchstart","touchmove","touchend touchcancel"]:["touchstart mousedown","touchmove mousemove","touchend touchcancel mouseup"],t.Gestures.EVENT_TYPES[t.Gestures.EVENT_START]=e[0],t.Gestures.EVENT_TYPES[t.Gestures.EVENT_MOVE]=e[1],t.Gestures.EVENT_TYPES[t.Gestures.EVENT_END]=e[2]},getTouchList:function(e){return t.Gestures.HAS_POINTEREVENTS?t.Gestures.PointerEvent.getTouchList():e.touches?e.touches:(e.indentifier=1,[e])},collectEventData:function(e,i,n,r){var o=t.Gestures.POINTER_TOUCH;return(r.type.match(/mouse/)||t.Gestures.PointerEvent.matchType(t.Gestures.POINTER_MOUSE,r))&&(o=t.Gestures.POINTER_MOUSE),{center:t.Gestures.utils.getCenter(n),timeStamp:(new Date).getTime(),target:r.target,touches:n,eventType:i,pointerType:o,srcEvent:r,preventDefault:function(){this.srcEvent.preventManipulation&&this.srcEvent.preventManipulation(),this.srcEvent.preventDefault},stopPropagation:function(){this.srcEvent.stopPropagation()},stopDetect:function(){return t.Gestures.detection.stopDetect()}}}},t.Gestures.PointerEvent={pointers:{},getTouchList:function(){var t=this,e=[];return Object.keys(t.pointers).sort().forEach(function(i){e.push(t.pointers[i])}),e},updatePointer:function(e,i){return e==t.Gestures.EVENT_END?this.pointers={}:(i.identifier=i.pointerId,this.pointers[i.pointerId]=i),Object.keys(this.pointers).length},matchType:function(e,i){if(!i.pointerType)return!1;var n={};return n[t.Gestures.POINTER_MOUSE]=i.pointerType==i.MSPOINTER_TYPE_MOUSE||i.pointerType==t.Gestures.POINTER_MOUSE,n[t.Gestures.POINTER_TOUCH]=i.pointerType==i.MSPOINTER_TYPE_TOUCH||i.pointerType==t.Gestures.POINTER_TOUCH,n[t.Gestures.POINTER_PEN]=i.pointerType==i.MSPOINTER_TYPE_PEN||i.pointerType==t.Gestures.POINTER_PEN,n[e]},getEvents:function(){return["pointerdown MSPointerDown","pointermove MSPointerMove","pointerup pointercancel MSPointerUp MSPointerCancel"]},reset:function(){this.pointers={}}},t.Gestures.utils={extend:function(t,e,i){for(var n in e)void 0!==t[n]&&i||(t[n]=e[n]);return t},hasParent:function(t,e){for(;t;){if(t==e)return!0;t=t.parentNode}return!1},getCenter:function(t){for(var e=[],i=[],n=0,r=t.length;r>n;n++)e.push(t[n].pageX),i.push(t[n].pageY);return{pageX:(Math.min.apply(Math,e)+Math.max.apply(Math,e))/2,pageY:(Math.min.apply(Math,i)+Math.max.apply(Math,i))/2}},getVelocity:function(t,e,i){return{x:Math.abs(e/t)||0,y:Math.abs(i/t)||0}},getAngle:function(t,e){var i=e.pageY-t.pageY,n=e.pageX-t.pageX;return 180*Math.atan2(i,n)/Math.PI},getDirection:function(e,i){var n=Math.abs(e.pageX-i.pageX),r=Math.abs(e.pageY-i.pageY);return n>=r?e.pageX-i.pageX>0?t.Gestures.DIRECTION_LEFT:t.Gestures.DIRECTION_RIGHT:e.pageY-i.pageY>0?t.Gestures.DIRECTION_UP:t.Gestures.DIRECTION_DOWN},getDistance:function(t,e){var i=e.pageX-t.pageX,n=e.pageY-t.pageY;return Math.sqrt(i*i+n*n)},getScale:function(t,e){return t.length>=2&&e.length>=2?this.getDistance(e[0],e[1])/this.getDistance(t[0],t[1]):1},getRotation:function(t,e){return t.length>=2&&e.length>=2?this.getAngle(e[1],e[0])-this.getAngle(t[1],t[0]):0},isVertical:function(e){return e==t.Gestures.DIRECTION_UP||e==t.Gestures.DIRECTION_DOWN},stopDefaultBrowserBehavior:function(t,e){t&&t.classList&&(t.classList.add(e),t.onselectstart=function(){return!1})}},t.Gestures.detection={gestures:[],current:null,previous:null,stopped:!1,startDetect:function(e,i){this.current||(this.stopped=!1,this.current={inst:e,startEvent:t.Gestures.utils.extend({},i),lastEvent:!1,name:""},this.detect(i))},detect:function(e){if(this.current&&!this.stopped){e=this.extendEventData(e);for(var i=this.current.inst.options,n=0,r=this.gestures.length;r>n;n++){var o=this.gestures[n];if(!this.stopped&&i[o.name]!==!1&&o.handler.call(o,e,this.current.inst)===!1){this.stopDetect();break}}return this.current&&(this.current.lastEvent=e),e.eventType==t.Gestures.EVENT_END&&!e.touches.length-1&&this.stopDetect(),e}},stopDetect:function(){this.previous=t.Gestures.utils.extend({},this.current),this.current=null,this.stopped=!0},extendEventData:function(e){var i=this.current.startEvent;if(i&&(e.touches.length!=i.touches.length||e.touches===i.touches)){i.touches=[];for(var n=0,r=e.touches.length;r>n;n++)i.touches.push(t.Gestures.utils.extend({},e.touches[n]))}var o=e.timeStamp-i.timeStamp,s=e.center.pageX-i.center.pageX,a=e.center.pageY-i.center.pageY,l=t.Gestures.utils.getVelocity(o,s,a);return t.Gestures.utils.extend(e,{deltaTime:o,deltaX:s,deltaY:a,velocityX:l.x,velocityY:l.y,distance:t.Gestures.utils.getDistance(i.center,e.center),angle:t.Gestures.utils.getAngle(i.center,e.center),direction:t.Gestures.utils.getDirection(i.center,e.center),scale:t.Gestures.utils.getScale(i.touches,e.touches),rotation:t.Gestures.utils.getRotation(i.touches,e.touches),startEvent:i}),e},register:function(e){var i=e.defaults||{};return void 0===i[e.name]&&(i[e.name]=!0),t.Gestures.utils.extend(t.Gestures.defaults,i,!0),e.index=e.index||1e3,this.gestures.push(e),this.gestures.sort(function(t,e){return t.indexe.index?1:0}),this.gestures}},t.Gestures.gestures=t.Gestures.gestures||{},t.Gestures.gestures.Hold={name:"hold",index:10,defaults:{hold_timeout:500,hold_threshold:1},timer:null,handler:function(e,i){switch(e.eventType){case t.Gestures.EVENT_START:clearTimeout(this.timer),t.Gestures.detection.current.name=this.name,this.timer=setTimeout(function(){"hold"==t.Gestures.detection.current.name&&i.trigger("hold",e)},i.options.hold_timeout);break;case t.Gestures.EVENT_MOVE:e.distance>i.options.hold_threshold&&clearTimeout(this.timer);break;case t.Gestures.EVENT_END:clearTimeout(this.timer)}}},t.Gestures.gestures.Tap={name:"tap",index:100,defaults:{tap_max_touchtime:250,tap_max_distance:10,tap_always:!0,doubletap_distance:20,doubletap_interval:300},handler:function(e,i){if(e.eventType==t.Gestures.EVENT_END){var n=t.Gestures.detection.previous,r=!1;if(e.deltaTime>i.options.tap_max_touchtime||e.distance>i.options.tap_max_distance)return;n&&"tap"==n.name&&e.timeStamp-n.lastEvent.timeStamp0&&e.touches.length>i.options.swipe_max_touches)return;(e.velocityX>i.options.swipe_velocity||e.velocityY>i.options.swipe_velocity)&&(i.trigger(this.name,e),i.trigger(this.name+e.direction,e))}}},t.Gestures.gestures.Drag={name:"drag",index:50,defaults:{drag_min_distance:10,correct_for_drag_min_distance:!0,drag_max_touches:1,drag_block_horizontal:!0,drag_block_vertical:!0,drag_lock_to_axis:!1,drag_lock_min_distance:25},triggered:!1,handler:function(e,i){if(t.Gestures.detection.current.name!=this.name&&this.triggered)return i.trigger(this.name+"end",e),void(this.triggered=!1);if(!(i.options.drag_max_touches>0&&e.touches.length>i.options.drag_max_touches))switch(e.eventType){case t.Gestures.EVENT_START:this.triggered=!1;break;case t.Gestures.EVENT_MOVE:if(e.distancei.options.transform_min_rotation&&i.trigger("rotate",e),n>i.options.transform_min_scale&&(i.trigger("pinch",e),i.trigger("pinch"+(e.scale<1?"in":"out"),e));break;case t.Gestures.EVENT_END:this.triggered&&i.trigger(this.name+"end",e),this.triggered=!1}}},t.Gestures.gestures.Touch={name:"touch",index:-1/0,defaults:{prevent_default:!1,prevent_mouseevents:!1},handler:function(e,i){return i.options.prevent_mouseevents&&e.pointerType==t.Gestures.POINTER_MOUSE?void e.stopDetect():(i.options.prevent_default&&e.preventDefault(),void(e.eventType==t.Gestures.EVENT_START&&i.trigger(this.name,e)))}},t.Gestures.gestures.Release={name:"release",index:1/0,handler:function(e,i){e.eventType==t.Gestures.EVENT_END&&i.trigger(this.name,e)}}}(window.ionic),function(t){function e(){t.Platform.isCordova()?document.addEventListener("deviceready",i,!1):i(),window.removeEventListener("load",e,!1)}function i(){t.Platform.isReady=!0,t.Platform.detect();for(var e=0;e0?i=i.replace(".","_"):i+="_0",this.platforms.push(t+i.split("_")[0]),this.platforms.push(t+i),this.isAndroid()&&4.4>e&&(this.grade=4>e?"c":"b")}}},isCordova:function(){return!(!window.cordova&&!window.PhoneGap&&!window.phonegap)},isIPad:function(){return this.ua.toLowerCase().indexOf("ipad")>=0},isIOS:function(){return this.is("ios")},isAndroid:function(){return this.is("android")},platform:function(){return null===n&&this.setPlatform(this.device().platform),n},setPlatform:function(t){n="undefined"!=typeof t&&null!==t&&t.length?t.toLowerCase():this.ua.indexOf("Android")>0?"android":this.ua.indexOf("iPhone")>-1||this.ua.indexOf("iPad")>-1||this.ua.indexOf("iPod")>-1?"ios":""},version:function(){return null===r&&this.setVersion(this.device().version),r},setVersion:function(t){if("undefined"!=typeof t&&null!==t&&(t=t.split("."),t=parseFloat(t[0]+"."+(t.length>1?t[1]:0)),!isNaN(t)))return void(r=t);r=0;var e=this.platform(),i={android:/Android (\d+).(\d+)?/,ios:/OS (\d+)_(\d+)?/};i[e]&&(t=this.ua.match(i[e]),t.length>2&&(r=parseFloat(t[1]+"."+t[2])))},is:function(t){if(t=t.toLowerCase(),this.platforms)for(var e=0;e=0},exitApp:function(){this.ready(function(){navigator.app&&navigator.app.exitApp&&navigator.app.exitApp()})},showStatusBar:function(e){this._showStatusBar=e,this.ready(function(){t.Platform._showStatusBar?(StatusBar.show(),document.body.classList.remove("status-bar-hide")):(StatusBar.hide(),document.body.classList.add("status-bar-hide"))})},fullScreen:function(e,i){this.isFullScreen=e!==!1,t.DomUtil.ready(function(){t.Platform.isFullScreen?document.body.classList.add("fullscreen"):document.body.classList.remove("fullscreen")}),this.showStatusBar(i===!0)}};var n=null,r=null,o=[];window.addEventListener("load",e,!1)}(window.ionic),function(t,e){"use strict";e.CSS={},function(){var i,n=["webkitTransform","transform","-webkit-transform","webkit-transform","-moz-transform","moz-transform","MozTransform","mozTransform"];for(i=0;ir&&n;r++){if("INPUT"===n.tagName||"A"===n.tagName||"BUTTON"===n.tagName||"LABEL"===n.tagName||"TEXTAREA"===n.tagName||"SELECT"===n.tagName)return i.tapElement(n,e);n=n.parentElement}u()}}function r(t){return t.target.control||o(t)||s(t)?h(t):void a(t)}function o(t){var e,i,n;for(e in _)if(i=_[e],n||(n=l(t)),n.x>i.x-m&&n.xi.y-m&&n.yf.x+m||e.xf.y+m||e.ye&&(n&&"LABEL"!==n.tagName);e++){if(n.classList.contains("item")||n.classList.contains("button")){v[T]=n,T=T>24?0:T+1,i.requestAnimationFrame(function(){n.classList.add("active")});break}n=n.parentElement}}i.tapElement=function(i,n){var r=i.control||i;if(!r.disabled&&"file"!==r.type){var s=l(n),c=e.createEvent("MouseEvents");return c.initMouseEvent("click",!0,!0,t,1,0,0,s.x,s.y,!1,!1,!1,!1,0,null),r.dispatchEvent(c),"INPUT"===r.tagName||"TEXTAREA"===r.tagName||"SELECT"===r.tagName?(r.focus(),n.preventDefault()):u(),o(n)||a(n),i.control?h(n):void 0}};var _={},f={},g=1500,p=375,m=15,v={},T=0;e.addEventListener("click",r,!0),i.on("tap",n,e),e.addEventListener("touchend",c,!1),e.addEventListener("mouseup",c,!1),e.addEventListener("touchstart",d,!1),e.addEventListener("mousedown",d,!1)}(this,document,ionic),function(t){var e=["0","0","0"];t.Utils={arrayMove:function(t,e,i){if(i>=t.length)for(var n=i-t.length;n--+1;)t.push(void 0);return t.splice(i,0,t.splice(e,1)[0]),t},proxy:function(t,e){var i=Array.prototype.slice.call(arguments,2);return function(){return t.apply(e,i.concat(Array.prototype.slice.call(arguments)))}},debounce:function(t,e,i){var n,r,o,s,a;return function(){o=this,r=arguments,s=new Date;var l=function(){var c=new Date-s;e>c?n=setTimeout(l,e-c):(n=null,i||(a=t.apply(o,r)))},c=i&&!n;return n||(n=setTimeout(l,e)),c&&(a=t.apply(o,r)),a}},throttle:function(t,e,i){var n,r,o,s=null,a=0;i||(i={});var l=function(){a=i.leading===!1?0:Date.now(),s=null,o=t.apply(n,r)};return function(){var c=Date.now();a||i.leading!==!1||(a=c);var h=e-(c-a);return n=this,r=arguments,0>=h?(clearTimeout(s),s=null,a=c,o=t.apply(n,r)):s||i.trailing===!1||(s=setTimeout(l,h)),o}},inherit:function(e,i){var n,r=this;n=e&&e.hasOwnProperty("constructor")?e.constructor:function(){return r.apply(this,arguments)},t.extend(n,r,i);var o=function(){this.constructor=n};return o.prototype=r.prototype,n.prototype=new o,e&&t.extend(n.prototype,e),n.__super__=r.prototype,n},extend:function(t){for(var e=Array.prototype.slice.call(arguments,1),i=0;i2500&&(clearInterval(a),a=null)},1e3/n)),e}}(),stop:function(t){var e=null!=r[t];return e&&(r[t]=null),e},isRunning:function(t){return null!=r[t]},start:function(t,s,a,l,c,h){var u=e(),d=u,_=0,f=0,g=o++;if(h||(h=document.body),g%20===0){var p={};for(var m in r)p[m]=!0;r=p}var v=function(o){var p=o!==!0,m=e();if(!r[g]||s&&!s(g))return r[g]=null,void(a&&a(i-f/((m-u)/n),g,!1));if(p)for(var T=Math.round((m-d)/(n/i))-1,E=0;E1&&(_=1));var w=c?c(_):_;t(w,m,p)!==!1&&1!==_||!p?p&&(d=m,core.effect.Animate.requestAnimationFrame(v,h)):(r[g]=null,a&&a(i-f/((m-u)/n),g,1===_||null==l))};return r[g]=!0,core.effect.Animate.requestAnimationFrame(v,h),g}}}(this);var Scroller;!function(t){var e=function(){},i=function(t){return Math.pow(t-1,3)+1},n=function(t){return(t/=.5)<1?.5*Math.pow(t,3):.5*(Math.pow(t-2,3)+2)};t.views.Scroll=t.views.View.inherit({initialize:function(i){var n=this;this.__container=i.el,this.__content=i.el.firstElementChild,setTimeout(function(){n.__container&&n.__content&&(n.__container.scrollTop=0,n.__content.scrollTop=0)}),this.options={scrollingX:!1,scrollbarX:!0,scrollingY:!0,scrollbarY:!0,startX:0,startY:0,wheelDampen:6,minScrollbarSizeX:5,minScrollbarSizeY:5,scrollbarsFade:!0,scrollbarFadeDelay:300,scrollbarResizeFadeDelay:1e3,animating:!0,animationDuration:250,bouncing:!0,locking:!0,paging:!1,snapping:!1,zooming:!1,minZoom:.5,maxZoom:3,speedMultiplier:1,scrollingComplete:e,penetrationDeceleration:.03,penetrationAcceleration:.08,scrollEventInterval:50};for(var r in i)this.options[r]=i[r];this.hintResize=t.debounce(function(){n.resize()},1e3,!0),this.triggerScrollEvent=t.throttle(function(){t.trigger("scroll",{scrollTop:n.__scrollTop,scrollLeft:n.__scrollLeft,target:n.__container})},this.options.scrollEventInterval),this.triggerScrollEndEvent=function(){t.trigger("scrollend",{scrollTop:n.__scrollTop,scrollLeft:n.__scrollLeft,target:n.__container})},this.__scrollLeft=this.options.startX,this.__scrollTop=this.options.startY,this.__callback=this.getRenderFn(),this.__initEventHandlers(),this.__createScrollbars()},run:function(){this.resize(),this.__fadeScrollbars("out",this.options.scrollbarResizeFadeDelay)},__isSingleTouch:!1,__isTracking:!1,__didDecelerationComplete:!1,__isGesturing:!1,__isDragging:!1,__isDecelerating:!1,__isAnimating:!1,__clientLeft:0,__clientTop:0,__clientWidth:0,__clientHeight:0,__contentWidth:0,__contentHeight:0,__snapWidth:100,__snapHeight:100,__refreshHeight:null,__refreshActive:!1,__refreshActivate:null,__refreshDeactivate:null,__refreshStart:null,__zoomLevel:1,__scrollLeft:0,__scrollTop:0,__maxScrollLeft:0,__maxScrollTop:0,__scheduledLeft:0,__scheduledTop:0,__scheduledZoom:0,__lastTouchLeft:null,__lastTouchTop:null,__lastTouchMove:null,__positions:null,__minDecelerationScrollLeft:null,__minDecelerationScrollTop:null,__maxDecelerationScrollLeft:null,__maxDecelerationScrollTop:null,__decelerationVelocityX:null,__decelerationVelocityY:null,__transformProperty:null,__perspectiveProperty:null,__indicatorX:null,__indicatorY:null,__scrollbarFadeTimeout:null,__didWaitForSize:null,__sizerTimeout:null,__initEventHandlers:function(){function e(t){return t.target.tagName.match(IS_INPUT_LIKE_REGEX)||t.target.isContentEditable||t.target.tagName.match(IS_EMBEDDED_OBJECT_REGEX)}var i=this,n=this.__container;if(n.addEventListener("scrollChildIntoView",function(e){var r=window.innerHeight,o=e.target,s=e.target.offsetHeight,a=o.getBoundingClientRect().top,l=t.DomUtil.getPositionInParent(o,n).top;a+s>r&&i.scrollTo(0,l+s-.5*r,!0),e.stopPropagation()}),"ontouchstart"in window)n.addEventListener("touchstart",function(t){t.defaultPrevented||e(t)||(i.doTouchStart(t.touches,t.timeStamp),t.preventDefault())},!1),document.addEventListener("touchmove",function(t){t.defaultPrevented||i.doTouchMove(t.touches,t.timeStamp)},!1),document.addEventListener("touchend",function(t){i.doTouchEnd(t.timeStamp)},!1);else{var r=!1;n.addEventListener("mousedown",function(t){t.defaultPrevented||e(t)||(i.doTouchStart([{pageX:t.pageX,pageY:t.pageY}],t.timeStamp),t.preventDefault(),r=!0)},!1),document.addEventListener("mousemove",function(t){r&&!t.defaultPrevented&&(i.doTouchMove([{pageX:t.pageX,pageY:t.pageY}],t.timeStamp),r=!0)},!1),document.addEventListener("mouseup",function(t){r&&(i.doTouchEnd(t.timeStamp),r=!1)},!1),document.addEventListener("mousewheel",function(t){i.scrollBy(t.wheelDeltaX/i.options.wheelDampen,-t.wheelDeltaY/i.options.wheelDampen)})}},__createScrollbar:function(t){var e=document.createElement("div"),i=document.createElement("div"); -return i.className="scroll-bar-indicator",e.className="h"==t?"scroll-bar scroll-bar-h":"scroll-bar scroll-bar-v",e.appendChild(i),e},__createScrollbars:function(){var t,e;this.options.scrollingX&&(t={el:this.__createScrollbar("h"),sizeRatio:1},t.indicator=t.el.children[0],this.options.scrollbarX&&this.__container.appendChild(t.el),this.__indicatorX=t),this.options.scrollingY&&(e={el:this.__createScrollbar("v"),sizeRatio:1},e.indicator=e.el.children[0],this.options.scrollbarY&&this.__container.appendChild(e.el),this.__indicatorY=e)},__resizeScrollbars:function(){var t=this;if(t.__fadeScrollbars("in"),t.__indicatorX){var e=Math.max(Math.round(t.__clientWidth*t.__clientWidth/t.__contentWidth),20);e>t.__contentWidth&&(e=0),t.__indicatorX.size=e,t.__indicatorX.minScale=this.options.minScrollbarSizeX/e,t.__indicatorX.indicator.style.width=e+"px",t.__indicatorX.maxPos=t.__clientWidth-e,t.__indicatorX.sizeRatio=t.__maxScrollLeft?t.__indicatorX.maxPos/t.__maxScrollLeft:1}if(t.__indicatorY){var i=Math.max(Math.round(t.__clientHeight*t.__clientHeight/t.__contentHeight),20);i>t.__contentHeight&&(i=0),t.__indicatorY.size=i,t.__indicatorY.minScale=this.options.minScrollbarSizeY/i,t.__indicatorY.maxPos=t.__clientHeight-i,t.__indicatorY.indicator.style.height=i+"px",t.__indicatorY.sizeRatio=t.__maxScrollTop?t.__indicatorY.maxPos/t.__maxScrollTop:1}},__repositionScrollbars:function(){var t,e,i,n,r,o=this,s=0,a=0;o.__indicatorX&&(o.__indicatorY&&(s=10),n=Math.round(o.__indicatorX.sizeRatio*o.__scrollLeft)||0,e=o.__scrollLeft-(o.__maxScrollLeft-s),o.__scrollLeft<0?(widthScale=Math.max(o.__indicatorX.minScale,(o.__indicatorX.size-Math.abs(o.__scrollLeft))/o.__indicatorX.size),n=0,o.__indicatorX.indicator.style[o.__transformOriginProperty]="left center"):e>0?(widthScale=Math.max(o.__indicatorX.minScale,(o.__indicatorX.size-e)/o.__indicatorX.size),n=o.__indicatorX.maxPos-s,o.__indicatorX.indicator.style[o.__transformOriginProperty]="right center"):(n=Math.min(o.__maxScrollLeft,Math.max(0,n)),widthScale=1),o.__indicatorX.indicator.style[o.__transformProperty]="translate3d("+n+"px, 0, 0) scaleX("+widthScale+")"),o.__indicatorY&&(r=Math.round(o.__indicatorY.sizeRatio*o.__scrollTop)||0,o.__indicatorX&&(a=10),i=o.__scrollTop-(o.__maxScrollTop-a),o.__scrollTop<0?(t=Math.max(o.__indicatorY.minScale,(o.__indicatorY.size-Math.abs(o.__scrollTop))/o.__indicatorY.size),r=0,o.__indicatorY.indicator.style[o.__transformOriginProperty]="center top"):i>0?(t=Math.max(o.__indicatorY.minScale,(o.__indicatorY.size-i)/o.__indicatorY.size),r=o.__indicatorY.maxPos-a,o.__indicatorY.indicator.style[o.__transformOriginProperty]="center bottom"):(r=Math.min(o.__maxScrollTop,Math.max(0,r)),t=1),o.__indicatorY.indicator.style[o.__transformProperty]="translate3d(0,"+r+"px, 0) scaleY("+t+")")},__fadeScrollbars:function(t,e){var i=this;if(this.options.scrollbarsFade){var n="scroll-bar-fade-out";i.options.scrollbarsFade===!0&&(clearTimeout(i.__scrollbarFadeTimeout),"in"==t?(i.__indicatorX&&i.__indicatorX.indicator.classList.remove(n),i.__indicatorY&&i.__indicatorY.indicator.classList.remove(n)):i.__scrollbarFadeTimeout=setTimeout(function(){i.__indicatorX&&i.__indicatorX.indicator.classList.add(n),i.__indicatorY&&i.__indicatorY.indicator.classList.add(n)},e||i.options.scrollbarFadeDelay))}},__scrollingComplete:function(){var t=this;t.options.scrollingComplete(),t.__fadeScrollbars("out")},resize:function(){this.setDimensions(this.__container.clientWidth,this.__container.clientHeight,Math.max(this.__content.scrollWidth,this.__content.offsetWidth),Math.max(this.__content.scrollHeight,this.__content.offsetHeight))},getRenderFn:function(){var t,e=this,i=this.__content,n=document.documentElement.style;"MozAppearance"in n?t="gecko":"WebkitAppearance"in n?t="webkit":"string"==typeof navigator.cpuClass&&(t="trident");var r,o={trident:"ms",gecko:"Moz",webkit:"Webkit",presto:"O"}[t],s=document.createElement("div"),a=o+"Perspective",l=o+"Transform",c=o+"TransformOrigin";return e.__perspectiveProperty=l,e.__transformProperty=l,e.__transformOriginProperty=c,s.style[a]!==r?function(t,n){i.style[l]="translate3d("+-t+"px,"+-n+"px,0)",e.__repositionScrollbars(),e.triggerScrollEvent()}:s.style[l]!==r?function(t,n){i.style[l]="translate("+-t+"px,"+-n+"px)",e.__repositionScrollbars(),e.triggerScrollEvent()}:function(t,n,r){i.style.marginLeft=t?-t/r+"px":"",i.style.marginTop=n?-n/r+"px":"",i.style.zoom=r||"",e.__repositionScrollbars(),e.triggerScrollEvent()}},setDimensions:function(t,e,i,n){var r=this;t===+t&&(r.__clientWidth=t),e===+e&&(r.__clientHeight=e),i===+i&&(r.__contentWidth=i),n===+n&&(r.__contentHeight=n),r.__computeScrollMax(),r.__resizeScrollbars(),r.scrollTo(r.__scrollLeft,r.__scrollTop,!0)},setPosition:function(t,e){var i=this;i.__clientLeft=t||0,i.__clientTop=e||0},setSnapSize:function(t,e){var i=this;i.__snapWidth=t,i.__snapHeight=e},activatePullToRefresh:function(t,e,i,n){var r=this;r.__refreshHeight=t,r.__refreshActivate=e,r.__refreshDeactivate=i,r.__refreshStart=n},triggerPullToRefresh:function(){this.__publish(this.__scrollLeft,-this.__refreshHeight,this.__zoomLevel,!0),this.__refreshStart&&this.__refreshStart()},finishPullToRefresh:function(){var t=this;t.__refreshActive=!1,t.__refreshDeactivate&&t.__refreshDeactivate(),t.scrollTo(t.__scrollLeft,t.__scrollTop,!0)},getValues:function(){var t=this;return{left:t.__scrollLeft,top:t.__scrollTop,zoom:t.__zoomLevel}},getScrollMax:function(){var t=this;return{left:t.__maxScrollLeft,top:t.__maxScrollTop}},zoomTo:function(t,e,i,n){var r=this;if(!r.options.zooming)throw new Error("Zooming is not enabled!");r.__isDecelerating&&(core.effect.Animate.stop(r.__isDecelerating),r.__isDecelerating=!1);var o=r.__zoomLevel;null==i&&(i=r.__clientWidth/2),null==n&&(n=r.__clientHeight/2),t=Math.max(Math.min(t,r.options.maxZoom),r.options.minZoom),r.__computeScrollMax(t);var s=(i+r.__scrollLeft)*t/o-i,a=(n+r.__scrollTop)*t/o-n;s>r.__maxScrollLeft?s=r.__maxScrollLeft:0>s&&(s=0),a>r.__maxScrollTop?a=r.__maxScrollTop:0>a&&(a=0),r.__publish(s,a,t,e)},zoomBy:function(t,e,i,n){var r=this;r.zoomTo(r.__zoomLevel*t,e,i,n)},scrollTo:function(t,e,i,n){var r=this;if(r.__isDecelerating&&(core.effect.Animate.stop(r.__isDecelerating),r.__isDecelerating=!1),null!=n&&n!==r.__zoomLevel){if(!r.options.zooming)throw new Error("Zooming is not enabled!");t*=n,e*=n,r.__computeScrollMax(n)}else n=r.__zoomLevel;r.options.scrollingX?r.options.paging?t=Math.round(t/r.__clientWidth)*r.__clientWidth:r.options.snapping&&(t=Math.round(t/r.__snapWidth)*r.__snapWidth):t=r.__scrollLeft,r.options.scrollingY?r.options.paging?e=Math.round(e/r.__clientHeight)*r.__clientHeight:r.options.snapping&&(e=Math.round(e/r.__snapHeight)*r.__snapHeight):e=r.__scrollTop,t=Math.max(Math.min(r.__maxScrollLeft,t),0),e=Math.max(Math.min(r.__maxScrollTop,e),0),t===r.__scrollLeft&&e===r.__scrollTop&&(i=!1),r.__publish(t,e,n,i)},scrollBy:function(t,e,i){var n=this,r=n.__isAnimating?n.__scheduledLeft:n.__scrollLeft,o=n.__isAnimating?n.__scheduledTop:n.__scrollTop;n.scrollTo(r+(t||0),o+(e||0),i)},doMouseZoom:function(t,e,i,n){var r=this,o=t>0?.97:1.03;return r.zoomTo(r.__zoomLevel*o,!1,i-r.__clientLeft,n-r.__clientTop)},doTouchStart:function(t,e){if(this.hintResize(),null==t.length)throw new Error("Invalid touch list: "+t);if(e instanceof Date&&(e=e.valueOf()),"number"!=typeof e)throw new Error("Invalid timestamp value: "+e);var i=this;i.__fadeScrollbars("in"),i.__interruptedAnimation=!0,i.__isDecelerating&&(core.effect.Animate.stop(i.__isDecelerating),i.__isDecelerating=!1,i.__interruptedAnimation=!0),i.__isAnimating&&(core.effect.Animate.stop(i.__isAnimating),i.__isAnimating=!1,i.__interruptedAnimation=!0);var n,r,o=1===t.length;o?(n=t[0].pageX,r=t[0].pageY):(n=Math.abs(t[0].pageX+t[1].pageX)/2,r=Math.abs(t[0].pageY+t[1].pageY)/2),i.__initialTouchLeft=n,i.__initialTouchTop=r,i.__zoomLevelStart=i.__zoomLevel,i.__lastTouchLeft=n,i.__lastTouchTop=r,i.__lastTouchMove=e,i.__lastScale=1,i.__enableScrollX=!o&&i.options.scrollingX,i.__enableScrollY=!o&&i.options.scrollingY,i.__isTracking=!0,i.__didDecelerationComplete=!1,i.__isDragging=!o,i.__isSingleTouch=o,i.__positions=[]},doTouchMove:function(t,e,i){if(null==t.length)throw new Error("Invalid touch list: "+t);if(e instanceof Date&&(e=e.valueOf()),"number"!=typeof e)throw new Error("Invalid timestamp value: "+e);var n=this;if(n.__isTracking){var r,o;2===t.length?(r=Math.abs(t[0].pageX+t[1].pageX)/2,o=Math.abs(t[0].pageY+t[1].pageY)/2):(r=t[0].pageX,o=t[0].pageY);var s=n.__positions;if(n.__isDragging){var a=r-n.__lastTouchLeft,l=o-n.__lastTouchTop,c=n.__scrollLeft,h=n.__scrollTop,u=n.__zoomLevel;if(null!=i&&n.options.zooming){var d=u;if(u=u/n.__lastScale*i,u=Math.max(Math.min(u,n.options.maxZoom),n.options.minZoom),d!==u){var _=r-n.__clientLeft,f=o-n.__clientTop;c=(_+c)*u/d-_,h=(f+h)*u/d-f,n.__computeScrollMax(u)}}if(n.__enableScrollX){c-=a*this.options.speedMultiplier;var g=n.__maxScrollLeft;(c>g||0>c)&&(n.options.bouncing?c+=a/2*this.options.speedMultiplier:c=c>g?g:0)}if(n.__enableScrollY){h-=l*this.options.speedMultiplier;var p=n.__maxScrollTop;(h>p||0>h)&&(n.options.bouncing||n.__refreshHeight&&0>h?(h+=l/2*this.options.speedMultiplier,n.__enableScrollX||null==n.__refreshHeight||(!n.__refreshActive&&h<=-n.__refreshHeight?(n.__refreshActive=!0,n.__refreshActivate&&n.__refreshActivate()):n.__refreshActive&&h>-n.__refreshHeight&&(n.__refreshActive=!1,n.__refreshDeactivate&&n.__refreshDeactivate()))):h=h>p?p:0)}s.length>60&&s.splice(0,30),s.push(c,h,e),n.__publish(c,h,u)}else{var m=n.options.locking?3:0,v=5,T=Math.abs(r-n.__initialTouchLeft),E=Math.abs(o-n.__initialTouchTop);n.__enableScrollX=n.options.scrollingX&&T>=m,n.__enableScrollY=n.options.scrollingY&&E>=m,s.push(n.__scrollLeft,n.__scrollTop,e),n.__isDragging=(n.__enableScrollX||n.__enableScrollY)&&(T>=v||E>=v),n.__isDragging&&(n.__interruptedAnimation=!1)}n.__lastTouchLeft=r,n.__lastTouchTop=o,n.__lastTouchMove=e,n.__lastScale=i}},doTouchEnd:function(t){if(t instanceof Date&&(t=t.valueOf()),"number"!=typeof t)throw new Error("Invalid timestamp value: "+t);var e=this;if(e.__isTracking){if(e.__isTracking=!1,e.__isDragging)if(e.__isDragging=!1,e.__isSingleTouch&&e.options.animating&&t-e.__lastTouchMove<=100){for(var i=e.__positions,n=i.length-1,r=n,o=n;o>0&&i[o]>e.__lastTouchMove-100;o-=3)r=o;if(r!==n){var s=i[n]-i[r],a=e.__scrollLeft-i[r-2],l=e.__scrollTop-i[r-1];e.__decelerationVelocityX=a/s*(1e3/60),e.__decelerationVelocityY=l/s*(1e3/60);var c=e.options.paging||e.options.snapping?4:1;(Math.abs(e.__decelerationVelocityX)>c||Math.abs(e.__decelerationVelocityY)>c)&&(e.__refreshActive||e.__startDeceleration(t))}else e.__scrollingComplete()}else t-e.__lastTouchMove>100&&e.__scrollingComplete();e.__isDecelerating||(e.__refreshActive&&e.__refreshStart?(e.__publish(e.__scrollLeft,-e.__refreshHeight,e.__zoomLevel,!0),e.__refreshStart&&e.__refreshStart()):((e.__interruptedAnimation||e.__isDragging)&&e.__scrollingComplete(),e.scrollTo(e.__scrollLeft,e.__scrollTop,!0,e.__zoomLevel),e.__refreshActive&&(e.__refreshActive=!1,e.__refreshDeactivate&&e.__refreshDeactivate()))),e.__positions.length=0}},__publish:function(t,e,r,o){var s=this,a=s.__isAnimating;if(a&&(core.effect.Animate.stop(a),s.__isAnimating=!1),o&&s.options.animating){s.__scheduledLeft=t,s.__scheduledTop=e,s.__scheduledZoom=r;var l=s.__scrollLeft,c=s.__scrollTop,h=s.__zoomLevel,u=t-l,d=e-c,_=r-h,f=function(t,e,i){i&&(s.__scrollLeft=l+u*t,s.__scrollTop=c+d*t,s.__zoomLevel=h+_*t,s.__callback&&s.__callback(s.__scrollLeft,s.__scrollTop,s.__zoomLevel))},g=function(t){return s.__isAnimating===t},p=function(t,e,i){e===s.__isAnimating&&(s.__isAnimating=!1),(s.__didDecelerationComplete||i)&&s.__scrollingComplete(),s.options.zooming&&s.__computeScrollMax()};s.__isAnimating=core.effect.Animate.start(f,g,p,s.options.animationDuration,a?i:n)}else s.__scheduledLeft=s.__scrollLeft=t,s.__scheduledTop=s.__scrollTop=e,s.__scheduledZoom=s.__zoomLevel=r,s.__callback&&s.__callback(t,e,r),s.options.zooming&&s.__computeScrollMax()},__computeScrollMax:function(t){var e=this;null==t&&(t=e.__zoomLevel),e.__maxScrollLeft=Math.max(e.__contentWidth*t-e.__clientWidth,0),e.__maxScrollTop=Math.max(e.__contentHeight*t-e.__clientHeight,0),e.__didWaitForSize||0!=e.__maxScrollLeft||0!=e.__maxScrollTop||(e.__didWaitForSize=!0,e.__waitForSize())},__waitForSize:function(){var t=this;clearTimeout(t.__sizerTimeout);var e=function(){t.resize(),t.options.scrollingX&&0==t.__maxScrollLeft||t.options.scrollingY&&0==t.__maxScrollTop};e(),t.__sizerTimeout=setTimeout(e,1e3)},__startDeceleration:function(){var t=this;if(t.options.paging){var e=Math.max(Math.min(t.__scrollLeft,t.__maxScrollLeft),0),i=Math.max(Math.min(t.__scrollTop,t.__maxScrollTop),0),n=t.__clientWidth,r=t.__clientHeight;t.__minDecelerationScrollLeft=Math.floor(e/n)*n,t.__minDecelerationScrollTop=Math.floor(i/r)*r,t.__maxDecelerationScrollLeft=Math.ceil(e/n)*n,t.__maxDecelerationScrollTop=Math.ceil(i/r)*r}else t.__minDecelerationScrollLeft=0,t.__minDecelerationScrollTop=0,t.__maxDecelerationScrollLeft=t.__maxScrollLeft,t.__maxDecelerationScrollTop=t.__maxScrollTop;var o=function(e,i,n){t.__stepThroughDeceleration(n)};t.__minVelocityToKeepDecelerating=t.options.snapping?4:.1;var s=function(){var e=Math.abs(t.__decelerationVelocityX)>=t.__minVelocityToKeepDecelerating||Math.abs(t.__decelerationVelocityY)>=t.__minVelocityToKeepDecelerating;return e||(t.__didDecelerationComplete=!0),e},a=function(){t.__isDecelerating=!1,t.__didDecelerationComplete&&t.__scrollingComplete(),t.options.paging&&t.scrollTo(t.__scrollLeft,t.__scrollTop,t.options.snapping)};t.__isDecelerating=core.effect.Animate.start(o,s,a)},__stepThroughDeceleration:function(t){var e=this,i=e.__scrollLeft+e.__decelerationVelocityX,n=e.__scrollTop+e.__decelerationVelocityY;if(!e.options.bouncing){var r=Math.max(Math.min(e.__maxDecelerationScrollLeft,i),e.__minDecelerationScrollLeft);r!==i&&(i=r,e.__decelerationVelocityX=0);var o=Math.max(Math.min(e.__maxDecelerationScrollTop,n),e.__minDecelerationScrollTop);o!==n&&(n=o,e.__decelerationVelocityY=0)}if(t?e.__publish(i,n,e.__zoomLevel):(e.__scrollLeft=i,e.__scrollTop=n),!e.options.paging){var s=.95;e.__decelerationVelocityX*=s,e.__decelerationVelocityY*=s}if(e.options.bouncing){var a=0,l=0,c=e.options.penetrationDeceleration,h=e.options.penetrationAcceleration;if(ie.__maxDecelerationScrollLeft&&(a=e.__maxDecelerationScrollLeft-i),ne.__maxDecelerationScrollTop&&(l=e.__maxDecelerationScrollTop-n),0!==a){var u=a*e.__decelerationVelocityX<=e.__minDecelerationScrollLeft;u&&(e.__decelerationVelocityX+=a*c);var d=Math.abs(e.__decelerationVelocityX)<=e.__minVelocityToKeepDecelerating;(!u||d)&&(e.__decelerationVelocityX=a*h)}if(0!==l){var _=l*e.__decelerationVelocityY<=e.__minDecelerationScrollTop;_&&(e.__decelerationVelocityY+=l*c);var f=Math.abs(e.__decelerationVelocityY)<=e.__minVelocityToKeepDecelerating;(!_||f)&&(e.__decelerationVelocityY=l*h)}}}})}(ionic),function(t){"use strict";t.views.ActionSheet=t.views.View.inherit({initialize:function(t){this.el=t.el},show:function(){this.el.offsetWidth,this.el.classList.add("active")},hide:function(){this.el.offsetWidth,this.el.classList.remove("active")}})}(ionic),function(t){"use strict";t.views.HeaderBar=t.views.View.inherit({initialize:function(e){this.el=e.el,t.extend(this,{alignTitle:"center"},e),this.align()},align:function(e){e||(e=this.alignTitle);var i=this.el.querySelector(".title");if(i){var n,r,o,s=this.el.childNodes,a=0,l=0,c=!1;for(n=0;n10&&(i.style.left=t+"px",i.style.right=t+"px"),i.offsetWidth0&&(i.style.right=l+5+"px")):"left"==e?(i.classList.add("title-left"),a>0&&(i.style.left=a+15+"px")):"right"==e&&(i.classList.add("title-right"),l>0&&(i.style.right=l+15+"px"))})}}})}(ionic),function(t){"use strict";var e="item",i="item-content",n="item-sliding",r="item-options",o="item-placeholder",s="item-reordering",a="item-drag",l=function(){};l.prototype={start:function(){},drag:function(){},end:function(){}};var c=function(t){this.dragThresholdX=t.dragThresholdX||10,this.el=t.el};c.prototype=new l,c.prototype.start=function(o){var s,a,l,c;s=o.target.classList.contains(i)?o.target:o.target.classList.contains(e)?o.target.querySelector("."+i):t.DomUtil.getParentWithClass(o.target,i),s&&(s.classList.remove(n),l=parseFloat(s.style[t.CSS.TRANSFORM].replace("translate3d(","").split(",")[0])||0,a=s.parentNode.querySelector("."+r),a&&(c=a.offsetWidth,this._currentDrag={buttonsWidth:c,content:s,startOffsetX:l}))},c.prototype.drag=t.animationFrameThrottle(function(e){var i;if(this._currentDrag&&(!this._isDragging&&(Math.abs(e.gesture.deltaX)>this.dragThresholdX||Math.abs(this._currentDrag.startOffsetX)>0)&&(this._isDragging=!0),this._isDragging)){i=this._currentDrag.buttonsWidth;var n=Math.min(0,this._currentDrag.startOffsetX+e.gesture.deltaX);-i>n&&(n=Math.min(-i,-i+.4*(e.gesture.deltaX+i))),this._currentDrag.content.style[t.CSS.TRANSFORM]="translate3d("+n+"px, 0, 0)",this._currentDrag.content.style[t.CSS.TRANSITION]="none"}}),c.prototype.end=function(e,i){var n=this;if(!this._currentDrag)return void(i&&i());var r=-this._currentDrag.buttonsWidth;e.gesture.deltaX>-(this._currentDrag.buttonsWidth/2)&&("left"==e.gesture.direction&&Math.abs(e.gesture.velocityX)<.3?r=0:"right"==e.gesture.direction&&(r=0)),t.requestAnimationFrame(function(){n._currentDrag.content.style[t.CSS.TRANSFORM]=0===r?"":"translate3d("+r+"px, 0, 0)",n._currentDrag.content.style[t.CSS.TRANSITION]="",n._currentDrag=null,i&&i()})};var h=function(t){this.dragThresholdY=t.dragThresholdY||0,this.onReorder=t.onReorder,this.el=t.el,this.scrollEl=t.scrollEl,this.scrollView=t.scrollView};h.prototype=new l,h.prototype._moveElement=function(e){var i=e.gesture.center.pageY-this._currentDrag.elementHeight/2;this.el.style[t.CSS.TRANSFORM]="translate3d(0, "+i+"px, 0)"},h.prototype.start=function(e){var i=(this.el.offsetTop,t.DomUtil.getChildIndex(this.el,this.el.nodeName.toLowerCase())),n=this.el.offsetHeight,r=this.el.cloneNode(!0),a=(this.scrollEl||this.el).parentNode;r.classList.add(o),this.el.parentNode.insertBefore(r,this.el),this.el.classList.add(s),a.parentNode.appendChild(this.el),this._currentDrag={elementHeight:n,startIndex:i,placeholder:r,scrollHeight:scroll,list:r.parentNode},this._moveElement(e)},h.prototype.drag=t.animationFrameThrottle(function(t){if(this._currentDrag){var e=0,i=t.gesture.center.pageY;if(this.scrollView){var n=this.scrollEl;e=this.scrollView.getValues().top;var r=n.offsetTop,o=r-i+this._currentDrag.elementHeight/2,s=i+this._currentDrag.elementHeight/2-r-n.offsetHeight;t.gesture.deltaY<0&&o>0&&e>0&&this.scrollView.scrollBy(null,-o),t.gesture.deltaY>0&&s>0&&ethis.dragThresholdY&&(this._isDragging=!0),this._isDragging&&(this._moveElement(t),this._currentDrag.currentY=e+i-this._currentDrag.placeholder.parentNode.offsetTop,this._reorderItems())}}),h.prototype._reorderItems=function(){var e=(this._currentDrag.placeholder,Array.prototype.slice.call(this._currentDrag.placeholder.parentNode.children)),i=e.indexOf(this._currentDrag.placeholder),n=e[Math.max(0,i-1)],r=e[Math.min(e.length,i+1)],o=this._currentDrag.currentY;return n&&or.offsetTop+r.offsetHeight/2?(t.DomUtil.swapNodes(r,this._currentDrag.placeholder),i+1):void 0},h.prototype.end=function(e,i){if(!this._currentDrag)return void(i&&i());var n=this._currentDrag.placeholder,r=t.DomUtil.getChildIndex(n,n.nodeName.toLowerCase());this.el.classList.remove(s),this.el.style[t.CSS.TRANSFORM]="",n.parentNode.insertBefore(this.el,n),n.parentNode.removeChild(n),this.onReorder&&this.onReorder(this.el,this._currentDrag.startIndex,r),this._currentDrag=null,i&&i()},t.views.ListView=t.views.View.inherit({initialize:function(e){var i=this;e=t.extend({onReorder:function(){},virtualRemoveThreshold:-200,virtualAddThreshold:200},e),t.extend(this,e),!this.itemHeight&&this.listEl&&(this.itemHeight=this.listEl.children[0]&&parseInt(this.listEl.children[0].style.height,10)),this.onRefresh=e.onRefresh||function(){},this.onRefreshOpening=e.onRefreshOpening||function(){},this.onRefreshHolding=e.onRefreshHolding||function(){},window.ionic.onGesture("touch",function(t){i._handleTouch(t)},this.el),window.ionic.onGesture("release",function(t){i._handleEndDrag(t)},this.el),window.ionic.onGesture("drag",function(t){i._handleDrag(t)},this.el),this._initDrag()},stopRefreshing:function(){var t=this.el.querySelector(".list-refresher");t.style.height="0px"},didScroll:function(t){if(this.isVirtual){var e=this.itemHeight,i=(this.listEl.children.length,t.target.scrollHeight),n=this.el.parentNode.offsetHeight,r=(t.scrollTop,Math.max(0,t.scrollTop+this.virtualRemoveThreshold)),o=Math.min(i,Math.abs(t.scrollTop)+n+this.virtualAddThreshold),s=Math.floor((o-r)/e),a=parseInt(Math.abs(r/e),10),l=parseInt(Math.abs(o/e),10);this._virtualItemsToRemove=Array.prototype.slice.call(this.listEl.children,0,a);{Array.prototype.slice.call(this.listEl.children,a,a+s)}this.renderViewport&&this.renderViewport(r,o,a,l)}},didStopScrolling:function(){if(this.isVirtual)for(var t=0;t5)return this._dragOp=new c({el:this.el}),this._dragOp.start(e),void e.preventDefault()}else{var n=this._getItem(e.target);if(n)return this._dragOp=new h({el:n,scrollEl:this.scrollEl,scrollView:this.scrollView,onReorder:function(t,e,n){i.onReorder&&i.onReorder(t,e,n)}}),this._dragOp.start(e),void e.preventDefault()}},_handleEndDrag:function(t){var e=this;if(this._didDragUpOrDown=!1,this._dragOp){clearTimeout(this._touchTimeout);for(var i=e.el.querySelectorAll(".item"),n=0,r=i.length;r>n;n++)i[n].classList.remove("active");this._dragOp.end(t,function(){e._initDrag()})}},_handleDrag:function(t){Math.abs(t.gesture.deltaY)>5&&(this._didDragUpOrDown=!0),(Math.abs(t.gesture.deltaX)>10||Math.abs(t.gesture.deltaY)>10)&&clearTimeout(this._touchTimeout),clearTimeout(this._touchTimeout),this.isDragging||this._dragOp||this._startDrag(t),this._dragOp&&(t.gesture.srcEvent.preventDefault(),this._dragOp.drag(t))},_handleTouch:function(i){var n=this,r=t.DomUtil.getParentOrSelfWithClass(i.target,e);r&&(this._touchTimeout=setTimeout(function(){for(var t=n.el.querySelectorAll(".item"),e=0,i=t.length;i>e;e++)t[e].classList.remove("active");r.classList.add("active")},250))}})}(ionic),function(t){"use strict";t.views.Loading=t.views.View.inherit({initialize:function(t){this.el=t.el,this.maxWidth=t.maxWidth||200,this.showDelay=t.showDelay||0,this._loadingBox=this.el.querySelector(".loading")},show:function(){var t=this;if(this._loadingBox){var e=t._loadingBox,i=Math.min(t.maxWidth,Math.max(window.outerWidth-40,e.offsetWidth));e.style.width=i+"px",e.style.marginLeft=-e.offsetWidth/2+"px",e.style.marginTop=-e.offsetHeight/2+"px",this._showDelayTimeout=window.setTimeout(function(){t.el.classList.add("active")},t.showDelay)}},hide:function(){this.el.offsetWidth,window.clearTimeout(this._showDelayTimeout),this.el.classList.remove("active")}})}(ionic),function(t){"use strict";t.views.Modal=t.views.View.inherit({initialize:function(e){e=t.extend({focusFirstInput:!1,unfocusOnHide:!0,focusFirstDelay:600},e),t.extend(this,e),this.el=e.el},show:function(){var t=this;t.focusFirstInput&&window.setTimeout(function(){var e=t.el.querySelector("input, textarea");e&&e.focus&&e.focus()},t.focusFirstDelay)},hide:function(){if(this.unfocusOnHide){var t=this.el.querySelectorAll("input, textarea");window.setTimeout(function(){for(var e=0;ee?-m:e>E?m:0,0))}t.continuous&&_.transitions&&(s(r(E-1),-m,0),s(r(E+1),m,0)),_.transitions||(T.style.left=E*-m+"px"),f.style.visibility="visible",t.slidesChanged&&t.slidesChanged()}function i(){t.continuous?o(E-1):E&&o(E-1)}function n(){t.continuous?o(E+1):EE?e:E)-a-1),m*n,0);e=r(e),s(E,m*n,i||w),s(e,0,i||w),t.continuous&&s(r(e-n),-(m*n),0)}else e=r(e),l(E*-m,e*-m,i||w);E=e,d(t.callback&&t.callback(E,g[E]))}}function s(t,e,i){a(t,e,i),p[t]=e}function a(t,e,i){var n=g[t],r=n&&n.style;r&&(r.webkitTransitionDuration=r.MozTransitionDuration=r.msTransitionDuration=r.OTransitionDuration=r.transitionDuration=i+"ms",r.webkitTransform="translate("+e+"px,0)translateZ(0)",r.msTransform=r.MozTransform=r.OTransform="translateX("+e+"px)")}function l(e,i,n){if(!n)return void(T.style.left=i+"px");var r=+new Date,o=setInterval(function(){var s=+new Date-r;return s>n?(T.style.left=i+"px",y&&c(),t.transitionEnd&&t.transitionEnd.call(event,E,g[E]),void clearInterval(o)):void(T.style.left=(i-e)*(Math.floor(s/n*100)/100)+e+"px")},4)}function c(){S=setTimeout(n,y)}function h(){y=t.auto||0,clearTimeout(S)}var u=function(){},d=function(t){setTimeout(t||u,0)},_={addEventListener:!!window.addEventListener,touch:"ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch,transitions:function(t){var e=["transitionProperty","WebkitTransition","MozTransition","OTransition","msTransition"];for(var i in e)if(void 0!==t.style[e[i]])return!0;return!1}(document.createElement("swipe"))},f=t.el;if(f){var g,p,m,v,T=f.children[0];t=t||{};var E=parseInt(t.startSlide,10)||0,w=t.speed||300;t.continuous=void 0!==t.continuous?t.continuous:!0;var S,b,y=t.auto||0,D={},x={},L={handleEvent:function(i){switch(("mousedown"==i.type||"mouseup"==i.type||"mousemove"==i.type)&&(i.touches=[{pageX:i.pageX,pageY:i.pageY}]),i.type){case"mousedown":this.start(i);break;case"touchstart":this.start(i);break;case"touchmove":this.move(i);break;case"mousemove":this.move(i);break;case"touchend":d(this.end(i));break;case"mouseup":d(this.end(i));break;case"webkitTransitionEnd":case"msTransitionEnd":case"oTransitionEnd":case"otransitionend":case"transitionend":d(this.transitionEnd(i));break;case"resize":d(e)}t.stopPropagation&&i.stopPropagation()},start:function(t){var e=t.touches[0];D={x:e.pageX,y:e.pageY,time:+new Date},b=void 0,x={},_.touch?(T.addEventListener("touchmove",this,!1),T.addEventListener("touchend",this,!1)):(T.addEventListener("mousemove",this,!1),T.addEventListener("mouseup",this,!1),document.addEventListener("mouseup",this,!1))},move:function(e){if(!(e.touches.length>1||e.scale&&1!==e.scale)){t.disableScroll&&e.preventDefault();var i=e.touches[0];x={x:i.pageX-D.x,y:i.pageY-D.y},"undefined"==typeof b&&(b=!!(b||Math.abs(x.x)0||E==g.length-1&&x.x<0?Math.abs(x.x)/m+1:1),a(E-1,x.x+p[E-1],0),a(E,x.x+p[E],0),a(E+1,x.x+p[E+1],0)))}},end:function(){var e=+new Date-D.time,i=Number(e)<250&&Math.abs(x.x)>20||Math.abs(x.x)>m/2,n=!E&&x.x>0||E==g.length-1&&x.x<0;t.continuous&&(n=!1);var o=x.x<0;b||(i&&!n?(o?(t.continuous?(s(r(E-1),-m,0),s(r(E+2),m,0)):s(E-1,-m,0),s(E,p[E]-m,w),s(r(E+1),p[r(E+1)]-m,w),E=r(E+1)):(t.continuous?(s(r(E+1),m,0),s(r(E-2),-m,0)):s(E+1,m,0),s(E,p[E]+m,w),s(r(E-1),p[r(E-1)]+m,w),E=r(E-1)),t.callback&&t.callback(E,g[E])):t.continuous?(s(r(E-1),-m,w),s(E,0,w),s(r(E+1),m,w)):(s(E-1,-m,w),s(E,0,w),s(E+1,m,w))),_.touch?(T.removeEventListener("touchmove",L,!1),T.removeEventListener("touchend",L,!1)):(T.removeEventListener("mousemove",L,!1),T.removeEventListener("mouseup",L,!1),document.removeEventListener("mouseup",L,!1))},transitionEnd:function(e){parseInt(e.target.getAttribute("data-index"),10)==E&&(y&&c(),t.transitionEnd&&t.transitionEnd.call(e,E,g[E]))}};this.setup=function(){e()},this.slide=function(t,e){h(),o(t,e)},this.prev=function(){h(),i()},this.next=function(){h(),n()},this.stop=function(){h()},this.currentIndex=function(){return E},this.slidesCount=function(){return v},this.kill=function(){h(),T.style.width="",T.style.left="";for(var t=g.length;t--;){var e=g[t];e.style.width="",e.style.left="",_.transitions&&a(t,0,0)}_.addEventListener?(T.removeEventListener("touchstart",L,!1),T.removeEventListener("webkitTransitionEnd",L,!1),T.removeEventListener("msTransitionEnd",L,!1),T.removeEventListener("oTransitionEnd",L,!1),T.removeEventListener("otransitionend",L,!1),T.removeEventListener("transitionend",L,!1),window.removeEventListener("resize",L,!1)):window.onresize=null},this.load=function(){e(),y&&c(),_.addEventListener?(_.touch?T.addEventListener("touchstart",L,!1):T.addEventListener("mousedown",L,!1),_.transitions&&(T.addEventListener("webkitTransitionEnd",L,!1),T.addEventListener("msTransitionEnd",L,!1),T.addEventListener("oTransitionEnd",L,!1),T.addEventListener("otransitionend",L,!1),T.addEventListener("transitionend",L,!1)),window.addEventListener("resize",L,!1)):window.onresize=function(){e() -}}}}})}(ionic),function(t){"use strict";t.views.TabBarItem=t.views.View.inherit({initialize:function(t){this.el=t,this._buildItem()},create:function(e){var i=document.createElement("a");if(i.className="tab-item",e.icon){var n=document.createElement("i");n.className=e.icon,i.appendChild(n)}if(e.badge){var r=document.createElement("i");r.className="badge",r.innerHTML=e.badge,i.appendChild(r),i.className="tab-item has-badge"}return i.appendChild(document.createTextNode(e.title)),new t.views.TabBarItem(i)},_buildItem:function(){for(var e,i=this,n=Array.prototype.slice.call(this.el.children),r=0,o=n.length;o>r;r++)e=n[r],"i"==e.tagName.toLowerCase()&&/icon/.test(e.className)&&(this.icon=e.className),"i"==e.tagName.toLowerCase()&&/badge/.test(e.className)&&(this.badge=e.textContent.trim());for(this.title="",r=0,o=this.el.childNodes.length;o>r;r++)e=this.el.childNodes[r],"#text"===e.nodeName&&(this.title+=e.nodeValue.trim());this._tapHandler=function(t){i.onTap&&i.onTap(t)},t.on("tap",this._tapHandler,this.el)},onTap:function(){},destroy:function(){t.off("tap",this._tapHandler,this.el)},getIcon:function(){return this.icon},getTitle:function(){return this.title},getBadge:function(){return this.badge},setSelected:function(t){this.isSelected=t,t?this.el.classList.add("active"):this.el.classList.remove("active")}}),t.views.TabBar=t.views.View.inherit({initialize:function(t){this.el=t.el,this.items=[],this._buildItems()},getItems:function(){return this.items},addItem:function(e){var i=t.views.TabBarItem.prototype.create(e);this.appendItemElement(i),this.items.push(i),this._bindEventsOnItem(i)},appendItemElement:function(t){this.el&&this.el.appendChild(t.el)},removeItem:function(t){var e=this.items[t];e&&(e.onTap=void 0,e.destroy())},_bindEventsOnItem:function(t){var e=this;this._itemTapHandler||(this._itemTapHandler=function(){e.trySelectItem(this)}),t.onTap=this._itemTapHandler},getSelectedItem:function(){return this.selectedItem},setSelectedItem:function(t){this.selectedItem=this.items[t];for(var e=0,i=this.items.length;i>e;e+=1)this.items[e].setSelected(!1);this.selectedItem&&this.selectedItem.setSelected(!0)},selectItem:function(t){for(var e=0,i=this.items.length;i>e;e+=1)if(this.items[e]==t)return void this.setSelectedItem(e)},trySelectItem:function(t){for(var e=0,i=this.items.length;i>e;e+=1)if(this.items[e]==t)return void(this.tryTabSelect&&this.tryTabSelect(e))},_buildItems:function(){for(var e,i=Array.prototype.slice.call(this.el.children),n=0,r=i.length;r>n;n+=1)e=new t.views.TabBarItem(i[n]),this.items[n]=e,this._bindEventsOnItem(e);this.items.length>0&&(this.selectedItem=this.items[0])},destroy:function(){for(var t=0,e=this.items.length;e>t;t+=1)this.items[t].destroy();this.items.length=0}})}(window.ionic),function(t){"use strict";t.views.Toggle=t.views.View.inherit({initialize:function(e){var i=this;this.el=e.el,this.checkbox=e.checkbox,this.track=e.track,this.handle=e.handle,this.openPercent=-1,this.onChange=e.onChange||function(){},this.triggerThreshold=e.triggerThreshold||20,this.dragStartHandler=function(t){i.dragStart(t)},this.dragHandler=function(t){i.drag(t)},this.holdHandler=function(t){i.hold(t)},this.releaseHandler=function(t){i.release(t)},this.dragStartGesture=t.onGesture("dragstart",this.dragStartHandler,this.el),this.dragGesture=t.onGesture("drag",this.dragHandler,this.el),this.dragHoldGesture=t.onGesture("hold",this.holdHandler,this.el),this.dragReleaseGesture=t.onGesture("release",this.releaseHandler,this.el)},destroy:function(){t.offGesture(this.dragStartGesture,"dragstart",this.dragStartGesture),t.offGesture(this.dragGesture,"drag",this.dragGesture),t.offGesture(this.dragHoldGesture,"hold",this.holdHandler),t.offGesture(this.dragReleaseGesture,"release",this.releaseHandler)},tap:function(){"disabled"!==this.el.getAttribute("disabled")&&this.val(!this.checkbox.checked)},dragStart:function(t){this.checkbox.disabled||(this._dragInfo={width:this.el.offsetWidth,left:this.el.offsetLeft,right:this.el.offsetLeft+this.el.offsetWidth,triggerX:this.el.offsetWidth/2,initialState:this.checkbox.checked},t.gesture.srcEvent.preventDefault(),this.hold(t))},drag:function(e){var i=this;this._dragInfo&&(e.gesture.srcEvent.preventDefault(),t.requestAnimationFrame(function(){var t=(i.track.offsetLeft+i.handle.offsetWidth/2,i.track.offsetLeft+i.track.offsetWidth-i.handle.offsetWidth/2,e.gesture.deltaX,e.gesture.touches[0].pageX-i._dragInfo.left),n=i._dragInfo.width-i.triggerThreshold;i._dragInfo.initialState?ti._dragInfo.triggerX&&i.setOpenPercent(100):tn&&i.setOpenPercent(100)}))},endDrag:function(){this._dragInfo=null},hold:function(){this.el.classList.add("dragging")},release:function(t){this.el.classList.remove("dragging"),this.endDrag(t)},setOpenPercent:function(e){if(this.openPercent<0||ethis.openPercent+3)if(this.openPercent=e,0===e)this.val(!1);else if(100===e)this.val(!0);else{var i=Math.round(e/100*this.track.offsetWidth-this.handle.offsetWidth);i=1>i?0:i,this.handle.style[t.CSS.TRANSFORM]="translate3d("+i+"px,0,0)"}},val:function(e){return(e===!0||e===!1)&&(""!==this.handle.style[t.CSS.TRANSFORM]&&(this.handle.style[t.CSS.TRANSFORM]=""),this.checkbox.checked=e,this.openPercent=e?100:0,this.onChange&&this.onChange()),this.checkbox.checked}})}(ionic),function(t){"use strict";t.controllers.ViewController=function(){this.initialize.apply(this,arguments)},t.controllers.ViewController.inherit=t.inherit,t.extend(t.controllers.ViewController.prototype,{initialize:function(){},destroy:function(){}})}(window.ionic),function(t){"use strict";t.controllers.NavController=t.controllers.ViewController.inherit({initialize:function(t){var e=this;this.navBar=t.navBar,this.content=t.content,this.controllers=t.controllers||[],this._updateNavBar(),this.navBar.shouldGoBack=function(){e.pop()}},getControllers:function(){return this.controllers},getTopController:function(){return this.controllers[this.controllers.length-1]},push:function(t){var e=this.controllers[this.controllers.length-1];this.controllers.push(t);var i=this.switchingController&&this.switchingController(t)||!0;if(i!==!1){e&&(e.isVisible=!1,e.visibilityChanged&&e.visibilityChanged("push"));var n=this.controllers[this.controllers.length-1];return n.isVisible=!0,n.visibilityChanged&&n.visibilityChanged(e?"push":"first"),this._updateNavBar(),t}},pop:function(){var t,e;if(!(this.controllers.length<2))return e=this.controllers.pop(),e&&(e.isVisible=!1,e.visibilityChanged&&e.visibilityChanged("pop")),t=this.controllers[this.controllers.length-1],t.isVisible=!0,t.visibilityChanged&&t.visibilityChanged("pop"),this._updateNavBar(),e},showNavBar:function(){this.navBar&&this.navBar.show()},hideNavBar:function(){this.navBar&&this.navBar.hide()},_updateNavBar:function(){this.getTopController()&&this.navBar&&(this.navBar.setTitle(this.getTopController().title),this.navBar.showBackButton(this.controllers.length>1?!0:!1))}})}(window.ionic),function(t){"use strict";t.controllers.SideMenuController=t.controllers.ViewController.inherit({initialize:function(t){var e=this;this.left=t.left,this.right=t.right,this.content=t.content,this.dragThresholdX=t.dragThresholdX||10,this._rightShowing=!1,this._leftShowing=!1,this._isDragging=!1,this.content&&(this.content.onDrag=function(t){e._handleDrag(t)},this.content.onEndDrag=function(t){e._endDrag(t)})},setContent:function(t){var e=this;this.content=t,this.content.onDrag=function(t){e._handleDrag(t)},this.content.endDrag=function(t){e._endDrag(t)}},toggleLeft:function(){this.content.enableAnimation();var t=this.getOpenAmount();this.openPercentage(t>0?0:100)},toggleRight:function(){this.content.enableAnimation();var t=this.getOpenAmount();this.openPercentage(0>t?0:-100)},close:function(){this.openPercentage(0)},getOpenAmount:function(){return this.content&&this.content.getTranslateX()||0},getOpenRatio:function(){var t=this.getOpenAmount();return t>=0?t/this.left.width:t/this.right.width},isOpen:function(){return 1==this.getOpenRatio()},getOpenPercentage:function(){return 100*this.getOpenRatio()},openPercentage:function(t){var e=t/100;if(this.left&&t>=0)this.openAmount(this.left.width*e);else if(this.right&&0>t){{this.right.width}this.openAmount(this.right.width*e)}},openAmount:function(t){var e=this.left&&this.left.width||0,i=this.right&&this.right.width||0;return this.left&&this.left.isEnabled||!(t>0)?this.right&&this.right.isEnabled||!(0>t)?this._leftShowing&&t>e?void this.content.setTranslateX(e):this._rightShowing&&-i>t?void this.content.setTranslateX(-i):(this.content.setTranslateX(t),void(t>=0?(this._leftShowing=!0,this._rightShowing=!1,t>0&&(this.right&&this.right.pushDown&&this.right.pushDown(),this.left&&this.left.bringUp&&this.left.bringUp())):(this._rightShowing=!0,this._leftShowing=!1,this.right&&this.right.bringUp&&this.right.bringUp(),this.left&&this.left.pushDown&&this.left.pushDown()))):void this.content.setTranslateX(0):void this.content.setTranslateX(0)},snapToRest:function(t){this.content.enableAnimation(),this._isDragging=!1;var e=this.getOpenRatio();if(0===e)return void this.openPercentage(0);var i=.3,n=t.gesture.velocityX,r=t.gesture.direction;this.openPercentage(e>0&&.5>e&&"right"==r&&i>n?0:e>.5&&"left"==r&&i>n?100:0>e&&e>-.5&&"left"==r&&i>n?0:.5>e&&"right"==r&&i>n?-100:"right"==r&&e>=0&&(e>=.5||n>i)?100:"left"==r&&0>=e&&(-.5>=e||n>i)?-100:0)},_endDrag:function(t){this._isDragging&&this.snapToRest(t),this._startX=null,this._lastX=null,this._offsetX=null},_handleDrag:function(t){this._startX?this._lastX=t.gesture.touches[0].pageX:(this._startX=t.gesture.touches[0].pageX,this._lastX=this._startX),!this._isDragging&&Math.abs(this._lastX-this._startX)>this.dragThresholdX&&(this._startX=this._lastX,this._isDragging=!0,this.content.disableAnimation(),this._offsetX=this.getOpenAmount()),this._isDragging&&this.openAmount(this._offsetX+(this._lastX-this._startX))}})}(ionic),function(t){"use strict";t.controllers.TabBarController=t.controllers.ViewController.inherit({initialize:function(t){this.tabBar=t.tabBar,this._bindEvents(),this.controllers=[];for(var e=t.controllers||[],i=0;i=this.controllers.length)){var e=this.selectedController,i=this.selectedIndex;this.selectedController=this.controllers[t],this.selectedIndex=t,this._showController(t),this.tabBar.setSelectedItem(t),this.controllerChanged&&this.controllerChanged(e,i,this.selectedController,this.selectedIndex)}},_showController:function(t){for(var e,i=0,n=this.controllers.length;n>i;i++)e=this.controllers[i],e.isVisible=!1,e.visibilityChanged&&e.visibilityChanged();e=this.controllers[t],e.isVisible=!0,e.visibilityChanged&&e.visibilityChanged()},_clearSelected:function(){this.selectedController=null,this.selectedIndex=-1},getController:function(t){return this.controllers[t]},getControllers:function(){return this.controllers},getSelectedController:function(){return this.selectedController},getSelectedControllerIndex:function(){return this.selectedIndex},addController:function(t){this.controllers.push(t),this.tabBar.addItem({title:t.title,icon:t.icon,badge:t.badge}),this.selectedController||this.setSelectedController(0)},setControllers:function(t){this.controllers=t,this._clearSelected(),this.selectController(0)}})}(window.ionic); +!function(){window.ionic={controllers:{},views:{},version:"1.0.0-beta.1"},function(t){function e(t){return t*t*t}function i(t){return 3*t*t*(1-t)}function n(t){return 3*t*(1-t)*(1-t)}function r(t){return(1-t)*(1-t)*(1-t)}var o=function(t,e){return t||(t=0),e||(e=0),{x:t,y:e}};t.Animator={getQuadraticBezier:function(t,s,a,l,c){var u=new o;return u.x=s.x*e(t)+a.x*i(t)+l.x*n(t)+c.x*r(t),u.y=s.y*e(t)+a.y*i(t)+l.y*n(t)+c.y*r(t),u},getCubicBezier:function(t,e,i,n,r){epsilon=1e3/60/r/4;var o=function(e){var n=1-e;return 3*n*n*e*t+3*n*e*e*i+e*e*e},s=function(t){var i=1-t;return 3*i*i*t*e+3*i*t*t*n+t*t*t},a=function(e){var n=1-e;return 3*(2*(e-1)*e+n*n)*t+3*(-e*e*e+2*n*e)*i};return function(t){var e,i,n,r,l,c,u=t;for(n=u,c=0;8>c;c++){if(r=o(n)-u,Math.abs(r)n)return s(e);if(n>i)return s(i);for(;i>e;){if(r=o(n),Math.abs(r-u)r?e=n:i=n,n=.5*(i-e)+e}return s(n)}},animate:function(t){return{leave:function(){var e=function(){t.classList.remove("leave"),t.classList.remove("leave-active"),t.removeEventListener("webkitTransitionEnd",e),t.removeEventListener("transitionEnd",e)};return t.addEventListener("webkitTransitionEnd",e),t.addEventListener("transitionEnd",e),t.classList.add("leave"),t.classList.add("leave-active"),this},enter:function(){var e=function(){t.classList.remove("enter"),t.classList.remove("enter-active"),t.removeEventListener("webkitTransitionEnd",e),t.removeEventListener("transitionEnd",e)};return t.addEventListener("webkitTransitionEnd",e),t.addEventListener("transitionEnd",e),t.classList.add("enter"),t.classList.add("enter-active"),this}}}}}(ionic),function(t,e,i){function n(){o=!0;for(var t=0;tr;r++)if(i=n[r],i.nodeName&&i.nodeName.toLowerCase()==e){if(i==t)return o;o++}return Array.prototype.slice.call(t.parentNode.children).indexOf(t)},swapNodes:function(t,e){e.parentNode.insertBefore(t,e)},getParentWithClass:function(t,e,i){for(i=i||10;t.parentNode&&i--;){if(t.parentNode.classList&&t.parentNode.classList.contains(e))return t.parentNode;t=t.parentNode}return null},getParentOrSelfWithClass:function(t,e,i){for(i=i||10;t&&i--;){if(t.classList&&t.classList.contains(e))return t;t=t.parentNode}return null},rectContains:function(t,e,i,n,r,o){return i>t||t>r?!1:n>e||e>o?!1:!0}},i.requestAnimationFrame=i.DomUtil.requestAnimationFrame,i.animationFrameThrottle=i.DomUtil.animationFrameThrottle}(this,document,ionic),function(t){window.CustomEvent||!function(){var t;t=function(t,e){var i;e=e||{bubbles:!1,cancelable:!1,detail:void 0};try{i=document.createEvent("CustomEvent"),i.initCustomEvent(t,e.bubbles,e.cancelable,e.detail)}catch(n){i=document.createEvent("Event");for(var r in e)i[r]=e[r];i.initEvent(t,e.bubbles,e.cancelable)}return i},t.prototype=window.Event.prototype,window.CustomEvent=t}(),t.EventController={VIRTUALIZED_EVENTS:["tap","swipe","swiperight","swipeleft","drag","hold","release"],trigger:function(t,e,i,n){var r=new CustomEvent(t,{detail:e,bubbles:!!i,cancelable:!!n});e&&e.target&&e.target.dispatchEvent(r)||window.dispatchEvent(r)},on:function(e,i,n){for(var r=n||window,o=0,s=this.VIRTUALIZED_EVENTS.length;s>o;o++)if(e==this.VIRTUALIZED_EVENTS[o]){var a=new t.Gesture(n);return a.on(e,i),a}r.addEventListener(e,i)},off:function(t,e,i){i.removeEventListener(t,e)},onGesture:function(e,i,n){var r=new t.Gesture(n);return r.on(e,i),r},offGesture:function(t,e,i){t.off(e,i)},handlePopState:function(){}},t.on=function(){t.EventController.on.apply(t.EventController,arguments)},t.off=function(){t.EventController.off.apply(t.EventController,arguments)},t.trigger=t.EventController.trigger,t.onGesture=function(){return t.EventController.onGesture.apply(t.EventController.onGesture,arguments)},t.offGesture=function(){return t.EventController.offGesture.apply(t.EventController.offGesture,arguments)}}(window.ionic),function(t){function e(){if(!t.Gestures.READY){t.Gestures.event.determineEventTypes();for(var e in t.Gestures.gestures)t.Gestures.gestures.hasOwnProperty(e)&&t.Gestures.detection.register(t.Gestures.gestures[e]);t.Gestures.event.onTouch(t.Gestures.DOCUMENT,t.Gestures.EVENT_MOVE,t.Gestures.detection.detect),t.Gestures.event.onTouch(t.Gestures.DOCUMENT,t.Gestures.EVENT_END,t.Gestures.detection.detect),t.Gestures.READY=!0}}t.Gesture=function(e,i){return new t.Gestures.Instance(e,i||{})},t.Gestures={},t.Gestures.defaults={stop_browser_behavior:"disable-user-behavior"},t.Gestures.HAS_POINTEREVENTS=window.navigator.pointerEnabled||window.navigator.msPointerEnabled,t.Gestures.HAS_TOUCHEVENTS="ontouchstart"in window,t.Gestures.MOBILE_REGEX=/mobile|tablet|ip(ad|hone|od)|android|silk/i,t.Gestures.NO_MOUSEEVENTS=t.Gestures.HAS_TOUCHEVENTS&&window.navigator.userAgent.match(t.Gestures.MOBILE_REGEX),t.Gestures.EVENT_TYPES={},t.Gestures.DIRECTION_DOWN="down",t.Gestures.DIRECTION_LEFT="left",t.Gestures.DIRECTION_UP="up",t.Gestures.DIRECTION_RIGHT="right",t.Gestures.POINTER_MOUSE="mouse",t.Gestures.POINTER_TOUCH="touch",t.Gestures.POINTER_PEN="pen",t.Gestures.EVENT_START="start",t.Gestures.EVENT_MOVE="move",t.Gestures.EVENT_END="end",t.Gestures.DOCUMENT=window.document,t.Gestures.plugins={},t.Gestures.READY=!1,t.Gestures.Instance=function(i,n){var r=this;if(null!==i)return e(),this.element=i,this.enabled=!0,this.options=t.Gestures.utils.extend(t.Gestures.utils.extend({},t.Gestures.defaults),n||{}),this.options.stop_browser_behavior&&t.Gestures.utils.stopDefaultBrowserBehavior(this.element,this.options.stop_browser_behavior),t.Gestures.event.onTouch(i,t.Gestures.EVENT_START,function(e){r.enabled&&t.Gestures.detection.startDetect(r,e)}),this},t.Gestures.Instance.prototype={on:function(t,e){for(var i=t.split(" "),n=0;n0&&o==t.Gestures.EVENT_END?o=t.Gestures.EVENT_MOVE:u||(o=t.Gestures.EVENT_END),(u||null===i)&&(i=l),s.call(t.Gestures.detection,a.collectEventData(e,o,a.getTouchList(i,o),l)),t.Gestures.HAS_POINTEREVENTS&&o==t.Gestures.EVENT_END&&(u=t.Gestures.PointerEvent.updatePointer(o,l))),u||(i=null,n=!1,r=!1,t.Gestures.PointerEvent.reset())}})},determineEventTypes:function(){var e;e=t.Gestures.HAS_POINTEREVENTS?t.Gestures.PointerEvent.getEvents():t.Gestures.NO_MOUSEEVENTS?["touchstart","touchmove","touchend touchcancel"]:["touchstart mousedown","touchmove mousemove","touchend touchcancel mouseup"],t.Gestures.EVENT_TYPES[t.Gestures.EVENT_START]=e[0],t.Gestures.EVENT_TYPES[t.Gestures.EVENT_MOVE]=e[1],t.Gestures.EVENT_TYPES[t.Gestures.EVENT_END]=e[2]},getTouchList:function(e){return t.Gestures.HAS_POINTEREVENTS?t.Gestures.PointerEvent.getTouchList():e.touches?e.touches:(e.indentifier=1,[e])},collectEventData:function(e,i,n,r){var o=t.Gestures.POINTER_TOUCH;return(r.type.match(/mouse/)||t.Gestures.PointerEvent.matchType(t.Gestures.POINTER_MOUSE,r))&&(o=t.Gestures.POINTER_MOUSE),{center:t.Gestures.utils.getCenter(n),timeStamp:(new Date).getTime(),target:r.target,touches:n,eventType:i,pointerType:o,srcEvent:r,preventDefault:function(){this.srcEvent.preventManipulation&&this.srcEvent.preventManipulation(),this.srcEvent.preventDefault},stopPropagation:function(){this.srcEvent.stopPropagation()},stopDetect:function(){return t.Gestures.detection.stopDetect()}}}},t.Gestures.PointerEvent={pointers:{},getTouchList:function(){var t=this,e=[];return Object.keys(t.pointers).sort().forEach(function(i){e.push(t.pointers[i])}),e},updatePointer:function(e,i){return e==t.Gestures.EVENT_END?this.pointers={}:(i.identifier=i.pointerId,this.pointers[i.pointerId]=i),Object.keys(this.pointers).length},matchType:function(e,i){if(!i.pointerType)return!1;var n={};return n[t.Gestures.POINTER_MOUSE]=i.pointerType==i.MSPOINTER_TYPE_MOUSE||i.pointerType==t.Gestures.POINTER_MOUSE,n[t.Gestures.POINTER_TOUCH]=i.pointerType==i.MSPOINTER_TYPE_TOUCH||i.pointerType==t.Gestures.POINTER_TOUCH,n[t.Gestures.POINTER_PEN]=i.pointerType==i.MSPOINTER_TYPE_PEN||i.pointerType==t.Gestures.POINTER_PEN,n[e]},getEvents:function(){return["pointerdown MSPointerDown","pointermove MSPointerMove","pointerup pointercancel MSPointerUp MSPointerCancel"]},reset:function(){this.pointers={}}},t.Gestures.utils={extend:function(t,e,i){for(var n in e)void 0!==t[n]&&i||(t[n]=e[n]);return t},hasParent:function(t,e){for(;t;){if(t==e)return!0;t=t.parentNode}return!1},getCenter:function(t){for(var e=[],i=[],n=0,r=t.length;r>n;n++)e.push(t[n].pageX),i.push(t[n].pageY);return{pageX:(Math.min.apply(Math,e)+Math.max.apply(Math,e))/2,pageY:(Math.min.apply(Math,i)+Math.max.apply(Math,i))/2}},getVelocity:function(t,e,i){return{x:Math.abs(e/t)||0,y:Math.abs(i/t)||0}},getAngle:function(t,e){var i=e.pageY-t.pageY,n=e.pageX-t.pageX;return 180*Math.atan2(i,n)/Math.PI},getDirection:function(e,i){var n=Math.abs(e.pageX-i.pageX),r=Math.abs(e.pageY-i.pageY);return n>=r?e.pageX-i.pageX>0?t.Gestures.DIRECTION_LEFT:t.Gestures.DIRECTION_RIGHT:e.pageY-i.pageY>0?t.Gestures.DIRECTION_UP:t.Gestures.DIRECTION_DOWN},getDistance:function(t,e){var i=e.pageX-t.pageX,n=e.pageY-t.pageY;return Math.sqrt(i*i+n*n)},getScale:function(t,e){return t.length>=2&&e.length>=2?this.getDistance(e[0],e[1])/this.getDistance(t[0],t[1]):1},getRotation:function(t,e){return t.length>=2&&e.length>=2?this.getAngle(e[1],e[0])-this.getAngle(t[1],t[0]):0},isVertical:function(e){return e==t.Gestures.DIRECTION_UP||e==t.Gestures.DIRECTION_DOWN},stopDefaultBrowserBehavior:function(t,e){t&&t.classList&&(t.classList.add(e),t.onselectstart=function(){return!1})}},t.Gestures.detection={gestures:[],current:null,previous:null,stopped:!1,startDetect:function(e,i){this.current||(this.stopped=!1,this.current={inst:e,startEvent:t.Gestures.utils.extend({},i),lastEvent:!1,name:""},this.detect(i))},detect:function(e){if(this.current&&!this.stopped){e=this.extendEventData(e);for(var i=this.current.inst.options,n=0,r=this.gestures.length;r>n;n++){var o=this.gestures[n];if(!this.stopped&&i[o.name]!==!1&&o.handler.call(o,e,this.current.inst)===!1){this.stopDetect();break}}return this.current&&(this.current.lastEvent=e),e.eventType==t.Gestures.EVENT_END&&!e.touches.length-1&&this.stopDetect(),e}},stopDetect:function(){this.previous=t.Gestures.utils.extend({},this.current),this.current=null,this.stopped=!0},extendEventData:function(e){var i=this.current.startEvent;if(i&&(e.touches.length!=i.touches.length||e.touches===i.touches)){i.touches=[];for(var n=0,r=e.touches.length;r>n;n++)i.touches.push(t.Gestures.utils.extend({},e.touches[n]))}var o=e.timeStamp-i.timeStamp,s=e.center.pageX-i.center.pageX,a=e.center.pageY-i.center.pageY,l=t.Gestures.utils.getVelocity(o,s,a);return t.Gestures.utils.extend(e,{deltaTime:o,deltaX:s,deltaY:a,velocityX:l.x,velocityY:l.y,distance:t.Gestures.utils.getDistance(i.center,e.center),angle:t.Gestures.utils.getAngle(i.center,e.center),direction:t.Gestures.utils.getDirection(i.center,e.center),scale:t.Gestures.utils.getScale(i.touches,e.touches),rotation:t.Gestures.utils.getRotation(i.touches,e.touches),startEvent:i}),e},register:function(e){var i=e.defaults||{};return void 0===i[e.name]&&(i[e.name]=!0),t.Gestures.utils.extend(t.Gestures.defaults,i,!0),e.index=e.index||1e3,this.gestures.push(e),this.gestures.sort(function(t,e){return t.indexe.index?1:0}),this.gestures}},t.Gestures.gestures=t.Gestures.gestures||{},t.Gestures.gestures.Hold={name:"hold",index:10,defaults:{hold_timeout:500,hold_threshold:1},timer:null,handler:function(e,i){switch(e.eventType){case t.Gestures.EVENT_START:clearTimeout(this.timer),t.Gestures.detection.current.name=this.name,this.timer=setTimeout(function(){"hold"==t.Gestures.detection.current.name&&i.trigger("hold",e)},i.options.hold_timeout);break;case t.Gestures.EVENT_MOVE:e.distance>i.options.hold_threshold&&clearTimeout(this.timer);break;case t.Gestures.EVENT_END:clearTimeout(this.timer)}}},t.Gestures.gestures.Tap={name:"tap",index:100,defaults:{tap_max_touchtime:250,tap_max_distance:10,tap_always:!0,doubletap_distance:20,doubletap_interval:300},handler:function(e,i){if(e.eventType==t.Gestures.EVENT_END){var n=t.Gestures.detection.previous,r=!1;if(e.deltaTime>i.options.tap_max_touchtime||e.distance>i.options.tap_max_distance)return;n&&"tap"==n.name&&e.timeStamp-n.lastEvent.timeStamp0&&e.touches.length>i.options.swipe_max_touches)return;(e.velocityX>i.options.swipe_velocity||e.velocityY>i.options.swipe_velocity)&&(i.trigger(this.name,e),i.trigger(this.name+e.direction,e))}}},t.Gestures.gestures.Drag={name:"drag",index:50,defaults:{drag_min_distance:10,correct_for_drag_min_distance:!0,drag_max_touches:1,drag_block_horizontal:!0,drag_block_vertical:!0,drag_lock_to_axis:!1,drag_lock_min_distance:25},triggered:!1,handler:function(e,i){if(t.Gestures.detection.current.name!=this.name&&this.triggered)return i.trigger(this.name+"end",e),void(this.triggered=!1);if(!(i.options.drag_max_touches>0&&e.touches.length>i.options.drag_max_touches))switch(e.eventType){case t.Gestures.EVENT_START:this.triggered=!1;break;case t.Gestures.EVENT_MOVE:if(e.distancei.options.transform_min_rotation&&i.trigger("rotate",e),n>i.options.transform_min_scale&&(i.trigger("pinch",e),i.trigger("pinch"+(e.scale<1?"in":"out"),e));break;case t.Gestures.EVENT_END:this.triggered&&i.trigger(this.name+"end",e),this.triggered=!1}}},t.Gestures.gestures.Touch={name:"touch",index:-1/0,defaults:{prevent_default:!1,prevent_mouseevents:!1},handler:function(e,i){return i.options.prevent_mouseevents&&e.pointerType==t.Gestures.POINTER_MOUSE?void e.stopDetect():(i.options.prevent_default&&e.preventDefault(),void(e.eventType==t.Gestures.EVENT_START&&i.trigger(this.name,e)))}},t.Gestures.gestures.Release={name:"release",index:1/0,handler:function(e,i){e.eventType==t.Gestures.EVENT_END&&i.trigger(this.name,e)}}}(window.ionic),function(t,e,i){function n(){i.Platform.isCordova()?e.addEventListener("deviceready",r,!1):r(),t.removeEventListener("load",n,!1)}function r(){i.Platform.isReady=!0,i.Platform.detect();for(var t=0;t0?i=i.replace(".","_"):i+="_0",this.platforms.push(t+i.split("_")[0]),this.platforms.push(t+i),this.isAndroid()&&4.4>e&&(this.grade=4>e?"c":"b")}}},isCordova:function(){return!(!t.cordova&&!t.PhoneGap&&!t.phonegap)},isIPad:function(){return this.ua.toLowerCase().indexOf("ipad")>=0},isIOS:function(){return this.is("ios")},isAndroid:function(){return this.is("android")},platform:function(){return null===o&&this.setPlatform(this.device().platform),o},setPlatform:function(t){o="undefined"!=typeof t&&null!==t&&t.length?t.toLowerCase():this.ua.indexOf("Android")>0?"android":this.ua.indexOf("iPhone")>-1||this.ua.indexOf("iPad")>-1||this.ua.indexOf("iPod")>-1?"ios":""},version:function(){return null===s&&this.setVersion(this.device().version),s},setVersion:function(t){if("undefined"!=typeof t&&null!==t&&(t=t.split("."),t=parseFloat(t[0]+"."+(t.length>1?t[1]:0)),!isNaN(t)))return void(s=t);s=0;var e=this.platform(),i={android:/Android (\d+).(\d+)?/,ios:/OS (\d+)_(\d+)?/};i[e]&&(t=this.ua.match(i[e]),t.length>2&&(s=parseFloat(t[1]+"."+t[2])))},is:function(t){if(t=t.toLowerCase(),this.platforms)for(var e=0;e=0},exitApp:function(){this.ready(function(){navigator.app&&navigator.app.exitApp&&navigator.app.exitApp()})},showStatusBar:function(n){this._showStatusBar=n,this.ready(function(){i.requestAnimationFrame(function(){i.Platform._showStatusBar?(t.StatusBar&&t.StatusBar.show(),e.body.classList.remove("status-bar-hide")):(t.StatusBar&&t.StatusBar.hide(),e.body.classList.add("status-bar-hide"))})})},fullScreen:function(t,n){this.isFullScreen=t!==!1,i.DomUtil.ready(function(){i.requestAnimationFrame(function(){i.Platform.isFullScreen?e.body.classList.add("fullscreen"):e.body.classList.remove("fullscreen")}),i.Platform.showStatusBar(n===!0)})}};var o=null,s=null,a=[];t.addEventListener("load",n,!1)}(this,document,ionic),function(t,e){"use strict";e.CSS={},function(){var i,n=["webkitTransform","transform","-webkit-transform","webkit-transform","-moz-transform","moz-transform","MozTransform","mozTransform"];for(i=0;ir&&n;r++){if("INPUT"===n.tagName||"A"===n.tagName||"BUTTON"===n.tagName||"LABEL"===n.tagName||"TEXTAREA"===n.tagName)return i.tapElement(n,e);n=n.parentElement}h()}}function r(t){return t.target.control||o(t)||s(t)?u(t):void a(t)}function o(t){var e,i,n;for(e in f)if(i=f[e],n||(n=l(t)),n.x>i.x-v&&n.xi.y-v&&n.yg.x+2||e.xg.y+2||e.yc&&a;c++){if(r&&a.classList.contains("item")){r=a;break}if(("A"==a.tagName||"BUTTON"==a.tagName||a.getAttribute("ng-click"))&&(r=a),a.classList.contains("button")){r=a;break}a=a.parentElement}r&&(s[l]=r,"touchstart"===n.type?(t.body.removeEventListener("mousedown",e.activator.start),t.body.addEventListener("touchmove",o,!1),setTimeout(i,85)):(t.body.addEventListener("mousemove",o,!1),e.requestAnimationFrame(i)),l=l>19?0:l+1)})}},window.addEventListener("load",function(){t.body.addEventListener("touchstart",e.activator.start,!1),t.body.addEventListener("mousedown",e.activator.start,!1),t.body.addEventListener("touchend",r,!1),t.body.addEventListener("mouseup",r,!1),t.body.addEventListener("touchcancel",r,!1)},!1)}(document,ionic),function(t){var e=["0","0","0"];t.Utils={arrayMove:function(t,e,i){if(i>=t.length)for(var n=i-t.length;n--+1;)t.push(void 0);return t.splice(i,0,t.splice(e,1)[0]),t},proxy:function(t,e){var i=Array.prototype.slice.call(arguments,2);return function(){return t.apply(e,i.concat(Array.prototype.slice.call(arguments)))}},debounce:function(t,e,i){var n,r,o,s,a;return function(){o=this,r=arguments,s=new Date;var l=function(){var c=new Date-s;e>c?n=setTimeout(l,e-c):(n=null,i||(a=t.apply(o,r)))},c=i&&!n;return n||(n=setTimeout(l,e)),c&&(a=t.apply(o,r)),a}},throttle:function(t,e,i){var n,r,o,s=null,a=0;i||(i={});var l=function(){a=i.leading===!1?0:Date.now(),s=null,o=t.apply(n,r)};return function(){var c=Date.now();a||i.leading!==!1||(a=c);var u=e-(c-a);return n=this,r=arguments,0>=u?(clearTimeout(s),s=null,a=c,o=t.apply(n,r)):s||i.trailing===!1||(s=setTimeout(l,u)),o}},inherit:function(e,i){var n,r=this;n=e&&e.hasOwnProperty("constructor")?e.constructor:function(){return r.apply(this,arguments)},t.extend(n,r,i);var o=function(){this.constructor=n};return o.prototype=r.prototype,n.prototype=new o,e&&t.extend(n.prototype,e),n.__super__=r.prototype,n},extend:function(t){for(var e=Array.prototype.slice.call(arguments,1),i=0;i2500&&(clearInterval(a),a=null)},1e3/n)),e}}(),stop:function(t){var e=null!=r[t];return e&&(r[t]=null),e},isRunning:function(t){return null!=r[t]},start:function(t,a,l,c,u,h){var d=e(),_=d,f=0,g=0,p=o++;if(h||(h=document.body),p%20===0){var m={};for(var v in r)m[v]=!0;r=m}var T=function(o){var m=o!==!0,v=e();if(!r[p]||a&&!a(p))return r[p]=null,void(l&&l(i-g/((v-d)/n),p,!1));if(m)for(var E=Math.round((v-_)/(n/i))-1,w=0;w1&&(f=1));var y=u?u(f):f;t(y,v,m)!==!1&&1!==f||!m?m&&(_=v,s.effect.Animate.requestAnimationFrame(T,h)):(r[p]=null,l&&l(i-g/((v-d)/n),p,1===f||null==c))};return r[p]=!0,s.effect.Animate.requestAnimationFrame(T,h),p}}}(this);!function(i){var n=function(){},r=function(t){return Math.pow(t-1,3)+1},o=function(t){return(t/=.5)<1?.5*Math.pow(t,3):.5*(Math.pow(t-2,3)+2)};i.views.Scroll=i.views.View.inherit({initialize:function(t){var e=this;this.__container=t.el,this.__content=t.el.firstElementChild,setTimeout(function(){e.__container&&e.__content&&(e.__container.scrollTop=0,e.__content.scrollTop=0)}),this.options={scrollingX:!1,scrollbarX:!0,scrollingY:!0,scrollbarY:!0,startX:0,startY:0,wheelDampen:6,minScrollbarSizeX:5,minScrollbarSizeY:5,scrollbarsFade:!0,scrollbarFadeDelay:300,scrollbarResizeFadeDelay:1e3,animating:!0,animationDuration:250,bouncing:!0,locking:!0,paging:!1,snapping:!1,zooming:!1,minZoom:.5,maxZoom:3,speedMultiplier:1,scrollingComplete:n,penetrationDeceleration:.03,penetrationAcceleration:.08,scrollEventInterval:50};for(var r in t)this.options[r]=t[r];this.hintResize=i.debounce(function(){e.resize()},1e3,!0),this.triggerScrollEvent=i.throttle(function(){i.trigger("scroll",{scrollTop:e.__scrollTop,scrollLeft:e.__scrollLeft,target:e.__container})},this.options.scrollEventInterval),this.triggerScrollEndEvent=function(){i.trigger("scrollend",{scrollTop:e.__scrollTop,scrollLeft:e.__scrollLeft,target:e.__container})},this.__scrollLeft=this.options.startX,this.__scrollTop=this.options.startY,this.__callback=this.getRenderFn(),this.__initEventHandlers(),this.__createScrollbars()},run:function(){this.resize(),this.__fadeScrollbars("out",this.options.scrollbarResizeFadeDelay)},__isSingleTouch:!1,__isTracking:!1,__didDecelerationComplete:!1,__isGesturing:!1,__isDragging:!1,__isDecelerating:!1,__isAnimating:!1,__clientLeft:0,__clientTop:0,__clientWidth:0,__clientHeight:0,__contentWidth:0,__contentHeight:0,__snapWidth:100,__snapHeight:100,__refreshHeight:null,__refreshActive:!1,__refreshActivate:null,__refreshDeactivate:null,__refreshStart:null,__zoomLevel:1,__scrollLeft:0,__scrollTop:0,__maxScrollLeft:0,__maxScrollTop:0,__scheduledLeft:0,__scheduledTop:0,__scheduledZoom:0,__lastTouchLeft:null,__lastTouchTop:null,__lastTouchMove:null,__positions:null,__minDecelerationScrollLeft:null,__minDecelerationScrollTop:null,__maxDecelerationScrollLeft:null,__maxDecelerationScrollTop:null,__decelerationVelocityX:null,__decelerationVelocityY:null,__transformProperty:null,__perspectiveProperty:null,__indicatorX:null,__indicatorY:null,__scrollbarFadeTimeout:null,__didWaitForSize:null,__sizerTimeout:null,__initEventHandlers:function(){function n(i){return i.target.tagName.match(t)||i.target.isContentEditable||i.target.tagName.match(e)||i.target.dataset.preventScroll}var r=this,o=this.__container;if(o.addEventListener("scrollChildIntoView",function(t){var e=window.innerHeight,n=t.target,s=t.target.offsetHeight,a=n.getBoundingClientRect().top,l=i.DomUtil.getPositionInParent(n,o).top;a+s>e&&r.scrollTo(0,l+s-.5*e,!0),t.stopPropagation() +}),"ontouchstart"in window)o.addEventListener("touchstart",function(t){t.defaultPrevented||n(t)||(r.doTouchStart(t.touches,t.timeStamp),t.preventDefault())},!1),document.addEventListener("touchmove",function(t){t.defaultPrevented||r.doTouchMove(t.touches,t.timeStamp)},!1),document.addEventListener("touchend",function(t){r.doTouchEnd(t.timeStamp)},!1);else{var s=!1;o.addEventListener("mousedown",function(t){t.defaultPrevented||n(t)||(r.doTouchStart([{pageX:t.pageX,pageY:t.pageY}],t.timeStamp),t.preventDefault(),s=!0)},!1),document.addEventListener("mousemove",function(t){s&&!t.defaultPrevented&&(r.doTouchMove([{pageX:t.pageX,pageY:t.pageY}],t.timeStamp),s=!0)},!1),document.addEventListener("mouseup",function(t){s&&(r.doTouchEnd(t.timeStamp),s=!1)},!1);var a=i.debounce(function(){r.__fadeScrollbars("in")},500,!0),l=i.debounce(function(){r.__fadeScrollbars("out")},100,!1);document.addEventListener("mousewheel",function(t){a(),r.scrollBy(t.wheelDeltaX/r.options.wheelDampen,-t.wheelDeltaY/r.options.wheelDampen),l()})}},__createScrollbar:function(t){var e=document.createElement("div"),i=document.createElement("div");return i.className="scroll-bar-indicator",e.className="h"==t?"scroll-bar scroll-bar-h":"scroll-bar scroll-bar-v",e.appendChild(i),e},__createScrollbars:function(){var t,e;this.options.scrollingX&&(t={el:this.__createScrollbar("h"),sizeRatio:1},t.indicator=t.el.children[0],this.options.scrollbarX&&this.__container.appendChild(t.el),this.__indicatorX=t),this.options.scrollingY&&(e={el:this.__createScrollbar("v"),sizeRatio:1},e.indicator=e.el.children[0],this.options.scrollbarY&&this.__container.appendChild(e.el),this.__indicatorY=e)},__resizeScrollbars:function(){var t=this;if(t.__indicatorX){var e=Math.max(Math.round(t.__clientWidth*t.__clientWidth/t.__contentWidth),20);e>t.__contentWidth&&(e=0),t.__indicatorX.size=e,t.__indicatorX.minScale=this.options.minScrollbarSizeX/e,t.__indicatorX.indicator.style.width=e+"px",t.__indicatorX.maxPos=t.__clientWidth-e,t.__indicatorX.sizeRatio=t.__maxScrollLeft?t.__indicatorX.maxPos/t.__maxScrollLeft:1}if(t.__indicatorY){var i=Math.max(Math.round(t.__clientHeight*t.__clientHeight/t.__contentHeight),20);i>t.__contentHeight&&(i=0),t.__indicatorY.size=i,t.__indicatorY.minScale=this.options.minScrollbarSizeY/i,t.__indicatorY.maxPos=t.__clientHeight-i,t.__indicatorY.indicator.style.height=i+"px",t.__indicatorY.sizeRatio=t.__maxScrollTop?t.__indicatorY.maxPos/t.__maxScrollTop:1}},__repositionScrollbars:function(){var t,e,i,n,r,o=this,s=0,a=0;o.__indicatorX&&(o.__indicatorY&&(s=10),n=Math.round(o.__indicatorX.sizeRatio*o.__scrollLeft)||0,e=o.__scrollLeft-(o.__maxScrollLeft-s),o.__scrollLeft<0?(widthScale=Math.max(o.__indicatorX.minScale,(o.__indicatorX.size-Math.abs(o.__scrollLeft))/o.__indicatorX.size),n=0,o.__indicatorX.indicator.style[o.__transformOriginProperty]="left center"):e>0?(widthScale=Math.max(o.__indicatorX.minScale,(o.__indicatorX.size-e)/o.__indicatorX.size),n=o.__indicatorX.maxPos-s,o.__indicatorX.indicator.style[o.__transformOriginProperty]="right center"):(n=Math.min(o.__maxScrollLeft,Math.max(0,n)),widthScale=1),o.__indicatorX.indicator.style[o.__transformProperty]="translate3d("+n+"px, 0, 0) scaleX("+widthScale+")"),o.__indicatorY&&(r=Math.round(o.__indicatorY.sizeRatio*o.__scrollTop)||0,o.__indicatorX&&(a=10),i=o.__scrollTop-(o.__maxScrollTop-a),o.__scrollTop<0?(t=Math.max(o.__indicatorY.minScale,(o.__indicatorY.size-Math.abs(o.__scrollTop))/o.__indicatorY.size),r=0,o.__indicatorY.indicator.style[o.__transformOriginProperty]="center top"):i>0?(t=Math.max(o.__indicatorY.minScale,(o.__indicatorY.size-i)/o.__indicatorY.size),r=o.__indicatorY.maxPos-a,o.__indicatorY.indicator.style[o.__transformOriginProperty]="center bottom"):(r=Math.min(o.__maxScrollTop,Math.max(0,r)),t=1),o.__indicatorY.indicator.style[o.__transformProperty]="translate3d(0,"+r+"px, 0) scaleY("+t+")")},__fadeScrollbars:function(t,e){var i=this;if(this.options.scrollbarsFade){var n="scroll-bar-fade-out";i.options.scrollbarsFade===!0&&(clearTimeout(i.__scrollbarFadeTimeout),"in"==t?(i.__indicatorX&&i.__indicatorX.indicator.classList.remove(n),i.__indicatorY&&i.__indicatorY.indicator.classList.remove(n)):i.__scrollbarFadeTimeout=setTimeout(function(){i.__indicatorX&&i.__indicatorX.indicator.classList.add(n),i.__indicatorY&&i.__indicatorY.indicator.classList.add(n)},e||i.options.scrollbarFadeDelay))}},__scrollingComplete:function(){var t=this;t.options.scrollingComplete(),t.__fadeScrollbars("out")},resize:function(){this.setDimensions(this.__container.clientWidth,this.__container.clientHeight,Math.max(this.__content.scrollWidth,this.__content.offsetWidth),Math.max(this.__content.scrollHeight,this.__content.offsetHeight))},getRenderFn:function(){var t,e=this,i=this.__content,n=document.documentElement.style;"MozAppearance"in n?t="gecko":"WebkitAppearance"in n?t="webkit":"string"==typeof navigator.cpuClass&&(t="trident");var r,o={trident:"ms",gecko:"Moz",webkit:"Webkit",presto:"O"}[t],s=document.createElement("div"),a=o+"Perspective",l=o+"Transform",c=o+"TransformOrigin";return e.__perspectiveProperty=l,e.__transformProperty=l,e.__transformOriginProperty=c,s.style[a]!==r?function(t,n){i.style[l]="translate3d("+-t+"px,"+-n+"px,0)",e.__repositionScrollbars(),e.triggerScrollEvent()}:s.style[l]!==r?function(t,n){i.style[l]="translate("+-t+"px,"+-n+"px)",e.__repositionScrollbars(),e.triggerScrollEvent()}:function(t,n,r){i.style.marginLeft=t?-t/r+"px":"",i.style.marginTop=n?-n/r+"px":"",i.style.zoom=r||"",e.__repositionScrollbars(),e.triggerScrollEvent()}},setDimensions:function(t,e,i,n){var r=this;t===+t&&(r.__clientWidth=t),e===+e&&(r.__clientHeight=e),i===+i&&(r.__contentWidth=i),n===+n&&(r.__contentHeight=n),r.__computeScrollMax(),r.__resizeScrollbars(),r.scrollTo(r.__scrollLeft,r.__scrollTop,!0)},setPosition:function(t,e){var i=this;i.__clientLeft=t||0,i.__clientTop=e||0},setSnapSize:function(t,e){var i=this;i.__snapWidth=t,i.__snapHeight=e},activatePullToRefresh:function(t,e,i,n){var r=this;r.__refreshHeight=t,r.__refreshActivate=e,r.__refreshDeactivate=i,r.__refreshStart=n},triggerPullToRefresh:function(){this.__publish(this.__scrollLeft,-this.__refreshHeight,this.__zoomLevel,!0),this.__refreshStart&&this.__refreshStart()},finishPullToRefresh:function(){var t=this;t.__refreshActive=!1,t.__refreshDeactivate&&t.__refreshDeactivate(),t.scrollTo(t.__scrollLeft,t.__scrollTop,!0)},getValues:function(){var t=this;return{left:t.__scrollLeft,top:t.__scrollTop,zoom:t.__zoomLevel}},getScrollMax:function(){var t=this;return{left:t.__maxScrollLeft,top:t.__maxScrollTop}},zoomTo:function(t,e,i,n){var r=this;if(!r.options.zooming)throw new Error("Zooming is not enabled!");r.__isDecelerating&&(core.effect.Animate.stop(r.__isDecelerating),r.__isDecelerating=!1);var o=r.__zoomLevel;null==i&&(i=r.__clientWidth/2),null==n&&(n=r.__clientHeight/2),t=Math.max(Math.min(t,r.options.maxZoom),r.options.minZoom),r.__computeScrollMax(t);var s=(i+r.__scrollLeft)*t/o-i,a=(n+r.__scrollTop)*t/o-n;s>r.__maxScrollLeft?s=r.__maxScrollLeft:0>s&&(s=0),a>r.__maxScrollTop?a=r.__maxScrollTop:0>a&&(a=0),r.__publish(s,a,t,e)},zoomBy:function(t,e,i,n){var r=this;r.zoomTo(r.__zoomLevel*t,e,i,n)},scrollTo:function(t,e,i,n){var r=this;if(r.__isDecelerating&&(core.effect.Animate.stop(r.__isDecelerating),r.__isDecelerating=!1),null!=n&&n!==r.__zoomLevel){if(!r.options.zooming)throw new Error("Zooming is not enabled!");t*=n,e*=n,r.__computeScrollMax(n)}else n=r.__zoomLevel;r.options.scrollingX?r.options.paging?t=Math.round(t/r.__clientWidth)*r.__clientWidth:r.options.snapping&&(t=Math.round(t/r.__snapWidth)*r.__snapWidth):t=r.__scrollLeft,r.options.scrollingY?r.options.paging?e=Math.round(e/r.__clientHeight)*r.__clientHeight:r.options.snapping&&(e=Math.round(e/r.__snapHeight)*r.__snapHeight):e=r.__scrollTop,t=Math.max(Math.min(r.__maxScrollLeft,t),0),e=Math.max(Math.min(r.__maxScrollTop,e),0),t===r.__scrollLeft&&e===r.__scrollTop&&(i=!1),r.__publish(t,e,n,i)},scrollBy:function(t,e,i){var n=this,r=n.__isAnimating?n.__scheduledLeft:n.__scrollLeft,o=n.__isAnimating?n.__scheduledTop:n.__scrollTop;n.scrollTo(r+(t||0),o+(e||0),i)},doMouseZoom:function(t,e,i,n){var r=this,o=t>0?.97:1.03;return r.zoomTo(r.__zoomLevel*o,!1,i-r.__clientLeft,n-r.__clientTop)},doTouchStart:function(t,e){if(this.hintResize(),null==t.length)throw new Error("Invalid touch list: "+t);if(e instanceof Date&&(e=e.valueOf()),"number"!=typeof e)throw new Error("Invalid timestamp value: "+e);var i=this;i.__interruptedAnimation=!0,i.__isDecelerating&&(core.effect.Animate.stop(i.__isDecelerating),i.__isDecelerating=!1,i.__interruptedAnimation=!0),i.__isAnimating&&(core.effect.Animate.stop(i.__isAnimating),i.__isAnimating=!1,i.__interruptedAnimation=!0);var n,r,o=1===t.length;o?(n=t[0].pageX,r=t[0].pageY):(n=Math.abs(t[0].pageX+t[1].pageX)/2,r=Math.abs(t[0].pageY+t[1].pageY)/2),i.__initialTouchLeft=n,i.__initialTouchTop=r,i.__zoomLevelStart=i.__zoomLevel,i.__lastTouchLeft=n,i.__lastTouchTop=r,i.__lastTouchMove=e,i.__lastScale=1,i.__enableScrollX=!o&&i.options.scrollingX,i.__enableScrollY=!o&&i.options.scrollingY,i.__isTracking=!0,i.__didDecelerationComplete=!1,i.__isDragging=!o,i.__isSingleTouch=o,i.__positions=[]},doTouchMove:function(t,e,i){if(null==t.length)throw new Error("Invalid touch list: "+t);if(e instanceof Date&&(e=e.valueOf()),"number"!=typeof e)throw new Error("Invalid timestamp value: "+e);var n=this;if(n.__isTracking){var r,o;2===t.length?(r=Math.abs(t[0].pageX+t[1].pageX)/2,o=Math.abs(t[0].pageY+t[1].pageY)/2):(r=t[0].pageX,o=t[0].pageY);var s=n.__positions;if(n.__isDragging){var a=r-n.__lastTouchLeft,l=o-n.__lastTouchTop,c=n.__scrollLeft,u=n.__scrollTop,h=n.__zoomLevel;if(null!=i&&n.options.zooming){var d=h;if(h=h/n.__lastScale*i,h=Math.max(Math.min(h,n.options.maxZoom),n.options.minZoom),d!==h){var _=r-n.__clientLeft,f=o-n.__clientTop;c=(_+c)*h/d-_,u=(f+u)*h/d-f,n.__computeScrollMax(h)}}if(n.__enableScrollX){c-=a*this.options.speedMultiplier;var g=n.__maxScrollLeft;(c>g||0>c)&&(n.options.bouncing?c+=a/2*this.options.speedMultiplier:c=c>g?g:0)}if(n.__enableScrollY){u-=l*this.options.speedMultiplier;var p=n.__maxScrollTop;(u>p||0>u)&&(n.options.bouncing||n.__refreshHeight&&0>u?(u+=l/2*this.options.speedMultiplier,n.__enableScrollX||null==n.__refreshHeight||(!n.__refreshActive&&u<=-n.__refreshHeight?(n.__refreshActive=!0,n.__refreshActivate&&n.__refreshActivate()):n.__refreshActive&&u>-n.__refreshHeight&&(n.__refreshActive=!1,n.__refreshDeactivate&&n.__refreshDeactivate()))):u=u>p?p:0)}s.length>60&&s.splice(0,30),s.push(c,u,e),n.__publish(c,u,h)}else{var m=n.options.locking?3:0,v=5,T=Math.abs(r-n.__initialTouchLeft),E=Math.abs(o-n.__initialTouchTop);n.__enableScrollX=n.options.scrollingX&&T>=m,n.__enableScrollY=n.options.scrollingY&&E>=m,s.push(n.__scrollLeft,n.__scrollTop,e),n.__isDragging=(n.__enableScrollX||n.__enableScrollY)&&(T>=v||E>=v),n.__isDragging&&(n.__interruptedAnimation=!1,n.__fadeScrollbars("in"))}n.__lastTouchLeft=r,n.__lastTouchTop=o,n.__lastTouchMove=e,n.__lastScale=i}},doTouchEnd:function(t){if(t instanceof Date&&(t=t.valueOf()),"number"!=typeof t)throw new Error("Invalid timestamp value: "+t);var e=this;if(e.__isTracking){if(e.__isTracking=!1,e.__isDragging)if(e.__isDragging=!1,e.__isSingleTouch&&e.options.animating&&t-e.__lastTouchMove<=100){for(var i=e.__positions,n=i.length-1,r=n,o=n;o>0&&i[o]>e.__lastTouchMove-100;o-=3)r=o;if(r!==n){var s=i[n]-i[r],a=e.__scrollLeft-i[r-2],l=e.__scrollTop-i[r-1];e.__decelerationVelocityX=a/s*(1e3/60),e.__decelerationVelocityY=l/s*(1e3/60);var c=e.options.paging||e.options.snapping?4:1;(Math.abs(e.__decelerationVelocityX)>c||Math.abs(e.__decelerationVelocityY)>c)&&(e.__refreshActive||e.__startDeceleration(t))}else e.__scrollingComplete()}else t-e.__lastTouchMove>100&&e.__scrollingComplete();e.__isDecelerating||(e.__refreshActive&&e.__refreshStart?(e.__publish(e.__scrollLeft,-e.__refreshHeight,e.__zoomLevel,!0),e.__refreshStart&&e.__refreshStart()):((e.__interruptedAnimation||e.__isDragging)&&e.__scrollingComplete(),e.scrollTo(e.__scrollLeft,e.__scrollTop,!0,e.__zoomLevel),e.__refreshActive&&(e.__refreshActive=!1,e.__refreshDeactivate&&e.__refreshDeactivate()))),e.__positions.length=0}},__publish:function(t,e,i,n){var s=this,a=s.__isAnimating;if(a&&(core.effect.Animate.stop(a),s.__isAnimating=!1),n&&s.options.animating){s.__scheduledLeft=t,s.__scheduledTop=e,s.__scheduledZoom=i;var l=s.__scrollLeft,c=s.__scrollTop,u=s.__zoomLevel,h=t-l,d=e-c,_=i-u,f=function(t,e,i){i&&(s.__scrollLeft=l+h*t,s.__scrollTop=c+d*t,s.__zoomLevel=u+_*t,s.__callback&&s.__callback(s.__scrollLeft,s.__scrollTop,s.__zoomLevel))},g=function(t){return s.__isAnimating===t},p=function(t,e,i){e===s.__isAnimating&&(s.__isAnimating=!1),(s.__didDecelerationComplete||i)&&s.__scrollingComplete(),s.options.zooming&&s.__computeScrollMax()};s.__isAnimating=core.effect.Animate.start(f,g,p,s.options.animationDuration,a?r:o)}else s.__scheduledLeft=s.__scrollLeft=t,s.__scheduledTop=s.__scrollTop=e,s.__scheduledZoom=s.__zoomLevel=i,s.__callback&&s.__callback(t,e,i),s.options.zooming&&s.__computeScrollMax()},__computeScrollMax:function(t){var e=this;null==t&&(t=e.__zoomLevel),e.__maxScrollLeft=Math.max(e.__contentWidth*t-e.__clientWidth,0),e.__maxScrollTop=Math.max(e.__contentHeight*t-e.__clientHeight,0),e.__didWaitForSize||0!=e.__maxScrollLeft||0!=e.__maxScrollTop||(e.__didWaitForSize=!0,e.__waitForSize())},__waitForSize:function(){var t=this;clearTimeout(t.__sizerTimeout);var e=function(){t.resize(),t.options.scrollingX&&0==t.__maxScrollLeft||t.options.scrollingY&&0==t.__maxScrollTop};e(),t.__sizerTimeout=setTimeout(e,1e3)},__startDeceleration:function(){var t=this;if(t.options.paging){var e=Math.max(Math.min(t.__scrollLeft,t.__maxScrollLeft),0),i=Math.max(Math.min(t.__scrollTop,t.__maxScrollTop),0),n=t.__clientWidth,r=t.__clientHeight;t.__minDecelerationScrollLeft=Math.floor(e/n)*n,t.__minDecelerationScrollTop=Math.floor(i/r)*r,t.__maxDecelerationScrollLeft=Math.ceil(e/n)*n,t.__maxDecelerationScrollTop=Math.ceil(i/r)*r}else t.__minDecelerationScrollLeft=0,t.__minDecelerationScrollTop=0,t.__maxDecelerationScrollLeft=t.__maxScrollLeft,t.__maxDecelerationScrollTop=t.__maxScrollTop;var o=function(e,i,n){t.__stepThroughDeceleration(n)};t.__minVelocityToKeepDecelerating=t.options.snapping?4:.1;var s=function(){var e=Math.abs(t.__decelerationVelocityX)>=t.__minVelocityToKeepDecelerating||Math.abs(t.__decelerationVelocityY)>=t.__minVelocityToKeepDecelerating;return e||(t.__didDecelerationComplete=!0),e},a=function(){t.__isDecelerating=!1,t.__didDecelerationComplete&&t.__scrollingComplete(),t.options.paging&&t.scrollTo(t.__scrollLeft,t.__scrollTop,t.options.snapping)};t.__isDecelerating=core.effect.Animate.start(o,s,a)},__stepThroughDeceleration:function(t){var e=this,i=e.__scrollLeft+e.__decelerationVelocityX,n=e.__scrollTop+e.__decelerationVelocityY;if(!e.options.bouncing){var r=Math.max(Math.min(e.__maxDecelerationScrollLeft,i),e.__minDecelerationScrollLeft);r!==i&&(i=r,e.__decelerationVelocityX=0);var o=Math.max(Math.min(e.__maxDecelerationScrollTop,n),e.__minDecelerationScrollTop);o!==n&&(n=o,e.__decelerationVelocityY=0)}if(t?e.__publish(i,n,e.__zoomLevel):(e.__scrollLeft=i,e.__scrollTop=n),!e.options.paging){var s=.95;e.__decelerationVelocityX*=s,e.__decelerationVelocityY*=s}if(e.options.bouncing){var a=0,l=0,c=e.options.penetrationDeceleration,u=e.options.penetrationAcceleration;if(ie.__maxDecelerationScrollLeft&&(a=e.__maxDecelerationScrollLeft-i),ne.__maxDecelerationScrollTop&&(l=e.__maxDecelerationScrollTop-n),0!==a){var h=a*e.__decelerationVelocityX<=e.__minDecelerationScrollLeft;h&&(e.__decelerationVelocityX+=a*c);var d=Math.abs(e.__decelerationVelocityX)<=e.__minVelocityToKeepDecelerating;(!h||d)&&(e.__decelerationVelocityX=a*u)}if(0!==l){var _=l*e.__decelerationVelocityY<=e.__minDecelerationScrollTop;_&&(e.__decelerationVelocityY+=l*c);var f=Math.abs(e.__decelerationVelocityY)<=e.__minVelocityToKeepDecelerating;(!_||f)&&(e.__decelerationVelocityY=l*u)}}}})}(ionic),function(t){"use strict";t.views.ActionSheet=t.views.View.inherit({initialize:function(t){this.el=t.el},show:function(){this.el.offsetWidth,this.el.classList.add("active")},hide:function(){this.el.offsetWidth,this.el.classList.remove("active")}})}(ionic),function(t){"use strict";t.views.HeaderBar=t.views.View.inherit({initialize:function(e){this.el=e.el,t.extend(this,{alignTitle:"center"},e),this.align()},align:function(e){e||(e=this.alignTitle);var i=this.el.querySelector(".title");if(i){var n,r,o,s=this.el.childNodes,a=0,l=0,c=!1;for(n=0;n10&&(i.style.left=t+"px",i.style.right=t+"px"),i.offsetWidth0&&(i.style.right=l+5+"px")):"left"==e?(i.classList.add("title-left"),a>0&&(i.style.left=a+15+"px")):"right"==e&&(i.classList.add("title-right"),l>0&&(i.style.right=l+15+"px"))})}}})}(ionic),function(t){"use strict";var e="item",i="item-content",n="item-sliding",r="item-options",o="item-placeholder",s="item-reordering",a="item-reorder",l=function(){};l.prototype={start:function(){},drag:function(){},end:function(){},isSameItem:function(){return!1}};var c=function(t){this.dragThresholdX=t.dragThresholdX||10,this.el=t.el};c.prototype=new l,c.prototype.start=function(o){var s,a,l,c;s=o.target.classList.contains(i)?o.target:o.target.classList.contains(e)?o.target.querySelector("."+i):t.DomUtil.getParentWithClass(o.target,i),s&&(s.classList.remove(n),l=parseFloat(s.style[t.CSS.TRANSFORM].replace("translate3d(","").split(",")[0])||0,a=s.parentNode.querySelector("."+r),a&&(c=a.offsetWidth,this._currentDrag={buttonsWidth:c,content:s,startOffsetX:l}))},c.prototype.isSameItem=function(t){return t._lastDrag&&this._currentDrag?this._currentDrag.content==t._lastDrag.content:!1},c.prototype.clean=function(){var e=this._lastDrag;e&&t.requestAnimationFrame(function(){e.content.style[t.CSS.TRANSITION]="",e.content.style[t.CSS.TRANSFORM]="translate3d(0, 0, 0)"})},c.prototype.drag=t.animationFrameThrottle(function(e){var i;if(this._currentDrag&&(!this._isDragging&&(Math.abs(e.gesture.deltaX)>this.dragThresholdX||Math.abs(this._currentDrag.startOffsetX)>0)&&(this._isDragging=!0),this._isDragging)){i=this._currentDrag.buttonsWidth;var n=Math.min(0,this._currentDrag.startOffsetX+e.gesture.deltaX);-i>n&&(n=Math.min(-i,-i+.4*(e.gesture.deltaX+i))),this._currentDrag.content.style[t.CSS.TRANSFORM]="translate3d("+n+"px, 0, 0)",this._currentDrag.content.style[t.CSS.TRANSITION]="none"}}),c.prototype.end=function(e,i){var n=this;if(!this._currentDrag)return void(i&&i());var r=-this._currentDrag.buttonsWidth;e.gesture.deltaX>-(this._currentDrag.buttonsWidth/2)&&("left"==e.gesture.direction&&Math.abs(e.gesture.velocityX)<.3?r=0:"right"==e.gesture.direction&&(r=0)),t.requestAnimationFrame(function(){n._currentDrag.content.style[t.CSS.TRANSFORM]=0===r?"":"translate3d("+r+"px, 0, 0)",n._currentDrag.content.style[t.CSS.TRANSITION]="",n._lastDrag=n._currentDrag,n._currentDrag=null,i&&i()})};var u=function(t){this.dragThresholdY=t.dragThresholdY||0,this.onReorder=t.onReorder,this.el=t.el,this.scrollEl=t.scrollEl,this.scrollView=t.scrollView};u.prototype=new l,u.prototype._moveElement=function(e){var i=e.gesture.center.pageY-this._currentDrag.elementHeight/2;this.el.style[t.CSS.TRANSFORM]="translate3d(0, "+i+"px, 0)"},u.prototype.start=function(e){var i=(this.el.offsetTop,t.DomUtil.getChildIndex(this.el,this.el.nodeName.toLowerCase())),n=this.el.offsetHeight,r=this.el.cloneNode(!0),a=(this.scrollEl||this.el).parentNode;r.classList.add(o),this.el.parentNode.insertBefore(r,this.el),this.el.classList.add(s),a.parentNode.appendChild(this.el),this._currentDrag={elementHeight:n,startIndex:i,placeholder:r,scrollHeight:scroll,list:r.parentNode},this._moveElement(e)},u.prototype.drag=t.animationFrameThrottle(function(t){if(this._currentDrag){var e=0,i=t.gesture.center.pageY;if(this.scrollView){var n=this.scrollEl;e=this.scrollView.getValues().top;var r=n.offsetTop,o=r-i+this._currentDrag.elementHeight/2,s=i+this._currentDrag.elementHeight/2-r-n.offsetHeight;t.gesture.deltaY<0&&o>0&&e>0&&this.scrollView.scrollBy(null,-o),t.gesture.deltaY>0&&s>0&&ethis.dragThresholdY&&(this._isDragging=!0),this._isDragging&&(this._moveElement(t),this._currentDrag.currentY=e+i-this._currentDrag.placeholder.parentNode.offsetTop,this._reorderItems())}}),u.prototype._reorderItems=function(){var e=(this._currentDrag.placeholder,Array.prototype.slice.call(this._currentDrag.placeholder.parentNode.children)),i=e.indexOf(this._currentDrag.placeholder),n=e[Math.max(0,i-1)],r=e[Math.min(e.length,i+1)],o=this._currentDrag.currentY;return n&&or.offsetTop+r.offsetHeight/2?(t.DomUtil.swapNodes(r,this._currentDrag.placeholder),i+1):void 0},u.prototype.end=function(e,i){if(!this._currentDrag)return void(i&&i());var n=this._currentDrag.placeholder,r=t.DomUtil.getChildIndex(n,n.nodeName.toLowerCase());this.el.classList.remove(s),this.el.style[t.CSS.TRANSFORM]="",n.parentNode.insertBefore(this.el,n),n.parentNode.removeChild(n),this.onReorder&&this.onReorder(this.el,this._currentDrag.startIndex,r),this._currentDrag=null,i&&i()},t.views.ListView=t.views.View.inherit({initialize:function(e){var i=this;e=t.extend({onReorder:function(){},virtualRemoveThreshold:-200,virtualAddThreshold:200,canSwipe:!1},e),t.extend(this,e),!this.itemHeight&&this.listEl&&(this.itemHeight=this.listEl.children[0]&&parseInt(this.listEl.children[0].style.height,10)),this.onRefresh=e.onRefresh||function(){},this.onRefreshOpening=e.onRefreshOpening||function(){},this.onRefreshHolding=e.onRefreshHolding||function(){},window.ionic.onGesture("release",function(t){i._handleEndDrag(t)},this.el),window.ionic.onGesture("drag",function(t){i._handleDrag(t)},this.el),this._initDrag()},stopRefreshing:function(){var t=this.el.querySelector(".list-refresher");t.style.height="0px"},didScroll:function(t){if(this.isVirtual){var e=this.itemHeight,i=(this.listEl.children.length,t.target.scrollHeight),n=this.el.parentNode.offsetHeight,r=(t.scrollTop,Math.max(0,t.scrollTop+this.virtualRemoveThreshold)),o=Math.min(i,Math.abs(t.scrollTop)+n+this.virtualAddThreshold),s=Math.floor((o-r)/e),a=parseInt(Math.abs(r/e),10),l=parseInt(Math.abs(o/e),10);this._virtualItemsToRemove=Array.prototype.slice.call(this.listEl.children,0,a);{Array.prototype.slice.call(this.listEl.children,a,a+s)}this.renderViewport&&this.renderViewport(r,o,a,l)}},didStopScrolling:function(){if(this.isVirtual)for(var t=0;t5){var r=this._getItem(e.target);r&&r.querySelector(".item-options")&&(this._dragOp=new c({el:this.el}),this._dragOp.start(e),e.preventDefault())}}else{var r=this._getItem(e.target);r&&(this._dragOp=new u({el:r,scrollEl:this.scrollEl,scrollView:this.scrollView,onReorder:function(t,e,n){i.onReorder&&i.onReorder(t,e,n)}}),this._dragOp.start(e),e.preventDefault())}n&&this._dragOp&&!this._dragOp.isSameItem(n)&&e.defaultPrevented&&n.clean&&n.clean()},_handleEndDrag:function(t){var e=this;this._didDragUpOrDown=!1,this._dragOp&&this._dragOp.end(t,function(){e._initDrag()})},_handleDrag:function(t){this.canSwipe&&(Math.abs(t.gesture.deltaY)>5&&(this._didDragUpOrDown=!0),this.isDragging||this._dragOp||this._startDrag(t),this._dragOp&&(t.gesture.srcEvent.preventDefault(),this._dragOp.drag(t)))}})}(ionic),function(t){"use strict";t.views.Loading=t.views.View.inherit({initialize:function(t){this.el=t.el,this.maxWidth=t.maxWidth||200,this.showDelay=t.showDelay||0,this._loadingBox=this.el.querySelector(".loading")||this.el},show:function(){var t=this;if(this._loadingBox){var e=t._loadingBox,i=Math.min(t.maxWidth,Math.max(window.outerWidth-40,e.offsetWidth));e.style.width=i+"px",e.style.marginLeft=-e.offsetWidth/2+"px",e.style.marginTop=-e.offsetHeight/2+"px",this._showDelayTimeout=window.setTimeout(function(){t.el.classList.add("active")},t.showDelay)}},hide:function(){this.el.offsetWidth,window.clearTimeout(this._showDelayTimeout),this.el.classList.remove("active")},setContent:function(t){this._loadingBox&&(this._loadingBox.innerHTML=t||"")}})}(ionic),function(t){"use strict";t.views.Modal=t.views.View.inherit({initialize:function(e){e=t.extend({focusFirstInput:!1,unfocusOnHide:!0,focusFirstDelay:600},e),t.extend(this,e),this.el=e.el},show:function(){var t=this;t.focusFirstInput&&window.setTimeout(function(){var e=t.el.querySelector("input, textarea");e&&e.focus&&e.focus()},t.focusFirstDelay)},hide:function(){if(this.unfocusOnHide){var t=this.el.querySelectorAll("input, textarea");window.setTimeout(function(){for(var e=0;ee?-m:e>E?m:0,0))}t.continuous&&_.transitions&&(s(r(E-1),-m,0),s(r(E+1),m,0)),_.transitions||(T.style.left=E*-m+"px"),f.style.visibility="visible",t.slidesChanged&&t.slidesChanged()}function i(){t.continuous?o(E-1):E&&o(E-1)}function n(){t.continuous?o(E+1):EE?e:E)-a-1),m*n,0);e=r(e),s(E,m*n,i||w),s(e,0,i||w),t.continuous&&s(r(e-n),-(m*n),0)}else e=r(e),l(E*-m,e*-m,i||w);E=e,d(t.callback&&t.callback(E,g[E]))}}function s(t,e,i){a(t,e,i),p[t]=e}function a(t,e,i){var n=g[t],r=n&&n.style;r&&(r.webkitTransitionDuration=r.MozTransitionDuration=r.msTransitionDuration=r.OTransitionDuration=r.transitionDuration=i+"ms",r.webkitTransform="translate("+e+"px,0)translateZ(0)",r.msTransform=r.MozTransform=r.OTransform="translateX("+e+"px)")}function l(e,i,n){if(!n)return void(T.style.left=i+"px");var r=+new Date,o=setInterval(function(){var s=+new Date-r;return s>n?(T.style.left=i+"px",S&&c(),t.transitionEnd&&t.transitionEnd.call(event,E,g[E]),void clearInterval(o)):void(T.style.left=(i-e)*(Math.floor(s/n*100)/100)+e+"px")},4)}function c(){y=setTimeout(n,S)}function u(){S=t.auto||0,clearTimeout(y)}var h=function(){},d=function(t){setTimeout(t||h,0)},_={addEventListener:!!window.addEventListener,touch:"ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch,transitions:function(t){var e=["transitionProperty","WebkitTransition","MozTransition","OTransition","msTransition"];for(var i in e)if(void 0!==t.style[e[i]])return!0;return!1}(document.createElement("swipe"))},f=t.el;if(f){var g,p,m,v,T=f.children[0];t=t||{};var E=parseInt(t.startSlide,10)||0,w=t.speed||300;t.continuous=void 0!==t.continuous?t.continuous:!0;var y,b,S=t.auto||0,D={},x={},L={handleEvent:function(i){switch(("mousedown"==i.type||"mouseup"==i.type||"mousemove"==i.type)&&(i.touches=[{pageX:i.pageX,pageY:i.pageY}]),i.type){case"mousedown":this.start(i);break;case"touchstart":this.start(i);break;case"touchmove":this.move(i);break;case"mousemove":this.move(i);break;case"touchend":d(this.end(i));break;case"mouseup":d(this.end(i));break;case"webkitTransitionEnd":case"msTransitionEnd":case"oTransitionEnd":case"otransitionend":case"transitionend":d(this.transitionEnd(i));break;case"resize":d(e)}t.stopPropagation&&i.stopPropagation()},start:function(t){var e=t.touches[0];D={x:e.pageX,y:e.pageY,time:+new Date},b=void 0,x={},_.touch?(T.addEventListener("touchmove",this,!1),T.addEventListener("touchend",this,!1)):(T.addEventListener("mousemove",this,!1),T.addEventListener("mouseup",this,!1),document.addEventListener("mouseup",this,!1))},move:function(e){if(!(e.touches.length>1||e.scale&&1!==e.scale)){t.disableScroll&&e.preventDefault();var i=e.touches[0];x={x:i.pageX-D.x,y:i.pageY-D.y},"undefined"==typeof b&&(b=!!(b||Math.abs(x.x)0||E==g.length-1&&x.x<0?Math.abs(x.x)/m+1:1),a(E-1,x.x+p[E-1],0),a(E,x.x+p[E],0),a(E+1,x.x+p[E+1],0)))}},end:function(){var e=+new Date-D.time,i=Number(e)<250&&Math.abs(x.x)>20||Math.abs(x.x)>m/2,n=!E&&x.x>0||E==g.length-1&&x.x<0;t.continuous&&(n=!1);var o=x.x<0;b||(i&&!n?(o?(t.continuous?(s(r(E-1),-m,0),s(r(E+2),m,0)):s(E-1,-m,0),s(E,p[E]-m,w),s(r(E+1),p[r(E+1)]-m,w),E=r(E+1)):(t.continuous?(s(r(E+1),m,0),s(r(E-2),-m,0)):s(E+1,m,0),s(E,p[E]+m,w),s(r(E-1),p[r(E-1)]+m,w),E=r(E-1)),t.callback&&t.callback(E,g[E])):t.continuous?(s(r(E-1),-m,w),s(E,0,w),s(r(E+1),m,w)):(s(E-1,-m,w),s(E,0,w),s(E+1,m,w))),_.touch?(T.removeEventListener("touchmove",L,!1),T.removeEventListener("touchend",L,!1)):(T.removeEventListener("mousemove",L,!1),T.removeEventListener("mouseup",L,!1),document.removeEventListener("mouseup",L,!1)) +},transitionEnd:function(e){parseInt(e.target.getAttribute("data-index"),10)==E&&(S&&c(),t.transitionEnd&&t.transitionEnd.call(e,E,g[E]))}};this.update=function(){setTimeout(e)},this.setup=function(){e()},this.slide=function(t,e){u(),o(t,e)},this.prev=this.previous=function(){u(),i()},this.next=function(){u(),n()},this.stop=function(){u()},this.currentIndex=function(){return E},this.slidesCount=function(){return v},this.kill=function(){u(),T.style.width="",T.style.left="";for(var t=g.length;t--;){var e=g[t];e.style.width="",e.style.left="",_.transitions&&a(t,0,0)}_.addEventListener?(T.removeEventListener("touchstart",L,!1),T.removeEventListener("webkitTransitionEnd",L,!1),T.removeEventListener("msTransitionEnd",L,!1),T.removeEventListener("oTransitionEnd",L,!1),T.removeEventListener("otransitionend",L,!1),T.removeEventListener("transitionend",L,!1),window.removeEventListener("resize",L,!1)):window.onresize=null},this.load=function(){e(),S&&c(),_.addEventListener?(_.touch?T.addEventListener("touchstart",L,!1):T.addEventListener("mousedown",L,!1),_.transitions&&(T.addEventListener("webkitTransitionEnd",L,!1),T.addEventListener("msTransitionEnd",L,!1),T.addEventListener("oTransitionEnd",L,!1),T.addEventListener("otransitionend",L,!1),T.addEventListener("transitionend",L,!1)),window.addEventListener("resize",L,!1)):window.onresize=function(){e()}}}}})}(ionic),function(t){"use strict";t.views.TabBarItem=t.views.View.inherit({initialize:function(t){this.el=t,this._buildItem()},create:function(e){var i=document.createElement("a");if(i.className="tab-item",e.icon){var n=document.createElement("i");n.className=e.icon,i.appendChild(n)}if(e.badge){var r=document.createElement("i");r.className="badge",r.innerHTML=e.badge,i.appendChild(r),i.className="tab-item has-badge"}return i.appendChild(document.createTextNode(e.title)),new t.views.TabBarItem(i)},_buildItem:function(){for(var e,i=this,n=Array.prototype.slice.call(this.el.children),r=0,o=n.length;o>r;r++)e=n[r],"i"==e.tagName.toLowerCase()&&/icon/.test(e.className)&&(this.icon=e.className),"i"==e.tagName.toLowerCase()&&/badge/.test(e.className)&&(this.badge=e.textContent.trim());for(this.title="",r=0,o=this.el.childNodes.length;o>r;r++)e=this.el.childNodes[r],"#text"===e.nodeName&&(this.title+=e.nodeValue.trim());this._tapHandler=function(t){i.onTap&&i.onTap(t)},t.on("tap",this._tapHandler,this.el)},onTap:function(){},destroy:function(){t.off("tap",this._tapHandler,this.el)},getIcon:function(){return this.icon},getTitle:function(){return this.title},getBadge:function(){return this.badge},setSelected:function(t){this.isSelected=t,t?this.el.classList.add("active"):this.el.classList.remove("active")}}),t.views.TabBar=t.views.View.inherit({initialize:function(t){this.el=t.el,this.items=[],this._buildItems()},getItems:function(){return this.items},addItem:function(e){var i=t.views.TabBarItem.prototype.create(e);this.appendItemElement(i),this.items.push(i),this._bindEventsOnItem(i)},appendItemElement:function(t){this.el&&this.el.appendChild(t.el)},removeItem:function(t){var e=this.items[t];e&&(e.onTap=void 0,e.destroy())},_bindEventsOnItem:function(t){var e=this;this._itemTapHandler||(this._itemTapHandler=function(){e.trySelectItem(this)}),t.onTap=this._itemTapHandler},getSelectedItem:function(){return this.selectedItem},setSelectedItem:function(t){this.selectedItem=this.items[t];for(var e=0,i=this.items.length;i>e;e+=1)this.items[e].setSelected(!1);this.selectedItem&&this.selectedItem.setSelected(!0)},selectItem:function(t){for(var e=0,i=this.items.length;i>e;e+=1)if(this.items[e]==t)return void this.setSelectedItem(e)},trySelectItem:function(t){for(var e=0,i=this.items.length;i>e;e+=1)if(this.items[e]==t)return void(this.tryTabSelect&&this.tryTabSelect(e))},_buildItems:function(){for(var e,i=Array.prototype.slice.call(this.el.children),n=0,r=i.length;r>n;n+=1)e=new t.views.TabBarItem(i[n]),this.items[n]=e,this._bindEventsOnItem(e);this.items.length>0&&(this.selectedItem=this.items[0])},destroy:function(){for(var t=0,e=this.items.length;e>t;t+=1)this.items[t].destroy();this.items.length=0}})}(window.ionic),function(t){"use strict";t.views.Toggle=t.views.View.inherit({initialize:function(e){var i=this;this.el=e.el,this.checkbox=e.checkbox,this.track=e.track,this.handle=e.handle,this.openPercent=-1,this.onChange=e.onChange||function(){},this.triggerThreshold=e.triggerThreshold||20,this.dragStartHandler=function(t){i.dragStart(t)},this.dragHandler=function(t){i.drag(t)},this.holdHandler=function(t){i.hold(t)},this.releaseHandler=function(t){i.release(t)},this.dragStartGesture=t.onGesture("dragstart",this.dragStartHandler,this.el),this.dragGesture=t.onGesture("drag",this.dragHandler,this.el),this.dragHoldGesture=t.onGesture("hold",this.holdHandler,this.el),this.dragReleaseGesture=t.onGesture("release",this.releaseHandler,this.el)},destroy:function(){t.offGesture(this.dragStartGesture,"dragstart",this.dragStartGesture),t.offGesture(this.dragGesture,"drag",this.dragGesture),t.offGesture(this.dragHoldGesture,"hold",this.holdHandler),t.offGesture(this.dragReleaseGesture,"release",this.releaseHandler)},tap:function(){"disabled"!==this.el.getAttribute("disabled")&&this.val(!this.checkbox.checked)},dragStart:function(t){this.checkbox.disabled||(this._dragInfo={width:this.el.offsetWidth,left:this.el.offsetLeft,right:this.el.offsetLeft+this.el.offsetWidth,triggerX:this.el.offsetWidth/2,initialState:this.checkbox.checked},t.gesture.srcEvent.preventDefault(),this.hold(t))},drag:function(e){var i=this;this._dragInfo&&(e.gesture.srcEvent.preventDefault(),t.requestAnimationFrame(function(){var t=(i.track.offsetLeft+i.handle.offsetWidth/2,i.track.offsetLeft+i.track.offsetWidth-i.handle.offsetWidth/2,e.gesture.deltaX,e.gesture.touches[0].pageX-i._dragInfo.left),n=i._dragInfo.width-i.triggerThreshold;i._dragInfo.initialState?ti._dragInfo.triggerX&&i.setOpenPercent(100):tn&&i.setOpenPercent(100)}))},endDrag:function(){this._dragInfo=null},hold:function(){this.el.classList.add("dragging")},release:function(t){this.el.classList.remove("dragging"),this.endDrag(t)},setOpenPercent:function(e){if(this.openPercent<0||ethis.openPercent+3)if(this.openPercent=e,0===e)this.val(!1);else if(100===e)this.val(!0);else{var i=Math.round(e/100*this.track.offsetWidth-this.handle.offsetWidth);i=1>i?0:i,this.handle.style[t.CSS.TRANSFORM]="translate3d("+i+"px,0,0)"}},val:function(e){return(e===!0||e===!1)&&(""!==this.handle.style[t.CSS.TRANSFORM]&&(this.handle.style[t.CSS.TRANSFORM]=""),this.checkbox.checked=e,this.openPercent=e?100:0,this.onChange&&this.onChange()),this.checkbox.checked}})}(ionic),function(t){"use strict";t.controllers.ViewController=function(){this.initialize.apply(this,arguments)},t.controllers.ViewController.inherit=t.inherit,t.extend(t.controllers.ViewController.prototype,{initialize:function(){},destroy:function(){}})}(window.ionic),function(t){"use strict";t.controllers.NavController=t.controllers.ViewController.inherit({initialize:function(t){var e=this;this.navBar=t.navBar,this.content=t.content,this.controllers=t.controllers||[],this._updateNavBar(),this.navBar.shouldGoBack=function(){e.pop()}},getControllers:function(){return this.controllers},getTopController:function(){return this.controllers[this.controllers.length-1]},push:function(t){var e=this.controllers[this.controllers.length-1];this.controllers.push(t);var i=this.switchingController&&this.switchingController(t)||!0;if(i!==!1){e&&(e.isVisible=!1,e.visibilityChanged&&e.visibilityChanged("push"));var n=this.controllers[this.controllers.length-1];return n.isVisible=!0,n.visibilityChanged&&n.visibilityChanged(e?"push":"first"),this._updateNavBar(),t}},pop:function(){var t,e;if(!(this.controllers.length<2))return e=this.controllers.pop(),e&&(e.isVisible=!1,e.visibilityChanged&&e.visibilityChanged("pop")),t=this.controllers[this.controllers.length-1],t.isVisible=!0,t.visibilityChanged&&t.visibilityChanged("pop"),this._updateNavBar(),e},showNavBar:function(){this.navBar&&this.navBar.show()},hideNavBar:function(){this.navBar&&this.navBar.hide()},_updateNavBar:function(){this.getTopController()&&this.navBar&&(this.navBar.setTitle(this.getTopController().title),this.navBar.showBackButton(this.controllers.length>1?!0:!1))}})}(window.ionic),function(t){"use strict";t.controllers.SideMenuController=t.controllers.ViewController.inherit({initialize:function(t){var e=this;this.left=t.left,this.right=t.right,this.content=t.content,this.dragThresholdX=t.dragThresholdX||10,this._rightShowing=!1,this._leftShowing=!1,this._isDragging=!1,this.content&&(this.content.onDrag=function(t){e._handleDrag(t)},this.content.onEndDrag=function(t){e._endDrag(t)})},setContent:function(t){var e=this;this.content=t,this.content.onDrag=function(t){e._handleDrag(t)},this.content.endDrag=function(t){e._endDrag(t)}},isOpenLeft:function(){return this.getOpenAmount()>0},isOpenRight:function(){return this.getOpenAmount()<0},toggleLeft:function(t){var e=this.getOpenAmount();0===arguments.length&&(t=0>=e),this.content.enableAnimation(),this.openPercentage(t?100:0)},toggleRight:function(t){var e=this.getOpenAmount();0===arguments.length&&(t=e>=0),this.content.enableAnimation(),this.openPercentage(t?-100:0)},close:function(){this.openPercentage(0)},getOpenAmount:function(){return this.content&&this.content.getTranslateX()||0},getOpenRatio:function(){var t=this.getOpenAmount();return t>=0?t/this.left.width:t/this.right.width},isOpen:function(){return 1==this.getOpenRatio()},getOpenPercentage:function(){return 100*this.getOpenRatio()},openPercentage:function(t){var e=t/100;if(this.left&&t>=0)this.openAmount(this.left.width*e);else if(this.right&&0>t){{this.right.width}this.openAmount(this.right.width*e)}},openAmount:function(t){var e=this.left&&this.left.width||0,i=this.right&&this.right.width||0;return(this.left&&this.left.isEnabled||!(t>0))&&(this.right&&this.right.isEnabled||!(0>t))?this._leftShowing&&t>e?void this.content.setTranslateX(e):this._rightShowing&&-i>t?void this.content.setTranslateX(-i):(this.content.setTranslateX(t),void(t>=0?(this._leftShowing=!0,this._rightShowing=!1,t>0&&(this.right&&this.right.pushDown&&this.right.pushDown(),this.left&&this.left.bringUp&&this.left.bringUp())):(this._rightShowing=!0,this._leftShowing=!1,this.right&&this.right.bringUp&&this.right.bringUp(),this.left&&this.left.pushDown&&this.left.pushDown()))):void this.content.setTranslateX(0)},snapToRest:function(t){this.content.enableAnimation(),this._isDragging=!1;var e=this.getOpenRatio();if(0===e)return void this.openPercentage(0);var i=.3,n=t.gesture.velocityX,r=t.gesture.direction;this.openPercentage(e>0&&.5>e&&"right"==r&&i>n?0:e>.5&&"left"==r&&i>n?100:0>e&&e>-.5&&"left"==r&&i>n?0:.5>e&&"right"==r&&i>n?-100:"right"==r&&e>=0&&(e>=.5||n>i)?100:"left"==r&&0>=e&&(-.5>=e||n>i)?-100:0)},_endDrag:function(t){this._isDragging&&this.snapToRest(t),this._startX=null,this._lastX=null,this._offsetX=null},_handleDrag:function(t){this._startX?this._lastX=t.gesture.touches[0].pageX:(this._startX=t.gesture.touches[0].pageX,this._lastX=this._startX),!this._isDragging&&Math.abs(this._lastX-this._startX)>this.dragThresholdX&&(this._startX=this._lastX,this._isDragging=!0,this.content.disableAnimation(),this._offsetX=this.getOpenAmount()),this._isDragging&&this.openAmount(this._offsetX+(this._lastX-this._startX))}})}(ionic),function(t){"use strict";t.controllers.TabBarController=t.controllers.ViewController.inherit({initialize:function(t){this.tabBar=t.tabBar,this._bindEvents(),this.controllers=[];for(var e=t.controllers||[],i=0;i=this.controllers.length)){var e=this.selectedController,i=this.selectedIndex;this.selectedController=this.controllers[t],this.selectedIndex=t,this._showController(t),this.tabBar.setSelectedItem(t),this.controllerChanged&&this.controllerChanged(e,i,this.selectedController,this.selectedIndex)}},_showController:function(t){for(var e,i=0,n=this.controllers.length;n>i;i++)e=this.controllers[i],e.isVisible=!1,e.visibilityChanged&&e.visibilityChanged();e=this.controllers[t],e.isVisible=!0,e.visibilityChanged&&e.visibilityChanged()},_clearSelected:function(){this.selectedController=null,this.selectedIndex=-1},getController:function(t){return this.controllers[t]},getControllers:function(){return this.controllers},getSelectedController:function(){return this.selectedController},getSelectedControllerIndex:function(){return this.selectedIndex},addController:function(t){this.controllers.push(t),this.tabBar.addItem({title:t.title,icon:t.icon,badge:t.badge}),this.selectedController||this.setSelectedController(0)},setControllers:function(t){this.controllers=t,this._clearSelected(),this.selectController(0)}})}(window.ionic)}(); /*! * ionic.bundle.js is a concatenation of: * ionic.js, angular.js, angular-animate.js, @@ -307,7 +307,7 @@ n=document.createElement("pre"),M=/^(\s*)([\s\S]*?)(\s*)$/;h.module("ngSanitize" * Copyright 2014 Drifty Co. * http://drifty.com/ * - * Ionic, v0.9.27 + * Ionic, v1.0.0-beta.1 * A powerful HTML5 mobile app framework. * http://ionicframework.com/ * @@ -317,5 +317,5 @@ n=document.createElement("pre"),M=/^(\s*)([\s\S]*?)(\s*)$/;h.module("ngSanitize" * */ -function $LocationDecorator(e,t){return e.__hash=e.hash,e.hash=function(n){return angular.isDefined(n)&&t(function(){var e=document.querySelector(".scroll-content");e&&(e.scrollTop=0)},0,!1),e.__hash(n)},e}angular.module("ionic.service",["ionic.service.bind","ionic.service.platform","ionic.service.actionSheet","ionic.service.gesture","ionic.service.loading","ionic.service.modal","ionic.service.popup","ionic.service.templateLoad","ionic.service.view","ionic.decorator.location"]),angular.module("ionic.ui.service",["ionic.ui.service.scrollDelegate","ionic.ui.service.slideBoxDelegate","ionic.ui.service.sideMenuDelegate"]),angular.module("ionic.ui",["ionic.ui.content","ionic.ui.scroll","ionic.ui.tabs","ionic.ui.viewState","ionic.ui.header","ionic.ui.sideMenu","ionic.ui.slideBox","ionic.ui.list","ionic.ui.checkbox","ionic.ui.toggle","ionic.ui.radio","ionic.ui.touch","ionic.ui.popup"]),angular.module("ionic",["ionic.service","ionic.ui.service","ionic.ui","ngAnimate","ngSanitize","ui.router"]),angular.element.prototype.addClass=function(e){var t,n,i,o,r,a;if(e&&"ng-scope"!=e&&"ng-isolate-scope"!=e)for(t=0;t')(c),s=angular.element(l[0].querySelector(".action-sheet-wrapper")),u=function(e){s.removeClass("action-sheet-up"),e&&o(function(){r.cancel()},200),i.removeClass(l,"active",function(){c.$destroy()}),t[0].body.classList.remove("action-sheet-open"),c.$deregisterBackButton&&c.$deregisterBackButton()};c.$deregisterBackButton=a.registerBackButtonAction(function(){u()},300),c.cancel=function(){u(!0)},c.buttonClicked=function(e){(r.buttonClicked&&r.buttonClicked(e))===!0&&u(!1)},c.destructiveButtonClicked=function(){(r.destructiveButtonClicked&&r.destructiveButtonClicked())===!0&&u(!1)},t[0].body.appendChild(l[0]),t[0].body.classList.add("action-sheet-open");var d=new ionic.views.ActionSheet({el:l[0]});return c.sheet=d,i.addClass(l,"active"),o(function(){s.addClass("action-sheet-up")},20),d}}}]),angular.module("ionic.service.bind",[]).factory("$ionicBind",["$parse","$interpolate",function(e,t){var n=/^\s*([@=&])(\??)\s*(\w*)\s*$/;return function(i,o,r){angular.forEach(r||{},function(r,a){var c,l,s=r.match(n)||[],u=s[3]||a,d=s[1];switch(d){case"@":if(!o[u])return;o.$observe(u,function(e){i[a]=e}),o[u]&&(i[a]=t(o[u])(i));break;case"=":if(!o[u])return;l=i.$watch(o[u],function(e){i[a]=e}),i.$on("$destroy",l);break;case"&":if(o[u]&&o[u].match(RegExp(a+"(.*?)")))throw new Error('& expression binding "'+a+'" looks like it will recursively call "'+o[u]+'" and cause a stack overflow! Please choose a different scopeName.');c=e(o[u]),i[a]=function(e){return c(i,e)}}})}}]),angular.module("ionic.service.gesture",[]).factory("$ionicGesture",[function(){return{on:function(e,t,n){return window.ionic.onGesture(e,t,n[0])},off:function(e,t,n){return window.ionic.offGesture(e,t,n)}}}]),angular.module("ionic.service.loading",["ionic.ui.loading"]).factory("$ionicLoading",["$rootScope","$document","$compile",function(e,t,n){return{show:function(i){var o={content:"",animation:"fade-in",showBackdrop:!0,maxWidth:200,showDelay:0};i=angular.extend(o,i);var r=e.$new(!0);angular.extend(r,i);var a=angular.element(t[0].querySelector(".loading-backdrop"));a.length&&a.remove();var c=n(""+i.content+"")(r);t[0].body.appendChild(c[0]);var l=new ionic.views.Loading({el:c[0],maxWidth:i.maxWidth,showDelay:i.showDelay});return l.show(),r.loading=l,l}}}]),angular.module("ionic.service.modal",["ionic.service.templateLoad","ionic.service.platform","ionic.ui.modal"]).factory("$ionicModal",["$rootScope","$document","$compile","$timeout","$ionicPlatform","$ionicTemplateLoader",function(e,t,n,i,o,r){var a=ionic.views.Modal.inherit({initialize:function(e){ionic.views.Modal.prototype.initialize.call(this,e),this.animation=e.animation||"slide-in-up"},show:function(){var e=this,n=angular.element(e.modalEl);e.el.classList.remove("hide"),t[0].body.classList.add("modal-open"),e._isShown=!0,e.el.parentElement||(n.addClass(e.animation),t[0].body.appendChild(e.el)),n.addClass("ng-enter active").removeClass("ng-leave ng-leave-active"),i(function(){n.addClass("ng-enter-active"),e.scope.$parent&&e.scope.$parent.$broadcast("modal.shown"),e.el.classList.add("active")},20),e._deregisterBackButton=o.registerBackButtonAction(function(){e.hide()},200),ionic.views.Modal.prototype.show.call(e)},hide:function(){var e=this;e._isShown=!1;var n=angular.element(e.modalEl);e.el.classList.remove("active"),n.addClass("ng-leave"),i(function(){n.addClass("ng-leave-active").removeClass("ng-enter ng-enter-active active")},20),i(function(){t[0].body.classList.remove("modal-open"),e.el.classList.add("hide")},350),ionic.views.Modal.prototype.hide.call(e),e.scope.$parent&&e.scope.$parent.$broadcast("modal.hidden"),e._deregisterBackButton&&e._deregisterBackButton()},remove:function(){var e=this;e.hide(),e.scope.$parent&&e.scope.$parent.$broadcast("modal.removed"),i(function(){e.scope.$destroy(),e.el&&e.el.parentElement&&e.el.parentElement.removeChild(e.el)},750)},isShown:function(){return!!this._isShown}}),c=function(t,i){var o=i.scope&&i.scope.$new()||e.$new(!0),r=n(""+t+"")(o);i.el=r[0],i.modalEl=i.el.querySelector(".modal");var c=new a(i);return c.scope=o,i.scope||(o.modal=c),c};return{fromTemplate:function(e,t){var n=c(e,t||{});return n},fromTemplateUrl:function(e,t,n){var i;return angular.isFunction(t)&&(i=t,t=n),r.load(e).then(function(e){var n=c(e,t||{});return i&&i(n),n})}}}]),function(e){"use strict";angular.module("ionic.service.platform",[]).provider("$ionicPlatform",function(){return{$get:["$q","$rootScope",function(t,n){return{onHardwareBackButton:function(t){e.Platform.ready(function(){document.addEventListener("backbutton",t,!1)})},offHardwareBackButton:function(t){e.Platform.ready(function(){document.removeEventListener("backbutton",t)})},registerBackButtonAction:function(t,i,o){var r=this;r._hasBackButtonHandler||(n.$backButtonActions={},r.onHardwareBackButton(r.hardwareBackButtonClick),r._hasBackButtonHandler=!0);var a={id:o?o:e.Utils.nextUid(),priority:i?i:0,fn:t};return n.$backButtonActions[a.id]=a,function(){delete n.$backButtonActions[a.id]}},hardwareBackButtonClick:function(e){var t,i;for(i in n.$backButtonActions)(!t||n.$backButtonActions[i].priority>=t.priority)&&(t=n.$backButtonActions[i]);return t?(t.fn(e),t):void 0},is:function(t){return e.Platform.is(t)},ready:function(n){var i=t.defer();return e.Platform.ready(function(){i.resolve(),n()}),i.promise}}}]}})}(ionic),function(e){"use strict";angular.module("ionic.service.popup",["ionic.service.templateLoad"]).factory("$ionicPopup",["$rootScope","$q","$document","$compile","$timeout","$ionicTemplateLoader",function(t,n,i,o,r,a){var c={stackPushDelay:50},l=function(e){e.el.style.marginLeft=-e.el.offsetWidth/2+"px",e.el.style.marginTop=-e.el.offsetHeight/2+"px"},s=function(e){var t=e.el.querySelector(".popup-body");t&&""==t.innerHTML.trim()&&(t.style.display="none")},u=function(t){e.requestAnimationFrame(function(){s(t),l(t),t.el.classList.remove("popup-hidden"),t.el.classList.add("popup-showing"),t.el.classList.add("active")})},d=function(t){e.requestAnimationFrame(function(){t.el.classList.remove("popup-hidden"),t.el.classList.add("popup-showing"),t.el.classList.add("active")})},f=function(t){e.requestAnimationFrame(function(){t.el.classList.remove("active"),t.el.classList.add("popup-hidden")})},v=function(e){e.el.offsetWidth,e.el.classList.remove("active"),e.el.classList.add("popup-hidden"),r(function(){e.el.remove()},400)},p=[],g=null,h=function(){var e=o("")(t.$new(!0));i[0].body.appendChild(e[0]),g=e},m=function(){g.remove()},$=function(e){var t=p[p.length-1];p.push(e),1==p.length&&h(),t?(f(t),r(function(){u(e)},c.stackPushDelay)):u(e)},b=function(){var e=p.pop(),t=p[p.length-1];v(e),t?d(t):m()},w=function(e,t){var n={el:e[0],scope:t};return t.popup=n,n},y=function(e,t){return''+(t||"")+""},k=function(e,r){var c=n.defer(),l={title:"",animation:"fade-in"};e=angular.extend(l,e);var s=e.scope&&e.scope.$new()||t.$new(!0);if(angular.extend(s,e),s.onClose=function(e,t){b(s.popup),r.resolve(t)},e.templateUrl)a.load(e.templateUrl).then(function(t){var n=y(e,t),r=o(n)(s);i[0].body.appendChild(r[0]),c.resolve(w(r,s))},function(e){c.reject(e)});else{var u=y(e,e.content),d=o(u)(s);i[0].body.appendChild(d[0]),c.resolve(w(d,s))}return c.promise};return{showPopup:function(e){var t=n.defer();return k(e,t).then(function(t){$(t,e)},function(e){console.error("Unable to load popup:",e)}),t.promise},show:function(e){return this.showPopup(e)},alert:function(e){return this.showPopup({content:e.content||"",title:e.title||"",buttons:[{text:e.okText||"OK",type:e.okType||"button-positive",onTap:function(){return!0}}]})},confirm:function(e){return this.showPopup({content:e.content||"",title:e.title||"",buttons:[{text:e.cancelText||"Cancel",type:e.cancelType||"button-default",onTap:function(e){e.preventDefault()}},{text:e.okText||"OK",type:e.okType||"button-positive",onTap:function(){return!0}}]})},prompt:function(e){var n=t.$new(!0);return n.data={},this.showPopup({content:e.content||'',title:e.title||"",subTitle:e.subTitle||"",scope:n,buttons:[{text:e.cancelText||"Cancel",type:e.cancelType||"button-default",onTap:function(e){e.preventDefault()}},{text:e.okText||"OK",type:e.okType||"button-positive",onTap:function(){return n.data.response}}]})}}}])}(ionic),angular.module("ionic.service.templateLoad",[]).factory("$ionicTemplateLoader",["$q","$http","$templateCache",function(e,t,n){return{load:function(e){return t.get(e,{cache:n}).then(function(e){return e.data&&e.data.trim()})}}}]),angular.module("ionic.service.view",["ui.router","ionic.service.platform"]).run(["$rootScope","$state","$location","$document","$animate","$ionicPlatform",function(e,t,n,i,o,r){function a(t){return e.$viewHistory.backView?e.$viewHistory.backView.go():ionic.Platform.exitApp(),t.preventDefault(),!1}e.$viewHistory={histories:{root:{historyId:"root",parentHistoryId:null,stack:[],cursor:-1}},views:{},backView:null,forwardView:null,currentView:null,disabledRegistrableTagNames:[]},e.$on("viewState.changeHistory",function(i,o){if(o){var r=o.historyId?e.$viewHistory.histories[o.historyId]:null;if(r&&r.cursor>-1&&r.cursor-1&&c.stack.length>0&&c.cursor=u.index;p--)v.stack[p].destroy(),v.stack.splice(p)}}else d.navAction="initialView";o.views[d.viewId]=this.createView({viewId:d.viewId,index:c.stack.length,historyId:c.historyId,backViewId:l&&l.viewId?l.viewId:null,forwardViewId:null,stateId:a,stateName:this.getCurrentStateName(),stateParams:this.getCurrentStateParams(),url:n.url(),scrollValues:null}),c.stack.push(o.views[d.viewId])}return this.setNavViews(d.viewId),c.cursor=o.currentView.index,d},setNavViews:function(t){var n=e.$viewHistory;n.currentView=this._getViewById(t),n.backView=this._getBackView(n.currentView),n.forwardView=this._getForwardView(n.currentView),e.$broadcast("$viewHistory.historyChange",{showBack:n.backView&&n.backView.historyId===n.currentView.historyId})},registerHistory:function(e){e.$historyId=ionic.Utils.nextUid()},createView:function(e){var t=new c;return t.initialize(e)},getCurrentView:function(){return e.$viewHistory.currentView},getBackView:function(){return e.$viewHistory.backView},getForwardView:function(){return e.$viewHistory.forwardView},getNavDirection:function(){return e.$viewHistory.navDirection},getCurrentStateName:function(){return t&&t.current?t.current.name:null},isCurrentStateNavView:function(e){return t&&t.current&&t.current.views&&t.current.views[e]?!0:!1},getCurrentStateParams:function(){var e;if(t&&t.params)for(var n in t.params)t.params.hasOwnProperty(n)&&(e=e||{},e[n]=t.params[n]);return e},getCurrentStateId:function(){var e;if(t&&t.current&&t.current.name){if(e=t.current.name,t.params)for(var n in t.params)t.params.hasOwnProperty(n)&&t.params[n]&&(e+="_"+n+"="+t.params[n]);return e}return ionic.Utils.nextUid()},goToHistoryRoot:function(t){if(t){var n=e.$viewHistory.histories[t];if(n&&n.stack.length){if(e.$viewHistory.currentView&&e.$viewHistory.currentView.viewId===n.stack[0].viewId)return;e.$viewHistory.forcedNav={viewId:n.stack[0].viewId,navAction:"moveBack",navDirection:"back"},n.stack[0].go()}}},_getViewById:function(t){return t?e.$viewHistory.views[t]:null},_getBackView:function(e){return e?this._getViewById(e.backViewId):null},_getForwardView:function(e){return e?this._getViewById(e.forwardViewId):null},_getHistoryById:function(t){return t?e.$viewHistory.histories[t]:null},_getHistory:function(t){var n=this._getParentHistoryObj(t);return e.$viewHistory.histories[n.historyId]||(e.$viewHistory.histories[n.historyId]={historyId:n.historyId,parentHistoryId:this._getParentHistoryObj(n.scope.$parent).historyId,stack:[],cursor:-1}),e.$viewHistory.histories[n.historyId]},_getParentHistoryObj:function(t){for(var n=t;n;){if(n.hasOwnProperty("$historyId"))return{historyId:n.$historyId,scope:n};n=n.$parent}return{historyId:"root",scope:e}},getRenderer:function(e,t,n){function i(e){for(var t="";!t&&e;)t=e.getAttribute("animation"),e=e.parentElement;return t}function o(){s&&e[0].classList.add(s),"back"===r.navDirection?e[0].classList.add("reverse"):e[0].classList.remove("reverse")}var r,c,l=this,s=angular.isDefined(n.$nextAnimation)?n.$nextAnimation:i(e[0]);return n.$nextAnimation=void 0,function(t){return{enter:function(n){return c&&t?(o(),n.addClass("ng-enter"),document.body.classList.add("disable-pointer-events"),void a.enter(n,e,null,function(){document.body.classList.remove("disable-pointer-events"),s&&e[0].classList.remove(s)})):void e.append(n)},leave:function(){var n=e.contents();return c&&t?(o(),void a.leave(n,function(){n.remove()})):void n.remove()},register:function(e){return r=l.register(n,e),c=null!==s&&null!==r.navDirection,r}}}},disableRegisterByTagName:function(t){e.$viewHistory.disabledRegistrableTagNames.push(t.toUpperCase())},isTagNameRegistrable:function(t){var n,i,o=e.$viewHistory.disabledRegistrableTagNames;for(n=0;n
{{titleText}}
'}}])}(),function(e){"use strict";angular.module("ionic.ui.header",["ngAnimate","ngSanitize"]).directive("barHeader",["$ionicScrollDelegate",function(e){return{restrict:"C",link:function(t,n){e.tapScrollToTop(n)}}}]).directive("ionHeaderBar",["$ionicScrollDelegate",function(){return{restrict:"E",replace:!0,transclude:!0,template:'

',scope:{leftButtons:"=",rightButtons:"=",title:"@",type:"@",alignTitle:"@"},link:function(t,n){var i=new e.views.HeaderBar({el:n[0],alignTitle:t.alignTitle||"center"});n.addClass(t.type),t.headerBarView=i,t.$watchCollection("leftButtons",function(){i.align()}),t.$watchCollection("rightButtons",function(){i.align()}),t.$watch("title",function(){i.align()})}}}]).directive("ionFooterBar",function(){return{restrict:"E",replace:!0,transclude:!0,template:'
',scope:{type:"@"},link:function(e,t){t.addClass(e.type)}}})}(ionic),function(){"use strict";angular.module("ionic.ui.checkbox",[]).directive("ionCheckbox",function(){return{restrict:"E",replace:!0,require:"?ngModel",scope:{ngModel:"=?",ngValue:"=?",ngChecked:"=?",ngChange:"&"},transclude:!0,template:'
',compile:function(e,t){var n=e.find("input");t.name&&n.attr("name",t.name),t.ngChecked&&n.attr("ng-checked","ngChecked"),t.ngTrueValue&&n.attr("ng-true-value",t.ngTrueValue),t.ngFalseValue&&n.attr("ng-false-value",t.ngFalseValue)}}})}(),function(){"use strict";angular.module("ionic.ui.content",["ionic.ui.service","ionic.ui.scroll"]).directive("ionPane",function(){return{restrict:"E",link:function(e,t){t.addClass("pane")}}}).directive("ionContent",["$parse","$timeout","$ionicScrollDelegate","$controller","$ionicBind",function(e,t,n,i,o){return{restrict:"E",replace:!0,transclude:!0,require:"^?ionNavView",scope:!0,template:'
',compile:function(e,n,r){function a(e,a,c){var l,s,u=angular.element(a[0].querySelector(".scroll"));o(e,c,{$onScroll:"&onScroll",$onScrollComplete:"&onScrollComplete",hasBouncing:"@",scroll:"@",padding:"@",hasScrollX:"@",hasScrollY:"@",scrollbarX:"@",scrollbarY:"@",startX:"@",startY:"@",scrollEventInterval:"@"}),"false"===e.scroll||("true"===n.overflowScroll?a.addClass("overflow-scroll"):(s=i("$ionicScroll",{$scope:e,scrollViewOptions:{el:a[0],bouncing:e.$eval(e.hasBouncing),startX:e.$eval(e.startX)||0,startY:e.$eval(e.startY)||0,scrollbarX:e.$eval(e.scrollbarX)!==!1,scrollbarY:e.$eval(e.scrollbarY)!==!1,scrollingX:e.$eval(e.hasScrollX)===!0,scrollingY:e.$eval(e.hasScrollY)!==!1,scrollEventInterval:parseInt(e.scrollEventInterval,10)||20,scrollingComplete:function(){e.$onScrollComplete({scrollTop:this.__scrollTop,scrollLeft:this.__scrollLeft})}}}),l=e.$parent.scrollView=s.scrollView,e.$on("$viewContentLoaded",function(n,i){i||(i={});var o=i.scrollValues;o&&t(function(){l.scrollTo(+o.left||null,+o.top||null)},0),e.$on("$destroy",function(){i.scrollValues=l.getValues()})}))),r(e,function(e){s&&e.data("$$ionicScrollController",s),u.append(e)})}return"true"==n.hasHeader&&e.addClass("has-header"),"true"==n.hasSubheader&&e.addClass("has-subheader"),"true"==n.hasFooter&&e.addClass("has-footer"),"true"==n.hasTabs&&e.addClass("has-tabs"),"true"==n.padding&&e.find("div").addClass("padding"),{pre:a}}}}]).directive("ionRefresher",["$ionicBind",function(e){return{restrict:"E",replace:!0,require:"^$ionicScroll",template:'
',compile:function(t,n){return angular.isUndefined(n.pullingIcon)&&n.$set("pullingIcon","ion-arrow-down-c"),angular.isUndefined(n.refreshingIcon)&&n.$set("refreshingIcon","ion-loading-d"),function(t,n,i,o){e(t,i,{pullingIcon:"@",pullingText:"@",refreshingIcon:"@",refreshingText:"@",$onRefresh:"&onRefresh",$onPulling:"&onPulling"}),o.setRefresher(t,n[0]),t.$on("scroll.refreshComplete",function(){n[0].classList.remove("active"),o.scrollView.finishPullToRefresh()})}}}}]).directive("ionInfiniteScroll",["$timeout",function(e){return{restrict:"E",require:["^$ionicScroll","ionInfiniteScroll"],template:'
',scope:!0,controller:["$scope","$attrs",function(e,t){this.isLoading=!1,this.scrollView=null,this.getMaxScroll=function(){var e=t.distance||"1%";return e.indexOf("%")>-1?this.scrollView.getScrollMax().top*(1-parseInt(e,10)/100):this.scrollView.getScrollMax().top-parseInt(e,10)}}],link:function(t,n,i,o){var r=o[0],a=o[1],c=a.scrollView=r.scrollView;t.icon=function(){return angular.isDefined(i.icon)?i.icon:"ion-loading-d"},t.$on("scroll.infiniteScrollComplete",function(){n[0].classList.remove("active"),e(function(){c.resize()},0,!1),a.isLoading=!1}),r.$element.on("scroll",ionic.animationFrameThrottle(function(){!a.isLoading&&c.getValues().top>=a.getMaxScroll()&&(n[0].classList.add("active"),a.isLoading=!0,t.$parent.$apply(i.onInfinite||""))}))}}}])}(),function(){"use strict";angular.module("ionic.ui.list",["ngAnimate"]).directive("ionItem",["$timeout","$parse",function(){return{restrict:"E",require:"?^ionList",replace:!0,transclude:!0,scope:{item:"=",itemType:"@",canDelete:"@",canReorder:"@",canSwipe:"@",onDelete:"&",optionButtons:"&",deleteIcon:"@",reorderIcon:"@"},template:'
',link:function(e,t,n,i){if(i){var o=i.scope,r=i.attrs;n.$observe("href",function(t){t&&(e.href=t.trim())}),e.itemType||(e.itemType=o.itemType),t.addClass(e.itemType||o.itemType),e.itemClass=e.itemType,"false"!==(n.canDelete?e.canDelete:o.canDelete)&&(n.onDelete||r.onDelete)&&(e.deleteClick=function(){n.onDelete?e.onDelete({item:e.item}):r.onDelete&&o.onDelete({item:e.item})},e.deleteIconClass=e.deleteIcon||o.deleteIcon||"ion-minus-circled"),"true"===(n.canReorder?e.canReorder:o.canReorder)&&(e.reorderIconClass=e.reorderIcon||o.reorderIcon||"ion-navicon"),"false"!==(n.canSwipe?e.canSwipe:o.canSwipe)&&(e.itemOptionButtons=e.optionButtons(),"undefined"==typeof e.itemOptionButtons&&(e.itemOptionButtons=o.optionButtons()))}}}}]).directive("ionList",["$timeout",function(e){return{restrict:"E",replace:!0,transclude:!0,require:"^?$ionicScroll",scope:{itemType:"@",canDelete:"@",canReorder:"@",canSwipe:"@",showDelete:"=",showReorder:"=",onDelete:"&",onReorder:"&",optionButtons:"&",deleteIcon:"@",reorderIcon:"@"},template:"
",controller:["$scope","$attrs",function(e,t){this.scope=e,this.attrs=t}],link:function(t,n,i,o){t.listView=new ionic.views.ListView({el:n[0],listEl:n[0].children[0],scrollEl:o&&o.element,scrollView:o&&o.scrollView,onReorder:function(e,n,i){t.$apply(function(){t.onReorder({el:e,start:n,end:i})})}}),i.animation&&n[0].classList.add(i.animation);var r=t.$watch("showReorder",function(t){t?n[0].classList.add("item-options-hide"):t===!1&&e(function(){n[0].classList.remove("item-options-hide")},250)});t.$on("$destroy",function(){r()})}}}])}(),function(){"use strict";angular.module("ionic.ui.loading",[]).directive("ionLoading",function(){return{restrict:"E",replace:!0,transclude:!0,link:function(e,t){t.addClass(e.animation||"")},template:'
'}})}(),function(){"use strict";angular.module("ionic.ui.modal",[]).directive("ionModal",[function(){return{restrict:"E",transclude:!0,replace:!0,template:''}}])}(),function(){angular.module("ionic.ui.navAnimation",[]).directive("ionNavAnimation",function(){return{restrict:"A",require:"^?ionNavView",link:function(e,t,n,i){i&&ionic.on("tap",function(){i.setNextAnimation(n.ionNavAnimation)},t[0])}}})}(),function(){"use strict";angular.module("ionic.ui.popup",[]).directive("ionPopupBackdrop",function(){return{restrict:"E",replace:!0,template:''}}).directive("ionPopup",["$ionicBind",function(e){return{restrict:"E",replace:!0,transclude:!0,scope:!0,link:function(t,n,i){e(t,i,{title:"@",buttons:"=",$onButtonTap:"&onButtonTap",$onClose:"&onClose"}),t._buttonTapped=function(e,n){var i=e.onTap&&e.onTap(n); -return n.defaultPrevented?t.$onClose({button:e,result:!1,event:n}):i?t.$onClose({button:e,result:i,event:n}):void t.$onButtonTap({button:e,event:n})}},template:''}}])}(),function(e){"use strict";angular.module("ionic.ui.radio",[]).directive("ionRadio",function(){return{restrict:"E",replace:!0,require:"?ngModel",scope:{ngModel:"=?",ngValue:"=?",ngChange:"&",icon:"@"},transclude:!0,template:'',compile:function(e,t){t.name&&e.children().eq(0).attr("name",t.name),t.icon&&e.children().eq(2).removeClass("ion-checkmark").addClass(t.icon)}}}).directive("ionRadioButtons",function(){return{restrict:"E",replace:!0,require:"?ngModel",scope:{value:"@"},transclude:!0,template:'
',controller:["$scope","$element",function(e,t){this.select=function(e){for(var n,i=t.children(),o=0;o
',transclude:!0,scope:{direction:"@",paging:"@",onRefresh:"&",onScroll:"&",scroll:"@",scrollbarX:"@",scrollbarY:"@"},controller:function(){},compile:function(e,t){function i(e,i){var o,r,a=i[0].children[0];"true"==t.padding&&a.classList.add("padding"),e.$eval(e.paging)===!0&&a.classList.add("scroll-paging"),e.direction||(e.direction="y");var c=e.$eval(e.paging)===!0,l={el:i[0],paging:c,scrollbarX:e.$eval(e.scrollbarX)!==!1,scrollbarY:e.$eval(e.scrollbarY)!==!1,scrollingX:e.direction.indexOf("x")>=0,scrollingY:e.direction.indexOf("y")>=0};c&&(l.speedMultiplier=.8,l.bouncing=!1),r=n("$ionicScroll",{$scope:e,scrollViewOptions:l}),o=e.$parent.scrollView=r.scrollView}return{pre:i}}}}])}(),function(){"use strict";angular.module("ionic.ui.sideMenu",["ionic.service.gesture","ionic.service.view"]).run(["$ionicViewService",function(e){e.disableRegisterByTagName("ion-side-menus")}]).directive("ionSideMenus",function(){return{restrict:"ECA",controller:["$scope","$attrs","$parse",function(e,t,n){angular.extend(this,ionic.controllers.SideMenuController.prototype),ionic.controllers.SideMenuController.call(this,{left:{width:275},right:{width:275}}),e.sideMenuContentTranslateX=0,n(t.model||"sideMenuController").assign(e,this)}],replace:!0,transclude:!0,template:'
'}}).directive("ionSideMenuContent",["$timeout","$ionicGesture",function(e,t){return{restrict:"AC",require:"^ionSideMenus",scope:!0,compile:function(n,i){return function(n,o,r,a){function c(e){0!==a.getOpenAmount()&&(a.close(),e.gesture.srcEvent.preventDefault())}o.addClass("menu-content"),angular.isDefined(i.dragContent)?n.$watch(i.dragContent,function(e){n.dragContent=e}):n.dragContent=!0;var l=!1,s=!1;ionic.on("tap",c,o[0]);var u=function(e){if(n.dragContent){if(l||e.gesture.srcEvent.defaultPrevented)return;s=!0,a._handleDrag(e),e.gesture.srcEvent.preventDefault()}},d=function(e){s&&e.gesture.srcEvent.preventDefault()},f=t.on("dragright",u,o),v=t.on("dragleft",u,o),p=t.on("dragup",d,o),g=t.on("dragdown",d,o),h=function(e){s=!1,l||a._endDrag(e),l=!1},m=t.on("release",h,o);a.setContent({onDrag:function(){},endDrag:function(){},getTranslateX:function(){return n.sideMenuContentTranslateX||0},setTranslateX:ionic.animationFrameThrottle(function(t){o[0].style[ionic.CSS.TRANSFORM]="translate3d("+t+"px, 0, 0)",e(function(){n.sideMenuContentTranslateX=t})}),enableAnimation:function(){n.animationEnabled=!0,o[0].classList.add("menu-animated")},disableAnimation:function(){n.animationEnabled=!1,o[0].classList.remove("menu-animated")}}),n.$on("$destroy",function(){t.off(v,"dragleft",u),t.off(f,"dragright",u),t.off(p,"dragup",u),t.off(g,"dragdown",u),t.off(m,"release",h),ionic.off("tap",c,o[0])})}}}}]).directive("ionSideMenu",function(){return{restrict:"E",require:"^ionSideMenus",replace:!0,transclude:!0,scope:!0,template:'',compile:function(e,t,n){return angular.isUndefined(t.isEnabled)&&t.$set("isEnabled","true"),angular.isUndefined(t.width)&&t.$set("width","275"),function(e,t,i,o){e.side=i.side||"left";var r=o[e.side]=new ionic.views.SideMenu({width:275,el:t[0],isEnabled:!0});e.$watch(i.width,function(e){var t=+e;t&&t==e&&r.setWidth(+e)}),e.$watch(i.isEnabled,function(e){r.setIsEnabled(!!e)}),n(e,function(e){t.append(e)})}}}})}(),function(){"use strict";angular.module("ionic.ui.slideBox",[]).directive("ionSlideBox",["$timeout","$compile","$ionicSlideBoxDelegate",function(e,t,n){return{restrict:"E",replace:!0,transclude:!0,scope:{doesContinue:"@",slideInterval:"@",showPager:"@",disableScroll:"@",onSlideChanged:"&",activeSlide:"=?"},controller:["$scope","$element","$attrs","$parse",function(t,i,o,r){var a=t.$eval(t.doesContinue)===!0,c=a?t.$eval(t.slideInterval)||4e3:0,l=new ionic.views.Slider({el:i[0],auto:c,disableScroll:t.$eval(t.disableScroll)===!0||!1,continuous:a,startSlide:t.activeSlide,slidesChanged:function(){t.currentSlide=l.currentIndex(),e(function(){})},callback:function(n){t.currentSlide=n,t.onSlideChanged({index:t.currentSlide}),t.$parent.$broadcast("slideBox.slideChanged",n),t.activeSlide=n,e(function(){})}});t.$watch("activeSlide",function(e){angular.isDefined(e)&&l.slide(e)}),t.$on("slideBox.nextSlide",function(){l.next()}),t.$on("slideBox.prevSlide",function(){l.prev()}),t.$on("slideBox.setSlide",function(e,t){l.slide(t)}),r(o.model||"slideBoxController").assign(t.$parent,l),n.register(t,i),this.slidesCount=function(){return l.slidesCount()},e(function(){l.load()})}],template:'
',link:function(e,n){if(e.$eval(e.showPager)!==!1){var i=e.$new(),o=angular.element("");n.append(o),t(o)(i)}}}}]).directive("ionSlide",function(){return{restrict:"E",require:"^ionSlideBox",compile:function(e){return e.addClass("slider-slide"),function(){}}}}).directive("ionPager",function(){return{restrict:"E",replace:!0,require:"^ionSlideBox",template:'
',link:function(e,t,n,i){var o=function(e){for(var n=t[0].children,i=n.length,o=0;i>o;o++)o==e?n[o].classList.add("active"):n[o].classList.remove("active")};e.numSlides=function(){return new Array(i.slidesCount())},e.$watch("currentSlide",function(e){o(e)})}}})}(),angular.module("ionic.ui.tabs",["ionic.service.view"]).run(["$ionicViewService",function(e){e.disableRegisterByTagName("ion-tabs")}]).controller("ionicTabs",["$scope","$ionicViewService","$element",function(e,t){var n=null,i=this;i.tabs=[],i.selectedTabIndex=function(){return i.tabs.indexOf(n)},i.selectedTab=function(){return n},i.add=function(e){t.registerHistory(e),i.tabs.push(e),1===i.tabs.length&&i.select(e)},i.remove=function(e){var t=i.tabs.indexOf(e);if(-1!==t){if(e.$tabSelected)if(i.deselect(e),1===i.tabs.length);else{var n=t===i.tabs.length-1?t-1:t+1;i.select(i.tabs[n])}i.tabs.splice(t,1)}},i.deselect=function(e){e.$tabSelected&&(n=null,e.$tabSelected=!1,(e.onDeselect||angular.noop)())},i.select=function(o,r){var a;if(angular.isNumber(o)?(a=o,o=i.tabs[a]):a=i.tabs.indexOf(o),!o||-1==a)throw new Error('Cannot select tab "'+a+'"!');if(n&&n.$historyId==o.$historyId)r&&t.goToHistoryRoot(o.$historyId);else if(angular.forEach(i.tabs,function(e){i.deselect(e)}),n=o,o.$tabSelected=!0,(o.onSelect||angular.noop)(),r){var c={type:"tab",tabIndex:a,historyId:o.$historyId,navViewName:o.navViewName,hasNavView:!!o.navViewName,title:o.title,url:o.href,uiSref:o.uiSref};e.$emit("viewState.changeHistory",c)}}}]).directive("ionTabs",["$ionicViewService","$ionicBind","$parse",function(e,t,n){return{restrict:"E",replace:!0,scope:!0,transclude:!0,controller:"ionicTabs",template:'
',compile:function(e,i,o){return angular.isUndefined(i.tabsType)&&i.$set("tabsType","tabs-positive"),function(e,r,a,c){t(e,a,{$animation:"@animation",$tabsStyle:"@tabsStyle",$tabsType:"@tabsType"}),n(i.model||"tabsController").assign(e,c),c.$scope=e,c.$element=r,c.$tabsElement=angular.element(r[0].querySelector(".tabs")),o(e,function(e){r.append(e)})}}}}]).controller("ionicTab",["$scope","$ionicViewService","$rootScope","$element",function(e){this.$scope=e}]).directive("ionTab",["$rootScope","$animate","$ionicBind","$compile","$ionicViewService",function(e,t,n,i,o){function r(e,t){return angular.isDefined(t)?" "+e+'="'+t+'"':""}return{restrict:"E",require:["^ionTabs","ionTab"],replace:!0,controller:"ionicTab",scope:!0,compile:function(e,a){var c=e[0].querySelector("ion-nav-view")||e[0].querySelector("data-ion-nav-view"),l=c&&c.getAttribute("name"),s=angular.element('
').append(e.contents().remove());return function(e,c,u,d){function f(){o.isCurrentStateNavView(e.navViewName)&&tabsCtrl.select(e)}var v,p,g;tabsCtrl=d[0],tabCtrl=d[1],n(e,u,{animate:"=",onSelect:"&",onDeselect:"&",title:"@",uiSref:"@",href:"@"}),tabsCtrl.add(e),e.$on("$destroy",function(){tabsCtrl.remove(e),g.isolateScope().$destroy(),g.remove()}),l&&(e.navViewName=l,e.$on("$stateChangeSuccess",f),f()),g=angular.element(""),g.data("$ionTabsController",tabsCtrl),g.data("$ionTabController",tabCtrl),tabsCtrl.$tabsElement.append(i(g)(e)),e.$watch("$tabSelected",function(n){n||e.$broadcast("tab.hidden",e),v&&v.$destroy(),v=null,p&&t.leave(p),p=null,n&&(v=e.$new(),p=s.clone(),t.enter(p,tabsCtrl.$element),i(p)(v),e.$broadcast("tab.shown",e))})}}}}]).directive("ionTabNav",["$ionicNgClick",function(e){return{restrict:"E",replace:!0,require:["^ionTabs","^ionTab"],template:'{{badge}}',scope:{title:"@",icon:"@",iconOn:"@",iconOff:"@",badge:"=",badgeStyle:"@"},compile:function(){return function(t,n,i,o){var r=o[0],a=o[1];t.selectTab=function(e){e.preventDefault(),r.select(a.$scope,!0)},i.ngClick||e(t,n,"selectTab($event)"),t.getIconOn=function(){return t.iconOn||t.icon},t.getIconOff=function(){return t.iconOff||t.icon},t.isTabActive=function(){return r.selectedTab()===a.$scope}}}}}]),function(e){"use strict";angular.module("ionic.ui.toggle",[]).directive("ionToggle",["$ionicGesture","$timeout",function(){return{restrict:"E",replace:!0,require:"?ngModel",scope:{ngModel:"=?",ngValue:"=?",ngChecked:"=?",ngChange:"&",ngDisabled:"=?"},transclude:!0,template:'
',compile:function(t,n){var i=t.find("input");return n.name&&i.attr("name",n.name),n.ngChecked&&i.attr("ng-checked","ngChecked"),n.ngTrueValue&&i.attr("ng-true-value",n.ngTrueValue),n.ngFalseValue&&i.attr("ng-false-value",n.ngFalseValue),function(t,n){var i,o,r,a;i=n[0].getElementsByTagName("label")[0],o=i.children[0],r=i.children[1],a=r.children[0];var c=angular.element(o).controller("ngModel");t.toggle=new e.views.Toggle({el:i,track:r,checkbox:o,handle:a,onChange:function(){c.$setViewValue(o.checked?!0:!1),t.$apply()}}),t.$on("$destroy",function(){t.toggle.destroy()})}}}}])}(window.ionic),function(e,t){"use strict";e.module("ionic.ui.touch",[]).config(["$provide",function(e){e.decorator("ngClickDirective",["$delegate",function(e){return e.shift(),e}])}]).factory("$ionicNgClick",["$parse",function(e){function n(e){t.tapElement(e.target,e)}return function(i,o,r){var a=e(r);o.on("click",function(e){i.$apply(function(){a(i,{$event:e})})}),t.on("tap",n,o[0]),o.onclick=function(){},i.$on("$destroy",function(){t.off("tap",n,o[0])})}}]).directive("ngClick",["$ionicNgClick",function(e){return function(t,n,i){e(t,n,i.ngClick)}}]).directive("ionStopEvent",function(){function e(e){e.stopPropagation()}return{restrict:"A",link:function(t,n,i){n.bind(i.ionStopEvent,e)}}})}(window.angular,window.ionic),function(){"use strict";angular.module("ionic.ui.viewState",["ionic.service.view","ionic.service.gesture","ngSanitize"]).directive("ionNavBar",["$ionicViewService","$rootScope","$animate","$compile",function(e,t,n,i){return{restrict:"E",replace:!0,scope:{animation:"@",type:"@",backType:"@backButtonType",backLabel:"@backButtonLabel",backIcon:"@backButtonIcon",alignTitle:"@"},controller:function(){},template:'',compile:function(){return function(e,t){function o(t){angular.isDefined(t.hideBackButton)&&(e.backButtonEnabled=!!t.hideBackButton),e.isReverse="back"==t.navDirection,e.animateEnabled=!(!t.navDirection||t.animate===!1),e.leftButtons=t.leftButtons,e.rightButtons=t.rightButtons,e.oldTitle=e.title,e.title=t&&t.title||"",e.oldTitle!==e.title&&(e.animateEnabled?r():a.align())}function r(){var o,r,c;c=t[0].querySelectorAll(".title"),c.length&&(o=i('

')(e),angular.element(c[0]).replaceWith(o)),r=i('

')(e),ionic.requestAnimationFrame(function(){o&&n.leave(angular.element(o));var i=o&&angular.element(o)||null;n.enter(r,t,i,function(){a.align()}),angular.forEach(c,function(e){e&&e.parentNode&&angular.element(e).remove()}),e.$digest(),ionic.requestAnimationFrame(function(){r[0].classList.remove("invisible")})})}e.backButtonEnabled=!1,e.animateEnabled=!0,e.isReverse=!1,e.isInvisible=!0,e.navBarClass=function(){return(e.type?" "+e.type:"")+(e.isReverse?" reverse":"")+(e.isInvisible?" invisible":"")+(!e.animationDisabled&&e.animation?" "+e.animation:"")};var a=new ionic.views.HeaderBar({el:t[0],alignTitle:e.alignTitle||"center"});e.headerBarView=a,e.$on("viewState.viewEnter",function(e,t){o(t)}),e.$on("viewState.showNavBar",function(t,n){e.isInvisible=!n});var c=[e.$parent.$on("$viewHistory.historyChange",function(t,n){e.backButtonEnabled=!!n.showBack}),e.$parent.$on("viewState.leftButtonsChanged",function(t,n){e.leftButtons=n}),e.$parent.$on("viewState.rightButtonsChanged",function(t,n){e.rightButtons=n}),e.$parent.$on("viewState.showBackButton",function(t,n){e.backButtonEnabled=!!n}),e.$parent.$on("viewState.titleUpdated",function(t,n){e.title=n&&n.title||""})];e.$on("$destroy",function(){for(var e=0;e {{label}}',link:function(e){e.goBack=t}}}]).directive("ionNavView",["$ionicViewService","$state","$compile","$controller","$animate",function(e,t,n,i,o){var r=!1,a={restrict:"E",terminal:!0,priority:2e3,transclude:!0,controller:["$scope",function(e){this.setNextAnimation=function(t){e.$nextAnimation=t}}],compile:function(c,l,s){return function(c,l,u){function d(r){o.enabled()===!1&&(r=!1);var a=t.$current&&t.$current.locals[p];if(a!==v){var s=e.getRenderer(l,u,c);if(f&&(f.$destroy(),f=null),!a)return v=null,$.state=null,l.append(h);var d=angular.element("
").html(a.$template).contents(),m=s().register(d);s(r).leave(),v=a,$.state=a.$$state,s(r).enter(d);var b=n(d);if(f=c.$new(),f.$navDirection=m.navDirection,a.$$controller){a.$scope=f;var w=i(a.$$controller,a);l.children().data("$ngControllerController",w)}b(f);var y=e._getViewById(m.viewId)||{};f.$broadcast("$viewContentLoaded",y),g&&f.$eval(g),d=null}}var f,v,p=u[a.name]||u.name||"",g=u.onload||"",h=s(c);l.append(h);var m=l.parent().inheritedData("$uiView");p.indexOf("@")<0&&(p=p+"@"+(m?m.state.name:""));var $={name:p,state:null};l.data("$uiView",$);var b=function(){if(!r){r=!0;try{d(!0)}catch(e){throw r=!1,e}r=!1}};c.$on("$stateChangeSuccess",b),c.$on("$viewContentLoading",b),d(!1)}}};return a}])}(),function(){"use strict";angular.module("ionic.ui.virtRepeat",[]).directive("ionVirtRepeat",function(){return{require:["?ngModel","^virtualList"],transclude:"element",priority:1e3,terminal:!0,compile:function(){return function(e,t,n,i){var o=i[1];o.listView.renderViewport=function(){}}}}})}(ionic),function(){"use strict";function e(e){var t=e.match(/^\s*([\$\w]+)\s+in\s+(\S*)\s*$/);if(!t)throw new Error("Expected sfVirtualRepeat in form of '_item_ in _collection_' but got '"+e+"'.");return{value:t[1],collection:t[2]}}function t(e){var t={overflow:"auto"},n=window.getComputedStyle?window.getComputedStyle(e[0]):e[0].currentStyle,i=n&&n.getPropertyValue("max-height"),o=n&&n.getPropertyValue("height");i&&"0px"!==i?t.maxHeight=i:t.height=o&&"0px"!==o?o:window.innerHeight,e.css(t)}function n(e){var t={margin:0,padding:0,border:0,"box-sizing":"border-box"};e.css(t)}function i(e){var t=window.getComputedStyle?window.getComputedStyle(e):e.currentStyle,n=t&&t.getPropertyValue("max-height"),i=t&&t.getPropertyValue("height");if(i&&"0px"!==i&&"auto"!==i)$log.info('Row height is "%s" from css height',i);else if(n&&"0px"!==n&&"none"!==n)i=n,$log.info('Row height is "%s" from css max-height',i);else{if(!e.clientHeight)throw new Error("Unable to compute height of row");i=e.clientHeight+"px",$log.info('Row height is "%s" from client height',i)}return angular.element(e).css("height",i),parseInt(i,10)}angular.module("ionic.ui.virtualRepeat",[]).directive("ionVirtualRepeat",["$log",function(o){return{require:["?ngModel, ^virtualList"],transclude:"element",priority:1e3,terminal:!0,compile:function(r,a){var c=e(a.sfVirtualRepeat);return function(e,r,a,l){function s(e,t,n){var i=n.$new();return i[c.value]=t[e],i.$index=e,i.$first=0===e,i.$last=e===t.length-1,i.$middle=!(i.$first||i.$last),i.$watch(function(){i[c.value]=t[e]}),i}function u(e,t,n,i,o){var r,a,c,l=document.createDocumentFragment(),u=[];for(a=e;a!==t;a++)c=s(a,n,i),r=linker(c,angular.noop),u.push(r),l.appendChild(r[0]);return o.after(l),u}function d(){var e=clip(y.firstActive,y.firstVisible-y.lowWater,y.firstVisible-y.highWater),t=clip(y.firstActive+y.active,y.firstVisible+y.visible+y.lowWater,y.firstVisible+y.visible+y.highWater);y.firstActive=Math.max(0,e),y.active=Math.min(t,y.total)-y.firstActive}function f(t){$&&e.$apply(function(){y.firstVisible=Math.floor(t.target.scrollTop/$),y.visible=Math.ceil(w.viewport[0].clientHeight/$),o.log("scroll to row %o",y.firstVisible),b=t.target.scrollTop+t.target.clientHeight>=t.target.scrollHeight,d(),o.log(" state is now %o",y),o.log(" sticky = %o",b)})}function v(e){var t=e.$eval(c.collection);return t.length!==y.total&&(y.total=t.length,d()),{start:y.firstActive,active:y.active,len:t.length}}function p(e,t){var n,i,o=Array.prototype[e];for(i=0;t>i;i++)n=o.call(m),n.scope().$destroy(),n.remove()}function g(e,t,n){var a,l=t.start+t.active,s=n.$eval(c.collection);if(e===t)o.info("initial listen"),a=u(e.start,l,s,n,r),m=a,m.length&&($=i(a[0][0]));else{var d=e.start+e.active,f=e.start>=t.start,v=f?e.start-t.start:t.start-e.start,g=d>=l?d-l:l-d,h=v<(f?t.active:e.active);if(o.info("change by %o,%o rows %s",v,g,f?"forward":"backward"),h){if(f?(o.info("need to remove from the top"),p("shift",v)):v&&(o.info("need to add at the top"),a=u(e.start,t.start,s,n,r),m=a.concat(m)),l>d)o.info("need to remove from the bottom"),p("pop",l-d);else if(g){var y=m[m.length-1];o.info("need to add to the bottom"),a=u(l,d,s,n,y),m=m.concat(a)}}else o.info("non-contiguous change"),p("pop",m.length),m=u(e.start,d,s,n,r);!$&&m.length&&($=i(m[0][0])),w.content.css({"padding-top":e.start*$+"px"})}w.content.css({height:e.len*$+"px"}),b&&(w.viewport[0].scrollTop=w.viewport[0].clientHeight+w.viewport[0].scrollHeight)}var h=l[1],m=[],$=0,b=!1,w=h.element,y="ngModel"in a?e.$eval(a.ngModel):{};y.firstActive=0,y.firstVisible=0,y.visible=0,y.active=0,y.total=0,y.lowWater=y.lowWater||100,y.highWater=y.highWater||300,n(w.content),t(w.viewport),w.bind("momentumScrolled",f),e.$on("$destroy",function(){w.unbind("momentumScrolled",f)}),e.$watch(v,g,!0)}}}}])}(ionic),function(){"use strict";angular.module("ionic.ui.scroll").controller("$ionicScroll",["$scope","scrollViewOptions","$timeout","$ionicScrollDelegate","$window",function(e,t,n,i,o){function r(){l.resize()}var a=this,c=this.element=t.el,l=this.scrollView=new ionic.views.Scroll(t);angular.isDefined(t.bouncing)||ionic.Platform.ready(function(){l.options.bouncing=!ionic.Platform.isAndroid()});var s=this.$element=angular.element(c);s.data("$$ionicScrollController",this),i.register(e,s,l),o.addEventListener("resize",r),e.$on("$destroy",function(){o.removeEventListener("resize",r)}),this.setRefresher=function(e,t){var n=this.refresher=t,i=a.refresher.clientHeight||0;l.activatePullToRefresh(i,function(){n.classList.add("active"),e.$onPulling()},function(){n.classList.remove("refreshing"),n.classList.remove("active")},function(){n.classList.add("refreshing"),e.$onRefresh()})},n(function(){l.run()})}])}(); \ No newline at end of file +!function(){function e(e){return["$log",function(t){function n(e){this.handle=e}var i=this,o=this._instances=[];this._registerInstance=function(e,t){return t||(t=ionic.Utils.nextUid()),e.$$delegateHandle=t,o.push(e),function(){var t=o.indexOf(e);-1!==t&&o.splice(t,1)}},this.$getByHandle=function(e){return e?new n(e):i},e.forEach(function(e){function r(e,t,n){var i,o;return e.forEach(function(e,r){o=e[t].apply(e,n),0===r&&(i=o)}),i}n.prototype[e]=function(){var n=this.handle,i=o.filter(function(e){return e.$$delegateHandle===n});return i.length?r(i,e,arguments):t.warn('Delegate for handle "'+this.handle+'" could not find a','corresponding element with delegate-handle="'+this.handle+'"!',e,"was not called!")},i[e]=function(){return r(o,e,arguments)}})}]}angular.module("ionic.service",["ionic.service.bind","ionic.service.platform","ionic.service.actionSheet","ionic.service.gesture","ionic.service.loading","ionic.service.modal","ionic.service.popup","ionic.service.templateLoad","ionic.service.view","ionic.decorator.location"]),angular.module("ionic.ui",["ionic.ui.checkbox","ionic.ui.content","ionic.ui.header","ionic.ui.list","ionic.ui.navBar","ionic.ui.popup","ionic.ui.radio","ionic.ui.scroll","ionic.ui.sideMenu","ionic.ui.slideBox","ionic.ui.tabs","ionic.ui.toggle","ionic.ui.touch","ionic.ui.viewState"]),angular.module("ionic",["ionic.service","ionic.ui","ngAnimate","ngSanitize","ui.router"]),angular.element.prototype.addClass=function(e){var t,n,i,o,r,a;if(e&&"ng-scope"!=e&&"ng-isolate-scope"!=e)for(t=0;t')(c),l=angular.element(s[0].querySelector(".action-sheet-wrapper")),u=function(e){l.removeClass("action-sheet-up"),e&&o(function(){r.cancel()},200),i.removeClass(s,"active",function(){c.$destroy()}),t[0].body.classList.remove("action-sheet-open"),c.$deregisterBackButton&&c.$deregisterBackButton()};c.$deregisterBackButton=a.registerBackButtonAction(function(){u()},300),c.cancel=function(){u(!0)},c.buttonClicked=function(e){(r.buttonClicked&&r.buttonClicked(e))===!0&&u(!1)},c.destructiveButtonClicked=function(){(r.destructiveButtonClicked&&r.destructiveButtonClicked())===!0&&u(!1)},t[0].body.appendChild(s[0]),t[0].body.classList.add("action-sheet-open");var d=new ionic.views.ActionSheet({el:s[0]});return c.sheet=d,i.addClass(s,"active"),o(function(){l.addClass("action-sheet-up")},20),d}}}]),angular.module("ionic.service.bind",[]).factory("$ionicBind",["$parse","$interpolate",function(e,t){var n=/^\s*([@=&])(\??)\s*(\w*)\s*$/;return function(i,o,r){angular.forEach(r||{},function(r,a){var c,s,l=r.match(n)||[],u=l[3]||a,d=l[1];switch(d){case"@":if(!o[u])return;o.$observe(u,function(e){i[a]=e}),o[u]&&(i[a]=t(o[u])(i));break;case"=":if(!o[u])return;s=i.$watch(o[u],function(e){i[a]=e}),i.$on("$destroy",s);break;case"&":if(o[u]&&o[u].match(RegExp(a+"(.*?)")))throw new Error('& expression binding "'+a+'" looks like it will recursively call "'+o[u]+'" and cause a stack overflow! Please choose a different scopeName.');c=e(o[u]),i[a]=function(e){return c(i,e)}}})}}]),angular.module("ionic.service.gesture",[]).factory("$ionicGesture",[function(){return{on:function(e,t,n){return window.ionic.onGesture(e,t,n[0])},off:function(e,t,n){return window.ionic.offGesture(e,t,n)}}}]),angular.module("ionic.service.loading",["ionic.ui.loading"]).factory("$ionicLoading",["$rootScope","$document","$compile",function(e,t,n){return{show:function(i){var o={content:"",animation:"fade-in",showBackdrop:!0,maxWidth:200,showDelay:0};i=angular.extend(o,i);var r=e.$new(!0);angular.extend(r,i);var a=angular.element(t[0].querySelector(".loading-backdrop"));a.length&&a.remove();var c=n(""+i.content+"")(r);t[0].body.appendChild(c[0]);var s=new ionic.views.Loading({el:c[0],maxWidth:i.maxWidth,showDelay:i.showDelay});return s.show(),r.loading=s,s}}}]),angular.module("ionic.service.modal",["ionic.service.templateLoad","ionic.service.platform","ionic.ui.modal"]).factory("$ionicModal",["$rootScope","$document","$compile","$timeout","$ionicPlatform","$ionicTemplateLoader",function(e,t,n,i,o,r){var a=ionic.views.Modal.inherit({initialize:function(e){ionic.views.Modal.prototype.initialize.call(this,e),this.animation=e.animation||"slide-in-up"},show:function(){var e=this,n=angular.element(e.modalEl);e.el.classList.remove("hide"),t[0].body.classList.add("modal-open"),e._isShown=!0,e.el.parentElement||(n.addClass(e.animation),t[0].body.appendChild(e.el)),n.addClass("ng-enter active").removeClass("ng-leave ng-leave-active"),i(function(){n.addClass("ng-enter-active"),e.scope.$parent&&e.scope.$parent.$broadcast("modal.shown"),e.el.classList.add("active")},20),e._deregisterBackButton=o.registerBackButtonAction(function(){e.hide()},200),ionic.views.Modal.prototype.show.call(e)},hide:function(){var e=this;e._isShown=!1;var n=angular.element(e.modalEl);e.el.classList.remove("active"),n.addClass("ng-leave"),i(function(){n.addClass("ng-leave-active").removeClass("ng-enter ng-enter-active active")},20),i(function(){t[0].body.classList.remove("modal-open"),e.el.classList.add("hide")},350),ionic.views.Modal.prototype.hide.call(e),e.scope.$parent&&e.scope.$parent.$broadcast("modal.hidden"),e._deregisterBackButton&&e._deregisterBackButton()},remove:function(){var e=this;e.hide(),e.scope.$parent&&e.scope.$parent.$broadcast("modal.removed"),i(function(){e.scope.$destroy(),e.el&&e.el.parentElement&&e.el.parentElement.removeChild(e.el)},750)},isShown:function(){return!!this._isShown}}),c=function(t,i){var o=i.scope&&i.scope.$new()||e.$new(!0),r=n(""+t+"")(o);i.el=r[0],i.modalEl=i.el.querySelector(".modal");var c=new a(i);return c.scope=o,i.scope||(o.modal=c),c};return{fromTemplate:function(e,t){var n=c(e,t||{});return n},fromTemplateUrl:function(e,t,n){var i;return angular.isFunction(t)&&(i=t,t=n),r.load(e).then(function(e){var n=c(e,t||{});return i&&i(n),n})}}}]),function(e){"use strict";angular.module("ionic.service.platform",[]).provider("$ionicPlatform",function(){return{$get:["$q","$rootScope",function(t,n){return{onHardwareBackButton:function(t){e.Platform.ready(function(){document.addEventListener("backbutton",t,!1)})},offHardwareBackButton:function(t){e.Platform.ready(function(){document.removeEventListener("backbutton",t)})},registerBackButtonAction:function(t,i,o){var r=this;r._hasBackButtonHandler||(n.$backButtonActions={},r.onHardwareBackButton(r.hardwareBackButtonClick),r._hasBackButtonHandler=!0);var a={id:o?o:e.Utils.nextUid(),priority:i?i:0,fn:t};return n.$backButtonActions[a.id]=a,function(){delete n.$backButtonActions[a.id]}},hardwareBackButtonClick:function(e){var t,i;for(i in n.$backButtonActions)(!t||n.$backButtonActions[i].priority>=t.priority)&&(t=n.$backButtonActions[i]);return t?(t.fn(e),t):void 0},is:function(t){return e.Platform.is(t)},ready:function(n){var i=t.defer();return e.Platform.ready(function(){i.resolve(),n()}),i.promise}}}]}})}(ionic),function(e){"use strict";angular.module("ionic.service.popup",["ionic.service.templateLoad"]).factory("$ionicPopup",["$rootScope","$q","$document","$compile","$timeout","$ionicTemplateLoader",function(t,n,i,o,r,a){var c={stackPushDelay:50},s=function(e){e.el.style.marginLeft=-e.el.offsetWidth/2+"px",e.el.style.marginTop=-e.el.offsetHeight/2+"px"},l=function(e){var t=e.el.querySelector(".popup-body");t&&""==t.innerHTML.trim()&&(t.style.display="none")},u=function(e){var t,n;t=e.el.querySelectorAll("button"),n=t[t.length-1],n&&n.focus()},d=function(t){e.requestAnimationFrame(function(){l(t),s(t),t.el.classList.remove("popup-hidden"),t.el.classList.add("popup-showing"),t.el.classList.add("active"),u(t)})},f=function(t){e.requestAnimationFrame(function(){t.el.classList.remove("popup-hidden"),t.el.classList.add("popup-showing"),t.el.classList.add("active"),u(t)})},v=function(t){e.requestAnimationFrame(function(){t.el.classList.remove("active"),t.el.classList.add("popup-hidden")})},p=function(e){e.el.offsetWidth,e.el.classList.remove("active"),e.el.classList.add("popup-hidden"),r(function(){e.el.remove()},400)},g=[],h=null,m=function(){var e=o("")(t.$new(!0));i[0].body.appendChild(e[0]),h=e,i[0].body.classList.add("popup-open")},$=function(){h.remove(),r(function(){i[0].body.classList.remove("popup-open")},300)},b=function(e){var t=g[g.length-1];g.push(e),1==g.length&&m(),t?(v(t),r(function(){d(e)},c.stackPushDelay)):d(e)},w=function(){var e=g.pop(),t=g[g.length-1];p(e),t?f(t):$()},y=function(e,t){var n={el:e[0],scope:t,close:function(){w(this)}};return t.popup=n,n},k=function(e,t){return''+(t||"")+""},S=function(e,r){var c=n.defer(),s={title:"",animation:"fade-in"};e=angular.extend(s,e);var l=e.scope&&e.scope.$new()||t.$new(!0);if(angular.extend(l,e),l.onClose=function(e,t){w(l.popup),r.resolve(t)},e.templateUrl)a.load(e.templateUrl).then(function(t){var n=k(e,t),r=o(n)(l);i[0].body.appendChild(r[0]),c.resolve(y(r,l))},function(e){c.reject(e)});else{var u=k(e,e.content),d=o(u)(l);i[0].body.appendChild(d[0]),c.resolve(y(d,l))}return c.promise};return{showPopup:function(e){var t=n.defer();return S(e,t).then(function(n){t.notify(n),b(n,e)},function(){}),t.promise},show:function(e){return this.showPopup(e)},alert:function(e){return this.showPopup({content:e.content||"",title:e.title||"",buttons:[{text:e.okText||"OK",type:e.okType||"button-positive",onTap:function(){return!0}}]})},confirm:function(e){return this.showPopup({content:e.content||"",title:e.title||"",buttons:[{text:e.cancelText||"Cancel",type:e.cancelType||"button-default",onTap:function(e){e.preventDefault()}},{text:e.okText||"OK",type:e.okType||"button-positive",onTap:function(){return!0}}]})},prompt:function(e){var n=t.$new(!0);return n.data={},this.showPopup({content:e.content||'',title:e.title||"",subTitle:e.subTitle||"",scope:n,buttons:[{text:e.cancelText||"Cancel",type:e.cancelType||"button-default",onTap:function(e){e.preventDefault()}},{text:e.okText||"OK",type:e.okType||"button-positive",onTap:function(){return n.data.response}}]})}}}])}(ionic),angular.module("ionic.service.templateLoad",[]).factory("$ionicTemplateLoader",["$q","$http","$templateCache",function(e,t,n){return{load:function(e){return t.get(e,{cache:n}).then(function(e){return e.data&&e.data.trim()})}}}]),angular.module("ionic.service.view",["ui.router","ionic.service.platform"]).run(["$rootScope","$state","$location","$document","$animate","$ionicPlatform",function(e,t,n,i,o,r){function a(t){return e.$viewHistory.backView?e.$viewHistory.backView.go():ionic.Platform.exitApp(),t.preventDefault(),!1}e.$viewHistory={histories:{root:{historyId:"root",parentHistoryId:null,stack:[],cursor:-1}},views:{},backView:null,forwardView:null,currentView:null,disabledRegistrableTagNames:[]},e.$on("viewState.changeHistory",function(i,o){if(o){var r=o.historyId?e.$viewHistory.histories[o.historyId]:null;if(r&&r.cursor>-1&&r.cursor-1&&c.stack.length>0&&c.cursor=u.index;g--)p.stack[g].destroy(),p.stack.splice(g)}}else f.navAction="initialView";o.views[f.viewId]=this.createView({viewId:f.viewId,index:c.stack.length,historyId:c.historyId,backViewId:s&&s.viewId?s.viewId:null,forwardViewId:null,stateId:a,stateName:this.getCurrentStateName(),stateParams:this.getCurrentStateParams(),url:n.url()}),"moveBack"==f.navAction&&e.$emit("$viewHistory.viewBack",s.viewId,f.viewId),c.stack.push(o.views[f.viewId])}return d&&(d.disableAnimate&&(f.navDirection=null),d.disableBack&&(o.views[f.viewId].backViewId=null),this.nextViewOptions(null)),this.setNavViews(f.viewId),c.cursor=o.currentView.index,f},setNavViews:function(t){var n=e.$viewHistory;n.currentView=this._getViewById(t),n.backView=this._getBackView(n.currentView),n.forwardView=this._getForwardView(n.currentView),e.$broadcast("$viewHistory.historyChange",{showBack:n.backView&&n.backView.historyId===n.currentView.historyId})},registerHistory:function(e){e.$historyId=ionic.Utils.nextUid()},createView:function(e){var t=new c;return t.initialize(e)},getCurrentView:function(){return e.$viewHistory.currentView},getBackView:function(){return e.$viewHistory.backView},getForwardView:function(){return e.$viewHistory.forwardView},getNavDirection:function(){return e.$viewHistory.navDirection},getCurrentStateName:function(){return t&&t.current?t.current.name:null},isCurrentStateNavView:function(e){return t&&t.current&&t.current.views&&t.current.views[e]?!0:!1},getCurrentStateParams:function(){var e;if(t&&t.params)for(var n in t.params)t.params.hasOwnProperty(n)&&(e=e||{},e[n]=t.params[n]);return e},getCurrentStateId:function(){var e;if(t&&t.current&&t.current.name){if(e=t.current.name,t.params)for(var n in t.params)t.params.hasOwnProperty(n)&&t.params[n]&&(e+="_"+n+"="+t.params[n]);return e}return ionic.Utils.nextUid()},goToHistoryRoot:function(t){if(t){var n=e.$viewHistory.histories[t];if(n&&n.stack.length){if(e.$viewHistory.currentView&&e.$viewHistory.currentView.viewId===n.stack[0].viewId)return;e.$viewHistory.forcedNav={viewId:n.stack[0].viewId,navAction:"moveBack",navDirection:"back"},n.stack[0].go()}}},_getViewById:function(t){return t?e.$viewHistory.views[t]:null},_getBackView:function(e){return e?this._getViewById(e.backViewId):null},_getForwardView:function(e){return e?this._getViewById(e.forwardViewId):null},_getHistoryById:function(t){return t?e.$viewHistory.histories[t]:null},_getHistory:function(t){var n=this._getParentHistoryObj(t);return e.$viewHistory.histories[n.historyId]||(e.$viewHistory.histories[n.historyId]={historyId:n.historyId,parentHistoryId:this._getParentHistoryObj(n.scope.$parent).historyId,stack:[],cursor:-1}),e.$viewHistory.histories[n.historyId]},_getParentHistoryObj:function(t){for(var n=t;n;){if(n.hasOwnProperty("$historyId"))return{historyId:n.$historyId,scope:n};n=n.$parent}return{historyId:"root",scope:e}},nextViewOptions:function(e){return arguments.length?void(this._nextOpts=e):this._nextOpts},getRenderer:function(e,t,n){function i(e){for(var t="";!t&&e;)t=e.getAttribute("animation"),e=e.parentElement;return t}function o(){l&&e[0].classList.add(l),"back"===r.navDirection?e[0].classList.add("reverse"):e[0].classList.remove("reverse")}var r,c,s=this,l=angular.isDefined(n.$nextAnimation)?n.$nextAnimation:i(e[0]);return n.$nextAnimation=void 0,function(t){return{enter:function(n){return c&&t?(o(),n.addClass("ng-enter"),document.body.classList.add("disable-pointer-events"),void a.enter(n,e,null,function(){document.body.classList.remove("disable-pointer-events"),l&&e[0].classList.remove(l)})):void e.append(n)},leave:function(){var n=e.contents();return c&&t?(o(),void a.leave(n,function(){n.remove()})):void n.remove()},register:function(e){return r=s.register(n,e),c=null!==l&&null!==r.navDirection,r}}}},disableRegisterByTagName:function(t){e.$viewHistory.disabledRegistrableTagNames.push(t.toUpperCase())},isTagNameRegistrable:function(t){var n,i,o=e.$viewHistory.disabledRegistrableTagNames;for(n=0;n
{{titleText}}
'}}])}(),function(e){"use strict";function t(){return["$ionicScrollDelegate",function(t){return{restrict:"E",link:function(n,i){function o(n){if(!e.DomUtil.getParentOrSelfWithClass(n.target,"button",4)){var o=n.gesture&&n.gesture.touches[0]||n.detail.touches[0],r=i[0].getBoundingClientRect();e.DomUtil.rectContains(o.pageX,o.pageY,r.left,r.top-20,r.left+r.width,r.top+r.height)&&t.scrollTop(!0)}}e.on("tap",o,i[0]),n.$on("$destroy",function(){e.off("tap",o,i[0])})}}}]}function n(t){return[function(){return{restrict:"E",compile:function(n){function i(n,i,o){var r=(new e.views.HeaderBar({el:i[0],alignTitle:o.alignTitle||"center"}),i[0]),a=n.$parent||n;t?(n.$watch(function(){return r.className},function(e){var t=-1!==e.indexOf("bar-subheader");a.$hasHeader=!t,a.$hasSubheader=t}),n.$on("$destroy",function(){a.$hasHeader=a.$hasSubheader=null})):(n.$watch(function(){return r.className},function(e){var t=-1!==e.indexOf("bar-subfooter");a.$hasFooter=!t,a.$hasSubfooter=t}),n.$on("$destroy",function(){a.$hasFooter=a.$hasSubfooter=null}),n.$watch("$hasTabs",function(e){i.toggleClass("has-tabs",!!e)}))}return n.addClass(t?"bar bar-header":"bar bar-footer"),{pre:i}}}}]}angular.module("ionic.ui.header",["ngAnimate","ngSanitize"]).directive("ionNavBar",t()).directive("ionHeaderBar",t()).directive("ionHeaderBar",n(!0)).directive("ionFooterBar",n(!1))}(ionic),function(){"use strict";angular.module("ionic.ui.checkbox",[]).directive("ionCheckbox",function(){return{restrict:"E",replace:!0,require:"?ngModel",scope:{ngModel:"=?",ngValue:"=?",ngChecked:"=?",ngChange:"&"},transclude:!0,template:'
',compile:function(e,t){var n=e.find("input");t.name&&n.attr("name",t.name),t.ngChecked&&n.attr("ng-checked","ngChecked"),t.ngTrueValue&&n.attr("ng-true-value",t.ngTrueValue),t.ngFalseValue&&n.attr("ng-false-value",t.ngFalseValue)}}})}(),function(){"use strict";angular.module("ionic.ui.content",["ionic.ui.scroll"]).directive("ionPane",function(){return{restrict:"E",link:function(e,t){t.addClass("pane")}}}).directive("ionContent",["$timeout","$controller","$ionicBind",function(e,t,n){return{restrict:"E",require:"^?ionNavView",scope:!0,compile:function(e,i){function o(e,o,a){e.$watch(function(){return(e.$hasHeader?" has-header":"")+(e.$hasSubheader?" has-subheader":"")+(e.$hasFooter?" has-footer":"")+(e.$hasSubfooter?" has-subfooter":"")+(e.$hasTabs?" has-tabs":"")+(e.$hasTabsTop?" has-tabs-top":"")},function(e,t){o.removeClass(t),o.addClass(e)}),n(e,a,{$onScroll:"&onScroll",$onScrollComplete:"&onScrollComplete",hasBouncing:"@",scroll:"@",padding:"@",hasScrollX:"@",hasScrollY:"@",scrollbarX:"@",scrollbarY:"@",startX:"@",startY:"@",scrollEventInterval:"@"}),angular.isDefined(a.padding)&&e.$watch(a.padding,function(e){r.toggleClass("padding",!!e)}),"false"===e.scroll||("true"===i.overflowScroll?o.addClass("overflow-scroll"):t("$ionicScroll",{$scope:e,scrollViewOptions:{el:o[0],delegateHandle:i.delegateHandle,bouncing:e.$eval(e.hasBouncing),startX:e.$eval(e.startX)||0,startY:e.$eval(e.startY)||0,scrollbarX:e.$eval(e.scrollbarX)!==!1,scrollbarY:e.$eval(e.scrollbarY)!==!1,scrollingX:e.$eval(e.hasScrollX)===!0,scrollingY:e.$eval(e.hasScrollY)!==!1,scrollEventInterval:parseInt(e.scrollEventInterval,10)||20,scrollingComplete:function(){e.$onScrollComplete({scrollTop:this.__scrollTop,scrollLeft:this.__scrollLeft})}}}))}e.addClass("scroll-content");var r=angular.element('
');return r.append(e.contents()),e.append(r),{pre:o}}}}]).directive("ionRefresher",["$ionicBind",function(e){return{restrict:"E",replace:!0,require:"^$ionicScroll",template:'
',compile:function(t,n){return angular.isUndefined(n.pullingIcon)&&n.$set("pullingIcon","ion-arrow-down-c"),angular.isUndefined(n.refreshingIcon)&&n.$set("refreshingIcon","ion-loading-d"),function(t,n,i,o){e(t,i,{pullingIcon:"@",pullingText:"@",refreshingIcon:"@",refreshingText:"@",$onRefresh:"&onRefresh",$onPulling:"&onPulling"}),o._setRefresher(t,n[0]),t.$on("scroll.refreshComplete",function(){n[0].classList.remove("active"),o.scrollView.finishPullToRefresh()})}}}}]).directive("ionInfiniteScroll",["$timeout",function(e){return{restrict:"E",require:["^$ionicScroll","ionInfiniteScroll"],template:'
',scope:!0,controller:["$scope","$attrs",function(e,t){this.isLoading=!1,this.scrollView=null,this.getMaxScroll=function(){var e=t.distance||"1%";return e.indexOf("%")>-1?this.scrollView.getScrollMax().top*(1-parseInt(e,10)/100):this.scrollView.getScrollMax().top-parseInt(e,10)}}],link:function(t,n,i,o){var r=o[0],a=o[1],c=a.scrollView=r.scrollView;t.icon=function(){return angular.isDefined(i.icon)?i.icon:"ion-loading-d"},t.$on("scroll.infiniteScrollComplete",function(){n[0].classList.remove("active"),e(function(){c.resize()},0,!1),a.isLoading=!1}),r.$element.on("scroll",ionic.animationFrameThrottle(function(){!a.isLoading&&c.getValues().top>=a.getMaxScroll()&&(n[0].classList.add("active"),a.isLoading=!0,t.$parent.$apply(i.onInfinite||""))}))}}}])}(),function(){"use strict";angular.module("ionic.ui.list",["ngAnimate"]).directive("ionItem",["$timeout","$parse",function(){return{restrict:"E",require:"?^ionList",replace:!0,transclude:!0,scope:{item:"=",itemType:"@",canDelete:"@",canReorder:"@",canSwipe:"@",onDelete:"&",optionButtons:"&",deleteIcon:"@",reorderIcon:"@"},template:'
',link:function(e,t,n,i){if(i){var o=i.scope,r=i.attrs;n.$observe("href",function(t){t&&(e.href=t.trim())}),e.itemType||(e.itemType=o.itemType),t.addClass(e.itemType||o.itemType),e.itemClass=e.itemType,"false"!==(n.canDelete?e.canDelete:o.canDelete)&&(n.onDelete||r.onDelete)&&(e.deleteClick=function(){n.onDelete?e.onDelete({item:e.item,index:e.$parent.$index}):r.onDelete&&o.onDelete({item:e.item,index:e.$parent.$index})},e.deleteIconClass=e.deleteIcon||o.deleteIcon||"ion-minus-circled",t.addClass("item-left-editable")),"true"===(n.canReorder?e.canReorder:o.canReorder)&&(e.reorderIconClass=e.reorderIcon||o.reorderIcon||"ion-navicon",t.addClass("item-right-editable")),"false"!==(n.canSwipe?e.canSwipe:o.canSwipe)&&(e.itemOptionButtons=e.optionButtons(),"undefined"==typeof e.itemOptionButtons&&(e.itemOptionButtons=o.optionButtons()),t.addClass("item-swipeable"))}}}}]).directive("ionList",["$timeout",function(e){return{restrict:"E",replace:!0,transclude:!0,require:"^?$ionicScroll",scope:{itemType:"@",canDelete:"@",canReorder:"@",canSwipe:"@",showDelete:"=",showReorder:"=",onDelete:"&",onReorder:"&",optionButtons:"&",deleteIcon:"@",reorderIcon:"@"},template:"
",controller:["$scope","$attrs",function(e,t){this.scope=e,this.attrs=t}],link:function(t,n,i,o){t.listView=new ionic.views.ListView({canSwipe:"false"!==t.canSwipe&&!!t.optionButtons(),el:n[0],listEl:n[0].children[0],scrollEl:o&&o.element,scrollView:o&&o.scrollView,onReorder:function(e,n,i){t.$apply(function(){t.onReorder({el:e,start:n,end:i})})}}),i.animation&&n[0].classList.add(i.animation);var r=t.$watch("showReorder",function(i){i?(n[0].classList.add("item-options-hide"),t.listView&&t.listView.clearDragEffects()):i===!1&&e(function(){n[0].classList.remove("item-options-hide")},250)});t.$on("$destroy",function(){r()})}}}])}(),function(){"use strict";angular.module("ionic.ui.loading",[]).directive("ionLoading",function(){return{restrict:"E",replace:!0,transclude:!0,link:function(e,t){t.addClass(e.animation||"")},template:'
'}})}(),function(){"use strict";angular.module("ionic.ui.modal",[]).directive("ionModal",[function(){return{restrict:"E",transclude:!0,replace:!0,template:''}}])}(),angular.module("ionic.ui.navBar",["ionic.service.view","ngSanitize"]).service("$ionicNavBarDelegate",e(["back","align","showBackButton","showBar","setTitle","changeTitle","getTitle","getPreviousTitle"])).controller("$ionicNavBar",["$scope","$element","$attrs","$ionicViewService","$animate","$compile","$ionicNavBarDelegate",function(e,t,n,i,o,r,a){t.parent().data("$ionNavBarController",this);var c=a._registerInstance(this,n.delegateHandle);e.$on("$destroy",c);var s=this;this.leftButtonsElement=angular.element(t[0].querySelector(".buttons.left-buttons")),this.rightButtonsElement=angular.element(t[0].querySelector(".buttons.right-buttons")),this.back=function(e){var t=i.getBackView();return t&&t.go(),e&&(e.alreadyHandled=!0),!1},this.align=function(e){this._headerBarView.align(e)},this.showBackButton=function(t){e.backButtonShown=!!t},this.showBar=function(t){e.isInvisible=!t},this.setTitle=function(t){e.oldTitle=e.title,e.title=t||""},this.changeTitle=function(t,n){return e.title===t?!1:(this.setTitle(t),e.isReverse="back"==n,e.shouldAnimate=!!n,e.shouldAnimate?this._animateTitles():this._headerBarView.align(),!0)},this.getTitle=function(){return e.title||""},this.getPreviousTitle=function(){return e.oldTitle||""},this._animateTitles=function(){var n,i,a;a=t[0].querySelectorAll(".title"),a.length&&(n=r('

')(e),angular.element(a[0]).replaceWith(n)),i=r('

')(e),ionic.requestAnimationFrame(function(){n&&o.leave(angular.element(n));var r=n&&angular.element(n)||null;o.enter(i,t,r,function(){s._headerBarView.align()}),angular.forEach(a,function(e){e&&e.parentNode&&angular.element(e).remove()}),e.$digest(),ionic.requestAnimationFrame(function(){i[0].classList.remove("invisible")})})}}]).directive("ionNavBar",["$ionicViewService","$rootScope","$animate","$compile",function(){return{restrict:"E",controller:"$ionicNavBar",scope:!0,compile:function(e){function t(e,t,n,i){i._headerBarView=new ionic.views.HeaderBar({el:t[0],alignTitle:n.alignTitle||"center"}),e.backButtonShown=!1,e.shouldAnimate=!0,e.isReverse=!1,e.isInvisible=!0,e.$parent.$hasHeader=!0,e.$on("$destroy",function(){e.$parent.$hasHeader=!1}),e.$watch(function(){return(e.isReverse?" reverse":"")+(e.isInvisible?" invisible":"")+(e.shouldAnimate?"":" no-animation")},function(e,n){t.removeClass(n),t.addClass(e)})}return e.addClass("bar bar-header nav-bar").append('

'),{pre:t} +}}}]).directive("ionNavBackButton",["$ionicNgClick",function(e){return{restrict:"E",require:"^ionNavBar",compile:function(t){return t.addClass("button back-button"),function(t,n,i,o){i.ngClick||(t.$navBack=o.back,e(t,n,"$navBack($event)"));var r=t.$parent.$on("$viewHistory.historyChange",function(e,n){t.hasBackButton=!!n.showBack});t.$on("$destroy",r),t.$watch("!!(backButtonShown && hasBackButton)",function(e){n.toggleClass("hide",!e)})}}}}]).directive("ionNavButtons",["$compile","$animate",function(e,t){return{require:"^ionNavBar",restrict:"E",compile:function(n){var i=n.contents().remove();return function(n,o,r,a){var c="right"===r.side?a.rightButtonsElement:a.leftButtonsElement,s=angular.element("
").append(i);o.append(s),e(s)(n),t.enter(s,c),n.$on("$destroy",function(){t.leave(s)}),o.css("display","none")}}}}]),function(){"use strict";angular.module("ionic.ui.popup",[]).directive("ionPopupBackdrop",function(){return{restrict:"E",replace:!0,template:''}}).directive("ionPopup",["$ionicBind",function(e){return{restrict:"E",replace:!0,transclude:!0,scope:!0,template:'',link:function(t,n,i){e(t,i,{title:"@",buttons:"=",$onButtonTap:"&onButtonTap",$onClose:"&onClose"}),t._buttonTapped=function(e,n){var i=e.onTap&&e.onTap(n);return n.defaultPrevented?t.$onClose({button:e,result:!1,event:n}):i?t.$onClose({button:e,result:i,event:n}):void t.$onButtonTap({button:e,event:n})}}}}])}(),function(e){"use strict";angular.module("ionic.ui.radio",[]).directive("ionRadio",function(){return{restrict:"E",replace:!0,require:"?ngModel",scope:{ngModel:"=?",ngValue:"=?",ngChange:"&",icon:"@"},transclude:!0,template:'',compile:function(e,t){t.name&&e.children().eq(0).attr("name",t.name),t.icon&&e.children().eq(2).removeClass("ion-checkmark").addClass(t.icon)}}}).directive("ionRadioButtons",function(){return{restrict:"E",replace:!0,require:"?ngModel",scope:{value:"@"},transclude:!0,template:'
',controller:["$scope","$element",function(e,t){this.select=function(e){for(var n,i=t.children(),o=0;o=0,scrollingY:e.direction.indexOf("y")>=0};s&&(l.speedMultiplier=.8,l.bouncing=!1),c=t("$ionicScroll",{$scope:e,scrollViewOptions:l}),a=e.$parent.scrollView=c.scrollView}e.addClass("scroll-view");var o=angular.element('
');return o.append(e.contents()),e.append(o),{pre:i}}}}])}(),function(){"use strict";angular.module("ionic.ui.sideMenu",["ionic.service.gesture","ionic.service.view"]).run(["$ionicViewService",function(e){e.disableRegisterByTagName("ion-side-menus")}]).service("$ionicSideMenuDelegate",e(["toggleLeft","toggleRight","isOpenLeft","isOpenRight","canDragContent"])).directive("ionSideMenus",function(){return{restrict:"ECA",controller:["$scope","$attrs","$ionicSideMenuDelegate",function(e,t,n){angular.extend(this,ionic.controllers.SideMenuController.prototype),ionic.controllers.SideMenuController.call(this,{left:{width:275},right:{width:275}}),this.canDragContent=function(t){return arguments.length&&(e.dragContent=!!t),e.dragContent},e.sideMenuContentTranslateX=0;var i=n._registerInstance(this,t.delegateHandle);e.$on("$destroy",i)}],replace:!0,transclude:!0,template:'
'}}).directive("ionSideMenuContent",["$timeout","$ionicGesture",function(e,t){return{restrict:"EA",require:"^ionSideMenus",scope:!0,compile:function(n,i){function o(n,o,r,a){function c(e){0!==a.getOpenAmount()&&(a.close(),e.gesture.srcEvent.preventDefault())}o.addClass("menu-content pane"),angular.isDefined(i.dragContent)?n.$watch(i.dragContent,function(e){a.canDragContent(e)}):a.canDragContent(!0);var s=!1,l=!1;ionic.on("tap",c,o[0]);var u=function(e){if(n.dragContent){if(s||e.gesture.srcEvent.defaultPrevented)return;l=!0,a._handleDrag(e),e.gesture.srcEvent.preventDefault()}},d=function(e){l&&e.gesture.srcEvent.preventDefault()},f=t.on("dragright",u,o),v=t.on("dragleft",u,o),p=t.on("dragup",d,o),g=t.on("dragdown",d,o),h=function(e){l=!1,s||a._endDrag(e),s=!1},m=t.on("release",h,o);a.setContent({onDrag:function(){},endDrag:function(){},getTranslateX:function(){return n.sideMenuContentTranslateX||0},setTranslateX:ionic.animationFrameThrottle(function(t){o[0].style[ionic.CSS.TRANSFORM]="translate3d("+t+"px, 0, 0)",e(function(){n.sideMenuContentTranslateX=t})}),enableAnimation:function(){n.animationEnabled=!0,o[0].classList.add("menu-animated")},disableAnimation:function(){n.animationEnabled=!1,o[0].classList.remove("menu-animated")}}),n.$on("$destroy",function(){t.off(v,"dragleft",u),t.off(f,"dragright",u),t.off(p,"dragup",u),t.off(g,"dragdown",u),t.off(m,"release",h),ionic.off("tap",c,o[0])})}return{pre:o}}}}]).directive("ionSideMenu",function(){return{restrict:"E",require:"^ionSideMenus",scope:!0,compile:function(e,t){return angular.isUndefined(t.isEnabled)&&t.$set("isEnabled","true"),angular.isUndefined(t.width)&&t.$set("width","275"),e.addClass("menu menu-"+t.side),function(e,t,n,i){e.side=n.side||"left";var o=i[e.side]=new ionic.views.SideMenu({width:275,el:t[0],isEnabled:!0});e.$watch(n.width,function(e){var t=+e;t&&t==e&&o.setWidth(+e)}),e.$watch(n.isEnabled,function(e){o.setIsEnabled(!!e)})}}}}).directive("menuToggle",["$ionicViewService",function(){return{restrict:"AC",require:"^ionSideMenus",link:function(e,t,n,i){var o=e.$eval(n.menuToggle)||"left";t.bind("click",function(){"left"===o?i.toggleLeft():"right"===o&&i.toggleRight()})}}}]).directive("menuClose",["$ionicViewService",function(){return{restrict:"AC",require:"^ionSideMenus",link:function(e,t,n,i){t.bind("click",function(){i.close()})}}}])}(),function(){"use strict";angular.module("ionic.ui.slideBox",[]).service("$ionicSlideBoxDelegate",e(["update","slide","previous","next","stop","currentIndex","slidesCount"])).directive("ionSlideBox",["$timeout","$compile","$ionicSlideBoxDelegate",function(e,t,n){return{restrict:"E",replace:!0,transclude:!0,scope:{doesContinue:"@",slideInterval:"@",showPager:"@",disableScroll:"@",onSlideChanged:"&",activeSlide:"=?"},controller:["$scope","$element","$attrs",function(t,i,o){var r=t.$eval(t.doesContinue)===!0,a=r?t.$eval(t.slideInterval)||4e3:0,c=new ionic.views.Slider({el:i[0],auto:a,disableScroll:t.$eval(t.disableScroll)===!0||!1,continuous:r,startSlide:t.activeSlide,slidesChanged:function(){t.currentSlide=c.currentIndex(),e(function(){})},callback:function(n){t.currentSlide=n,t.onSlideChanged({index:t.currentSlide}),t.$parent.$broadcast("slideBox.slideChanged",n),t.activeSlide=n,e(function(){})}});t.$watch("activeSlide",function(e){angular.isDefined(e)&&c.slide(e)}),t.$on("slideBox.nextSlide",function(){c.next()}),t.$on("slideBox.prevSlide",function(){c.prev()}),t.$on("slideBox.setSlide",function(e,t){c.slide(t)}),this.__slider=c;var s=n._registerInstance(c,o.delegateHandle);t.$on("$destroy",s),this.slidesCount=function(){return c.slidesCount()},e(function(){c.load()})}],template:'
',link:function(e,n){if(e.$eval(e.showPager)!==!1){var i=e.$new(),o=angular.element("");n.append(o),t(o)(i)}}}}]).directive("ionSlide",function(){return{restrict:"E",require:"^ionSlideBox",compile:function(e){return e.addClass("slider-slide"),function(){}}}}).directive("ionPager",function(){return{restrict:"E",replace:!0,require:"^ionSlideBox",template:'
',link:function(e,t,n,i){var o=function(e){for(var n=t[0].children,i=n.length,o=0;i>o;o++)o==e?n[o].classList.add("active"):n[o].classList.remove("active")};e.numSlides=function(){return new Array(i.slidesCount())},e.$watch("currentSlide",function(e){o(e)})}}})}(),angular.module("ionic.ui.tabs",["ionic.service.view"]).run(["$ionicViewService",function(e){e.disableRegisterByTagName("ion-tabs")}]).service("$ionicTabsDelegate",e(["select","selectedIndex"])).controller("ionicTabs",["$scope","$ionicViewService","$element",function(e,t){var n=null,i=this;i.tabs=[],i.selectedIndex=function(){return i.tabs.indexOf(n)},i.selectedTab=function(){return n},i.add=function(e){t.registerHistory(e),i.tabs.push(e),1===i.tabs.length&&i.select(e)},i.remove=function(e){var t=i.tabs.indexOf(e);if(-1!==t){if(e.$tabSelected)if(i.deselect(e),1===i.tabs.length);else{var n=t===i.tabs.length-1?t-1:t+1;i.select(i.tabs[n])}i.tabs.splice(t,1)}},i.deselect=function(e){e.$tabSelected&&(n=null,e.$tabSelected=!1,(e.onDeselect||angular.noop)())},i.select=function(o,r){var a;if(angular.isNumber(o)?(a=o,o=i.tabs[a]):a=i.tabs.indexOf(o),!o||-1==a)throw new Error('Cannot select tab "'+a+'"!');if(n&&n.$historyId==o.$historyId)r&&t.goToHistoryRoot(o.$historyId);else if(angular.forEach(i.tabs,function(e){i.deselect(e)}),n=o,o.$tabSelected=!0,(o.onSelect||angular.noop)(),r){var c={type:"tab",tabIndex:a,historyId:o.$historyId,navViewName:o.navViewName,hasNavView:!!o.navViewName,title:o.title,url:o.href,uiSref:o.uiSref};e.$emit("viewState.changeHistory",c)}}}]).directive("ionTabs",["$ionicViewService","$ionicTabsDelegate",function(e,t){return{restrict:"E",scope:!0,controller:"ionicTabs",compile:function(e){function n(e,n,i,o){var r=t._registerInstance(o,i.delegateHandle);e.$on("$destroy",r),o.$scope=e,o.$element=n,o.$tabsElement=angular.element(n[0].querySelector(".tabs"));var a=n[0];e.$watch(function(){return a.className},function(t){var n=-1!==t.indexOf("tabs-top"),i=-1!==t.indexOf("tabs-item-hide");e.$hasTabs=!n&&!i,e.$hasTabsTop=n&&!i}),e.$on("$destroy",function(){e.$hasTabs=e.$hasTabsTop=null})}e.addClass("view");var i=angular.element('
');return i.append(e.contents()),e.append(i),{pre:n}}}}]).controller("ionicTab",["$scope","$ionicViewService","$rootScope","$element",function(e){this.$scope=e}]).directive("ionTab",["$rootScope","$animate","$ionicBind","$compile","$ionicViewService",function(e,t,n,i,o){function r(e,t){return angular.isDefined(t)?" "+e+'="'+t+'"':""}return{restrict:"E",require:["^ionTabs","ionTab"],replace:!0,controller:"ionicTab",scope:!0,compile:function(e,a){var c=e[0].querySelector("ion-nav-view")||e[0].querySelector("data-ion-nav-view"),s=c&&c.getAttribute("name"),l=(angular.element(e[0].querySelector("ion-tab-nav")||e[0].querySelector("data-ion-tab-nav")).remove(),angular.element('
').append(e.contents().remove()));return function(e,c,u,d){function f(){o.isCurrentStateNavView(e.navViewName)&&tabsCtrl.select(e)}var v,p,g;tabsCtrl=d[0],tabCtrl=d[1],c[0].removeAttribute("title"),n(e,u,{animate:"=",onSelect:"&",onDeselect:"&",title:"@",uiSref:"@",href:"@"}),tabsCtrl.add(e),e.$on("$destroy",function(){tabsCtrl.remove(e),g.isolateScope().$destroy(),g.remove()}),s&&(e.navViewName=s,e.$on("$stateChangeSuccess",f),f()),g=angular.element(""),g.data("$ionTabsController",tabsCtrl),g.data("$ionTabController",tabCtrl),tabsCtrl.$tabsElement.append(i(g)(e)),e.$watch("$tabSelected",function(n){v&&v.$destroy(),v=null,p&&t.leave(p),p=null,n&&(v=e.$new(),p=l.clone(),t.enter(p,tabsCtrl.$element),i(p)(v))})}}}}]).directive("ionTabNav",["$ionicNgClick",function(e){return{restrict:"E",replace:!0,require:["^ionTabs","^ionTab"],template:'{{badge}}',scope:{title:"@",icon:"@",iconOn:"@",iconOff:"@",badge:"=",badgeStyle:"@"},compile:function(){return function(t,n,i,o){var r=o[0],a=o[1];n[0].removeAttribute("title"),t.selectTab=function(e){e.preventDefault(),r.select(a.$scope,!0)},i.ngClick||e(t,n,"selectTab($event)"),t.getIconOn=function(){return t.iconOn||t.icon},t.getIconOff=function(){return t.iconOff||t.icon},t.isTabActive=function(){return r.selectedTab()===a.$scope}}}}}]),function(e){"use strict";angular.module("ionic.ui.toggle",[]).directive("ionToggle",["$ionicGesture","$timeout",function(){return{restrict:"E",replace:!0,require:"?ngModel",scope:{ngModel:"=?",ngValue:"=?",ngChecked:"=?",ngChange:"&",ngDisabled:"=?"},transclude:!0,template:'
',compile:function(t,n){var i=t.find("input");return n.name&&i.attr("name",n.name),n.ngChecked&&i.attr("ng-checked","ngChecked"),n.ngTrueValue&&i.attr("ng-true-value",n.ngTrueValue),n.ngFalseValue&&i.attr("ng-false-value",n.ngFalseValue),function(t,n){var i,o,r,a;i=n[0].getElementsByTagName("label")[0],o=i.children[0],r=i.children[1],a=r.children[0];var c=angular.element(o).controller("ngModel");t.toggle=new e.views.Toggle({el:i,track:r,checkbox:o,handle:a,onChange:function(){c.$setViewValue(o.checked?!0:!1),t.$apply()}}),t.$on("$destroy",function(){t.toggle.destroy()})}}}}])}(window.ionic),function(e,t){"use strict";e.module("ionic.ui.touch",[]).config(["$provide",function(e){e.decorator("ngClickDirective",["$delegate",function(e){return e.shift(),e}])}]).factory("$ionicNgClick",["$parse",function(e){function n(e){t.tapElement(e.target,e)}return function(i,o,r){var a=e(r);o.on("click",function(e){i.$apply(function(){a(i,{$event:e})})}),t.on("release",n,o[0]),o.onclick=function(){},i.$on("$destroy",function(){t.off("release",n,o[0])})}}]).directive("ngClick",["$ionicNgClick",function(e){return function(t,n,i){e(t,n,i.ngClick)}}]).directive("ionStopEvent",function(){function e(e){e.stopPropagation()}return{restrict:"A",link:function(t,n,i){n.bind(i.ionStopEvent,e)}}})}(window.angular,window.ionic),function(){"use strict";angular.module("ionic.ui.viewState",["ionic.service.view","ionic.service.gesture","ngSanitize"]).directive("ionView",["$ionicViewService","$rootScope","$animate",function(){return{restrict:"EA",priority:1e3,require:"^?ionNavBar",compile:function(e){return e.addClass("pane"),e[0].removeAttribute("title"),function(e,t,n,i){if(i){var o=n.title;i.changeTitle(o,e.$navDirection),n.$observe("title",function(e){e!==o&&i.setTitle(e)}),e.$watch(n.hideBackButton,function(e){i.showBackButton(!e)}),e.$watch(n.hideNavBar,function(e){i.showBar(!e)})}}}}}]).directive("ionNavView",["$ionicViewService","$state","$compile","$controller","$animate",function(e,t,n,i,o){var r=!1,a={restrict:"E",terminal:!0,priority:2e3,transclude:!0,controller:[function(){}],compile:function(c,s,l){return function(c,s,u){function d(r){o.enabled()===!1&&(r=!1);var a=t.$current&&t.$current.locals[p];if(a!==v){var l=e.getRenderer(s,u,c);if(f&&(f.$destroy(),f=null),!a)return v=null,$.state=null,s.append(h);var d=angular.element("
").html(a.$template).contents(),m=l().register(d);l(r).leave(),v=a,$.state=a.$$state,l(r).enter(d);var b=n(d);if(f=c.$new(),f.$navDirection=m.navDirection,a.$$controller){a.$scope=f;var w=i(a.$$controller,a);s.children().data("$ngControllerController",w)}b(f);var y=e._getViewById(m.viewId)||{};f.$broadcast("$viewContentLoaded",y),g&&f.$eval(g),d=null}}var f,v,p=u[a.name]||u.name||"",g=u.onload||"",h=l(c);s.append(h);var m=s.parent().inheritedData("$uiView");p.indexOf("@")<0&&(p=p+"@"+(m?m.state.name:""));var $={name:p,state:null};s.data("$uiView",$);var b=function(){if(!r){r=!0;try{d(!0)}catch(e){throw r=!1,e}r=!1}};c.$on("$stateChangeSuccess",b),c.$on("$viewContentLoading",b),d(!1)}}};return a}]).directive("navClear",["$ionicViewService",function(e){return{restrict:"AC",link:function(t,n){n.bind("click",function(){e.nextViewOptions({disableAnimate:!0,disableBack:!0})})}}}])}(),angular.module("ionic.ui.scroll").service("$ionicScrollDelegate",e(["resize","scrollTop","scrollBottom","scrollTo","anchorScroll","rememberScrollPosition","forgetScrollPosition","scrollToRememberedPosition"])).factory("$$scrollValueCache",function(){return{}}).controller("$ionicScroll",["$scope","scrollViewOptions","$timeout","$window","$$scrollValueCache","$location","$rootScope","$document","$ionicScrollDelegate",function(e,t,n,i,o,r,a,c,s){var l=this;this._scrollViewOptions=t;var u=this.element=t.el,d=this.$element=angular.element(u),f=this.scrollView=new ionic.views.Scroll(t);(d.parent().length?d.parent():d).data("$$ionicScrollController",this);var v=s._registerInstance(this,t.delegateHandle);angular.isDefined(t.bouncing)||ionic.Platform.ready(function(){f.options.bouncing=!ionic.Platform.isAndroid()});var p=angular.bind(f,f.resize);ionic.on("resize",p,i);var g=angular.noop;e.$on("$destroy",function(){v(),ionic.off("resize",p,i),i.removeEventListener("resize",p),g(),l._rememberScrollId&&(o[l._rememberScrollId]=f.getValues())}),d.on("scroll",function(t){var n=(t.originalEvent||t).detail||{};e.$onScroll&&e.$onScroll({event:t,scrollTop:n.scrollTop||0,scrollLeft:n.scrollLeft||0})}),e.$on("$viewContentLoaded",function(e,t){if(!e.defaultPrevented){e.preventDefault();var n=t&&t.viewId;n&&(l.rememberScrollPosition(n),l.scrollToRememberedPosition(),g=a.$on("$viewHistory.viewBack",function(e,t){n===t&&l.forgetScrollPosition()}))}}),n(function(){f.run()}),this._rememberScrollId=null,this.resize=function(){return n(p)},this.scrollTop=function(e){this.resize().then(function(){f.scrollTo(0,0,!!e)})},this.scrollBottom=function(e){this.resize().then(function(){var t=f.getScrollMax();f.scrollTo(t.left,t.top,!!e)})},this.scrollTo=function(e,t,n){this.resize().then(function(){f.scrollTo(e,t,!!n)})},this.anchorScroll=function(e){this.resize().then(function(){var t=r.hash(),n=t&&c[0].getElementById(t);if(t&&n){var i=ionic.DomUtil.getPositionInParent(n,l.$element);f.scrollTo(i.left,i.top,!!e)}else f.scrollTo(0,0,!!e)})},this.rememberScrollPosition=function(e){if(!e)throw new Error("Must supply an id to remember the scroll by!");this._rememberScrollId=e},this.forgetScrollPosition=function(){delete o[this._rememberScrollId],this._rememberScrollId=null},this.scrollToRememberedPosition=function(e){var t=o[this._rememberScrollId];t&&this.resize().then(function(){f.scrollTo(+t.left,+t.top,e)})},this._setRefresher=function(e,t){var n=this.refresher=t,i=l.refresher.clientHeight||0;f.activatePullToRefresh(i,function(){n.classList.add("active"),e.$onPulling()},function(){n.classList.remove("refreshing"),n.classList.remove("active")},function(){n.classList.add("refreshing"),e.$onRefresh()})}}])}(); \ No newline at end of file diff --git a/release/js/ionic.js b/release/js/ionic.js index 1105ae1350..664e4712d7 100644 --- a/release/js/ionic.js +++ b/release/js/ionic.js @@ -2,7 +2,7 @@ * Copyright 2014 Drifty Co. * http://drifty.com/ * - * Ionic, v0.9.27 + * Ionic, v1.0.0-beta.1 * A powerful HTML5 mobile app framework. * http://ionicframework.com/ * @@ -12,13 +12,14 @@ * */ +(function() { // Create namespaces // window.ionic = { controllers: {}, views: {}, - version: '{{ VERSION }}' + version: '1.0.0-beta.1' }; (function(ionic) { @@ -135,16 +136,19 @@ window.ionic = { }; })(ionic); -(function(ionic) { +(function(window, document, ionic) { - var readyCallbacks = [], - domReady = function() { + var readyCallbacks = []; + var isDomReady = false; + + function domReady() { + isDomReady = true; for(var x=0; x startCoordinates.x + HIT_RADIUS || - c.x < startCoordinates.x - HIT_RADIUS || - c.y > startCoordinates.y + HIT_RADIUS || - c.y < startCoordinates.y - HIT_RADIUS); + // Quick check for 0,0 which could be simulated mouse click for form submission + if(c.x === 0 && c.y === 0) { + return false; + } + + return (c.x > startCoordinates.x + 2 || + c.x < startCoordinates.x - 2 || + c.y > startCoordinates.y + 2 || + c.y < startCoordinates.y - 2); } function recordCoordinates(event) { @@ -2482,23 +2492,19 @@ window.ionic = { gesture.originalEvent.changedTouches[0]) || touches[0].originalEvent || touches[0]; - if(e) return { x: e.clientX, y: e.clientY }; + if(e) return { x: e.clientX || e.pageX, y: e.clientY || e.pageY }; } return { x:0, y:0 }; } + var clickPreventTimerId; function removeClickPrevent(e) { - setTimeout(function(){ + clearTimeout(clickPreventTimerId); + clickPreventTimerId = setTimeout(function(){ var tap = isRecentTap(e); if(tap) delete tapCoordinates[tap.id]; + startCoordinates = {}; }, REMOVE_PREVENT_DELAY); - - setTimeout(function(){ - for(var hitKey in hitElements) { - hitElements[hitKey] && hitElements[hitKey].classList.remove('active'); - delete hitElements[hitKey]; - } - }, 150); } function stopEvent(e){ @@ -2510,8 +2516,7 @@ window.ionic = { function blurActive() { var ele = document.activeElement; if(ele && (ele.tagName === "INPUT" || - ele.tagName === "TEXTAREA" || - ele.tagName === "SELECT")) { + ele.tagName === "TEXTAREA")) { // using a timeout to prevent funky scrolling while a keyboard hides setTimeout(function(){ ele.blur(); @@ -2521,46 +2526,143 @@ window.ionic = { function recordStartCoordinates(e) { startCoordinates = getCoordinates(e); - - var x, ele = e.target; - for(x=0; x<5; x++) { - if(!ele || ele.tagName === 'LABEL') break; - if( ele.classList.contains('item') || ele.classList.contains('button') ) { - hitElements[hitCounts] = ele; - hitCounts = (hitCounts > 24 ? 0 : hitCounts + 1); - ionic.requestAnimationFrame(function(){ - ele.classList.add('active'); - }); - break; - } - ele = ele.parentElement; - } } var tapCoordinates = {}; // used to remember coordinates to ignore if they happen again quickly var startCoordinates = {}; // used to remember where the coordinates of the start of the tap var CLICK_PREVENT_DURATION = 1500; // max milliseconds ghostclicks in the same area should be prevented - var REMOVE_PREVENT_DELAY = 375; // delay after a touchend/mouseup before removing the ghostclick prevent + var REMOVE_PREVENT_DELAY = 380; // delay after a touchend/mouseup before removing the ghostclick prevent var HIT_RADIUS = 15; - var hitElements = {}; - var hitCounts = 0; - // set global click handler and check if the event should stop or not - document.addEventListener('click', preventGhostClick, true); + ionic.Platform.ready(function(){ - // global tap event listener polyfill for HTML elements that were "tapped" by the user - ionic.on("tap", tapPolyfill, document); + if(ionic.Platform.grade === 'c') { + // low performing phones should have a longer ghostclick prevent + REMOVE_PREVENT_DELAY = 800; + } - // listeners used to remove ghostclick prevention - document.addEventListener('touchend', removeClickPrevent, false); - document.addEventListener('mouseup', removeClickPrevent, false); + // set global click handler and check if the event should stop or not + document.addEventListener('click', preventGhostClick, true); - // in the case the user touched the screen, then scrolled, it shouldn't fire the click - document.addEventListener('touchstart', recordStartCoordinates, false); - document.addEventListener('mousedown', recordStartCoordinates, false); + // global release event listener polyfill for HTML elements that were tapped or held + ionic.on("release", tapPolyfill, document); + + // listeners used to remove ghostclick prevention + document.addEventListener('touchend', removeClickPrevent, false); + document.addEventListener('mouseup', removeClickPrevent, false); + + // in the case the user touched the screen, then scrolled, it shouldn't fire the click + document.addEventListener('touchstart', recordStartCoordinates, false); + document.addEventListener('mousedown', recordStartCoordinates, false); + }); })(this, document, ionic); +(function(document, ionic) { + 'use strict'; + + var queueElements = {}; // elements that should get an active state in XX milliseconds + var activeElements = {}; // elements that are currently active + var keyId = 0; // a counter for unique keys for the above ojects + + ionic.activator = { + + start: function(e) { + // when an element is touched/clicked, it climbs up a few + // parents to see if it is an .item or .button element + ionic.requestAnimationFrame(function(){ + var ele = e.target; + var eleToActivate; + + for(var x=0; x<4; x++) { + if(!ele) break; + if(eleToActivate && ele.classList.contains('item')) { + eleToActivate = ele; + break; + } + if( ele.tagName == 'A' || ele.tagName == 'BUTTON' || ele.getAttribute('ng-click') ) { + eleToActivate = ele; + } + if( ele.classList.contains('button') ) { + eleToActivate = ele; + break; + } + ele = ele.parentElement; + } + + if(eleToActivate) { + // queue that this element should be set to active + queueElements[keyId] = eleToActivate; + + // in XX milliseconds, set the queued elements to active + // add listeners to clear all queued/active elements onMove + if(e.type === 'touchstart') { + document.body.removeEventListener('mousedown', ionic.activator.start); + document.body.addEventListener('touchmove', clear, false); + setTimeout(activateElements, 85); + } else { + document.body.addEventListener('mousemove', clear, false); + ionic.requestAnimationFrame(activateElements); + } + + keyId = (keyId > 19 ? 0 : keyId + 1); + } + + }); + } + }; + + function activateElements() { + // activate all elements in the queue + for(var key in queueElements) { + if(queueElements[key]) { + queueElements[key].classList.add('active'); + activeElements[key] = queueElements[key]; + } + } + queueElements = {}; + } + + function deactivateElements() { + for(var key in activeElements) { + if(activeElements[key]) { + activeElements[key].classList.remove('active'); + delete activeElements[key]; + } + } + } + + function onEnd(e) { + // clear out any active/queued elements after XX milliseconds + setTimeout(clear, 200); + } + + function clear() { + // clear out any elements that are queued to be set to active + queueElements = {}; + + // in the next frame, remove the active class from all active elements + ionic.requestAnimationFrame(deactivateElements); + + // remove onMove listeners that clear out active elements + document.body.removeEventListener('mousemove', clear); + document.body.removeEventListener('touchmove', clear); + } + + // use window.onload because this doesn't need to run immediately + window.addEventListener('load', function(){ + // start an active element + document.body.addEventListener('touchstart', ionic.activator.start, false); + document.body.addEventListener('mousedown', ionic.activator.start, false); + + // clear all active elements after XX milliseconds + document.body.addEventListener('touchend', onEnd, false); + document.body.addEventListener('mouseup', onEnd, false); + document.body.addEventListener('touchcancel', onEnd, false); + }, false); + +})(document, ionic); + (function(ionic) { /* for nextUid() function below */ @@ -2773,12 +2875,12 @@ function androidKeyboardFix() { //If the height changes, and it's less than before, we have a keyboard open } else if (rememberedDeviceHeight !== window.innerHeight && window.innerHeight < rememberedDeviceHeight) { - document.body.classList.add('hide-footer'); + document.body.classList.add('footer-hide'); //Wait for next frame so document.activeElement is set ionic.requestAnimationFrame(handleKeyboardChange); } else { //Otherwise we have a keyboard close or a *really* weird resize - document.body.classList.remove('hide-footer'); + document.body.classList.remove('footer-hide'); } function handleKeyboardChange() { @@ -2850,7 +2952,7 @@ var IS_EMBEDDED_OBJECT_REGEX = /object|embed/i; // Create namespaces if (!global.core) { - global.core = { effect : {} }; + var core = global.core = { effect : {} }; } else if (!core.effect) { core.effect = {}; @@ -3436,8 +3538,9 @@ ionic.views.Scroll = ionic.views.View.inherit({ function shouldIgnorePress(e) { // Don't react if initial down happens on a form element return e.target.tagName.match(IS_INPUT_LIKE_REGEX) || - e.target.isContentEditable || - e.target.tagName.match(IS_EMBEDDED_OBJECT_REGEX); + e.target.isContentEditable || + e.target.tagName.match(IS_EMBEDDED_OBJECT_REGEX) || + e.target.dataset.preventScroll; } @@ -3502,8 +3605,18 @@ ionic.views.Scroll = ionic.views.View.inherit({ mousedown = false; }, false); + var wheelShowBarFn = ionic.debounce(function() { + self.__fadeScrollbars('in'); + }, 500, true); + + var wheelHideBarFn = ionic.debounce(function() { + self.__fadeScrollbars('out'); + }, 100, false); + document.addEventListener("mousewheel", function(e) { + wheelShowBarFn(); self.scrollBy(e.wheelDeltaX/self.options.wheelDampen, -e.wheelDeltaY/self.options.wheelDampen); + wheelHideBarFn(); }); } }, @@ -3558,9 +3671,6 @@ ionic.views.Scroll = ionic.views.View.inherit({ __resizeScrollbars: function() { var self = this; - // Bring the scrollbars in to show the content change - self.__fadeScrollbars('in'); - // Update horiz bar if(self.__indicatorX) { var width = Math.max(Math.round(self.__clientWidth * self.__clientWidth / (self.__contentWidth)), 20); @@ -4175,8 +4285,6 @@ ionic.views.Scroll = ionic.views.View.inherit({ var self = this; - self.__fadeScrollbars('in'); - // Reset interruptedAnimation flag self.__interruptedAnimation = true; @@ -4419,6 +4527,7 @@ ionic.views.Scroll = ionic.views.View.inherit({ self.__isDragging = (self.__enableScrollX || self.__enableScrollY) && (distanceX >= minimumTrackingForDrag || distanceY >= minimumTrackingForDrag); if (self.__isDragging) { self.__interruptedAnimation = false; + self.__fadeScrollbars('in'); } } @@ -4921,15 +5030,6 @@ ionic.views.Scroll = ionic.views.View.inherit({ (function(ionic) { 'use strict'; - /** - * @ngdoc controller - * @name ionicBar - * @module ionic - * @group page layout - * @description - * Controller for the {@link ionic.directive:ionHeaderBar} and - * {@link ionic.directive:ionFooterBar} directives. - */ ionic.views.HeaderBar = ionic.views.View.inherit({ initialize: function(opts) { this.el = opts.el; @@ -4941,16 +5041,6 @@ ionic.views.Scroll = ionic.views.View.inherit({ this.align(); }, - /** - * @ngdoc method - * @name ionicBar#align - * @description - * Aligns the title text with the buttons in the bar - * so that the title size is maximized and aligned correctly - * as much as possible. - * @param {string=} direction Which direction to align the title towards. - * Available: 'left', 'right', 'center'. Default: 'center'. - */ align: function(align) { align || (align = this.alignTitle); @@ -5034,7 +5124,7 @@ ionic.views.Scroll = ionic.views.View.inherit({ var ITEM_OPTIONS_CLASS = 'item-options'; var ITEM_PLACEHOLDER_CLASS = 'item-placeholder'; var ITEM_REORDERING_CLASS = 'item-reordering'; - var ITEM_DRAG_CLASS = 'item-drag'; + var ITEM_REORDER_BTN_CLASS = 'item-reorder'; var DragOp = function() {}; DragOp.prototype = { @@ -5043,6 +5133,9 @@ ionic.views.Scroll = ionic.views.View.inherit({ drag: function(e) { }, end: function(e) { + }, + isSameItem: function(item) { + return false; } }; @@ -5054,6 +5147,7 @@ ionic.views.Scroll = ionic.views.View.inherit({ }; SlideDrag.prototype = new DragOp(); + SlideDrag.prototype.start = function(e) { var content, buttons, offsetX, buttonsWidth; @@ -5091,6 +5185,27 @@ ionic.views.Scroll = ionic.views.View.inherit({ }; }; + /** + * Check if this is the same item that was previously dragged. + */ + SlideDrag.prototype.isSameItem = function(op) { + if(op._lastDrag && this._currentDrag) { + return this._currentDrag.content == op._lastDrag.content; + } + return false; + }; + + SlideDrag.prototype.clean = function(e) { + var lastDrag = this._lastDrag; + + if(!lastDrag) return; + + ionic.requestAnimationFrame(function() { + lastDrag.content.style[ionic.CSS.TRANSITION] = ''; + lastDrag.content.style[ionic.CSS.TRANSFORM] = 'translate3d(0, 0, 0)'; + }); + }; + SlideDrag.prototype.drag = ionic.animationFrameThrottle(function(e) { var buttonsWidth; @@ -5151,21 +5266,7 @@ ionic.views.Scroll = ionic.views.View.inherit({ } - // var content = this._currentDrag.content; - - // var onRestingAnimationEnd = function(e) { - // if(e.propertyName == '-webkit-transform') { - // if(content) content.classList.remove(ITEM_SLIDING_CLASS); - // } - // e.target.removeEventListener('webkitTransitionEnd', onRestingAnimationEnd); - // }; - ionic.requestAnimationFrame(function() { - // var currentX = parseFloat(_this._currentDrag.content.style[ionic.CSS.TRANSFORM].replace('translate3d(', '').split(',')[0]) || 0; - // if(currentX !== restingPoint) { - // _this._currentDrag.content.classList.add(ITEM_SLIDING_CLASS); - // _this._currentDrag.content.addEventListener('webkitTransitionEnd', onRestingAnimationEnd); - // } if(restingPoint === 0) { _this._currentDrag.content.style[ionic.CSS.TRANSFORM] = ''; } else { @@ -5175,9 +5276,9 @@ ionic.views.Scroll = ionic.views.View.inherit({ // Kill the current drag + _this._lastDrag = _this._currentDrag; _this._currentDrag = null; - // We are done, notify caller doneCallback && doneCallback(); }); @@ -5331,7 +5432,8 @@ ionic.views.Scroll = ionic.views.View.inherit({ opts = ionic.extend({ onReorder: function(el, oldIndex, newIndex) {}, virtualRemoveThreshold: -200, - virtualAddThreshold: 200 + virtualAddThreshold: 200, + canSwipe: false }, opts); ionic.extend(this, opts); @@ -5346,10 +5448,6 @@ ionic.views.Scroll = ionic.views.View.inherit({ this.onRefreshOpening = opts.onRefreshOpening || function() {}; this.onRefreshHolding = opts.onRefreshHolding || function() {}; - window.ionic.onGesture('touch', function(e) { - _this._handleTouch(e); - }, this.el); - window.ionic.onGesture('release', function(e) { _this._handleEndDrag(e); }, this.el); @@ -5427,10 +5525,22 @@ ionic.views.Scroll = ionic.views.View.inherit({ } }, + /** + * Clear any active drag effects on the list. + */ + clearDragEffects: function() { + if(this._lastDragOp) { + this._lastDragOp.clean && this._lastDragOp.clean(); + this._lastDragOp = null; + } + }, + _initDrag: function() { //ionic.views.ListView.__super__._initDrag.call(this); - //this._isDragging = false; + // Store the last one + this._lastDragOp = this._dragOp; + this._dragOp = null; }, @@ -5449,10 +5559,14 @@ ionic.views.Scroll = ionic.views.View.inherit({ _startDrag: function(e) { var _this = this; + var didStart = false; + this._isDragging = false; + var lastDragOp = this._lastDragOp; + // Check if this is a reorder drag - if(ionic.DomUtil.getParentOrSelfWithClass(e.target, ITEM_DRAG_CLASS) && (e.gesture.direction == 'up' || e.gesture.direction == 'down')) { + if(ionic.DomUtil.getParentOrSelfWithClass(e.target, ITEM_REORDER_BTN_CLASS) && (e.gesture.direction == 'up' || e.gesture.direction == 'down')) { var item = this._getItem(e.target); if(item) { @@ -5466,20 +5580,25 @@ ionic.views.Scroll = ionic.views.View.inherit({ }); this._dragOp.start(e); e.preventDefault(); - return; } } // Or check if this is a swipe to the side drag else if(!this._didDragUpOrDown && (e.gesture.direction == 'left' || e.gesture.direction == 'right') && Math.abs(e.gesture.deltaX) > 5) { - this._dragOp = new SlideDrag({ el: this.el }); - this._dragOp.start(e); - e.preventDefault(); - return; + + // Make sure this is an item with buttons + var item = this._getItem(e.target); + if(item && item.querySelector('.item-options')) { + this._dragOp = new SlideDrag({ el: this.el }); + this._dragOp.start(e); + e.preventDefault(); + } } - // We aren't handling it, so pass it up the chain - //ionic.views.ListView.__super__._startDrag.call(this, e); + // If we had a last drag operation and this is a new one on a different item, clean that last one + if(lastDragOp && this._dragOp && !this._dragOp.isSameItem(lastDragOp) && e.defaultPrevented) { + lastDragOp.clean && lastDragOp.clean(); + } }, @@ -5493,13 +5612,6 @@ ionic.views.Scroll = ionic.views.View.inherit({ return; } - // Cancel touch timeout - clearTimeout(this._touchTimeout); - var items = _this.el.querySelectorAll('.item'); - for(var i = 0, l = items.length; i < l; i++) { - items[i].classList.remove('active'); - } - this._dragOp.end(e, function() { _this._initDrag(); }); @@ -5511,17 +5623,14 @@ ionic.views.Scroll = ionic.views.View.inherit({ _handleDrag: function(e) { var _this = this, content, buttons; + if (!this.canSwipe) { + return; + } + if(Math.abs(e.gesture.deltaY) > 5) { this._didDragUpOrDown = true; } - // If the user has a touch timeout to highlight an element, clear it if we - // get sufficient draggage - if(Math.abs(e.gesture.deltaX) > 10 || Math.abs(e.gesture.deltaY) > 10) { - clearTimeout(this._touchTimeout); - } - - clearTimeout(this._touchTimeout); // If we get a drag event, make sure we aren't in another drag, then check if we should // start one if(!this.isDragging && !this._dragOp) { @@ -5536,25 +5645,7 @@ ionic.views.Scroll = ionic.views.View.inherit({ e.gesture.srcEvent.preventDefault(); this._dragOp.drag(e); - }, - - /** - * Handle the touch event to show the active state on an item if necessary. - */ - _handleTouch: function(e) { - var _this = this; - - var item = ionic.DomUtil.getParentOrSelfWithClass(e.target, ITEM_CLASS); - if(!item) { return; } - - this._touchTimeout = setTimeout(function() { - var items = _this.el.querySelectorAll('.item'); - for(var i = 0, l = items.length; i < l; i++) { - items[i].classList.remove('active'); - } - item.classList.add('active'); - }, 250); - }, + } }); @@ -5578,7 +5669,7 @@ ionic.views.Scroll = ionic.views.View.inherit({ this.showDelay = opts.showDelay || 0; - this._loadingBox = this.el.querySelector('.loading'); + this._loadingBox = this.el.querySelector('.loading') || this.el; }, show: function() { var _this = this; @@ -5607,6 +5698,11 @@ ionic.views.Scroll = ionic.views.View.inherit({ window.clearTimeout(this._showDelayTimeout); this.el.classList.remove('active'); + }, + setContent: function(html) { + if (this._loadingBox) { + this._loadingBox.innerHTML = html || ''; + } } }); @@ -5788,14 +5884,6 @@ ionic.views.Scroll = ionic.views.View.inherit({ * */ -/** - * @ngdoc controller - * @name ionicSlideBox - * @module ionic - * @description - * Controller for the {@link ionic.directive:ionSlideBox} directive. - */ - (function(ionic) { 'use strict'; @@ -6251,16 +6339,13 @@ ionic.views.Slider = ionic.views.View.inherit({ } // Public API + this.update = function() { + setTimeout(setup); + }; this.setup = function() { setup(); }; - /** - * @ngdoc method - * @name ionicSlideBox#slide - * @param {number} to The index to slide to. - * @param {number=} speed The number of milliseconds for the change to take. - */ this.slide = function(to, speed) { // cancel slideshow stop(); @@ -6268,23 +6353,13 @@ ionic.views.Slider = ionic.views.View.inherit({ slide(to, speed); }; - /** - * @ngdoc method - * @name ionicSlideBox#prev - * @description Go to the previous slide. Wraps around if at the beginning. - */ - this.prev = function() { + this.prev = this.previous = function() { // cancel slideshow stop(); prev(); }; - /** - * @ngdoc method - * @name ionicSlideBox#next - * @description Go to the next slide. Wraps around if at the end. - */ this.next = function() { // cancel slideshow stop(); @@ -6292,32 +6367,16 @@ ionic.views.Slider = ionic.views.View.inherit({ next(); }; - /** - * @ngdoc method - * @name ionicSlideBox#stop - * @description Stop sliding. The slideBox will not move again until - * explicitly told to do so. - */ this.stop = function() { // cancel slideshow stop(); }; - /** - * @ngdoc method - * @name ionicSlideBox#currentIndex - * @returns number The index of the current slide. - */ this.currentIndex = function() { // return current index position return index; }; - /** - * @ngdoc method - * @name ionicSlideBox#slidesCount - * @returns number The number of slides there are currently. - */ this.slidesCount = function() { // return total number of slides return length; @@ -6996,13 +7055,24 @@ ionic.controllers.NavController = ionic.controllers.ViewController.inherit({ }; }, + isOpenLeft: function() { + return this.getOpenAmount() > 0; + }, + + isOpenRight: function() { + return this.getOpenAmount() < 0; + }, + /** * Toggle the left menu to open 100% */ - toggleLeft: function() { - this.content.enableAnimation(); + toggleLeft: function(shouldOpen) { var openAmount = this.getOpenAmount(); - if(openAmount > 0) { + if (arguments.length === 0) { + shouldOpen = openAmount <= 0; + } + this.content.enableAnimation(); + if(!shouldOpen) { this.openPercentage(0); } else { this.openPercentage(100); @@ -7012,10 +7082,13 @@ ionic.controllers.NavController = ionic.controllers.ViewController.inherit({ /** * Toggle the right menu to open 100% */ - toggleRight: function() { - this.content.enableAnimation(); + toggleRight: function(shouldOpen) { var openAmount = this.getOpenAmount(); - if(openAmount < 0) { + if (arguments.length === 0) { + shouldOpen = openAmount >= 0; + } + this.content.enableAnimation(); + if(!shouldOpen) { this.openPercentage(0); } else { this.openPercentage(-100); @@ -7381,3 +7454,5 @@ ionic.controllers.TabBarController = ionic.controllers.ViewController.inherit({ }); })(window.ionic); + +})(); \ No newline at end of file diff --git a/release/js/ionic.min.js b/release/js/ionic.min.js index 6301b7124a..2919365bc9 100644 --- a/release/js/ionic.min.js +++ b/release/js/ionic.min.js @@ -2,7 +2,7 @@ * Copyright 2014 Drifty Co. * http://drifty.com/ * - * Ionic, v0.9.27 + * Ionic, v1.0.0-beta.1 * A powerful HTML5 mobile app framework. * http://ionicframework.com/ * @@ -12,6 +12,6 @@ * */ -window.ionic={controllers:{},views:{},version:"{{ VERSION }}"},function(t){function e(t){return t*t*t}function i(t){return 3*t*t*(1-t)}function n(t){return 3*t*(1-t)*(1-t)}function r(t){return(1-t)*(1-t)*(1-t)}var o=function(t,e){return t||(t=0),e||(e=0),{x:t,y:e}};t.Animator={getQuadraticBezier:function(t,s,a,l,c){var h=new o;return h.x=s.x*e(t)+a.x*i(t)+l.x*n(t)+c.x*r(t),h.y=s.y*e(t)+a.y*i(t)+l.y*n(t)+c.y*r(t),h},getCubicBezier:function(t,e,i,n,r){epsilon=1e3/60/r/4;var o=function(e){var n=1-e;return 3*n*n*e*t+3*n*e*e*i+e*e*e},s=function(t){var i=1-t;return 3*i*i*t*e+3*i*t*t*n+t*t*t},a=function(e){var n=1-e;return 3*(2*(e-1)*e+n*n)*t+3*(-e*e*e+2*n*e)*i};return function(t){var e,i,n,r,l,c,h=t;for(n=h,c=0;8>c;c++){if(r=o(n)-h,Math.abs(r)n)return s(e);if(n>i)return s(i);for(;i>e;){if(r=o(n),Math.abs(r-h)r?e=n:i=n,n=.5*(i-e)+e}return s(n)}},animate:function(t){return{leave:function(){var e=function(){t.classList.remove("leave"),t.classList.remove("leave-active"),t.removeEventListener("webkitTransitionEnd",e),t.removeEventListener("transitionEnd",e)};return t.addEventListener("webkitTransitionEnd",e),t.addEventListener("transitionEnd",e),t.classList.add("leave"),t.classList.add("leave-active"),this},enter:function(){var e=function(){t.classList.remove("enter"),t.classList.remove("enter-active"),t.removeEventListener("webkitTransitionEnd",e),t.removeEventListener("transitionEnd",e)};return t.addEventListener("webkitTransitionEnd",e),t.addEventListener("transitionEnd",e),t.classList.add("enter"),t.classList.add("enter-active"),this}}}}}(ionic),function(t){var e=[],i=function(){for(var n=0;nr;r++)if(i=n[r],i.nodeName&&i.nodeName.toLowerCase()==e){if(i==t)return o;o++}return Array.prototype.slice.call(t.parentNode.children).indexOf(t)},swapNodes:function(t,e){e.parentNode.insertBefore(t,e)},getParentWithClass:function(t,e){for(;t.parentNode;){if(t.parentNode.classList&&t.parentNode.classList.contains(e))return t.parentNode;t=t.parentNode}return null},getParentOrSelfWithClass:function(t,e){for(;t;){if(t.classList&&t.classList.contains(e))return t;t=t.parentNode}return null},rectContains:function(t,e,i,n,r,o){return i>t||t>r?!1:n>e||e>o?!1:!0}},t.requestAnimationFrame=t.DomUtil.requestAnimationFrame,t.animationFrameThrottle=t.DomUtil.animationFrameThrottle}(window.ionic),function(t){window.CustomEvent||!function(){var t;t=function(t,e){var i;e=e||{bubbles:!1,cancelable:!1,detail:void 0};try{i=document.createEvent("CustomEvent"),i.initCustomEvent(t,e.bubbles,e.cancelable,e.detail)}catch(n){i=document.createEvent("Event");for(var r in e)i[r]=e[r];i.initEvent(t,e.bubbles,e.cancelable)}return i},t.prototype=window.Event.prototype,window.CustomEvent=t}(),t.EventController={VIRTUALIZED_EVENTS:["tap","swipe","swiperight","swipeleft","drag","hold","release"],trigger:function(t,e,i,n){var r=new CustomEvent(t,{detail:e,bubbles:!!i,cancelable:!!n});e&&e.target&&e.target.dispatchEvent(r)||window.dispatchEvent(r)},on:function(e,i,n){for(var r=n||window,o=0,s=this.VIRTUALIZED_EVENTS.length;s>o;o++)if(e==this.VIRTUALIZED_EVENTS[o]){var a=new t.Gesture(n);return a.on(e,i),a}r.addEventListener(e,i)},off:function(t,e,i){i.removeEventListener(t,e)},onGesture:function(e,i,n){var r=new t.Gesture(n);return r.on(e,i),r},offGesture:function(t,e,i){t.off(e,i)},handlePopState:function(){}},t.on=function(){t.EventController.on.apply(t.EventController,arguments)},t.off=function(){t.EventController.off.apply(t.EventController,arguments)},t.trigger=t.EventController.trigger,t.onGesture=function(){return t.EventController.onGesture.apply(t.EventController.onGesture,arguments)},t.offGesture=function(){return t.EventController.offGesture.apply(t.EventController.offGesture,arguments)}}(window.ionic),function(t){function e(){if(!t.Gestures.READY){t.Gestures.event.determineEventTypes();for(var e in t.Gestures.gestures)t.Gestures.gestures.hasOwnProperty(e)&&t.Gestures.detection.register(t.Gestures.gestures[e]);t.Gestures.event.onTouch(t.Gestures.DOCUMENT,t.Gestures.EVENT_MOVE,t.Gestures.detection.detect),t.Gestures.event.onTouch(t.Gestures.DOCUMENT,t.Gestures.EVENT_END,t.Gestures.detection.detect),t.Gestures.READY=!0}}t.Gesture=function(e,i){return new t.Gestures.Instance(e,i||{})},t.Gestures={},t.Gestures.defaults={stop_browser_behavior:"disable-user-behavior"},t.Gestures.HAS_POINTEREVENTS=window.navigator.pointerEnabled||window.navigator.msPointerEnabled,t.Gestures.HAS_TOUCHEVENTS="ontouchstart"in window,t.Gestures.MOBILE_REGEX=/mobile|tablet|ip(ad|hone|od)|android|silk/i,t.Gestures.NO_MOUSEEVENTS=t.Gestures.HAS_TOUCHEVENTS&&window.navigator.userAgent.match(t.Gestures.MOBILE_REGEX),t.Gestures.EVENT_TYPES={},t.Gestures.DIRECTION_DOWN="down",t.Gestures.DIRECTION_LEFT="left",t.Gestures.DIRECTION_UP="up",t.Gestures.DIRECTION_RIGHT="right",t.Gestures.POINTER_MOUSE="mouse",t.Gestures.POINTER_TOUCH="touch",t.Gestures.POINTER_PEN="pen",t.Gestures.EVENT_START="start",t.Gestures.EVENT_MOVE="move",t.Gestures.EVENT_END="end",t.Gestures.DOCUMENT=window.document,t.Gestures.plugins={},t.Gestures.READY=!1,t.Gestures.Instance=function(i,n){var r=this;if(null!==i)return e(),this.element=i,this.enabled=!0,this.options=t.Gestures.utils.extend(t.Gestures.utils.extend({},t.Gestures.defaults),n||{}),this.options.stop_browser_behavior&&t.Gestures.utils.stopDefaultBrowserBehavior(this.element,this.options.stop_browser_behavior),t.Gestures.event.onTouch(i,t.Gestures.EVENT_START,function(e){r.enabled&&t.Gestures.detection.startDetect(r,e)}),this},t.Gestures.Instance.prototype={on:function(t,e){for(var i=t.split(" "),n=0;n0&&o==t.Gestures.EVENT_END?o=t.Gestures.EVENT_MOVE:h||(o=t.Gestures.EVENT_END),(h||null===i)&&(i=l),s.call(t.Gestures.detection,a.collectEventData(e,o,a.getTouchList(i,o),l)),t.Gestures.HAS_POINTEREVENTS&&o==t.Gestures.EVENT_END&&(h=t.Gestures.PointerEvent.updatePointer(o,l))),h||(i=null,n=!1,r=!1,t.Gestures.PointerEvent.reset())}})},determineEventTypes:function(){var e;e=t.Gestures.HAS_POINTEREVENTS?t.Gestures.PointerEvent.getEvents():t.Gestures.NO_MOUSEEVENTS?["touchstart","touchmove","touchend touchcancel"]:["touchstart mousedown","touchmove mousemove","touchend touchcancel mouseup"],t.Gestures.EVENT_TYPES[t.Gestures.EVENT_START]=e[0],t.Gestures.EVENT_TYPES[t.Gestures.EVENT_MOVE]=e[1],t.Gestures.EVENT_TYPES[t.Gestures.EVENT_END]=e[2]},getTouchList:function(e){return t.Gestures.HAS_POINTEREVENTS?t.Gestures.PointerEvent.getTouchList():e.touches?e.touches:(e.indentifier=1,[e])},collectEventData:function(e,i,n,r){var o=t.Gestures.POINTER_TOUCH;return(r.type.match(/mouse/)||t.Gestures.PointerEvent.matchType(t.Gestures.POINTER_MOUSE,r))&&(o=t.Gestures.POINTER_MOUSE),{center:t.Gestures.utils.getCenter(n),timeStamp:(new Date).getTime(),target:r.target,touches:n,eventType:i,pointerType:o,srcEvent:r,preventDefault:function(){this.srcEvent.preventManipulation&&this.srcEvent.preventManipulation(),this.srcEvent.preventDefault},stopPropagation:function(){this.srcEvent.stopPropagation()},stopDetect:function(){return t.Gestures.detection.stopDetect()}}}},t.Gestures.PointerEvent={pointers:{},getTouchList:function(){var t=this,e=[];return Object.keys(t.pointers).sort().forEach(function(i){e.push(t.pointers[i])}),e},updatePointer:function(e,i){return e==t.Gestures.EVENT_END?this.pointers={}:(i.identifier=i.pointerId,this.pointers[i.pointerId]=i),Object.keys(this.pointers).length},matchType:function(e,i){if(!i.pointerType)return!1;var n={};return n[t.Gestures.POINTER_MOUSE]=i.pointerType==i.MSPOINTER_TYPE_MOUSE||i.pointerType==t.Gestures.POINTER_MOUSE,n[t.Gestures.POINTER_TOUCH]=i.pointerType==i.MSPOINTER_TYPE_TOUCH||i.pointerType==t.Gestures.POINTER_TOUCH,n[t.Gestures.POINTER_PEN]=i.pointerType==i.MSPOINTER_TYPE_PEN||i.pointerType==t.Gestures.POINTER_PEN,n[e]},getEvents:function(){return["pointerdown MSPointerDown","pointermove MSPointerMove","pointerup pointercancel MSPointerUp MSPointerCancel"]},reset:function(){this.pointers={}}},t.Gestures.utils={extend:function(t,e,i){for(var n in e)void 0!==t[n]&&i||(t[n]=e[n]);return t},hasParent:function(t,e){for(;t;){if(t==e)return!0;t=t.parentNode}return!1},getCenter:function(t){for(var e=[],i=[],n=0,r=t.length;r>n;n++)e.push(t[n].pageX),i.push(t[n].pageY);return{pageX:(Math.min.apply(Math,e)+Math.max.apply(Math,e))/2,pageY:(Math.min.apply(Math,i)+Math.max.apply(Math,i))/2}},getVelocity:function(t,e,i){return{x:Math.abs(e/t)||0,y:Math.abs(i/t)||0}},getAngle:function(t,e){var i=e.pageY-t.pageY,n=e.pageX-t.pageX;return 180*Math.atan2(i,n)/Math.PI},getDirection:function(e,i){var n=Math.abs(e.pageX-i.pageX),r=Math.abs(e.pageY-i.pageY);return n>=r?e.pageX-i.pageX>0?t.Gestures.DIRECTION_LEFT:t.Gestures.DIRECTION_RIGHT:e.pageY-i.pageY>0?t.Gestures.DIRECTION_UP:t.Gestures.DIRECTION_DOWN},getDistance:function(t,e){var i=e.pageX-t.pageX,n=e.pageY-t.pageY;return Math.sqrt(i*i+n*n)},getScale:function(t,e){return t.length>=2&&e.length>=2?this.getDistance(e[0],e[1])/this.getDistance(t[0],t[1]):1},getRotation:function(t,e){return t.length>=2&&e.length>=2?this.getAngle(e[1],e[0])-this.getAngle(t[1],t[0]):0},isVertical:function(e){return e==t.Gestures.DIRECTION_UP||e==t.Gestures.DIRECTION_DOWN},stopDefaultBrowserBehavior:function(t,e){t&&t.classList&&(t.classList.add(e),t.onselectstart=function(){return!1})}},t.Gestures.detection={gestures:[],current:null,previous:null,stopped:!1,startDetect:function(e,i){this.current||(this.stopped=!1,this.current={inst:e,startEvent:t.Gestures.utils.extend({},i),lastEvent:!1,name:""},this.detect(i))},detect:function(e){if(this.current&&!this.stopped){e=this.extendEventData(e);for(var i=this.current.inst.options,n=0,r=this.gestures.length;r>n;n++){var o=this.gestures[n];if(!this.stopped&&i[o.name]!==!1&&o.handler.call(o,e,this.current.inst)===!1){this.stopDetect();break}}return this.current&&(this.current.lastEvent=e),e.eventType==t.Gestures.EVENT_END&&!e.touches.length-1&&this.stopDetect(),e}},stopDetect:function(){this.previous=t.Gestures.utils.extend({},this.current),this.current=null,this.stopped=!0},extendEventData:function(e){var i=this.current.startEvent;if(i&&(e.touches.length!=i.touches.length||e.touches===i.touches)){i.touches=[];for(var n=0,r=e.touches.length;r>n;n++)i.touches.push(t.Gestures.utils.extend({},e.touches[n]))}var o=e.timeStamp-i.timeStamp,s=e.center.pageX-i.center.pageX,a=e.center.pageY-i.center.pageY,l=t.Gestures.utils.getVelocity(o,s,a);return t.Gestures.utils.extend(e,{deltaTime:o,deltaX:s,deltaY:a,velocityX:l.x,velocityY:l.y,distance:t.Gestures.utils.getDistance(i.center,e.center),angle:t.Gestures.utils.getAngle(i.center,e.center),direction:t.Gestures.utils.getDirection(i.center,e.center),scale:t.Gestures.utils.getScale(i.touches,e.touches),rotation:t.Gestures.utils.getRotation(i.touches,e.touches),startEvent:i}),e},register:function(e){var i=e.defaults||{};return void 0===i[e.name]&&(i[e.name]=!0),t.Gestures.utils.extend(t.Gestures.defaults,i,!0),e.index=e.index||1e3,this.gestures.push(e),this.gestures.sort(function(t,e){return t.indexe.index?1:0}),this.gestures}},t.Gestures.gestures=t.Gestures.gestures||{},t.Gestures.gestures.Hold={name:"hold",index:10,defaults:{hold_timeout:500,hold_threshold:1},timer:null,handler:function(e,i){switch(e.eventType){case t.Gestures.EVENT_START:clearTimeout(this.timer),t.Gestures.detection.current.name=this.name,this.timer=setTimeout(function(){"hold"==t.Gestures.detection.current.name&&i.trigger("hold",e)},i.options.hold_timeout);break;case t.Gestures.EVENT_MOVE:e.distance>i.options.hold_threshold&&clearTimeout(this.timer);break;case t.Gestures.EVENT_END:clearTimeout(this.timer)}}},t.Gestures.gestures.Tap={name:"tap",index:100,defaults:{tap_max_touchtime:250,tap_max_distance:10,tap_always:!0,doubletap_distance:20,doubletap_interval:300},handler:function(e,i){if(e.eventType==t.Gestures.EVENT_END){var n=t.Gestures.detection.previous,r=!1;if(e.deltaTime>i.options.tap_max_touchtime||e.distance>i.options.tap_max_distance)return;n&&"tap"==n.name&&e.timeStamp-n.lastEvent.timeStamp0&&e.touches.length>i.options.swipe_max_touches)return;(e.velocityX>i.options.swipe_velocity||e.velocityY>i.options.swipe_velocity)&&(i.trigger(this.name,e),i.trigger(this.name+e.direction,e))}}},t.Gestures.gestures.Drag={name:"drag",index:50,defaults:{drag_min_distance:10,correct_for_drag_min_distance:!0,drag_max_touches:1,drag_block_horizontal:!0,drag_block_vertical:!0,drag_lock_to_axis:!1,drag_lock_min_distance:25},triggered:!1,handler:function(e,i){if(t.Gestures.detection.current.name!=this.name&&this.triggered)return i.trigger(this.name+"end",e),void(this.triggered=!1);if(!(i.options.drag_max_touches>0&&e.touches.length>i.options.drag_max_touches))switch(e.eventType){case t.Gestures.EVENT_START:this.triggered=!1;break;case t.Gestures.EVENT_MOVE:if(e.distancei.options.transform_min_rotation&&i.trigger("rotate",e),n>i.options.transform_min_scale&&(i.trigger("pinch",e),i.trigger("pinch"+(e.scale<1?"in":"out"),e));break;case t.Gestures.EVENT_END:this.triggered&&i.trigger(this.name+"end",e),this.triggered=!1}}},t.Gestures.gestures.Touch={name:"touch",index:-1/0,defaults:{prevent_default:!1,prevent_mouseevents:!1},handler:function(e,i){return i.options.prevent_mouseevents&&e.pointerType==t.Gestures.POINTER_MOUSE?void e.stopDetect():(i.options.prevent_default&&e.preventDefault(),void(e.eventType==t.Gestures.EVENT_START&&i.trigger(this.name,e)))}},t.Gestures.gestures.Release={name:"release",index:1/0,handler:function(e,i){e.eventType==t.Gestures.EVENT_END&&i.trigger(this.name,e)}}}(window.ionic),function(t){function e(){t.Platform.isCordova()?document.addEventListener("deviceready",i,!1):i(),window.removeEventListener("load",e,!1)}function i(){t.Platform.isReady=!0,t.Platform.detect();for(var e=0;e0?i=i.replace(".","_"):i+="_0",this.platforms.push(t+i.split("_")[0]),this.platforms.push(t+i),this.isAndroid()&&4.4>e&&(this.grade=4>e?"c":"b")}}},isCordova:function(){return!(!window.cordova&&!window.PhoneGap&&!window.phonegap)},isIPad:function(){return this.ua.toLowerCase().indexOf("ipad")>=0},isIOS:function(){return this.is("ios")},isAndroid:function(){return this.is("android")},platform:function(){return null===n&&this.setPlatform(this.device().platform),n},setPlatform:function(t){n="undefined"!=typeof t&&null!==t&&t.length?t.toLowerCase():this.ua.indexOf("Android")>0?"android":this.ua.indexOf("iPhone")>-1||this.ua.indexOf("iPad")>-1||this.ua.indexOf("iPod")>-1?"ios":""},version:function(){return null===r&&this.setVersion(this.device().version),r},setVersion:function(t){if("undefined"!=typeof t&&null!==t&&(t=t.split("."),t=parseFloat(t[0]+"."+(t.length>1?t[1]:0)),!isNaN(t)))return void(r=t);r=0;var e=this.platform(),i={android:/Android (\d+).(\d+)?/,ios:/OS (\d+)_(\d+)?/};i[e]&&(t=this.ua.match(i[e]),t.length>2&&(r=parseFloat(t[1]+"."+t[2])))},is:function(t){if(t=t.toLowerCase(),this.platforms)for(var e=0;e=0},exitApp:function(){this.ready(function(){navigator.app&&navigator.app.exitApp&&navigator.app.exitApp()})},showStatusBar:function(e){this._showStatusBar=e,this.ready(function(){t.Platform._showStatusBar?(StatusBar.show(),document.body.classList.remove("status-bar-hide")):(StatusBar.hide(),document.body.classList.add("status-bar-hide"))})},fullScreen:function(e,i){this.isFullScreen=e!==!1,t.DomUtil.ready(function(){t.Platform.isFullScreen?document.body.classList.add("fullscreen"):document.body.classList.remove("fullscreen")}),this.showStatusBar(i===!0)}};var n=null,r=null,o=[];window.addEventListener("load",e,!1)}(window.ionic),function(t,e){"use strict";e.CSS={},function(){var i,n=["webkitTransform","transform","-webkit-transform","webkit-transform","-moz-transform","moz-transform","MozTransform","mozTransform"];for(i=0;ir&&n;r++){if("INPUT"===n.tagName||"A"===n.tagName||"BUTTON"===n.tagName||"LABEL"===n.tagName||"TEXTAREA"===n.tagName||"SELECT"===n.tagName)return i.tapElement(n,e);n=n.parentElement}u()}}function r(t){return t.target.control||o(t)||s(t)?h(t):void a(t)}function o(t){var e,i,n;for(e in _)if(i=_[e],n||(n=l(t)),n.x>i.x-m&&n.xi.y-m&&n.yf.x+m||e.xf.y+m||e.ye&&(n&&"LABEL"!==n.tagName);e++){if(n.classList.contains("item")||n.classList.contains("button")){v[T]=n,T=T>24?0:T+1,i.requestAnimationFrame(function(){n.classList.add("active")});break}n=n.parentElement}}i.tapElement=function(i,n){var r=i.control||i;if(!r.disabled&&"file"!==r.type){var s=l(n),c=e.createEvent("MouseEvents");return c.initMouseEvent("click",!0,!0,t,1,0,0,s.x,s.y,!1,!1,!1,!1,0,null),r.dispatchEvent(c),"INPUT"===r.tagName||"TEXTAREA"===r.tagName||"SELECT"===r.tagName?(r.focus(),n.preventDefault()):u(),o(n)||a(n),i.control?h(n):void 0}};var _={},f={},g=1500,p=375,m=15,v={},T=0;e.addEventListener("click",r,!0),i.on("tap",n,e),e.addEventListener("touchend",c,!1),e.addEventListener("mouseup",c,!1),e.addEventListener("touchstart",d,!1),e.addEventListener("mousedown",d,!1)}(this,document,ionic),function(t){var e=["0","0","0"];t.Utils={arrayMove:function(t,e,i){if(i>=t.length)for(var n=i-t.length;n--+1;)t.push(void 0);return t.splice(i,0,t.splice(e,1)[0]),t},proxy:function(t,e){var i=Array.prototype.slice.call(arguments,2);return function(){return t.apply(e,i.concat(Array.prototype.slice.call(arguments)))}},debounce:function(t,e,i){var n,r,o,s,a;return function(){o=this,r=arguments,s=new Date;var l=function(){var c=new Date-s;e>c?n=setTimeout(l,e-c):(n=null,i||(a=t.apply(o,r)))},c=i&&!n;return n||(n=setTimeout(l,e)),c&&(a=t.apply(o,r)),a}},throttle:function(t,e,i){var n,r,o,s=null,a=0;i||(i={});var l=function(){a=i.leading===!1?0:Date.now(),s=null,o=t.apply(n,r)};return function(){var c=Date.now();a||i.leading!==!1||(a=c);var h=e-(c-a);return n=this,r=arguments,0>=h?(clearTimeout(s),s=null,a=c,o=t.apply(n,r)):s||i.trailing===!1||(s=setTimeout(l,h)),o}},inherit:function(e,i){var n,r=this;n=e&&e.hasOwnProperty("constructor")?e.constructor:function(){return r.apply(this,arguments)},t.extend(n,r,i);var o=function(){this.constructor=n};return o.prototype=r.prototype,n.prototype=new o,e&&t.extend(n.prototype,e),n.__super__=r.prototype,n},extend:function(t){for(var e=Array.prototype.slice.call(arguments,1),i=0;i2500&&(clearInterval(a),a=null)},1e3/n)),e}}(),stop:function(t){var e=null!=r[t];return e&&(r[t]=null),e},isRunning:function(t){return null!=r[t]},start:function(t,s,a,l,c,h){var u=e(),d=u,_=0,f=0,g=o++;if(h||(h=document.body),g%20===0){var p={};for(var m in r)p[m]=!0;r=p}var v=function(o){var p=o!==!0,m=e();if(!r[g]||s&&!s(g))return r[g]=null,void(a&&a(i-f/((m-u)/n),g,!1));if(p)for(var T=Math.round((m-d)/(n/i))-1,E=0;E1&&(_=1));var w=c?c(_):_;t(w,m,p)!==!1&&1!==_||!p?p&&(d=m,core.effect.Animate.requestAnimationFrame(v,h)):(r[g]=null,a&&a(i-f/((m-u)/n),g,1===_||null==l))};return r[g]=!0,core.effect.Animate.requestAnimationFrame(v,h),g}}}(this);var Scroller;!function(t){var e=function(){},i=function(t){return Math.pow(t-1,3)+1},n=function(t){return(t/=.5)<1?.5*Math.pow(t,3):.5*(Math.pow(t-2,3)+2)};t.views.Scroll=t.views.View.inherit({initialize:function(i){var n=this;this.__container=i.el,this.__content=i.el.firstElementChild,setTimeout(function(){n.__container&&n.__content&&(n.__container.scrollTop=0,n.__content.scrollTop=0)}),this.options={scrollingX:!1,scrollbarX:!0,scrollingY:!0,scrollbarY:!0,startX:0,startY:0,wheelDampen:6,minScrollbarSizeX:5,minScrollbarSizeY:5,scrollbarsFade:!0,scrollbarFadeDelay:300,scrollbarResizeFadeDelay:1e3,animating:!0,animationDuration:250,bouncing:!0,locking:!0,paging:!1,snapping:!1,zooming:!1,minZoom:.5,maxZoom:3,speedMultiplier:1,scrollingComplete:e,penetrationDeceleration:.03,penetrationAcceleration:.08,scrollEventInterval:50};for(var r in i)this.options[r]=i[r];this.hintResize=t.debounce(function(){n.resize()},1e3,!0),this.triggerScrollEvent=t.throttle(function(){t.trigger("scroll",{scrollTop:n.__scrollTop,scrollLeft:n.__scrollLeft,target:n.__container})},this.options.scrollEventInterval),this.triggerScrollEndEvent=function(){t.trigger("scrollend",{scrollTop:n.__scrollTop,scrollLeft:n.__scrollLeft,target:n.__container})},this.__scrollLeft=this.options.startX,this.__scrollTop=this.options.startY,this.__callback=this.getRenderFn(),this.__initEventHandlers(),this.__createScrollbars()},run:function(){this.resize(),this.__fadeScrollbars("out",this.options.scrollbarResizeFadeDelay)},__isSingleTouch:!1,__isTracking:!1,__didDecelerationComplete:!1,__isGesturing:!1,__isDragging:!1,__isDecelerating:!1,__isAnimating:!1,__clientLeft:0,__clientTop:0,__clientWidth:0,__clientHeight:0,__contentWidth:0,__contentHeight:0,__snapWidth:100,__snapHeight:100,__refreshHeight:null,__refreshActive:!1,__refreshActivate:null,__refreshDeactivate:null,__refreshStart:null,__zoomLevel:1,__scrollLeft:0,__scrollTop:0,__maxScrollLeft:0,__maxScrollTop:0,__scheduledLeft:0,__scheduledTop:0,__scheduledZoom:0,__lastTouchLeft:null,__lastTouchTop:null,__lastTouchMove:null,__positions:null,__minDecelerationScrollLeft:null,__minDecelerationScrollTop:null,__maxDecelerationScrollLeft:null,__maxDecelerationScrollTop:null,__decelerationVelocityX:null,__decelerationVelocityY:null,__transformProperty:null,__perspectiveProperty:null,__indicatorX:null,__indicatorY:null,__scrollbarFadeTimeout:null,__didWaitForSize:null,__sizerTimeout:null,__initEventHandlers:function(){function e(t){return t.target.tagName.match(IS_INPUT_LIKE_REGEX)||t.target.isContentEditable||t.target.tagName.match(IS_EMBEDDED_OBJECT_REGEX)}var i=this,n=this.__container;if(n.addEventListener("scrollChildIntoView",function(e){var r=window.innerHeight,o=e.target,s=e.target.offsetHeight,a=o.getBoundingClientRect().top,l=t.DomUtil.getPositionInParent(o,n).top;a+s>r&&i.scrollTo(0,l+s-.5*r,!0),e.stopPropagation()}),"ontouchstart"in window)n.addEventListener("touchstart",function(t){t.defaultPrevented||e(t)||(i.doTouchStart(t.touches,t.timeStamp),t.preventDefault())},!1),document.addEventListener("touchmove",function(t){t.defaultPrevented||i.doTouchMove(t.touches,t.timeStamp)},!1),document.addEventListener("touchend",function(t){i.doTouchEnd(t.timeStamp)},!1);else{var r=!1;n.addEventListener("mousedown",function(t){t.defaultPrevented||e(t)||(i.doTouchStart([{pageX:t.pageX,pageY:t.pageY}],t.timeStamp),t.preventDefault(),r=!0)},!1),document.addEventListener("mousemove",function(t){r&&!t.defaultPrevented&&(i.doTouchMove([{pageX:t.pageX,pageY:t.pageY}],t.timeStamp),r=!0)},!1),document.addEventListener("mouseup",function(t){r&&(i.doTouchEnd(t.timeStamp),r=!1)},!1),document.addEventListener("mousewheel",function(t){i.scrollBy(t.wheelDeltaX/i.options.wheelDampen,-t.wheelDeltaY/i.options.wheelDampen)})}},__createScrollbar:function(t){var e=document.createElement("div"),i=document.createElement("div"); -return i.className="scroll-bar-indicator",e.className="h"==t?"scroll-bar scroll-bar-h":"scroll-bar scroll-bar-v",e.appendChild(i),e},__createScrollbars:function(){var t,e;this.options.scrollingX&&(t={el:this.__createScrollbar("h"),sizeRatio:1},t.indicator=t.el.children[0],this.options.scrollbarX&&this.__container.appendChild(t.el),this.__indicatorX=t),this.options.scrollingY&&(e={el:this.__createScrollbar("v"),sizeRatio:1},e.indicator=e.el.children[0],this.options.scrollbarY&&this.__container.appendChild(e.el),this.__indicatorY=e)},__resizeScrollbars:function(){var t=this;if(t.__fadeScrollbars("in"),t.__indicatorX){var e=Math.max(Math.round(t.__clientWidth*t.__clientWidth/t.__contentWidth),20);e>t.__contentWidth&&(e=0),t.__indicatorX.size=e,t.__indicatorX.minScale=this.options.minScrollbarSizeX/e,t.__indicatorX.indicator.style.width=e+"px",t.__indicatorX.maxPos=t.__clientWidth-e,t.__indicatorX.sizeRatio=t.__maxScrollLeft?t.__indicatorX.maxPos/t.__maxScrollLeft:1}if(t.__indicatorY){var i=Math.max(Math.round(t.__clientHeight*t.__clientHeight/t.__contentHeight),20);i>t.__contentHeight&&(i=0),t.__indicatorY.size=i,t.__indicatorY.minScale=this.options.minScrollbarSizeY/i,t.__indicatorY.maxPos=t.__clientHeight-i,t.__indicatorY.indicator.style.height=i+"px",t.__indicatorY.sizeRatio=t.__maxScrollTop?t.__indicatorY.maxPos/t.__maxScrollTop:1}},__repositionScrollbars:function(){var t,e,i,n,r,o=this,s=0,a=0;o.__indicatorX&&(o.__indicatorY&&(s=10),n=Math.round(o.__indicatorX.sizeRatio*o.__scrollLeft)||0,e=o.__scrollLeft-(o.__maxScrollLeft-s),o.__scrollLeft<0?(widthScale=Math.max(o.__indicatorX.minScale,(o.__indicatorX.size-Math.abs(o.__scrollLeft))/o.__indicatorX.size),n=0,o.__indicatorX.indicator.style[o.__transformOriginProperty]="left center"):e>0?(widthScale=Math.max(o.__indicatorX.minScale,(o.__indicatorX.size-e)/o.__indicatorX.size),n=o.__indicatorX.maxPos-s,o.__indicatorX.indicator.style[o.__transformOriginProperty]="right center"):(n=Math.min(o.__maxScrollLeft,Math.max(0,n)),widthScale=1),o.__indicatorX.indicator.style[o.__transformProperty]="translate3d("+n+"px, 0, 0) scaleX("+widthScale+")"),o.__indicatorY&&(r=Math.round(o.__indicatorY.sizeRatio*o.__scrollTop)||0,o.__indicatorX&&(a=10),i=o.__scrollTop-(o.__maxScrollTop-a),o.__scrollTop<0?(t=Math.max(o.__indicatorY.minScale,(o.__indicatorY.size-Math.abs(o.__scrollTop))/o.__indicatorY.size),r=0,o.__indicatorY.indicator.style[o.__transformOriginProperty]="center top"):i>0?(t=Math.max(o.__indicatorY.minScale,(o.__indicatorY.size-i)/o.__indicatorY.size),r=o.__indicatorY.maxPos-a,o.__indicatorY.indicator.style[o.__transformOriginProperty]="center bottom"):(r=Math.min(o.__maxScrollTop,Math.max(0,r)),t=1),o.__indicatorY.indicator.style[o.__transformProperty]="translate3d(0,"+r+"px, 0) scaleY("+t+")")},__fadeScrollbars:function(t,e){var i=this;if(this.options.scrollbarsFade){var n="scroll-bar-fade-out";i.options.scrollbarsFade===!0&&(clearTimeout(i.__scrollbarFadeTimeout),"in"==t?(i.__indicatorX&&i.__indicatorX.indicator.classList.remove(n),i.__indicatorY&&i.__indicatorY.indicator.classList.remove(n)):i.__scrollbarFadeTimeout=setTimeout(function(){i.__indicatorX&&i.__indicatorX.indicator.classList.add(n),i.__indicatorY&&i.__indicatorY.indicator.classList.add(n)},e||i.options.scrollbarFadeDelay))}},__scrollingComplete:function(){var t=this;t.options.scrollingComplete(),t.__fadeScrollbars("out")},resize:function(){this.setDimensions(this.__container.clientWidth,this.__container.clientHeight,Math.max(this.__content.scrollWidth,this.__content.offsetWidth),Math.max(this.__content.scrollHeight,this.__content.offsetHeight))},getRenderFn:function(){var t,e=this,i=this.__content,n=document.documentElement.style;"MozAppearance"in n?t="gecko":"WebkitAppearance"in n?t="webkit":"string"==typeof navigator.cpuClass&&(t="trident");var r,o={trident:"ms",gecko:"Moz",webkit:"Webkit",presto:"O"}[t],s=document.createElement("div"),a=o+"Perspective",l=o+"Transform",c=o+"TransformOrigin";return e.__perspectiveProperty=l,e.__transformProperty=l,e.__transformOriginProperty=c,s.style[a]!==r?function(t,n){i.style[l]="translate3d("+-t+"px,"+-n+"px,0)",e.__repositionScrollbars(),e.triggerScrollEvent()}:s.style[l]!==r?function(t,n){i.style[l]="translate("+-t+"px,"+-n+"px)",e.__repositionScrollbars(),e.triggerScrollEvent()}:function(t,n,r){i.style.marginLeft=t?-t/r+"px":"",i.style.marginTop=n?-n/r+"px":"",i.style.zoom=r||"",e.__repositionScrollbars(),e.triggerScrollEvent()}},setDimensions:function(t,e,i,n){var r=this;t===+t&&(r.__clientWidth=t),e===+e&&(r.__clientHeight=e),i===+i&&(r.__contentWidth=i),n===+n&&(r.__contentHeight=n),r.__computeScrollMax(),r.__resizeScrollbars(),r.scrollTo(r.__scrollLeft,r.__scrollTop,!0)},setPosition:function(t,e){var i=this;i.__clientLeft=t||0,i.__clientTop=e||0},setSnapSize:function(t,e){var i=this;i.__snapWidth=t,i.__snapHeight=e},activatePullToRefresh:function(t,e,i,n){var r=this;r.__refreshHeight=t,r.__refreshActivate=e,r.__refreshDeactivate=i,r.__refreshStart=n},triggerPullToRefresh:function(){this.__publish(this.__scrollLeft,-this.__refreshHeight,this.__zoomLevel,!0),this.__refreshStart&&this.__refreshStart()},finishPullToRefresh:function(){var t=this;t.__refreshActive=!1,t.__refreshDeactivate&&t.__refreshDeactivate(),t.scrollTo(t.__scrollLeft,t.__scrollTop,!0)},getValues:function(){var t=this;return{left:t.__scrollLeft,top:t.__scrollTop,zoom:t.__zoomLevel}},getScrollMax:function(){var t=this;return{left:t.__maxScrollLeft,top:t.__maxScrollTop}},zoomTo:function(t,e,i,n){var r=this;if(!r.options.zooming)throw new Error("Zooming is not enabled!");r.__isDecelerating&&(core.effect.Animate.stop(r.__isDecelerating),r.__isDecelerating=!1);var o=r.__zoomLevel;null==i&&(i=r.__clientWidth/2),null==n&&(n=r.__clientHeight/2),t=Math.max(Math.min(t,r.options.maxZoom),r.options.minZoom),r.__computeScrollMax(t);var s=(i+r.__scrollLeft)*t/o-i,a=(n+r.__scrollTop)*t/o-n;s>r.__maxScrollLeft?s=r.__maxScrollLeft:0>s&&(s=0),a>r.__maxScrollTop?a=r.__maxScrollTop:0>a&&(a=0),r.__publish(s,a,t,e)},zoomBy:function(t,e,i,n){var r=this;r.zoomTo(r.__zoomLevel*t,e,i,n)},scrollTo:function(t,e,i,n){var r=this;if(r.__isDecelerating&&(core.effect.Animate.stop(r.__isDecelerating),r.__isDecelerating=!1),null!=n&&n!==r.__zoomLevel){if(!r.options.zooming)throw new Error("Zooming is not enabled!");t*=n,e*=n,r.__computeScrollMax(n)}else n=r.__zoomLevel;r.options.scrollingX?r.options.paging?t=Math.round(t/r.__clientWidth)*r.__clientWidth:r.options.snapping&&(t=Math.round(t/r.__snapWidth)*r.__snapWidth):t=r.__scrollLeft,r.options.scrollingY?r.options.paging?e=Math.round(e/r.__clientHeight)*r.__clientHeight:r.options.snapping&&(e=Math.round(e/r.__snapHeight)*r.__snapHeight):e=r.__scrollTop,t=Math.max(Math.min(r.__maxScrollLeft,t),0),e=Math.max(Math.min(r.__maxScrollTop,e),0),t===r.__scrollLeft&&e===r.__scrollTop&&(i=!1),r.__publish(t,e,n,i)},scrollBy:function(t,e,i){var n=this,r=n.__isAnimating?n.__scheduledLeft:n.__scrollLeft,o=n.__isAnimating?n.__scheduledTop:n.__scrollTop;n.scrollTo(r+(t||0),o+(e||0),i)},doMouseZoom:function(t,e,i,n){var r=this,o=t>0?.97:1.03;return r.zoomTo(r.__zoomLevel*o,!1,i-r.__clientLeft,n-r.__clientTop)},doTouchStart:function(t,e){if(this.hintResize(),null==t.length)throw new Error("Invalid touch list: "+t);if(e instanceof Date&&(e=e.valueOf()),"number"!=typeof e)throw new Error("Invalid timestamp value: "+e);var i=this;i.__fadeScrollbars("in"),i.__interruptedAnimation=!0,i.__isDecelerating&&(core.effect.Animate.stop(i.__isDecelerating),i.__isDecelerating=!1,i.__interruptedAnimation=!0),i.__isAnimating&&(core.effect.Animate.stop(i.__isAnimating),i.__isAnimating=!1,i.__interruptedAnimation=!0);var n,r,o=1===t.length;o?(n=t[0].pageX,r=t[0].pageY):(n=Math.abs(t[0].pageX+t[1].pageX)/2,r=Math.abs(t[0].pageY+t[1].pageY)/2),i.__initialTouchLeft=n,i.__initialTouchTop=r,i.__zoomLevelStart=i.__zoomLevel,i.__lastTouchLeft=n,i.__lastTouchTop=r,i.__lastTouchMove=e,i.__lastScale=1,i.__enableScrollX=!o&&i.options.scrollingX,i.__enableScrollY=!o&&i.options.scrollingY,i.__isTracking=!0,i.__didDecelerationComplete=!1,i.__isDragging=!o,i.__isSingleTouch=o,i.__positions=[]},doTouchMove:function(t,e,i){if(null==t.length)throw new Error("Invalid touch list: "+t);if(e instanceof Date&&(e=e.valueOf()),"number"!=typeof e)throw new Error("Invalid timestamp value: "+e);var n=this;if(n.__isTracking){var r,o;2===t.length?(r=Math.abs(t[0].pageX+t[1].pageX)/2,o=Math.abs(t[0].pageY+t[1].pageY)/2):(r=t[0].pageX,o=t[0].pageY);var s=n.__positions;if(n.__isDragging){var a=r-n.__lastTouchLeft,l=o-n.__lastTouchTop,c=n.__scrollLeft,h=n.__scrollTop,u=n.__zoomLevel;if(null!=i&&n.options.zooming){var d=u;if(u=u/n.__lastScale*i,u=Math.max(Math.min(u,n.options.maxZoom),n.options.minZoom),d!==u){var _=r-n.__clientLeft,f=o-n.__clientTop;c=(_+c)*u/d-_,h=(f+h)*u/d-f,n.__computeScrollMax(u)}}if(n.__enableScrollX){c-=a*this.options.speedMultiplier;var g=n.__maxScrollLeft;(c>g||0>c)&&(n.options.bouncing?c+=a/2*this.options.speedMultiplier:c=c>g?g:0)}if(n.__enableScrollY){h-=l*this.options.speedMultiplier;var p=n.__maxScrollTop;(h>p||0>h)&&(n.options.bouncing||n.__refreshHeight&&0>h?(h+=l/2*this.options.speedMultiplier,n.__enableScrollX||null==n.__refreshHeight||(!n.__refreshActive&&h<=-n.__refreshHeight?(n.__refreshActive=!0,n.__refreshActivate&&n.__refreshActivate()):n.__refreshActive&&h>-n.__refreshHeight&&(n.__refreshActive=!1,n.__refreshDeactivate&&n.__refreshDeactivate()))):h=h>p?p:0)}s.length>60&&s.splice(0,30),s.push(c,h,e),n.__publish(c,h,u)}else{var m=n.options.locking?3:0,v=5,T=Math.abs(r-n.__initialTouchLeft),E=Math.abs(o-n.__initialTouchTop);n.__enableScrollX=n.options.scrollingX&&T>=m,n.__enableScrollY=n.options.scrollingY&&E>=m,s.push(n.__scrollLeft,n.__scrollTop,e),n.__isDragging=(n.__enableScrollX||n.__enableScrollY)&&(T>=v||E>=v),n.__isDragging&&(n.__interruptedAnimation=!1)}n.__lastTouchLeft=r,n.__lastTouchTop=o,n.__lastTouchMove=e,n.__lastScale=i}},doTouchEnd:function(t){if(t instanceof Date&&(t=t.valueOf()),"number"!=typeof t)throw new Error("Invalid timestamp value: "+t);var e=this;if(e.__isTracking){if(e.__isTracking=!1,e.__isDragging)if(e.__isDragging=!1,e.__isSingleTouch&&e.options.animating&&t-e.__lastTouchMove<=100){for(var i=e.__positions,n=i.length-1,r=n,o=n;o>0&&i[o]>e.__lastTouchMove-100;o-=3)r=o;if(r!==n){var s=i[n]-i[r],a=e.__scrollLeft-i[r-2],l=e.__scrollTop-i[r-1];e.__decelerationVelocityX=a/s*(1e3/60),e.__decelerationVelocityY=l/s*(1e3/60);var c=e.options.paging||e.options.snapping?4:1;(Math.abs(e.__decelerationVelocityX)>c||Math.abs(e.__decelerationVelocityY)>c)&&(e.__refreshActive||e.__startDeceleration(t))}else e.__scrollingComplete()}else t-e.__lastTouchMove>100&&e.__scrollingComplete();e.__isDecelerating||(e.__refreshActive&&e.__refreshStart?(e.__publish(e.__scrollLeft,-e.__refreshHeight,e.__zoomLevel,!0),e.__refreshStart&&e.__refreshStart()):((e.__interruptedAnimation||e.__isDragging)&&e.__scrollingComplete(),e.scrollTo(e.__scrollLeft,e.__scrollTop,!0,e.__zoomLevel),e.__refreshActive&&(e.__refreshActive=!1,e.__refreshDeactivate&&e.__refreshDeactivate()))),e.__positions.length=0}},__publish:function(t,e,r,o){var s=this,a=s.__isAnimating;if(a&&(core.effect.Animate.stop(a),s.__isAnimating=!1),o&&s.options.animating){s.__scheduledLeft=t,s.__scheduledTop=e,s.__scheduledZoom=r;var l=s.__scrollLeft,c=s.__scrollTop,h=s.__zoomLevel,u=t-l,d=e-c,_=r-h,f=function(t,e,i){i&&(s.__scrollLeft=l+u*t,s.__scrollTop=c+d*t,s.__zoomLevel=h+_*t,s.__callback&&s.__callback(s.__scrollLeft,s.__scrollTop,s.__zoomLevel))},g=function(t){return s.__isAnimating===t},p=function(t,e,i){e===s.__isAnimating&&(s.__isAnimating=!1),(s.__didDecelerationComplete||i)&&s.__scrollingComplete(),s.options.zooming&&s.__computeScrollMax()};s.__isAnimating=core.effect.Animate.start(f,g,p,s.options.animationDuration,a?i:n)}else s.__scheduledLeft=s.__scrollLeft=t,s.__scheduledTop=s.__scrollTop=e,s.__scheduledZoom=s.__zoomLevel=r,s.__callback&&s.__callback(t,e,r),s.options.zooming&&s.__computeScrollMax()},__computeScrollMax:function(t){var e=this;null==t&&(t=e.__zoomLevel),e.__maxScrollLeft=Math.max(e.__contentWidth*t-e.__clientWidth,0),e.__maxScrollTop=Math.max(e.__contentHeight*t-e.__clientHeight,0),e.__didWaitForSize||0!=e.__maxScrollLeft||0!=e.__maxScrollTop||(e.__didWaitForSize=!0,e.__waitForSize())},__waitForSize:function(){var t=this;clearTimeout(t.__sizerTimeout);var e=function(){t.resize(),t.options.scrollingX&&0==t.__maxScrollLeft||t.options.scrollingY&&0==t.__maxScrollTop};e(),t.__sizerTimeout=setTimeout(e,1e3)},__startDeceleration:function(){var t=this;if(t.options.paging){var e=Math.max(Math.min(t.__scrollLeft,t.__maxScrollLeft),0),i=Math.max(Math.min(t.__scrollTop,t.__maxScrollTop),0),n=t.__clientWidth,r=t.__clientHeight;t.__minDecelerationScrollLeft=Math.floor(e/n)*n,t.__minDecelerationScrollTop=Math.floor(i/r)*r,t.__maxDecelerationScrollLeft=Math.ceil(e/n)*n,t.__maxDecelerationScrollTop=Math.ceil(i/r)*r}else t.__minDecelerationScrollLeft=0,t.__minDecelerationScrollTop=0,t.__maxDecelerationScrollLeft=t.__maxScrollLeft,t.__maxDecelerationScrollTop=t.__maxScrollTop;var o=function(e,i,n){t.__stepThroughDeceleration(n)};t.__minVelocityToKeepDecelerating=t.options.snapping?4:.1;var s=function(){var e=Math.abs(t.__decelerationVelocityX)>=t.__minVelocityToKeepDecelerating||Math.abs(t.__decelerationVelocityY)>=t.__minVelocityToKeepDecelerating;return e||(t.__didDecelerationComplete=!0),e},a=function(){t.__isDecelerating=!1,t.__didDecelerationComplete&&t.__scrollingComplete(),t.options.paging&&t.scrollTo(t.__scrollLeft,t.__scrollTop,t.options.snapping)};t.__isDecelerating=core.effect.Animate.start(o,s,a)},__stepThroughDeceleration:function(t){var e=this,i=e.__scrollLeft+e.__decelerationVelocityX,n=e.__scrollTop+e.__decelerationVelocityY;if(!e.options.bouncing){var r=Math.max(Math.min(e.__maxDecelerationScrollLeft,i),e.__minDecelerationScrollLeft);r!==i&&(i=r,e.__decelerationVelocityX=0);var o=Math.max(Math.min(e.__maxDecelerationScrollTop,n),e.__minDecelerationScrollTop);o!==n&&(n=o,e.__decelerationVelocityY=0)}if(t?e.__publish(i,n,e.__zoomLevel):(e.__scrollLeft=i,e.__scrollTop=n),!e.options.paging){var s=.95;e.__decelerationVelocityX*=s,e.__decelerationVelocityY*=s}if(e.options.bouncing){var a=0,l=0,c=e.options.penetrationDeceleration,h=e.options.penetrationAcceleration;if(ie.__maxDecelerationScrollLeft&&(a=e.__maxDecelerationScrollLeft-i),ne.__maxDecelerationScrollTop&&(l=e.__maxDecelerationScrollTop-n),0!==a){var u=a*e.__decelerationVelocityX<=e.__minDecelerationScrollLeft;u&&(e.__decelerationVelocityX+=a*c);var d=Math.abs(e.__decelerationVelocityX)<=e.__minVelocityToKeepDecelerating;(!u||d)&&(e.__decelerationVelocityX=a*h)}if(0!==l){var _=l*e.__decelerationVelocityY<=e.__minDecelerationScrollTop;_&&(e.__decelerationVelocityY+=l*c);var f=Math.abs(e.__decelerationVelocityY)<=e.__minVelocityToKeepDecelerating;(!_||f)&&(e.__decelerationVelocityY=l*h)}}}})}(ionic),function(t){"use strict";t.views.ActionSheet=t.views.View.inherit({initialize:function(t){this.el=t.el},show:function(){this.el.offsetWidth,this.el.classList.add("active")},hide:function(){this.el.offsetWidth,this.el.classList.remove("active")}})}(ionic),function(t){"use strict";t.views.HeaderBar=t.views.View.inherit({initialize:function(e){this.el=e.el,t.extend(this,{alignTitle:"center"},e),this.align()},align:function(e){e||(e=this.alignTitle);var i=this.el.querySelector(".title");if(i){var n,r,o,s=this.el.childNodes,a=0,l=0,c=!1;for(n=0;n10&&(i.style.left=t+"px",i.style.right=t+"px"),i.offsetWidth0&&(i.style.right=l+5+"px")):"left"==e?(i.classList.add("title-left"),a>0&&(i.style.left=a+15+"px")):"right"==e&&(i.classList.add("title-right"),l>0&&(i.style.right=l+15+"px"))})}}})}(ionic),function(t){"use strict";var e="item",i="item-content",n="item-sliding",r="item-options",o="item-placeholder",s="item-reordering",a="item-drag",l=function(){};l.prototype={start:function(){},drag:function(){},end:function(){}};var c=function(t){this.dragThresholdX=t.dragThresholdX||10,this.el=t.el};c.prototype=new l,c.prototype.start=function(o){var s,a,l,c;s=o.target.classList.contains(i)?o.target:o.target.classList.contains(e)?o.target.querySelector("."+i):t.DomUtil.getParentWithClass(o.target,i),s&&(s.classList.remove(n),l=parseFloat(s.style[t.CSS.TRANSFORM].replace("translate3d(","").split(",")[0])||0,a=s.parentNode.querySelector("."+r),a&&(c=a.offsetWidth,this._currentDrag={buttonsWidth:c,content:s,startOffsetX:l}))},c.prototype.drag=t.animationFrameThrottle(function(e){var i;if(this._currentDrag&&(!this._isDragging&&(Math.abs(e.gesture.deltaX)>this.dragThresholdX||Math.abs(this._currentDrag.startOffsetX)>0)&&(this._isDragging=!0),this._isDragging)){i=this._currentDrag.buttonsWidth;var n=Math.min(0,this._currentDrag.startOffsetX+e.gesture.deltaX);-i>n&&(n=Math.min(-i,-i+.4*(e.gesture.deltaX+i))),this._currentDrag.content.style[t.CSS.TRANSFORM]="translate3d("+n+"px, 0, 0)",this._currentDrag.content.style[t.CSS.TRANSITION]="none"}}),c.prototype.end=function(e,i){var n=this;if(!this._currentDrag)return void(i&&i());var r=-this._currentDrag.buttonsWidth;e.gesture.deltaX>-(this._currentDrag.buttonsWidth/2)&&("left"==e.gesture.direction&&Math.abs(e.gesture.velocityX)<.3?r=0:"right"==e.gesture.direction&&(r=0)),t.requestAnimationFrame(function(){n._currentDrag.content.style[t.CSS.TRANSFORM]=0===r?"":"translate3d("+r+"px, 0, 0)",n._currentDrag.content.style[t.CSS.TRANSITION]="",n._currentDrag=null,i&&i()})};var h=function(t){this.dragThresholdY=t.dragThresholdY||0,this.onReorder=t.onReorder,this.el=t.el,this.scrollEl=t.scrollEl,this.scrollView=t.scrollView};h.prototype=new l,h.prototype._moveElement=function(e){var i=e.gesture.center.pageY-this._currentDrag.elementHeight/2;this.el.style[t.CSS.TRANSFORM]="translate3d(0, "+i+"px, 0)"},h.prototype.start=function(e){var i=(this.el.offsetTop,t.DomUtil.getChildIndex(this.el,this.el.nodeName.toLowerCase())),n=this.el.offsetHeight,r=this.el.cloneNode(!0),a=(this.scrollEl||this.el).parentNode;r.classList.add(o),this.el.parentNode.insertBefore(r,this.el),this.el.classList.add(s),a.parentNode.appendChild(this.el),this._currentDrag={elementHeight:n,startIndex:i,placeholder:r,scrollHeight:scroll,list:r.parentNode},this._moveElement(e)},h.prototype.drag=t.animationFrameThrottle(function(t){if(this._currentDrag){var e=0,i=t.gesture.center.pageY;if(this.scrollView){var n=this.scrollEl;e=this.scrollView.getValues().top;var r=n.offsetTop,o=r-i+this._currentDrag.elementHeight/2,s=i+this._currentDrag.elementHeight/2-r-n.offsetHeight;t.gesture.deltaY<0&&o>0&&e>0&&this.scrollView.scrollBy(null,-o),t.gesture.deltaY>0&&s>0&&ethis.dragThresholdY&&(this._isDragging=!0),this._isDragging&&(this._moveElement(t),this._currentDrag.currentY=e+i-this._currentDrag.placeholder.parentNode.offsetTop,this._reorderItems())}}),h.prototype._reorderItems=function(){var e=(this._currentDrag.placeholder,Array.prototype.slice.call(this._currentDrag.placeholder.parentNode.children)),i=e.indexOf(this._currentDrag.placeholder),n=e[Math.max(0,i-1)],r=e[Math.min(e.length,i+1)],o=this._currentDrag.currentY;return n&&or.offsetTop+r.offsetHeight/2?(t.DomUtil.swapNodes(r,this._currentDrag.placeholder),i+1):void 0},h.prototype.end=function(e,i){if(!this._currentDrag)return void(i&&i());var n=this._currentDrag.placeholder,r=t.DomUtil.getChildIndex(n,n.nodeName.toLowerCase());this.el.classList.remove(s),this.el.style[t.CSS.TRANSFORM]="",n.parentNode.insertBefore(this.el,n),n.parentNode.removeChild(n),this.onReorder&&this.onReorder(this.el,this._currentDrag.startIndex,r),this._currentDrag=null,i&&i()},t.views.ListView=t.views.View.inherit({initialize:function(e){var i=this;e=t.extend({onReorder:function(){},virtualRemoveThreshold:-200,virtualAddThreshold:200},e),t.extend(this,e),!this.itemHeight&&this.listEl&&(this.itemHeight=this.listEl.children[0]&&parseInt(this.listEl.children[0].style.height,10)),this.onRefresh=e.onRefresh||function(){},this.onRefreshOpening=e.onRefreshOpening||function(){},this.onRefreshHolding=e.onRefreshHolding||function(){},window.ionic.onGesture("touch",function(t){i._handleTouch(t)},this.el),window.ionic.onGesture("release",function(t){i._handleEndDrag(t)},this.el),window.ionic.onGesture("drag",function(t){i._handleDrag(t)},this.el),this._initDrag()},stopRefreshing:function(){var t=this.el.querySelector(".list-refresher");t.style.height="0px"},didScroll:function(t){if(this.isVirtual){var e=this.itemHeight,i=(this.listEl.children.length,t.target.scrollHeight),n=this.el.parentNode.offsetHeight,r=(t.scrollTop,Math.max(0,t.scrollTop+this.virtualRemoveThreshold)),o=Math.min(i,Math.abs(t.scrollTop)+n+this.virtualAddThreshold),s=Math.floor((o-r)/e),a=parseInt(Math.abs(r/e),10),l=parseInt(Math.abs(o/e),10);this._virtualItemsToRemove=Array.prototype.slice.call(this.listEl.children,0,a);{Array.prototype.slice.call(this.listEl.children,a,a+s)}this.renderViewport&&this.renderViewport(r,o,a,l)}},didStopScrolling:function(){if(this.isVirtual)for(var t=0;t5)return this._dragOp=new c({el:this.el}),this._dragOp.start(e),void e.preventDefault()}else{var n=this._getItem(e.target);if(n)return this._dragOp=new h({el:n,scrollEl:this.scrollEl,scrollView:this.scrollView,onReorder:function(t,e,n){i.onReorder&&i.onReorder(t,e,n)}}),this._dragOp.start(e),void e.preventDefault()}},_handleEndDrag:function(t){var e=this;if(this._didDragUpOrDown=!1,this._dragOp){clearTimeout(this._touchTimeout);for(var i=e.el.querySelectorAll(".item"),n=0,r=i.length;r>n;n++)i[n].classList.remove("active");this._dragOp.end(t,function(){e._initDrag()})}},_handleDrag:function(t){Math.abs(t.gesture.deltaY)>5&&(this._didDragUpOrDown=!0),(Math.abs(t.gesture.deltaX)>10||Math.abs(t.gesture.deltaY)>10)&&clearTimeout(this._touchTimeout),clearTimeout(this._touchTimeout),this.isDragging||this._dragOp||this._startDrag(t),this._dragOp&&(t.gesture.srcEvent.preventDefault(),this._dragOp.drag(t))},_handleTouch:function(i){var n=this,r=t.DomUtil.getParentOrSelfWithClass(i.target,e);r&&(this._touchTimeout=setTimeout(function(){for(var t=n.el.querySelectorAll(".item"),e=0,i=t.length;i>e;e++)t[e].classList.remove("active");r.classList.add("active")},250))}})}(ionic),function(t){"use strict";t.views.Loading=t.views.View.inherit({initialize:function(t){this.el=t.el,this.maxWidth=t.maxWidth||200,this.showDelay=t.showDelay||0,this._loadingBox=this.el.querySelector(".loading")},show:function(){var t=this;if(this._loadingBox){var e=t._loadingBox,i=Math.min(t.maxWidth,Math.max(window.outerWidth-40,e.offsetWidth));e.style.width=i+"px",e.style.marginLeft=-e.offsetWidth/2+"px",e.style.marginTop=-e.offsetHeight/2+"px",this._showDelayTimeout=window.setTimeout(function(){t.el.classList.add("active")},t.showDelay)}},hide:function(){this.el.offsetWidth,window.clearTimeout(this._showDelayTimeout),this.el.classList.remove("active")}})}(ionic),function(t){"use strict";t.views.Modal=t.views.View.inherit({initialize:function(e){e=t.extend({focusFirstInput:!1,unfocusOnHide:!0,focusFirstDelay:600},e),t.extend(this,e),this.el=e.el},show:function(){var t=this;t.focusFirstInput&&window.setTimeout(function(){var e=t.el.querySelector("input, textarea");e&&e.focus&&e.focus()},t.focusFirstDelay)},hide:function(){if(this.unfocusOnHide){var t=this.el.querySelectorAll("input, textarea");window.setTimeout(function(){for(var e=0;ee?-m:e>E?m:0,0))}t.continuous&&_.transitions&&(s(r(E-1),-m,0),s(r(E+1),m,0)),_.transitions||(T.style.left=E*-m+"px"),f.style.visibility="visible",t.slidesChanged&&t.slidesChanged()}function i(){t.continuous?o(E-1):E&&o(E-1)}function n(){t.continuous?o(E+1):EE?e:E)-a-1),m*n,0);e=r(e),s(E,m*n,i||w),s(e,0,i||w),t.continuous&&s(r(e-n),-(m*n),0)}else e=r(e),l(E*-m,e*-m,i||w);E=e,d(t.callback&&t.callback(E,g[E]))}}function s(t,e,i){a(t,e,i),p[t]=e}function a(t,e,i){var n=g[t],r=n&&n.style;r&&(r.webkitTransitionDuration=r.MozTransitionDuration=r.msTransitionDuration=r.OTransitionDuration=r.transitionDuration=i+"ms",r.webkitTransform="translate("+e+"px,0)translateZ(0)",r.msTransform=r.MozTransform=r.OTransform="translateX("+e+"px)")}function l(e,i,n){if(!n)return void(T.style.left=i+"px");var r=+new Date,o=setInterval(function(){var s=+new Date-r;return s>n?(T.style.left=i+"px",y&&c(),t.transitionEnd&&t.transitionEnd.call(event,E,g[E]),void clearInterval(o)):void(T.style.left=(i-e)*(Math.floor(s/n*100)/100)+e+"px")},4)}function c(){S=setTimeout(n,y)}function h(){y=t.auto||0,clearTimeout(S)}var u=function(){},d=function(t){setTimeout(t||u,0)},_={addEventListener:!!window.addEventListener,touch:"ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch,transitions:function(t){var e=["transitionProperty","WebkitTransition","MozTransition","OTransition","msTransition"];for(var i in e)if(void 0!==t.style[e[i]])return!0;return!1}(document.createElement("swipe"))},f=t.el;if(f){var g,p,m,v,T=f.children[0];t=t||{};var E=parseInt(t.startSlide,10)||0,w=t.speed||300;t.continuous=void 0!==t.continuous?t.continuous:!0;var S,b,y=t.auto||0,D={},x={},L={handleEvent:function(i){switch(("mousedown"==i.type||"mouseup"==i.type||"mousemove"==i.type)&&(i.touches=[{pageX:i.pageX,pageY:i.pageY}]),i.type){case"mousedown":this.start(i);break;case"touchstart":this.start(i);break;case"touchmove":this.move(i);break;case"mousemove":this.move(i);break;case"touchend":d(this.end(i));break;case"mouseup":d(this.end(i));break;case"webkitTransitionEnd":case"msTransitionEnd":case"oTransitionEnd":case"otransitionend":case"transitionend":d(this.transitionEnd(i));break;case"resize":d(e)}t.stopPropagation&&i.stopPropagation()},start:function(t){var e=t.touches[0];D={x:e.pageX,y:e.pageY,time:+new Date},b=void 0,x={},_.touch?(T.addEventListener("touchmove",this,!1),T.addEventListener("touchend",this,!1)):(T.addEventListener("mousemove",this,!1),T.addEventListener("mouseup",this,!1),document.addEventListener("mouseup",this,!1))},move:function(e){if(!(e.touches.length>1||e.scale&&1!==e.scale)){t.disableScroll&&e.preventDefault();var i=e.touches[0];x={x:i.pageX-D.x,y:i.pageY-D.y},"undefined"==typeof b&&(b=!!(b||Math.abs(x.x)0||E==g.length-1&&x.x<0?Math.abs(x.x)/m+1:1),a(E-1,x.x+p[E-1],0),a(E,x.x+p[E],0),a(E+1,x.x+p[E+1],0)))}},end:function(){var e=+new Date-D.time,i=Number(e)<250&&Math.abs(x.x)>20||Math.abs(x.x)>m/2,n=!E&&x.x>0||E==g.length-1&&x.x<0;t.continuous&&(n=!1);var o=x.x<0;b||(i&&!n?(o?(t.continuous?(s(r(E-1),-m,0),s(r(E+2),m,0)):s(E-1,-m,0),s(E,p[E]-m,w),s(r(E+1),p[r(E+1)]-m,w),E=r(E+1)):(t.continuous?(s(r(E+1),m,0),s(r(E-2),-m,0)):s(E+1,m,0),s(E,p[E]+m,w),s(r(E-1),p[r(E-1)]+m,w),E=r(E-1)),t.callback&&t.callback(E,g[E])):t.continuous?(s(r(E-1),-m,w),s(E,0,w),s(r(E+1),m,w)):(s(E-1,-m,w),s(E,0,w),s(E+1,m,w))),_.touch?(T.removeEventListener("touchmove",L,!1),T.removeEventListener("touchend",L,!1)):(T.removeEventListener("mousemove",L,!1),T.removeEventListener("mouseup",L,!1),document.removeEventListener("mouseup",L,!1))},transitionEnd:function(e){parseInt(e.target.getAttribute("data-index"),10)==E&&(y&&c(),t.transitionEnd&&t.transitionEnd.call(e,E,g[E]))}};this.setup=function(){e()},this.slide=function(t,e){h(),o(t,e)},this.prev=function(){h(),i()},this.next=function(){h(),n()},this.stop=function(){h()},this.currentIndex=function(){return E},this.slidesCount=function(){return v},this.kill=function(){h(),T.style.width="",T.style.left="";for(var t=g.length;t--;){var e=g[t];e.style.width="",e.style.left="",_.transitions&&a(t,0,0)}_.addEventListener?(T.removeEventListener("touchstart",L,!1),T.removeEventListener("webkitTransitionEnd",L,!1),T.removeEventListener("msTransitionEnd",L,!1),T.removeEventListener("oTransitionEnd",L,!1),T.removeEventListener("otransitionend",L,!1),T.removeEventListener("transitionend",L,!1),window.removeEventListener("resize",L,!1)):window.onresize=null},this.load=function(){e(),y&&c(),_.addEventListener?(_.touch?T.addEventListener("touchstart",L,!1):T.addEventListener("mousedown",L,!1),_.transitions&&(T.addEventListener("webkitTransitionEnd",L,!1),T.addEventListener("msTransitionEnd",L,!1),T.addEventListener("oTransitionEnd",L,!1),T.addEventListener("otransitionend",L,!1),T.addEventListener("transitionend",L,!1)),window.addEventListener("resize",L,!1)):window.onresize=function(){e() -}}}}})}(ionic),function(t){"use strict";t.views.TabBarItem=t.views.View.inherit({initialize:function(t){this.el=t,this._buildItem()},create:function(e){var i=document.createElement("a");if(i.className="tab-item",e.icon){var n=document.createElement("i");n.className=e.icon,i.appendChild(n)}if(e.badge){var r=document.createElement("i");r.className="badge",r.innerHTML=e.badge,i.appendChild(r),i.className="tab-item has-badge"}return i.appendChild(document.createTextNode(e.title)),new t.views.TabBarItem(i)},_buildItem:function(){for(var e,i=this,n=Array.prototype.slice.call(this.el.children),r=0,o=n.length;o>r;r++)e=n[r],"i"==e.tagName.toLowerCase()&&/icon/.test(e.className)&&(this.icon=e.className),"i"==e.tagName.toLowerCase()&&/badge/.test(e.className)&&(this.badge=e.textContent.trim());for(this.title="",r=0,o=this.el.childNodes.length;o>r;r++)e=this.el.childNodes[r],"#text"===e.nodeName&&(this.title+=e.nodeValue.trim());this._tapHandler=function(t){i.onTap&&i.onTap(t)},t.on("tap",this._tapHandler,this.el)},onTap:function(){},destroy:function(){t.off("tap",this._tapHandler,this.el)},getIcon:function(){return this.icon},getTitle:function(){return this.title},getBadge:function(){return this.badge},setSelected:function(t){this.isSelected=t,t?this.el.classList.add("active"):this.el.classList.remove("active")}}),t.views.TabBar=t.views.View.inherit({initialize:function(t){this.el=t.el,this.items=[],this._buildItems()},getItems:function(){return this.items},addItem:function(e){var i=t.views.TabBarItem.prototype.create(e);this.appendItemElement(i),this.items.push(i),this._bindEventsOnItem(i)},appendItemElement:function(t){this.el&&this.el.appendChild(t.el)},removeItem:function(t){var e=this.items[t];e&&(e.onTap=void 0,e.destroy())},_bindEventsOnItem:function(t){var e=this;this._itemTapHandler||(this._itemTapHandler=function(){e.trySelectItem(this)}),t.onTap=this._itemTapHandler},getSelectedItem:function(){return this.selectedItem},setSelectedItem:function(t){this.selectedItem=this.items[t];for(var e=0,i=this.items.length;i>e;e+=1)this.items[e].setSelected(!1);this.selectedItem&&this.selectedItem.setSelected(!0)},selectItem:function(t){for(var e=0,i=this.items.length;i>e;e+=1)if(this.items[e]==t)return void this.setSelectedItem(e)},trySelectItem:function(t){for(var e=0,i=this.items.length;i>e;e+=1)if(this.items[e]==t)return void(this.tryTabSelect&&this.tryTabSelect(e))},_buildItems:function(){for(var e,i=Array.prototype.slice.call(this.el.children),n=0,r=i.length;r>n;n+=1)e=new t.views.TabBarItem(i[n]),this.items[n]=e,this._bindEventsOnItem(e);this.items.length>0&&(this.selectedItem=this.items[0])},destroy:function(){for(var t=0,e=this.items.length;e>t;t+=1)this.items[t].destroy();this.items.length=0}})}(window.ionic),function(t){"use strict";t.views.Toggle=t.views.View.inherit({initialize:function(e){var i=this;this.el=e.el,this.checkbox=e.checkbox,this.track=e.track,this.handle=e.handle,this.openPercent=-1,this.onChange=e.onChange||function(){},this.triggerThreshold=e.triggerThreshold||20,this.dragStartHandler=function(t){i.dragStart(t)},this.dragHandler=function(t){i.drag(t)},this.holdHandler=function(t){i.hold(t)},this.releaseHandler=function(t){i.release(t)},this.dragStartGesture=t.onGesture("dragstart",this.dragStartHandler,this.el),this.dragGesture=t.onGesture("drag",this.dragHandler,this.el),this.dragHoldGesture=t.onGesture("hold",this.holdHandler,this.el),this.dragReleaseGesture=t.onGesture("release",this.releaseHandler,this.el)},destroy:function(){t.offGesture(this.dragStartGesture,"dragstart",this.dragStartGesture),t.offGesture(this.dragGesture,"drag",this.dragGesture),t.offGesture(this.dragHoldGesture,"hold",this.holdHandler),t.offGesture(this.dragReleaseGesture,"release",this.releaseHandler)},tap:function(){"disabled"!==this.el.getAttribute("disabled")&&this.val(!this.checkbox.checked)},dragStart:function(t){this.checkbox.disabled||(this._dragInfo={width:this.el.offsetWidth,left:this.el.offsetLeft,right:this.el.offsetLeft+this.el.offsetWidth,triggerX:this.el.offsetWidth/2,initialState:this.checkbox.checked},t.gesture.srcEvent.preventDefault(),this.hold(t))},drag:function(e){var i=this;this._dragInfo&&(e.gesture.srcEvent.preventDefault(),t.requestAnimationFrame(function(){var t=(i.track.offsetLeft+i.handle.offsetWidth/2,i.track.offsetLeft+i.track.offsetWidth-i.handle.offsetWidth/2,e.gesture.deltaX,e.gesture.touches[0].pageX-i._dragInfo.left),n=i._dragInfo.width-i.triggerThreshold;i._dragInfo.initialState?ti._dragInfo.triggerX&&i.setOpenPercent(100):tn&&i.setOpenPercent(100)}))},endDrag:function(){this._dragInfo=null},hold:function(){this.el.classList.add("dragging")},release:function(t){this.el.classList.remove("dragging"),this.endDrag(t)},setOpenPercent:function(e){if(this.openPercent<0||ethis.openPercent+3)if(this.openPercent=e,0===e)this.val(!1);else if(100===e)this.val(!0);else{var i=Math.round(e/100*this.track.offsetWidth-this.handle.offsetWidth);i=1>i?0:i,this.handle.style[t.CSS.TRANSFORM]="translate3d("+i+"px,0,0)"}},val:function(e){return(e===!0||e===!1)&&(""!==this.handle.style[t.CSS.TRANSFORM]&&(this.handle.style[t.CSS.TRANSFORM]=""),this.checkbox.checked=e,this.openPercent=e?100:0,this.onChange&&this.onChange()),this.checkbox.checked}})}(ionic),function(t){"use strict";t.controllers.ViewController=function(){this.initialize.apply(this,arguments)},t.controllers.ViewController.inherit=t.inherit,t.extend(t.controllers.ViewController.prototype,{initialize:function(){},destroy:function(){}})}(window.ionic),function(t){"use strict";t.controllers.NavController=t.controllers.ViewController.inherit({initialize:function(t){var e=this;this.navBar=t.navBar,this.content=t.content,this.controllers=t.controllers||[],this._updateNavBar(),this.navBar.shouldGoBack=function(){e.pop()}},getControllers:function(){return this.controllers},getTopController:function(){return this.controllers[this.controllers.length-1]},push:function(t){var e=this.controllers[this.controllers.length-1];this.controllers.push(t);var i=this.switchingController&&this.switchingController(t)||!0;if(i!==!1){e&&(e.isVisible=!1,e.visibilityChanged&&e.visibilityChanged("push"));var n=this.controllers[this.controllers.length-1];return n.isVisible=!0,n.visibilityChanged&&n.visibilityChanged(e?"push":"first"),this._updateNavBar(),t}},pop:function(){var t,e;if(!(this.controllers.length<2))return e=this.controllers.pop(),e&&(e.isVisible=!1,e.visibilityChanged&&e.visibilityChanged("pop")),t=this.controllers[this.controllers.length-1],t.isVisible=!0,t.visibilityChanged&&t.visibilityChanged("pop"),this._updateNavBar(),e},showNavBar:function(){this.navBar&&this.navBar.show()},hideNavBar:function(){this.navBar&&this.navBar.hide()},_updateNavBar:function(){this.getTopController()&&this.navBar&&(this.navBar.setTitle(this.getTopController().title),this.navBar.showBackButton(this.controllers.length>1?!0:!1))}})}(window.ionic),function(t){"use strict";t.controllers.SideMenuController=t.controllers.ViewController.inherit({initialize:function(t){var e=this;this.left=t.left,this.right=t.right,this.content=t.content,this.dragThresholdX=t.dragThresholdX||10,this._rightShowing=!1,this._leftShowing=!1,this._isDragging=!1,this.content&&(this.content.onDrag=function(t){e._handleDrag(t)},this.content.onEndDrag=function(t){e._endDrag(t)})},setContent:function(t){var e=this;this.content=t,this.content.onDrag=function(t){e._handleDrag(t)},this.content.endDrag=function(t){e._endDrag(t)}},toggleLeft:function(){this.content.enableAnimation();var t=this.getOpenAmount();this.openPercentage(t>0?0:100)},toggleRight:function(){this.content.enableAnimation();var t=this.getOpenAmount();this.openPercentage(0>t?0:-100)},close:function(){this.openPercentage(0)},getOpenAmount:function(){return this.content&&this.content.getTranslateX()||0},getOpenRatio:function(){var t=this.getOpenAmount();return t>=0?t/this.left.width:t/this.right.width},isOpen:function(){return 1==this.getOpenRatio()},getOpenPercentage:function(){return 100*this.getOpenRatio()},openPercentage:function(t){var e=t/100;if(this.left&&t>=0)this.openAmount(this.left.width*e);else if(this.right&&0>t){{this.right.width}this.openAmount(this.right.width*e)}},openAmount:function(t){var e=this.left&&this.left.width||0,i=this.right&&this.right.width||0;return this.left&&this.left.isEnabled||!(t>0)?this.right&&this.right.isEnabled||!(0>t)?this._leftShowing&&t>e?void this.content.setTranslateX(e):this._rightShowing&&-i>t?void this.content.setTranslateX(-i):(this.content.setTranslateX(t),void(t>=0?(this._leftShowing=!0,this._rightShowing=!1,t>0&&(this.right&&this.right.pushDown&&this.right.pushDown(),this.left&&this.left.bringUp&&this.left.bringUp())):(this._rightShowing=!0,this._leftShowing=!1,this.right&&this.right.bringUp&&this.right.bringUp(),this.left&&this.left.pushDown&&this.left.pushDown()))):void this.content.setTranslateX(0):void this.content.setTranslateX(0)},snapToRest:function(t){this.content.enableAnimation(),this._isDragging=!1;var e=this.getOpenRatio();if(0===e)return void this.openPercentage(0);var i=.3,n=t.gesture.velocityX,r=t.gesture.direction;this.openPercentage(e>0&&.5>e&&"right"==r&&i>n?0:e>.5&&"left"==r&&i>n?100:0>e&&e>-.5&&"left"==r&&i>n?0:.5>e&&"right"==r&&i>n?-100:"right"==r&&e>=0&&(e>=.5||n>i)?100:"left"==r&&0>=e&&(-.5>=e||n>i)?-100:0)},_endDrag:function(t){this._isDragging&&this.snapToRest(t),this._startX=null,this._lastX=null,this._offsetX=null},_handleDrag:function(t){this._startX?this._lastX=t.gesture.touches[0].pageX:(this._startX=t.gesture.touches[0].pageX,this._lastX=this._startX),!this._isDragging&&Math.abs(this._lastX-this._startX)>this.dragThresholdX&&(this._startX=this._lastX,this._isDragging=!0,this.content.disableAnimation(),this._offsetX=this.getOpenAmount()),this._isDragging&&this.openAmount(this._offsetX+(this._lastX-this._startX))}})}(ionic),function(t){"use strict";t.controllers.TabBarController=t.controllers.ViewController.inherit({initialize:function(t){this.tabBar=t.tabBar,this._bindEvents(),this.controllers=[];for(var e=t.controllers||[],i=0;i=this.controllers.length)){var e=this.selectedController,i=this.selectedIndex;this.selectedController=this.controllers[t],this.selectedIndex=t,this._showController(t),this.tabBar.setSelectedItem(t),this.controllerChanged&&this.controllerChanged(e,i,this.selectedController,this.selectedIndex)}},_showController:function(t){for(var e,i=0,n=this.controllers.length;n>i;i++)e=this.controllers[i],e.isVisible=!1,e.visibilityChanged&&e.visibilityChanged();e=this.controllers[t],e.isVisible=!0,e.visibilityChanged&&e.visibilityChanged()},_clearSelected:function(){this.selectedController=null,this.selectedIndex=-1},getController:function(t){return this.controllers[t]},getControllers:function(){return this.controllers},getSelectedController:function(){return this.selectedController},getSelectedControllerIndex:function(){return this.selectedIndex},addController:function(t){this.controllers.push(t),this.tabBar.addItem({title:t.title,icon:t.icon,badge:t.badge}),this.selectedController||this.setSelectedController(0)},setControllers:function(t){this.controllers=t,this._clearSelected(),this.selectController(0)}})}(window.ionic); \ No newline at end of file +!function(){window.ionic={controllers:{},views:{},version:"1.0.0-beta.1"},function(t){function e(t){return t*t*t}function i(t){return 3*t*t*(1-t)}function n(t){return 3*t*(1-t)*(1-t)}function r(t){return(1-t)*(1-t)*(1-t)}var o=function(t,e){return t||(t=0),e||(e=0),{x:t,y:e}};t.Animator={getQuadraticBezier:function(t,s,a,l,c){var u=new o;return u.x=s.x*e(t)+a.x*i(t)+l.x*n(t)+c.x*r(t),u.y=s.y*e(t)+a.y*i(t)+l.y*n(t)+c.y*r(t),u},getCubicBezier:function(t,e,i,n,r){epsilon=1e3/60/r/4;var o=function(e){var n=1-e;return 3*n*n*e*t+3*n*e*e*i+e*e*e},s=function(t){var i=1-t;return 3*i*i*t*e+3*i*t*t*n+t*t*t},a=function(e){var n=1-e;return 3*(2*(e-1)*e+n*n)*t+3*(-e*e*e+2*n*e)*i};return function(t){var e,i,n,r,l,c,u=t;for(n=u,c=0;8>c;c++){if(r=o(n)-u,Math.abs(r)n)return s(e);if(n>i)return s(i);for(;i>e;){if(r=o(n),Math.abs(r-u)r?e=n:i=n,n=.5*(i-e)+e}return s(n)}},animate:function(t){return{leave:function(){var e=function(){t.classList.remove("leave"),t.classList.remove("leave-active"),t.removeEventListener("webkitTransitionEnd",e),t.removeEventListener("transitionEnd",e)};return t.addEventListener("webkitTransitionEnd",e),t.addEventListener("transitionEnd",e),t.classList.add("leave"),t.classList.add("leave-active"),this},enter:function(){var e=function(){t.classList.remove("enter"),t.classList.remove("enter-active"),t.removeEventListener("webkitTransitionEnd",e),t.removeEventListener("transitionEnd",e)};return t.addEventListener("webkitTransitionEnd",e),t.addEventListener("transitionEnd",e),t.classList.add("enter"),t.classList.add("enter-active"),this}}}}}(ionic),function(t,e,i){function n(){o=!0;for(var t=0;tr;r++)if(i=n[r],i.nodeName&&i.nodeName.toLowerCase()==e){if(i==t)return o;o++}return Array.prototype.slice.call(t.parentNode.children).indexOf(t)},swapNodes:function(t,e){e.parentNode.insertBefore(t,e)},getParentWithClass:function(t,e,i){for(i=i||10;t.parentNode&&i--;){if(t.parentNode.classList&&t.parentNode.classList.contains(e))return t.parentNode;t=t.parentNode}return null},getParentOrSelfWithClass:function(t,e,i){for(i=i||10;t&&i--;){if(t.classList&&t.classList.contains(e))return t;t=t.parentNode}return null},rectContains:function(t,e,i,n,r,o){return i>t||t>r?!1:n>e||e>o?!1:!0}},i.requestAnimationFrame=i.DomUtil.requestAnimationFrame,i.animationFrameThrottle=i.DomUtil.animationFrameThrottle}(this,document,ionic),function(t){window.CustomEvent||!function(){var t;t=function(t,e){var i;e=e||{bubbles:!1,cancelable:!1,detail:void 0};try{i=document.createEvent("CustomEvent"),i.initCustomEvent(t,e.bubbles,e.cancelable,e.detail)}catch(n){i=document.createEvent("Event");for(var r in e)i[r]=e[r];i.initEvent(t,e.bubbles,e.cancelable)}return i},t.prototype=window.Event.prototype,window.CustomEvent=t}(),t.EventController={VIRTUALIZED_EVENTS:["tap","swipe","swiperight","swipeleft","drag","hold","release"],trigger:function(t,e,i,n){var r=new CustomEvent(t,{detail:e,bubbles:!!i,cancelable:!!n});e&&e.target&&e.target.dispatchEvent(r)||window.dispatchEvent(r)},on:function(e,i,n){for(var r=n||window,o=0,s=this.VIRTUALIZED_EVENTS.length;s>o;o++)if(e==this.VIRTUALIZED_EVENTS[o]){var a=new t.Gesture(n);return a.on(e,i),a}r.addEventListener(e,i)},off:function(t,e,i){i.removeEventListener(t,e)},onGesture:function(e,i,n){var r=new t.Gesture(n);return r.on(e,i),r},offGesture:function(t,e,i){t.off(e,i)},handlePopState:function(){}},t.on=function(){t.EventController.on.apply(t.EventController,arguments)},t.off=function(){t.EventController.off.apply(t.EventController,arguments)},t.trigger=t.EventController.trigger,t.onGesture=function(){return t.EventController.onGesture.apply(t.EventController.onGesture,arguments)},t.offGesture=function(){return t.EventController.offGesture.apply(t.EventController.offGesture,arguments)}}(window.ionic),function(t){function e(){if(!t.Gestures.READY){t.Gestures.event.determineEventTypes();for(var e in t.Gestures.gestures)t.Gestures.gestures.hasOwnProperty(e)&&t.Gestures.detection.register(t.Gestures.gestures[e]);t.Gestures.event.onTouch(t.Gestures.DOCUMENT,t.Gestures.EVENT_MOVE,t.Gestures.detection.detect),t.Gestures.event.onTouch(t.Gestures.DOCUMENT,t.Gestures.EVENT_END,t.Gestures.detection.detect),t.Gestures.READY=!0}}t.Gesture=function(e,i){return new t.Gestures.Instance(e,i||{})},t.Gestures={},t.Gestures.defaults={stop_browser_behavior:"disable-user-behavior"},t.Gestures.HAS_POINTEREVENTS=window.navigator.pointerEnabled||window.navigator.msPointerEnabled,t.Gestures.HAS_TOUCHEVENTS="ontouchstart"in window,t.Gestures.MOBILE_REGEX=/mobile|tablet|ip(ad|hone|od)|android|silk/i,t.Gestures.NO_MOUSEEVENTS=t.Gestures.HAS_TOUCHEVENTS&&window.navigator.userAgent.match(t.Gestures.MOBILE_REGEX),t.Gestures.EVENT_TYPES={},t.Gestures.DIRECTION_DOWN="down",t.Gestures.DIRECTION_LEFT="left",t.Gestures.DIRECTION_UP="up",t.Gestures.DIRECTION_RIGHT="right",t.Gestures.POINTER_MOUSE="mouse",t.Gestures.POINTER_TOUCH="touch",t.Gestures.POINTER_PEN="pen",t.Gestures.EVENT_START="start",t.Gestures.EVENT_MOVE="move",t.Gestures.EVENT_END="end",t.Gestures.DOCUMENT=window.document,t.Gestures.plugins={},t.Gestures.READY=!1,t.Gestures.Instance=function(i,n){var r=this;if(null!==i)return e(),this.element=i,this.enabled=!0,this.options=t.Gestures.utils.extend(t.Gestures.utils.extend({},t.Gestures.defaults),n||{}),this.options.stop_browser_behavior&&t.Gestures.utils.stopDefaultBrowserBehavior(this.element,this.options.stop_browser_behavior),t.Gestures.event.onTouch(i,t.Gestures.EVENT_START,function(e){r.enabled&&t.Gestures.detection.startDetect(r,e)}),this},t.Gestures.Instance.prototype={on:function(t,e){for(var i=t.split(" "),n=0;n0&&o==t.Gestures.EVENT_END?o=t.Gestures.EVENT_MOVE:u||(o=t.Gestures.EVENT_END),(u||null===i)&&(i=l),s.call(t.Gestures.detection,a.collectEventData(e,o,a.getTouchList(i,o),l)),t.Gestures.HAS_POINTEREVENTS&&o==t.Gestures.EVENT_END&&(u=t.Gestures.PointerEvent.updatePointer(o,l))),u||(i=null,n=!1,r=!1,t.Gestures.PointerEvent.reset())}})},determineEventTypes:function(){var e;e=t.Gestures.HAS_POINTEREVENTS?t.Gestures.PointerEvent.getEvents():t.Gestures.NO_MOUSEEVENTS?["touchstart","touchmove","touchend touchcancel"]:["touchstart mousedown","touchmove mousemove","touchend touchcancel mouseup"],t.Gestures.EVENT_TYPES[t.Gestures.EVENT_START]=e[0],t.Gestures.EVENT_TYPES[t.Gestures.EVENT_MOVE]=e[1],t.Gestures.EVENT_TYPES[t.Gestures.EVENT_END]=e[2]},getTouchList:function(e){return t.Gestures.HAS_POINTEREVENTS?t.Gestures.PointerEvent.getTouchList():e.touches?e.touches:(e.indentifier=1,[e])},collectEventData:function(e,i,n,r){var o=t.Gestures.POINTER_TOUCH;return(r.type.match(/mouse/)||t.Gestures.PointerEvent.matchType(t.Gestures.POINTER_MOUSE,r))&&(o=t.Gestures.POINTER_MOUSE),{center:t.Gestures.utils.getCenter(n),timeStamp:(new Date).getTime(),target:r.target,touches:n,eventType:i,pointerType:o,srcEvent:r,preventDefault:function(){this.srcEvent.preventManipulation&&this.srcEvent.preventManipulation(),this.srcEvent.preventDefault},stopPropagation:function(){this.srcEvent.stopPropagation()},stopDetect:function(){return t.Gestures.detection.stopDetect()}}}},t.Gestures.PointerEvent={pointers:{},getTouchList:function(){var t=this,e=[];return Object.keys(t.pointers).sort().forEach(function(i){e.push(t.pointers[i])}),e},updatePointer:function(e,i){return e==t.Gestures.EVENT_END?this.pointers={}:(i.identifier=i.pointerId,this.pointers[i.pointerId]=i),Object.keys(this.pointers).length},matchType:function(e,i){if(!i.pointerType)return!1;var n={};return n[t.Gestures.POINTER_MOUSE]=i.pointerType==i.MSPOINTER_TYPE_MOUSE||i.pointerType==t.Gestures.POINTER_MOUSE,n[t.Gestures.POINTER_TOUCH]=i.pointerType==i.MSPOINTER_TYPE_TOUCH||i.pointerType==t.Gestures.POINTER_TOUCH,n[t.Gestures.POINTER_PEN]=i.pointerType==i.MSPOINTER_TYPE_PEN||i.pointerType==t.Gestures.POINTER_PEN,n[e]},getEvents:function(){return["pointerdown MSPointerDown","pointermove MSPointerMove","pointerup pointercancel MSPointerUp MSPointerCancel"]},reset:function(){this.pointers={}}},t.Gestures.utils={extend:function(t,e,i){for(var n in e)void 0!==t[n]&&i||(t[n]=e[n]);return t},hasParent:function(t,e){for(;t;){if(t==e)return!0;t=t.parentNode}return!1},getCenter:function(t){for(var e=[],i=[],n=0,r=t.length;r>n;n++)e.push(t[n].pageX),i.push(t[n].pageY);return{pageX:(Math.min.apply(Math,e)+Math.max.apply(Math,e))/2,pageY:(Math.min.apply(Math,i)+Math.max.apply(Math,i))/2}},getVelocity:function(t,e,i){return{x:Math.abs(e/t)||0,y:Math.abs(i/t)||0}},getAngle:function(t,e){var i=e.pageY-t.pageY,n=e.pageX-t.pageX;return 180*Math.atan2(i,n)/Math.PI},getDirection:function(e,i){var n=Math.abs(e.pageX-i.pageX),r=Math.abs(e.pageY-i.pageY);return n>=r?e.pageX-i.pageX>0?t.Gestures.DIRECTION_LEFT:t.Gestures.DIRECTION_RIGHT:e.pageY-i.pageY>0?t.Gestures.DIRECTION_UP:t.Gestures.DIRECTION_DOWN},getDistance:function(t,e){var i=e.pageX-t.pageX,n=e.pageY-t.pageY;return Math.sqrt(i*i+n*n)},getScale:function(t,e){return t.length>=2&&e.length>=2?this.getDistance(e[0],e[1])/this.getDistance(t[0],t[1]):1},getRotation:function(t,e){return t.length>=2&&e.length>=2?this.getAngle(e[1],e[0])-this.getAngle(t[1],t[0]):0},isVertical:function(e){return e==t.Gestures.DIRECTION_UP||e==t.Gestures.DIRECTION_DOWN},stopDefaultBrowserBehavior:function(t,e){t&&t.classList&&(t.classList.add(e),t.onselectstart=function(){return!1})}},t.Gestures.detection={gestures:[],current:null,previous:null,stopped:!1,startDetect:function(e,i){this.current||(this.stopped=!1,this.current={inst:e,startEvent:t.Gestures.utils.extend({},i),lastEvent:!1,name:""},this.detect(i))},detect:function(e){if(this.current&&!this.stopped){e=this.extendEventData(e);for(var i=this.current.inst.options,n=0,r=this.gestures.length;r>n;n++){var o=this.gestures[n];if(!this.stopped&&i[o.name]!==!1&&o.handler.call(o,e,this.current.inst)===!1){this.stopDetect();break}}return this.current&&(this.current.lastEvent=e),e.eventType==t.Gestures.EVENT_END&&!e.touches.length-1&&this.stopDetect(),e}},stopDetect:function(){this.previous=t.Gestures.utils.extend({},this.current),this.current=null,this.stopped=!0},extendEventData:function(e){var i=this.current.startEvent;if(i&&(e.touches.length!=i.touches.length||e.touches===i.touches)){i.touches=[];for(var n=0,r=e.touches.length;r>n;n++)i.touches.push(t.Gestures.utils.extend({},e.touches[n]))}var o=e.timeStamp-i.timeStamp,s=e.center.pageX-i.center.pageX,a=e.center.pageY-i.center.pageY,l=t.Gestures.utils.getVelocity(o,s,a);return t.Gestures.utils.extend(e,{deltaTime:o,deltaX:s,deltaY:a,velocityX:l.x,velocityY:l.y,distance:t.Gestures.utils.getDistance(i.center,e.center),angle:t.Gestures.utils.getAngle(i.center,e.center),direction:t.Gestures.utils.getDirection(i.center,e.center),scale:t.Gestures.utils.getScale(i.touches,e.touches),rotation:t.Gestures.utils.getRotation(i.touches,e.touches),startEvent:i}),e},register:function(e){var i=e.defaults||{};return void 0===i[e.name]&&(i[e.name]=!0),t.Gestures.utils.extend(t.Gestures.defaults,i,!0),e.index=e.index||1e3,this.gestures.push(e),this.gestures.sort(function(t,e){return t.indexe.index?1:0}),this.gestures}},t.Gestures.gestures=t.Gestures.gestures||{},t.Gestures.gestures.Hold={name:"hold",index:10,defaults:{hold_timeout:500,hold_threshold:1},timer:null,handler:function(e,i){switch(e.eventType){case t.Gestures.EVENT_START:clearTimeout(this.timer),t.Gestures.detection.current.name=this.name,this.timer=setTimeout(function(){"hold"==t.Gestures.detection.current.name&&i.trigger("hold",e)},i.options.hold_timeout);break;case t.Gestures.EVENT_MOVE:e.distance>i.options.hold_threshold&&clearTimeout(this.timer);break;case t.Gestures.EVENT_END:clearTimeout(this.timer)}}},t.Gestures.gestures.Tap={name:"tap",index:100,defaults:{tap_max_touchtime:250,tap_max_distance:10,tap_always:!0,doubletap_distance:20,doubletap_interval:300},handler:function(e,i){if(e.eventType==t.Gestures.EVENT_END){var n=t.Gestures.detection.previous,r=!1;if(e.deltaTime>i.options.tap_max_touchtime||e.distance>i.options.tap_max_distance)return;n&&"tap"==n.name&&e.timeStamp-n.lastEvent.timeStamp0&&e.touches.length>i.options.swipe_max_touches)return;(e.velocityX>i.options.swipe_velocity||e.velocityY>i.options.swipe_velocity)&&(i.trigger(this.name,e),i.trigger(this.name+e.direction,e))}}},t.Gestures.gestures.Drag={name:"drag",index:50,defaults:{drag_min_distance:10,correct_for_drag_min_distance:!0,drag_max_touches:1,drag_block_horizontal:!0,drag_block_vertical:!0,drag_lock_to_axis:!1,drag_lock_min_distance:25},triggered:!1,handler:function(e,i){if(t.Gestures.detection.current.name!=this.name&&this.triggered)return i.trigger(this.name+"end",e),void(this.triggered=!1);if(!(i.options.drag_max_touches>0&&e.touches.length>i.options.drag_max_touches))switch(e.eventType){case t.Gestures.EVENT_START:this.triggered=!1;break;case t.Gestures.EVENT_MOVE:if(e.distancei.options.transform_min_rotation&&i.trigger("rotate",e),n>i.options.transform_min_scale&&(i.trigger("pinch",e),i.trigger("pinch"+(e.scale<1?"in":"out"),e));break;case t.Gestures.EVENT_END:this.triggered&&i.trigger(this.name+"end",e),this.triggered=!1}}},t.Gestures.gestures.Touch={name:"touch",index:-1/0,defaults:{prevent_default:!1,prevent_mouseevents:!1},handler:function(e,i){return i.options.prevent_mouseevents&&e.pointerType==t.Gestures.POINTER_MOUSE?void e.stopDetect():(i.options.prevent_default&&e.preventDefault(),void(e.eventType==t.Gestures.EVENT_START&&i.trigger(this.name,e)))}},t.Gestures.gestures.Release={name:"release",index:1/0,handler:function(e,i){e.eventType==t.Gestures.EVENT_END&&i.trigger(this.name,e)}}}(window.ionic),function(t,e,i){function n(){i.Platform.isCordova()?e.addEventListener("deviceready",r,!1):r(),t.removeEventListener("load",n,!1)}function r(){i.Platform.isReady=!0,i.Platform.detect();for(var t=0;t0?i=i.replace(".","_"):i+="_0",this.platforms.push(t+i.split("_")[0]),this.platforms.push(t+i),this.isAndroid()&&4.4>e&&(this.grade=4>e?"c":"b")}}},isCordova:function(){return!(!t.cordova&&!t.PhoneGap&&!t.phonegap)},isIPad:function(){return this.ua.toLowerCase().indexOf("ipad")>=0},isIOS:function(){return this.is("ios")},isAndroid:function(){return this.is("android")},platform:function(){return null===o&&this.setPlatform(this.device().platform),o},setPlatform:function(t){o="undefined"!=typeof t&&null!==t&&t.length?t.toLowerCase():this.ua.indexOf("Android")>0?"android":this.ua.indexOf("iPhone")>-1||this.ua.indexOf("iPad")>-1||this.ua.indexOf("iPod")>-1?"ios":""},version:function(){return null===s&&this.setVersion(this.device().version),s},setVersion:function(t){if("undefined"!=typeof t&&null!==t&&(t=t.split("."),t=parseFloat(t[0]+"."+(t.length>1?t[1]:0)),!isNaN(t)))return void(s=t);s=0;var e=this.platform(),i={android:/Android (\d+).(\d+)?/,ios:/OS (\d+)_(\d+)?/};i[e]&&(t=this.ua.match(i[e]),t.length>2&&(s=parseFloat(t[1]+"."+t[2])))},is:function(t){if(t=t.toLowerCase(),this.platforms)for(var e=0;e=0},exitApp:function(){this.ready(function(){navigator.app&&navigator.app.exitApp&&navigator.app.exitApp()})},showStatusBar:function(n){this._showStatusBar=n,this.ready(function(){i.requestAnimationFrame(function(){i.Platform._showStatusBar?(t.StatusBar&&t.StatusBar.show(),e.body.classList.remove("status-bar-hide")):(t.StatusBar&&t.StatusBar.hide(),e.body.classList.add("status-bar-hide"))})})},fullScreen:function(t,n){this.isFullScreen=t!==!1,i.DomUtil.ready(function(){i.requestAnimationFrame(function(){i.Platform.isFullScreen?e.body.classList.add("fullscreen"):e.body.classList.remove("fullscreen")}),i.Platform.showStatusBar(n===!0)})}};var o=null,s=null,a=[];t.addEventListener("load",n,!1)}(this,document,ionic),function(t,e){"use strict";e.CSS={},function(){var i,n=["webkitTransform","transform","-webkit-transform","webkit-transform","-moz-transform","moz-transform","MozTransform","mozTransform"];for(i=0;ir&&n;r++){if("INPUT"===n.tagName||"A"===n.tagName||"BUTTON"===n.tagName||"LABEL"===n.tagName||"TEXTAREA"===n.tagName)return i.tapElement(n,e);n=n.parentElement}h()}}function r(t){return t.target.control||o(t)||s(t)?u(t):void a(t)}function o(t){var e,i,n;for(e in f)if(i=f[e],n||(n=l(t)),n.x>i.x-v&&n.xi.y-v&&n.yg.x+2||e.xg.y+2||e.yc&&a;c++){if(r&&a.classList.contains("item")){r=a;break}if(("A"==a.tagName||"BUTTON"==a.tagName||a.getAttribute("ng-click"))&&(r=a),a.classList.contains("button")){r=a;break}a=a.parentElement}r&&(s[l]=r,"touchstart"===n.type?(t.body.removeEventListener("mousedown",e.activator.start),t.body.addEventListener("touchmove",o,!1),setTimeout(i,85)):(t.body.addEventListener("mousemove",o,!1),e.requestAnimationFrame(i)),l=l>19?0:l+1)})}},window.addEventListener("load",function(){t.body.addEventListener("touchstart",e.activator.start,!1),t.body.addEventListener("mousedown",e.activator.start,!1),t.body.addEventListener("touchend",r,!1),t.body.addEventListener("mouseup",r,!1),t.body.addEventListener("touchcancel",r,!1)},!1)}(document,ionic),function(t){var e=["0","0","0"];t.Utils={arrayMove:function(t,e,i){if(i>=t.length)for(var n=i-t.length;n--+1;)t.push(void 0);return t.splice(i,0,t.splice(e,1)[0]),t},proxy:function(t,e){var i=Array.prototype.slice.call(arguments,2);return function(){return t.apply(e,i.concat(Array.prototype.slice.call(arguments)))}},debounce:function(t,e,i){var n,r,o,s,a;return function(){o=this,r=arguments,s=new Date;var l=function(){var c=new Date-s;e>c?n=setTimeout(l,e-c):(n=null,i||(a=t.apply(o,r)))},c=i&&!n;return n||(n=setTimeout(l,e)),c&&(a=t.apply(o,r)),a}},throttle:function(t,e,i){var n,r,o,s=null,a=0;i||(i={});var l=function(){a=i.leading===!1?0:Date.now(),s=null,o=t.apply(n,r)};return function(){var c=Date.now();a||i.leading!==!1||(a=c);var u=e-(c-a);return n=this,r=arguments,0>=u?(clearTimeout(s),s=null,a=c,o=t.apply(n,r)):s||i.trailing===!1||(s=setTimeout(l,u)),o}},inherit:function(e,i){var n,r=this;n=e&&e.hasOwnProperty("constructor")?e.constructor:function(){return r.apply(this,arguments)},t.extend(n,r,i);var o=function(){this.constructor=n};return o.prototype=r.prototype,n.prototype=new o,e&&t.extend(n.prototype,e),n.__super__=r.prototype,n},extend:function(t){for(var e=Array.prototype.slice.call(arguments,1),i=0;i2500&&(clearInterval(a),a=null)},1e3/n)),e}}(),stop:function(t){var e=null!=r[t];return e&&(r[t]=null),e},isRunning:function(t){return null!=r[t]},start:function(t,a,l,c,u,h){var d=e(),_=d,f=0,g=0,p=o++;if(h||(h=document.body),p%20===0){var m={};for(var v in r)m[v]=!0;r=m}var T=function(o){var m=o!==!0,v=e();if(!r[p]||a&&!a(p))return r[p]=null,void(l&&l(i-g/((v-d)/n),p,!1));if(m)for(var E=Math.round((v-_)/(n/i))-1,w=0;w1&&(f=1));var y=u?u(f):f;t(y,v,m)!==!1&&1!==f||!m?m&&(_=v,s.effect.Animate.requestAnimationFrame(T,h)):(r[p]=null,l&&l(i-g/((v-d)/n),p,1===f||null==c))};return r[p]=!0,s.effect.Animate.requestAnimationFrame(T,h),p}}}(this);!function(i){var n=function(){},r=function(t){return Math.pow(t-1,3)+1},o=function(t){return(t/=.5)<1?.5*Math.pow(t,3):.5*(Math.pow(t-2,3)+2)};i.views.Scroll=i.views.View.inherit({initialize:function(t){var e=this;this.__container=t.el,this.__content=t.el.firstElementChild,setTimeout(function(){e.__container&&e.__content&&(e.__container.scrollTop=0,e.__content.scrollTop=0)}),this.options={scrollingX:!1,scrollbarX:!0,scrollingY:!0,scrollbarY:!0,startX:0,startY:0,wheelDampen:6,minScrollbarSizeX:5,minScrollbarSizeY:5,scrollbarsFade:!0,scrollbarFadeDelay:300,scrollbarResizeFadeDelay:1e3,animating:!0,animationDuration:250,bouncing:!0,locking:!0,paging:!1,snapping:!1,zooming:!1,minZoom:.5,maxZoom:3,speedMultiplier:1,scrollingComplete:n,penetrationDeceleration:.03,penetrationAcceleration:.08,scrollEventInterval:50};for(var r in t)this.options[r]=t[r];this.hintResize=i.debounce(function(){e.resize()},1e3,!0),this.triggerScrollEvent=i.throttle(function(){i.trigger("scroll",{scrollTop:e.__scrollTop,scrollLeft:e.__scrollLeft,target:e.__container})},this.options.scrollEventInterval),this.triggerScrollEndEvent=function(){i.trigger("scrollend",{scrollTop:e.__scrollTop,scrollLeft:e.__scrollLeft,target:e.__container})},this.__scrollLeft=this.options.startX,this.__scrollTop=this.options.startY,this.__callback=this.getRenderFn(),this.__initEventHandlers(),this.__createScrollbars()},run:function(){this.resize(),this.__fadeScrollbars("out",this.options.scrollbarResizeFadeDelay)},__isSingleTouch:!1,__isTracking:!1,__didDecelerationComplete:!1,__isGesturing:!1,__isDragging:!1,__isDecelerating:!1,__isAnimating:!1,__clientLeft:0,__clientTop:0,__clientWidth:0,__clientHeight:0,__contentWidth:0,__contentHeight:0,__snapWidth:100,__snapHeight:100,__refreshHeight:null,__refreshActive:!1,__refreshActivate:null,__refreshDeactivate:null,__refreshStart:null,__zoomLevel:1,__scrollLeft:0,__scrollTop:0,__maxScrollLeft:0,__maxScrollTop:0,__scheduledLeft:0,__scheduledTop:0,__scheduledZoom:0,__lastTouchLeft:null,__lastTouchTop:null,__lastTouchMove:null,__positions:null,__minDecelerationScrollLeft:null,__minDecelerationScrollTop:null,__maxDecelerationScrollLeft:null,__maxDecelerationScrollTop:null,__decelerationVelocityX:null,__decelerationVelocityY:null,__transformProperty:null,__perspectiveProperty:null,__indicatorX:null,__indicatorY:null,__scrollbarFadeTimeout:null,__didWaitForSize:null,__sizerTimeout:null,__initEventHandlers:function(){function n(i){return i.target.tagName.match(t)||i.target.isContentEditable||i.target.tagName.match(e)||i.target.dataset.preventScroll}var r=this,o=this.__container;if(o.addEventListener("scrollChildIntoView",function(t){var e=window.innerHeight,n=t.target,s=t.target.offsetHeight,a=n.getBoundingClientRect().top,l=i.DomUtil.getPositionInParent(n,o).top;a+s>e&&r.scrollTo(0,l+s-.5*e,!0),t.stopPropagation() +}),"ontouchstart"in window)o.addEventListener("touchstart",function(t){t.defaultPrevented||n(t)||(r.doTouchStart(t.touches,t.timeStamp),t.preventDefault())},!1),document.addEventListener("touchmove",function(t){t.defaultPrevented||r.doTouchMove(t.touches,t.timeStamp)},!1),document.addEventListener("touchend",function(t){r.doTouchEnd(t.timeStamp)},!1);else{var s=!1;o.addEventListener("mousedown",function(t){t.defaultPrevented||n(t)||(r.doTouchStart([{pageX:t.pageX,pageY:t.pageY}],t.timeStamp),t.preventDefault(),s=!0)},!1),document.addEventListener("mousemove",function(t){s&&!t.defaultPrevented&&(r.doTouchMove([{pageX:t.pageX,pageY:t.pageY}],t.timeStamp),s=!0)},!1),document.addEventListener("mouseup",function(t){s&&(r.doTouchEnd(t.timeStamp),s=!1)},!1);var a=i.debounce(function(){r.__fadeScrollbars("in")},500,!0),l=i.debounce(function(){r.__fadeScrollbars("out")},100,!1);document.addEventListener("mousewheel",function(t){a(),r.scrollBy(t.wheelDeltaX/r.options.wheelDampen,-t.wheelDeltaY/r.options.wheelDampen),l()})}},__createScrollbar:function(t){var e=document.createElement("div"),i=document.createElement("div");return i.className="scroll-bar-indicator",e.className="h"==t?"scroll-bar scroll-bar-h":"scroll-bar scroll-bar-v",e.appendChild(i),e},__createScrollbars:function(){var t,e;this.options.scrollingX&&(t={el:this.__createScrollbar("h"),sizeRatio:1},t.indicator=t.el.children[0],this.options.scrollbarX&&this.__container.appendChild(t.el),this.__indicatorX=t),this.options.scrollingY&&(e={el:this.__createScrollbar("v"),sizeRatio:1},e.indicator=e.el.children[0],this.options.scrollbarY&&this.__container.appendChild(e.el),this.__indicatorY=e)},__resizeScrollbars:function(){var t=this;if(t.__indicatorX){var e=Math.max(Math.round(t.__clientWidth*t.__clientWidth/t.__contentWidth),20);e>t.__contentWidth&&(e=0),t.__indicatorX.size=e,t.__indicatorX.minScale=this.options.minScrollbarSizeX/e,t.__indicatorX.indicator.style.width=e+"px",t.__indicatorX.maxPos=t.__clientWidth-e,t.__indicatorX.sizeRatio=t.__maxScrollLeft?t.__indicatorX.maxPos/t.__maxScrollLeft:1}if(t.__indicatorY){var i=Math.max(Math.round(t.__clientHeight*t.__clientHeight/t.__contentHeight),20);i>t.__contentHeight&&(i=0),t.__indicatorY.size=i,t.__indicatorY.minScale=this.options.minScrollbarSizeY/i,t.__indicatorY.maxPos=t.__clientHeight-i,t.__indicatorY.indicator.style.height=i+"px",t.__indicatorY.sizeRatio=t.__maxScrollTop?t.__indicatorY.maxPos/t.__maxScrollTop:1}},__repositionScrollbars:function(){var t,e,i,n,r,o=this,s=0,a=0;o.__indicatorX&&(o.__indicatorY&&(s=10),n=Math.round(o.__indicatorX.sizeRatio*o.__scrollLeft)||0,e=o.__scrollLeft-(o.__maxScrollLeft-s),o.__scrollLeft<0?(widthScale=Math.max(o.__indicatorX.minScale,(o.__indicatorX.size-Math.abs(o.__scrollLeft))/o.__indicatorX.size),n=0,o.__indicatorX.indicator.style[o.__transformOriginProperty]="left center"):e>0?(widthScale=Math.max(o.__indicatorX.minScale,(o.__indicatorX.size-e)/o.__indicatorX.size),n=o.__indicatorX.maxPos-s,o.__indicatorX.indicator.style[o.__transformOriginProperty]="right center"):(n=Math.min(o.__maxScrollLeft,Math.max(0,n)),widthScale=1),o.__indicatorX.indicator.style[o.__transformProperty]="translate3d("+n+"px, 0, 0) scaleX("+widthScale+")"),o.__indicatorY&&(r=Math.round(o.__indicatorY.sizeRatio*o.__scrollTop)||0,o.__indicatorX&&(a=10),i=o.__scrollTop-(o.__maxScrollTop-a),o.__scrollTop<0?(t=Math.max(o.__indicatorY.minScale,(o.__indicatorY.size-Math.abs(o.__scrollTop))/o.__indicatorY.size),r=0,o.__indicatorY.indicator.style[o.__transformOriginProperty]="center top"):i>0?(t=Math.max(o.__indicatorY.minScale,(o.__indicatorY.size-i)/o.__indicatorY.size),r=o.__indicatorY.maxPos-a,o.__indicatorY.indicator.style[o.__transformOriginProperty]="center bottom"):(r=Math.min(o.__maxScrollTop,Math.max(0,r)),t=1),o.__indicatorY.indicator.style[o.__transformProperty]="translate3d(0,"+r+"px, 0) scaleY("+t+")")},__fadeScrollbars:function(t,e){var i=this;if(this.options.scrollbarsFade){var n="scroll-bar-fade-out";i.options.scrollbarsFade===!0&&(clearTimeout(i.__scrollbarFadeTimeout),"in"==t?(i.__indicatorX&&i.__indicatorX.indicator.classList.remove(n),i.__indicatorY&&i.__indicatorY.indicator.classList.remove(n)):i.__scrollbarFadeTimeout=setTimeout(function(){i.__indicatorX&&i.__indicatorX.indicator.classList.add(n),i.__indicatorY&&i.__indicatorY.indicator.classList.add(n)},e||i.options.scrollbarFadeDelay))}},__scrollingComplete:function(){var t=this;t.options.scrollingComplete(),t.__fadeScrollbars("out")},resize:function(){this.setDimensions(this.__container.clientWidth,this.__container.clientHeight,Math.max(this.__content.scrollWidth,this.__content.offsetWidth),Math.max(this.__content.scrollHeight,this.__content.offsetHeight))},getRenderFn:function(){var t,e=this,i=this.__content,n=document.documentElement.style;"MozAppearance"in n?t="gecko":"WebkitAppearance"in n?t="webkit":"string"==typeof navigator.cpuClass&&(t="trident");var r,o={trident:"ms",gecko:"Moz",webkit:"Webkit",presto:"O"}[t],s=document.createElement("div"),a=o+"Perspective",l=o+"Transform",c=o+"TransformOrigin";return e.__perspectiveProperty=l,e.__transformProperty=l,e.__transformOriginProperty=c,s.style[a]!==r?function(t,n){i.style[l]="translate3d("+-t+"px,"+-n+"px,0)",e.__repositionScrollbars(),e.triggerScrollEvent()}:s.style[l]!==r?function(t,n){i.style[l]="translate("+-t+"px,"+-n+"px)",e.__repositionScrollbars(),e.triggerScrollEvent()}:function(t,n,r){i.style.marginLeft=t?-t/r+"px":"",i.style.marginTop=n?-n/r+"px":"",i.style.zoom=r||"",e.__repositionScrollbars(),e.triggerScrollEvent()}},setDimensions:function(t,e,i,n){var r=this;t===+t&&(r.__clientWidth=t),e===+e&&(r.__clientHeight=e),i===+i&&(r.__contentWidth=i),n===+n&&(r.__contentHeight=n),r.__computeScrollMax(),r.__resizeScrollbars(),r.scrollTo(r.__scrollLeft,r.__scrollTop,!0)},setPosition:function(t,e){var i=this;i.__clientLeft=t||0,i.__clientTop=e||0},setSnapSize:function(t,e){var i=this;i.__snapWidth=t,i.__snapHeight=e},activatePullToRefresh:function(t,e,i,n){var r=this;r.__refreshHeight=t,r.__refreshActivate=e,r.__refreshDeactivate=i,r.__refreshStart=n},triggerPullToRefresh:function(){this.__publish(this.__scrollLeft,-this.__refreshHeight,this.__zoomLevel,!0),this.__refreshStart&&this.__refreshStart()},finishPullToRefresh:function(){var t=this;t.__refreshActive=!1,t.__refreshDeactivate&&t.__refreshDeactivate(),t.scrollTo(t.__scrollLeft,t.__scrollTop,!0)},getValues:function(){var t=this;return{left:t.__scrollLeft,top:t.__scrollTop,zoom:t.__zoomLevel}},getScrollMax:function(){var t=this;return{left:t.__maxScrollLeft,top:t.__maxScrollTop}},zoomTo:function(t,e,i,n){var r=this;if(!r.options.zooming)throw new Error("Zooming is not enabled!");r.__isDecelerating&&(core.effect.Animate.stop(r.__isDecelerating),r.__isDecelerating=!1);var o=r.__zoomLevel;null==i&&(i=r.__clientWidth/2),null==n&&(n=r.__clientHeight/2),t=Math.max(Math.min(t,r.options.maxZoom),r.options.minZoom),r.__computeScrollMax(t);var s=(i+r.__scrollLeft)*t/o-i,a=(n+r.__scrollTop)*t/o-n;s>r.__maxScrollLeft?s=r.__maxScrollLeft:0>s&&(s=0),a>r.__maxScrollTop?a=r.__maxScrollTop:0>a&&(a=0),r.__publish(s,a,t,e)},zoomBy:function(t,e,i,n){var r=this;r.zoomTo(r.__zoomLevel*t,e,i,n)},scrollTo:function(t,e,i,n){var r=this;if(r.__isDecelerating&&(core.effect.Animate.stop(r.__isDecelerating),r.__isDecelerating=!1),null!=n&&n!==r.__zoomLevel){if(!r.options.zooming)throw new Error("Zooming is not enabled!");t*=n,e*=n,r.__computeScrollMax(n)}else n=r.__zoomLevel;r.options.scrollingX?r.options.paging?t=Math.round(t/r.__clientWidth)*r.__clientWidth:r.options.snapping&&(t=Math.round(t/r.__snapWidth)*r.__snapWidth):t=r.__scrollLeft,r.options.scrollingY?r.options.paging?e=Math.round(e/r.__clientHeight)*r.__clientHeight:r.options.snapping&&(e=Math.round(e/r.__snapHeight)*r.__snapHeight):e=r.__scrollTop,t=Math.max(Math.min(r.__maxScrollLeft,t),0),e=Math.max(Math.min(r.__maxScrollTop,e),0),t===r.__scrollLeft&&e===r.__scrollTop&&(i=!1),r.__publish(t,e,n,i)},scrollBy:function(t,e,i){var n=this,r=n.__isAnimating?n.__scheduledLeft:n.__scrollLeft,o=n.__isAnimating?n.__scheduledTop:n.__scrollTop;n.scrollTo(r+(t||0),o+(e||0),i)},doMouseZoom:function(t,e,i,n){var r=this,o=t>0?.97:1.03;return r.zoomTo(r.__zoomLevel*o,!1,i-r.__clientLeft,n-r.__clientTop)},doTouchStart:function(t,e){if(this.hintResize(),null==t.length)throw new Error("Invalid touch list: "+t);if(e instanceof Date&&(e=e.valueOf()),"number"!=typeof e)throw new Error("Invalid timestamp value: "+e);var i=this;i.__interruptedAnimation=!0,i.__isDecelerating&&(core.effect.Animate.stop(i.__isDecelerating),i.__isDecelerating=!1,i.__interruptedAnimation=!0),i.__isAnimating&&(core.effect.Animate.stop(i.__isAnimating),i.__isAnimating=!1,i.__interruptedAnimation=!0);var n,r,o=1===t.length;o?(n=t[0].pageX,r=t[0].pageY):(n=Math.abs(t[0].pageX+t[1].pageX)/2,r=Math.abs(t[0].pageY+t[1].pageY)/2),i.__initialTouchLeft=n,i.__initialTouchTop=r,i.__zoomLevelStart=i.__zoomLevel,i.__lastTouchLeft=n,i.__lastTouchTop=r,i.__lastTouchMove=e,i.__lastScale=1,i.__enableScrollX=!o&&i.options.scrollingX,i.__enableScrollY=!o&&i.options.scrollingY,i.__isTracking=!0,i.__didDecelerationComplete=!1,i.__isDragging=!o,i.__isSingleTouch=o,i.__positions=[]},doTouchMove:function(t,e,i){if(null==t.length)throw new Error("Invalid touch list: "+t);if(e instanceof Date&&(e=e.valueOf()),"number"!=typeof e)throw new Error("Invalid timestamp value: "+e);var n=this;if(n.__isTracking){var r,o;2===t.length?(r=Math.abs(t[0].pageX+t[1].pageX)/2,o=Math.abs(t[0].pageY+t[1].pageY)/2):(r=t[0].pageX,o=t[0].pageY);var s=n.__positions;if(n.__isDragging){var a=r-n.__lastTouchLeft,l=o-n.__lastTouchTop,c=n.__scrollLeft,u=n.__scrollTop,h=n.__zoomLevel;if(null!=i&&n.options.zooming){var d=h;if(h=h/n.__lastScale*i,h=Math.max(Math.min(h,n.options.maxZoom),n.options.minZoom),d!==h){var _=r-n.__clientLeft,f=o-n.__clientTop;c=(_+c)*h/d-_,u=(f+u)*h/d-f,n.__computeScrollMax(h)}}if(n.__enableScrollX){c-=a*this.options.speedMultiplier;var g=n.__maxScrollLeft;(c>g||0>c)&&(n.options.bouncing?c+=a/2*this.options.speedMultiplier:c=c>g?g:0)}if(n.__enableScrollY){u-=l*this.options.speedMultiplier;var p=n.__maxScrollTop;(u>p||0>u)&&(n.options.bouncing||n.__refreshHeight&&0>u?(u+=l/2*this.options.speedMultiplier,n.__enableScrollX||null==n.__refreshHeight||(!n.__refreshActive&&u<=-n.__refreshHeight?(n.__refreshActive=!0,n.__refreshActivate&&n.__refreshActivate()):n.__refreshActive&&u>-n.__refreshHeight&&(n.__refreshActive=!1,n.__refreshDeactivate&&n.__refreshDeactivate()))):u=u>p?p:0)}s.length>60&&s.splice(0,30),s.push(c,u,e),n.__publish(c,u,h)}else{var m=n.options.locking?3:0,v=5,T=Math.abs(r-n.__initialTouchLeft),E=Math.abs(o-n.__initialTouchTop);n.__enableScrollX=n.options.scrollingX&&T>=m,n.__enableScrollY=n.options.scrollingY&&E>=m,s.push(n.__scrollLeft,n.__scrollTop,e),n.__isDragging=(n.__enableScrollX||n.__enableScrollY)&&(T>=v||E>=v),n.__isDragging&&(n.__interruptedAnimation=!1,n.__fadeScrollbars("in"))}n.__lastTouchLeft=r,n.__lastTouchTop=o,n.__lastTouchMove=e,n.__lastScale=i}},doTouchEnd:function(t){if(t instanceof Date&&(t=t.valueOf()),"number"!=typeof t)throw new Error("Invalid timestamp value: "+t);var e=this;if(e.__isTracking){if(e.__isTracking=!1,e.__isDragging)if(e.__isDragging=!1,e.__isSingleTouch&&e.options.animating&&t-e.__lastTouchMove<=100){for(var i=e.__positions,n=i.length-1,r=n,o=n;o>0&&i[o]>e.__lastTouchMove-100;o-=3)r=o;if(r!==n){var s=i[n]-i[r],a=e.__scrollLeft-i[r-2],l=e.__scrollTop-i[r-1];e.__decelerationVelocityX=a/s*(1e3/60),e.__decelerationVelocityY=l/s*(1e3/60);var c=e.options.paging||e.options.snapping?4:1;(Math.abs(e.__decelerationVelocityX)>c||Math.abs(e.__decelerationVelocityY)>c)&&(e.__refreshActive||e.__startDeceleration(t))}else e.__scrollingComplete()}else t-e.__lastTouchMove>100&&e.__scrollingComplete();e.__isDecelerating||(e.__refreshActive&&e.__refreshStart?(e.__publish(e.__scrollLeft,-e.__refreshHeight,e.__zoomLevel,!0),e.__refreshStart&&e.__refreshStart()):((e.__interruptedAnimation||e.__isDragging)&&e.__scrollingComplete(),e.scrollTo(e.__scrollLeft,e.__scrollTop,!0,e.__zoomLevel),e.__refreshActive&&(e.__refreshActive=!1,e.__refreshDeactivate&&e.__refreshDeactivate()))),e.__positions.length=0}},__publish:function(t,e,i,n){var s=this,a=s.__isAnimating;if(a&&(core.effect.Animate.stop(a),s.__isAnimating=!1),n&&s.options.animating){s.__scheduledLeft=t,s.__scheduledTop=e,s.__scheduledZoom=i;var l=s.__scrollLeft,c=s.__scrollTop,u=s.__zoomLevel,h=t-l,d=e-c,_=i-u,f=function(t,e,i){i&&(s.__scrollLeft=l+h*t,s.__scrollTop=c+d*t,s.__zoomLevel=u+_*t,s.__callback&&s.__callback(s.__scrollLeft,s.__scrollTop,s.__zoomLevel))},g=function(t){return s.__isAnimating===t},p=function(t,e,i){e===s.__isAnimating&&(s.__isAnimating=!1),(s.__didDecelerationComplete||i)&&s.__scrollingComplete(),s.options.zooming&&s.__computeScrollMax()};s.__isAnimating=core.effect.Animate.start(f,g,p,s.options.animationDuration,a?r:o)}else s.__scheduledLeft=s.__scrollLeft=t,s.__scheduledTop=s.__scrollTop=e,s.__scheduledZoom=s.__zoomLevel=i,s.__callback&&s.__callback(t,e,i),s.options.zooming&&s.__computeScrollMax()},__computeScrollMax:function(t){var e=this;null==t&&(t=e.__zoomLevel),e.__maxScrollLeft=Math.max(e.__contentWidth*t-e.__clientWidth,0),e.__maxScrollTop=Math.max(e.__contentHeight*t-e.__clientHeight,0),e.__didWaitForSize||0!=e.__maxScrollLeft||0!=e.__maxScrollTop||(e.__didWaitForSize=!0,e.__waitForSize())},__waitForSize:function(){var t=this;clearTimeout(t.__sizerTimeout);var e=function(){t.resize(),t.options.scrollingX&&0==t.__maxScrollLeft||t.options.scrollingY&&0==t.__maxScrollTop};e(),t.__sizerTimeout=setTimeout(e,1e3)},__startDeceleration:function(){var t=this;if(t.options.paging){var e=Math.max(Math.min(t.__scrollLeft,t.__maxScrollLeft),0),i=Math.max(Math.min(t.__scrollTop,t.__maxScrollTop),0),n=t.__clientWidth,r=t.__clientHeight;t.__minDecelerationScrollLeft=Math.floor(e/n)*n,t.__minDecelerationScrollTop=Math.floor(i/r)*r,t.__maxDecelerationScrollLeft=Math.ceil(e/n)*n,t.__maxDecelerationScrollTop=Math.ceil(i/r)*r}else t.__minDecelerationScrollLeft=0,t.__minDecelerationScrollTop=0,t.__maxDecelerationScrollLeft=t.__maxScrollLeft,t.__maxDecelerationScrollTop=t.__maxScrollTop;var o=function(e,i,n){t.__stepThroughDeceleration(n)};t.__minVelocityToKeepDecelerating=t.options.snapping?4:.1;var s=function(){var e=Math.abs(t.__decelerationVelocityX)>=t.__minVelocityToKeepDecelerating||Math.abs(t.__decelerationVelocityY)>=t.__minVelocityToKeepDecelerating;return e||(t.__didDecelerationComplete=!0),e},a=function(){t.__isDecelerating=!1,t.__didDecelerationComplete&&t.__scrollingComplete(),t.options.paging&&t.scrollTo(t.__scrollLeft,t.__scrollTop,t.options.snapping)};t.__isDecelerating=core.effect.Animate.start(o,s,a)},__stepThroughDeceleration:function(t){var e=this,i=e.__scrollLeft+e.__decelerationVelocityX,n=e.__scrollTop+e.__decelerationVelocityY;if(!e.options.bouncing){var r=Math.max(Math.min(e.__maxDecelerationScrollLeft,i),e.__minDecelerationScrollLeft);r!==i&&(i=r,e.__decelerationVelocityX=0);var o=Math.max(Math.min(e.__maxDecelerationScrollTop,n),e.__minDecelerationScrollTop);o!==n&&(n=o,e.__decelerationVelocityY=0)}if(t?e.__publish(i,n,e.__zoomLevel):(e.__scrollLeft=i,e.__scrollTop=n),!e.options.paging){var s=.95;e.__decelerationVelocityX*=s,e.__decelerationVelocityY*=s}if(e.options.bouncing){var a=0,l=0,c=e.options.penetrationDeceleration,u=e.options.penetrationAcceleration;if(ie.__maxDecelerationScrollLeft&&(a=e.__maxDecelerationScrollLeft-i),ne.__maxDecelerationScrollTop&&(l=e.__maxDecelerationScrollTop-n),0!==a){var h=a*e.__decelerationVelocityX<=e.__minDecelerationScrollLeft;h&&(e.__decelerationVelocityX+=a*c);var d=Math.abs(e.__decelerationVelocityX)<=e.__minVelocityToKeepDecelerating;(!h||d)&&(e.__decelerationVelocityX=a*u)}if(0!==l){var _=l*e.__decelerationVelocityY<=e.__minDecelerationScrollTop;_&&(e.__decelerationVelocityY+=l*c);var f=Math.abs(e.__decelerationVelocityY)<=e.__minVelocityToKeepDecelerating;(!_||f)&&(e.__decelerationVelocityY=l*u)}}}})}(ionic),function(t){"use strict";t.views.ActionSheet=t.views.View.inherit({initialize:function(t){this.el=t.el},show:function(){this.el.offsetWidth,this.el.classList.add("active")},hide:function(){this.el.offsetWidth,this.el.classList.remove("active")}})}(ionic),function(t){"use strict";t.views.HeaderBar=t.views.View.inherit({initialize:function(e){this.el=e.el,t.extend(this,{alignTitle:"center"},e),this.align()},align:function(e){e||(e=this.alignTitle);var i=this.el.querySelector(".title");if(i){var n,r,o,s=this.el.childNodes,a=0,l=0,c=!1;for(n=0;n10&&(i.style.left=t+"px",i.style.right=t+"px"),i.offsetWidth0&&(i.style.right=l+5+"px")):"left"==e?(i.classList.add("title-left"),a>0&&(i.style.left=a+15+"px")):"right"==e&&(i.classList.add("title-right"),l>0&&(i.style.right=l+15+"px"))})}}})}(ionic),function(t){"use strict";var e="item",i="item-content",n="item-sliding",r="item-options",o="item-placeholder",s="item-reordering",a="item-reorder",l=function(){};l.prototype={start:function(){},drag:function(){},end:function(){},isSameItem:function(){return!1}};var c=function(t){this.dragThresholdX=t.dragThresholdX||10,this.el=t.el};c.prototype=new l,c.prototype.start=function(o){var s,a,l,c;s=o.target.classList.contains(i)?o.target:o.target.classList.contains(e)?o.target.querySelector("."+i):t.DomUtil.getParentWithClass(o.target,i),s&&(s.classList.remove(n),l=parseFloat(s.style[t.CSS.TRANSFORM].replace("translate3d(","").split(",")[0])||0,a=s.parentNode.querySelector("."+r),a&&(c=a.offsetWidth,this._currentDrag={buttonsWidth:c,content:s,startOffsetX:l}))},c.prototype.isSameItem=function(t){return t._lastDrag&&this._currentDrag?this._currentDrag.content==t._lastDrag.content:!1},c.prototype.clean=function(){var e=this._lastDrag;e&&t.requestAnimationFrame(function(){e.content.style[t.CSS.TRANSITION]="",e.content.style[t.CSS.TRANSFORM]="translate3d(0, 0, 0)"})},c.prototype.drag=t.animationFrameThrottle(function(e){var i;if(this._currentDrag&&(!this._isDragging&&(Math.abs(e.gesture.deltaX)>this.dragThresholdX||Math.abs(this._currentDrag.startOffsetX)>0)&&(this._isDragging=!0),this._isDragging)){i=this._currentDrag.buttonsWidth;var n=Math.min(0,this._currentDrag.startOffsetX+e.gesture.deltaX);-i>n&&(n=Math.min(-i,-i+.4*(e.gesture.deltaX+i))),this._currentDrag.content.style[t.CSS.TRANSFORM]="translate3d("+n+"px, 0, 0)",this._currentDrag.content.style[t.CSS.TRANSITION]="none"}}),c.prototype.end=function(e,i){var n=this;if(!this._currentDrag)return void(i&&i());var r=-this._currentDrag.buttonsWidth;e.gesture.deltaX>-(this._currentDrag.buttonsWidth/2)&&("left"==e.gesture.direction&&Math.abs(e.gesture.velocityX)<.3?r=0:"right"==e.gesture.direction&&(r=0)),t.requestAnimationFrame(function(){n._currentDrag.content.style[t.CSS.TRANSFORM]=0===r?"":"translate3d("+r+"px, 0, 0)",n._currentDrag.content.style[t.CSS.TRANSITION]="",n._lastDrag=n._currentDrag,n._currentDrag=null,i&&i()})};var u=function(t){this.dragThresholdY=t.dragThresholdY||0,this.onReorder=t.onReorder,this.el=t.el,this.scrollEl=t.scrollEl,this.scrollView=t.scrollView};u.prototype=new l,u.prototype._moveElement=function(e){var i=e.gesture.center.pageY-this._currentDrag.elementHeight/2;this.el.style[t.CSS.TRANSFORM]="translate3d(0, "+i+"px, 0)"},u.prototype.start=function(e){var i=(this.el.offsetTop,t.DomUtil.getChildIndex(this.el,this.el.nodeName.toLowerCase())),n=this.el.offsetHeight,r=this.el.cloneNode(!0),a=(this.scrollEl||this.el).parentNode;r.classList.add(o),this.el.parentNode.insertBefore(r,this.el),this.el.classList.add(s),a.parentNode.appendChild(this.el),this._currentDrag={elementHeight:n,startIndex:i,placeholder:r,scrollHeight:scroll,list:r.parentNode},this._moveElement(e)},u.prototype.drag=t.animationFrameThrottle(function(t){if(this._currentDrag){var e=0,i=t.gesture.center.pageY;if(this.scrollView){var n=this.scrollEl;e=this.scrollView.getValues().top;var r=n.offsetTop,o=r-i+this._currentDrag.elementHeight/2,s=i+this._currentDrag.elementHeight/2-r-n.offsetHeight;t.gesture.deltaY<0&&o>0&&e>0&&this.scrollView.scrollBy(null,-o),t.gesture.deltaY>0&&s>0&&ethis.dragThresholdY&&(this._isDragging=!0),this._isDragging&&(this._moveElement(t),this._currentDrag.currentY=e+i-this._currentDrag.placeholder.parentNode.offsetTop,this._reorderItems())}}),u.prototype._reorderItems=function(){var e=(this._currentDrag.placeholder,Array.prototype.slice.call(this._currentDrag.placeholder.parentNode.children)),i=e.indexOf(this._currentDrag.placeholder),n=e[Math.max(0,i-1)],r=e[Math.min(e.length,i+1)],o=this._currentDrag.currentY;return n&&or.offsetTop+r.offsetHeight/2?(t.DomUtil.swapNodes(r,this._currentDrag.placeholder),i+1):void 0},u.prototype.end=function(e,i){if(!this._currentDrag)return void(i&&i());var n=this._currentDrag.placeholder,r=t.DomUtil.getChildIndex(n,n.nodeName.toLowerCase());this.el.classList.remove(s),this.el.style[t.CSS.TRANSFORM]="",n.parentNode.insertBefore(this.el,n),n.parentNode.removeChild(n),this.onReorder&&this.onReorder(this.el,this._currentDrag.startIndex,r),this._currentDrag=null,i&&i()},t.views.ListView=t.views.View.inherit({initialize:function(e){var i=this;e=t.extend({onReorder:function(){},virtualRemoveThreshold:-200,virtualAddThreshold:200,canSwipe:!1},e),t.extend(this,e),!this.itemHeight&&this.listEl&&(this.itemHeight=this.listEl.children[0]&&parseInt(this.listEl.children[0].style.height,10)),this.onRefresh=e.onRefresh||function(){},this.onRefreshOpening=e.onRefreshOpening||function(){},this.onRefreshHolding=e.onRefreshHolding||function(){},window.ionic.onGesture("release",function(t){i._handleEndDrag(t)},this.el),window.ionic.onGesture("drag",function(t){i._handleDrag(t)},this.el),this._initDrag()},stopRefreshing:function(){var t=this.el.querySelector(".list-refresher");t.style.height="0px"},didScroll:function(t){if(this.isVirtual){var e=this.itemHeight,i=(this.listEl.children.length,t.target.scrollHeight),n=this.el.parentNode.offsetHeight,r=(t.scrollTop,Math.max(0,t.scrollTop+this.virtualRemoveThreshold)),o=Math.min(i,Math.abs(t.scrollTop)+n+this.virtualAddThreshold),s=Math.floor((o-r)/e),a=parseInt(Math.abs(r/e),10),l=parseInt(Math.abs(o/e),10);this._virtualItemsToRemove=Array.prototype.slice.call(this.listEl.children,0,a);{Array.prototype.slice.call(this.listEl.children,a,a+s)}this.renderViewport&&this.renderViewport(r,o,a,l)}},didStopScrolling:function(){if(this.isVirtual)for(var t=0;t5){var r=this._getItem(e.target);r&&r.querySelector(".item-options")&&(this._dragOp=new c({el:this.el}),this._dragOp.start(e),e.preventDefault())}}else{var r=this._getItem(e.target);r&&(this._dragOp=new u({el:r,scrollEl:this.scrollEl,scrollView:this.scrollView,onReorder:function(t,e,n){i.onReorder&&i.onReorder(t,e,n)}}),this._dragOp.start(e),e.preventDefault())}n&&this._dragOp&&!this._dragOp.isSameItem(n)&&e.defaultPrevented&&n.clean&&n.clean()},_handleEndDrag:function(t){var e=this;this._didDragUpOrDown=!1,this._dragOp&&this._dragOp.end(t,function(){e._initDrag()})},_handleDrag:function(t){this.canSwipe&&(Math.abs(t.gesture.deltaY)>5&&(this._didDragUpOrDown=!0),this.isDragging||this._dragOp||this._startDrag(t),this._dragOp&&(t.gesture.srcEvent.preventDefault(),this._dragOp.drag(t)))}})}(ionic),function(t){"use strict";t.views.Loading=t.views.View.inherit({initialize:function(t){this.el=t.el,this.maxWidth=t.maxWidth||200,this.showDelay=t.showDelay||0,this._loadingBox=this.el.querySelector(".loading")||this.el},show:function(){var t=this;if(this._loadingBox){var e=t._loadingBox,i=Math.min(t.maxWidth,Math.max(window.outerWidth-40,e.offsetWidth));e.style.width=i+"px",e.style.marginLeft=-e.offsetWidth/2+"px",e.style.marginTop=-e.offsetHeight/2+"px",this._showDelayTimeout=window.setTimeout(function(){t.el.classList.add("active")},t.showDelay)}},hide:function(){this.el.offsetWidth,window.clearTimeout(this._showDelayTimeout),this.el.classList.remove("active")},setContent:function(t){this._loadingBox&&(this._loadingBox.innerHTML=t||"")}})}(ionic),function(t){"use strict";t.views.Modal=t.views.View.inherit({initialize:function(e){e=t.extend({focusFirstInput:!1,unfocusOnHide:!0,focusFirstDelay:600},e),t.extend(this,e),this.el=e.el},show:function(){var t=this;t.focusFirstInput&&window.setTimeout(function(){var e=t.el.querySelector("input, textarea");e&&e.focus&&e.focus()},t.focusFirstDelay)},hide:function(){if(this.unfocusOnHide){var t=this.el.querySelectorAll("input, textarea");window.setTimeout(function(){for(var e=0;ee?-m:e>E?m:0,0))}t.continuous&&_.transitions&&(s(r(E-1),-m,0),s(r(E+1),m,0)),_.transitions||(T.style.left=E*-m+"px"),f.style.visibility="visible",t.slidesChanged&&t.slidesChanged()}function i(){t.continuous?o(E-1):E&&o(E-1)}function n(){t.continuous?o(E+1):EE?e:E)-a-1),m*n,0);e=r(e),s(E,m*n,i||w),s(e,0,i||w),t.continuous&&s(r(e-n),-(m*n),0)}else e=r(e),l(E*-m,e*-m,i||w);E=e,d(t.callback&&t.callback(E,g[E]))}}function s(t,e,i){a(t,e,i),p[t]=e}function a(t,e,i){var n=g[t],r=n&&n.style;r&&(r.webkitTransitionDuration=r.MozTransitionDuration=r.msTransitionDuration=r.OTransitionDuration=r.transitionDuration=i+"ms",r.webkitTransform="translate("+e+"px,0)translateZ(0)",r.msTransform=r.MozTransform=r.OTransform="translateX("+e+"px)")}function l(e,i,n){if(!n)return void(T.style.left=i+"px");var r=+new Date,o=setInterval(function(){var s=+new Date-r;return s>n?(T.style.left=i+"px",S&&c(),t.transitionEnd&&t.transitionEnd.call(event,E,g[E]),void clearInterval(o)):void(T.style.left=(i-e)*(Math.floor(s/n*100)/100)+e+"px")},4)}function c(){y=setTimeout(n,S)}function u(){S=t.auto||0,clearTimeout(y)}var h=function(){},d=function(t){setTimeout(t||h,0)},_={addEventListener:!!window.addEventListener,touch:"ontouchstart"in window||window.DocumentTouch&&document instanceof DocumentTouch,transitions:function(t){var e=["transitionProperty","WebkitTransition","MozTransition","OTransition","msTransition"];for(var i in e)if(void 0!==t.style[e[i]])return!0;return!1}(document.createElement("swipe"))},f=t.el;if(f){var g,p,m,v,T=f.children[0];t=t||{};var E=parseInt(t.startSlide,10)||0,w=t.speed||300;t.continuous=void 0!==t.continuous?t.continuous:!0;var y,b,S=t.auto||0,D={},x={},L={handleEvent:function(i){switch(("mousedown"==i.type||"mouseup"==i.type||"mousemove"==i.type)&&(i.touches=[{pageX:i.pageX,pageY:i.pageY}]),i.type){case"mousedown":this.start(i);break;case"touchstart":this.start(i);break;case"touchmove":this.move(i);break;case"mousemove":this.move(i);break;case"touchend":d(this.end(i));break;case"mouseup":d(this.end(i));break;case"webkitTransitionEnd":case"msTransitionEnd":case"oTransitionEnd":case"otransitionend":case"transitionend":d(this.transitionEnd(i));break;case"resize":d(e)}t.stopPropagation&&i.stopPropagation()},start:function(t){var e=t.touches[0];D={x:e.pageX,y:e.pageY,time:+new Date},b=void 0,x={},_.touch?(T.addEventListener("touchmove",this,!1),T.addEventListener("touchend",this,!1)):(T.addEventListener("mousemove",this,!1),T.addEventListener("mouseup",this,!1),document.addEventListener("mouseup",this,!1))},move:function(e){if(!(e.touches.length>1||e.scale&&1!==e.scale)){t.disableScroll&&e.preventDefault();var i=e.touches[0];x={x:i.pageX-D.x,y:i.pageY-D.y},"undefined"==typeof b&&(b=!!(b||Math.abs(x.x)0||E==g.length-1&&x.x<0?Math.abs(x.x)/m+1:1),a(E-1,x.x+p[E-1],0),a(E,x.x+p[E],0),a(E+1,x.x+p[E+1],0)))}},end:function(){var e=+new Date-D.time,i=Number(e)<250&&Math.abs(x.x)>20||Math.abs(x.x)>m/2,n=!E&&x.x>0||E==g.length-1&&x.x<0;t.continuous&&(n=!1);var o=x.x<0;b||(i&&!n?(o?(t.continuous?(s(r(E-1),-m,0),s(r(E+2),m,0)):s(E-1,-m,0),s(E,p[E]-m,w),s(r(E+1),p[r(E+1)]-m,w),E=r(E+1)):(t.continuous?(s(r(E+1),m,0),s(r(E-2),-m,0)):s(E+1,m,0),s(E,p[E]+m,w),s(r(E-1),p[r(E-1)]+m,w),E=r(E-1)),t.callback&&t.callback(E,g[E])):t.continuous?(s(r(E-1),-m,w),s(E,0,w),s(r(E+1),m,w)):(s(E-1,-m,w),s(E,0,w),s(E+1,m,w))),_.touch?(T.removeEventListener("touchmove",L,!1),T.removeEventListener("touchend",L,!1)):(T.removeEventListener("mousemove",L,!1),T.removeEventListener("mouseup",L,!1),document.removeEventListener("mouseup",L,!1)) +},transitionEnd:function(e){parseInt(e.target.getAttribute("data-index"),10)==E&&(S&&c(),t.transitionEnd&&t.transitionEnd.call(e,E,g[E]))}};this.update=function(){setTimeout(e)},this.setup=function(){e()},this.slide=function(t,e){u(),o(t,e)},this.prev=this.previous=function(){u(),i()},this.next=function(){u(),n()},this.stop=function(){u()},this.currentIndex=function(){return E},this.slidesCount=function(){return v},this.kill=function(){u(),T.style.width="",T.style.left="";for(var t=g.length;t--;){var e=g[t];e.style.width="",e.style.left="",_.transitions&&a(t,0,0)}_.addEventListener?(T.removeEventListener("touchstart",L,!1),T.removeEventListener("webkitTransitionEnd",L,!1),T.removeEventListener("msTransitionEnd",L,!1),T.removeEventListener("oTransitionEnd",L,!1),T.removeEventListener("otransitionend",L,!1),T.removeEventListener("transitionend",L,!1),window.removeEventListener("resize",L,!1)):window.onresize=null},this.load=function(){e(),S&&c(),_.addEventListener?(_.touch?T.addEventListener("touchstart",L,!1):T.addEventListener("mousedown",L,!1),_.transitions&&(T.addEventListener("webkitTransitionEnd",L,!1),T.addEventListener("msTransitionEnd",L,!1),T.addEventListener("oTransitionEnd",L,!1),T.addEventListener("otransitionend",L,!1),T.addEventListener("transitionend",L,!1)),window.addEventListener("resize",L,!1)):window.onresize=function(){e()}}}}})}(ionic),function(t){"use strict";t.views.TabBarItem=t.views.View.inherit({initialize:function(t){this.el=t,this._buildItem()},create:function(e){var i=document.createElement("a");if(i.className="tab-item",e.icon){var n=document.createElement("i");n.className=e.icon,i.appendChild(n)}if(e.badge){var r=document.createElement("i");r.className="badge",r.innerHTML=e.badge,i.appendChild(r),i.className="tab-item has-badge"}return i.appendChild(document.createTextNode(e.title)),new t.views.TabBarItem(i)},_buildItem:function(){for(var e,i=this,n=Array.prototype.slice.call(this.el.children),r=0,o=n.length;o>r;r++)e=n[r],"i"==e.tagName.toLowerCase()&&/icon/.test(e.className)&&(this.icon=e.className),"i"==e.tagName.toLowerCase()&&/badge/.test(e.className)&&(this.badge=e.textContent.trim());for(this.title="",r=0,o=this.el.childNodes.length;o>r;r++)e=this.el.childNodes[r],"#text"===e.nodeName&&(this.title+=e.nodeValue.trim());this._tapHandler=function(t){i.onTap&&i.onTap(t)},t.on("tap",this._tapHandler,this.el)},onTap:function(){},destroy:function(){t.off("tap",this._tapHandler,this.el)},getIcon:function(){return this.icon},getTitle:function(){return this.title},getBadge:function(){return this.badge},setSelected:function(t){this.isSelected=t,t?this.el.classList.add("active"):this.el.classList.remove("active")}}),t.views.TabBar=t.views.View.inherit({initialize:function(t){this.el=t.el,this.items=[],this._buildItems()},getItems:function(){return this.items},addItem:function(e){var i=t.views.TabBarItem.prototype.create(e);this.appendItemElement(i),this.items.push(i),this._bindEventsOnItem(i)},appendItemElement:function(t){this.el&&this.el.appendChild(t.el)},removeItem:function(t){var e=this.items[t];e&&(e.onTap=void 0,e.destroy())},_bindEventsOnItem:function(t){var e=this;this._itemTapHandler||(this._itemTapHandler=function(){e.trySelectItem(this)}),t.onTap=this._itemTapHandler},getSelectedItem:function(){return this.selectedItem},setSelectedItem:function(t){this.selectedItem=this.items[t];for(var e=0,i=this.items.length;i>e;e+=1)this.items[e].setSelected(!1);this.selectedItem&&this.selectedItem.setSelected(!0)},selectItem:function(t){for(var e=0,i=this.items.length;i>e;e+=1)if(this.items[e]==t)return void this.setSelectedItem(e)},trySelectItem:function(t){for(var e=0,i=this.items.length;i>e;e+=1)if(this.items[e]==t)return void(this.tryTabSelect&&this.tryTabSelect(e))},_buildItems:function(){for(var e,i=Array.prototype.slice.call(this.el.children),n=0,r=i.length;r>n;n+=1)e=new t.views.TabBarItem(i[n]),this.items[n]=e,this._bindEventsOnItem(e);this.items.length>0&&(this.selectedItem=this.items[0])},destroy:function(){for(var t=0,e=this.items.length;e>t;t+=1)this.items[t].destroy();this.items.length=0}})}(window.ionic),function(t){"use strict";t.views.Toggle=t.views.View.inherit({initialize:function(e){var i=this;this.el=e.el,this.checkbox=e.checkbox,this.track=e.track,this.handle=e.handle,this.openPercent=-1,this.onChange=e.onChange||function(){},this.triggerThreshold=e.triggerThreshold||20,this.dragStartHandler=function(t){i.dragStart(t)},this.dragHandler=function(t){i.drag(t)},this.holdHandler=function(t){i.hold(t)},this.releaseHandler=function(t){i.release(t)},this.dragStartGesture=t.onGesture("dragstart",this.dragStartHandler,this.el),this.dragGesture=t.onGesture("drag",this.dragHandler,this.el),this.dragHoldGesture=t.onGesture("hold",this.holdHandler,this.el),this.dragReleaseGesture=t.onGesture("release",this.releaseHandler,this.el)},destroy:function(){t.offGesture(this.dragStartGesture,"dragstart",this.dragStartGesture),t.offGesture(this.dragGesture,"drag",this.dragGesture),t.offGesture(this.dragHoldGesture,"hold",this.holdHandler),t.offGesture(this.dragReleaseGesture,"release",this.releaseHandler)},tap:function(){"disabled"!==this.el.getAttribute("disabled")&&this.val(!this.checkbox.checked)},dragStart:function(t){this.checkbox.disabled||(this._dragInfo={width:this.el.offsetWidth,left:this.el.offsetLeft,right:this.el.offsetLeft+this.el.offsetWidth,triggerX:this.el.offsetWidth/2,initialState:this.checkbox.checked},t.gesture.srcEvent.preventDefault(),this.hold(t))},drag:function(e){var i=this;this._dragInfo&&(e.gesture.srcEvent.preventDefault(),t.requestAnimationFrame(function(){var t=(i.track.offsetLeft+i.handle.offsetWidth/2,i.track.offsetLeft+i.track.offsetWidth-i.handle.offsetWidth/2,e.gesture.deltaX,e.gesture.touches[0].pageX-i._dragInfo.left),n=i._dragInfo.width-i.triggerThreshold;i._dragInfo.initialState?ti._dragInfo.triggerX&&i.setOpenPercent(100):tn&&i.setOpenPercent(100)}))},endDrag:function(){this._dragInfo=null},hold:function(){this.el.classList.add("dragging")},release:function(t){this.el.classList.remove("dragging"),this.endDrag(t)},setOpenPercent:function(e){if(this.openPercent<0||ethis.openPercent+3)if(this.openPercent=e,0===e)this.val(!1);else if(100===e)this.val(!0);else{var i=Math.round(e/100*this.track.offsetWidth-this.handle.offsetWidth);i=1>i?0:i,this.handle.style[t.CSS.TRANSFORM]="translate3d("+i+"px,0,0)"}},val:function(e){return(e===!0||e===!1)&&(""!==this.handle.style[t.CSS.TRANSFORM]&&(this.handle.style[t.CSS.TRANSFORM]=""),this.checkbox.checked=e,this.openPercent=e?100:0,this.onChange&&this.onChange()),this.checkbox.checked}})}(ionic),function(t){"use strict";t.controllers.ViewController=function(){this.initialize.apply(this,arguments)},t.controllers.ViewController.inherit=t.inherit,t.extend(t.controllers.ViewController.prototype,{initialize:function(){},destroy:function(){}})}(window.ionic),function(t){"use strict";t.controllers.NavController=t.controllers.ViewController.inherit({initialize:function(t){var e=this;this.navBar=t.navBar,this.content=t.content,this.controllers=t.controllers||[],this._updateNavBar(),this.navBar.shouldGoBack=function(){e.pop()}},getControllers:function(){return this.controllers},getTopController:function(){return this.controllers[this.controllers.length-1]},push:function(t){var e=this.controllers[this.controllers.length-1];this.controllers.push(t);var i=this.switchingController&&this.switchingController(t)||!0;if(i!==!1){e&&(e.isVisible=!1,e.visibilityChanged&&e.visibilityChanged("push"));var n=this.controllers[this.controllers.length-1];return n.isVisible=!0,n.visibilityChanged&&n.visibilityChanged(e?"push":"first"),this._updateNavBar(),t}},pop:function(){var t,e;if(!(this.controllers.length<2))return e=this.controllers.pop(),e&&(e.isVisible=!1,e.visibilityChanged&&e.visibilityChanged("pop")),t=this.controllers[this.controllers.length-1],t.isVisible=!0,t.visibilityChanged&&t.visibilityChanged("pop"),this._updateNavBar(),e},showNavBar:function(){this.navBar&&this.navBar.show()},hideNavBar:function(){this.navBar&&this.navBar.hide()},_updateNavBar:function(){this.getTopController()&&this.navBar&&(this.navBar.setTitle(this.getTopController().title),this.navBar.showBackButton(this.controllers.length>1?!0:!1))}})}(window.ionic),function(t){"use strict";t.controllers.SideMenuController=t.controllers.ViewController.inherit({initialize:function(t){var e=this;this.left=t.left,this.right=t.right,this.content=t.content,this.dragThresholdX=t.dragThresholdX||10,this._rightShowing=!1,this._leftShowing=!1,this._isDragging=!1,this.content&&(this.content.onDrag=function(t){e._handleDrag(t)},this.content.onEndDrag=function(t){e._endDrag(t)})},setContent:function(t){var e=this;this.content=t,this.content.onDrag=function(t){e._handleDrag(t)},this.content.endDrag=function(t){e._endDrag(t)}},isOpenLeft:function(){return this.getOpenAmount()>0},isOpenRight:function(){return this.getOpenAmount()<0},toggleLeft:function(t){var e=this.getOpenAmount();0===arguments.length&&(t=0>=e),this.content.enableAnimation(),this.openPercentage(t?100:0)},toggleRight:function(t){var e=this.getOpenAmount();0===arguments.length&&(t=e>=0),this.content.enableAnimation(),this.openPercentage(t?-100:0)},close:function(){this.openPercentage(0)},getOpenAmount:function(){return this.content&&this.content.getTranslateX()||0},getOpenRatio:function(){var t=this.getOpenAmount();return t>=0?t/this.left.width:t/this.right.width},isOpen:function(){return 1==this.getOpenRatio()},getOpenPercentage:function(){return 100*this.getOpenRatio()},openPercentage:function(t){var e=t/100;if(this.left&&t>=0)this.openAmount(this.left.width*e);else if(this.right&&0>t){{this.right.width}this.openAmount(this.right.width*e)}},openAmount:function(t){var e=this.left&&this.left.width||0,i=this.right&&this.right.width||0;return(this.left&&this.left.isEnabled||!(t>0))&&(this.right&&this.right.isEnabled||!(0>t))?this._leftShowing&&t>e?void this.content.setTranslateX(e):this._rightShowing&&-i>t?void this.content.setTranslateX(-i):(this.content.setTranslateX(t),void(t>=0?(this._leftShowing=!0,this._rightShowing=!1,t>0&&(this.right&&this.right.pushDown&&this.right.pushDown(),this.left&&this.left.bringUp&&this.left.bringUp())):(this._rightShowing=!0,this._leftShowing=!1,this.right&&this.right.bringUp&&this.right.bringUp(),this.left&&this.left.pushDown&&this.left.pushDown()))):void this.content.setTranslateX(0)},snapToRest:function(t){this.content.enableAnimation(),this._isDragging=!1;var e=this.getOpenRatio();if(0===e)return void this.openPercentage(0);var i=.3,n=t.gesture.velocityX,r=t.gesture.direction;this.openPercentage(e>0&&.5>e&&"right"==r&&i>n?0:e>.5&&"left"==r&&i>n?100:0>e&&e>-.5&&"left"==r&&i>n?0:.5>e&&"right"==r&&i>n?-100:"right"==r&&e>=0&&(e>=.5||n>i)?100:"left"==r&&0>=e&&(-.5>=e||n>i)?-100:0)},_endDrag:function(t){this._isDragging&&this.snapToRest(t),this._startX=null,this._lastX=null,this._offsetX=null},_handleDrag:function(t){this._startX?this._lastX=t.gesture.touches[0].pageX:(this._startX=t.gesture.touches[0].pageX,this._lastX=this._startX),!this._isDragging&&Math.abs(this._lastX-this._startX)>this.dragThresholdX&&(this._startX=this._lastX,this._isDragging=!0,this.content.disableAnimation(),this._offsetX=this.getOpenAmount()),this._isDragging&&this.openAmount(this._offsetX+(this._lastX-this._startX))}})}(ionic),function(t){"use strict";t.controllers.TabBarController=t.controllers.ViewController.inherit({initialize:function(t){this.tabBar=t.tabBar,this._bindEvents(),this.controllers=[];for(var e=t.controllers||[],i=0;i=this.controllers.length)){var e=this.selectedController,i=this.selectedIndex;this.selectedController=this.controllers[t],this.selectedIndex=t,this._showController(t),this.tabBar.setSelectedItem(t),this.controllerChanged&&this.controllerChanged(e,i,this.selectedController,this.selectedIndex)}},_showController:function(t){for(var e,i=0,n=this.controllers.length;n>i;i++)e=this.controllers[i],e.isVisible=!1,e.visibilityChanged&&e.visibilityChanged();e=this.controllers[t],e.isVisible=!0,e.visibilityChanged&&e.visibilityChanged()},_clearSelected:function(){this.selectedController=null,this.selectedIndex=-1},getController:function(t){return this.controllers[t]},getControllers:function(){return this.controllers},getSelectedController:function(){return this.selectedController},getSelectedControllerIndex:function(){return this.selectedIndex},addController:function(t){this.controllers.push(t),this.tabBar.addItem({title:t.title,icon:t.icon,badge:t.badge}),this.selectedController||this.setSelectedController(0)},setControllers:function(t){this.controllers=t,this._clearSelected(),this.selectController(0)}})}(window.ionic)}(); \ No newline at end of file diff --git a/release/version.json b/release/version.json index 734ab4fde8..0b9016e4bf 100644 --- a/release/version.json +++ b/release/version.json @@ -1,6 +1,6 @@ { - "version": "0.9.27", - "codename": "salamander", - "date": "2014-03-15", - "time": "17:40:36" + "version": "1.0.0-beta.1", + "codename": "actinium", + "date": "2014-03-25", + "time": "20:55:55" }