Created
December 17, 2016 05:06
-
-
Save afourney/4517963b44ccbec1d83dd17d21132678 to your computer and use it in GitHub Desktop.
Pebble app store HTML
This file has been truncated, but you can view the full file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html manifest="/en_US/manifest.appcache" class="en_US lock-scroll"> | |
<head> | |
<script> | |
// Inject environments at runtime. Do not modify the __ENVIRONMENT__ comment below! | |
window.ENVIRONMENT = {}; | |
window.ENVIRONMENT.BUILD_DATE = '2016-11-03T18:01:54.908Z'; | |
window.ENVIRONMENT['ALGOLIA_INDEX'] = 'pebble-appstore-production'; | |
window.ENVIRONMENT['ALGOLIA_APP_ID'] = 'BUJATNZD81'; | |
window.ENVIRONMENT['ALGOLIA_API_KEY'] = '8dbb11cdde0f4f9d7bf787e83ac955ed'; | |
window.ENVIRONMENT['API_ROOT'] = 'https://api2.getpebble.com/v2/'; | |
window.ENVIRONMENT['ERROR_LOGGER_URL'] = 'https://client-errors.getpebble.com/log-client-error'; | |
window.ENVIRONMENT['FILTER_SEARCH_FOR_HARDWARE'] = 'chalk'; | |
window.ENVIRONMENT['HIDE_CATEGORIES_FOR_HARDWARE'] = 'chalk'; | |
window.ENVIRONMENT['LEGACY_API_ROOT'] = 'https://dev-portal.getpebble.com/api/'; | |
window.ENVIRONMENT['SEGMENT_WRITE_KEY'] = 'JeN6MFsrg3rBT4swvh7sc37s08pyl8iW'; | |
window.ENVIRONMENT['TREASURE_DATA_URL'] = 'https://in.treasuredata.com/js/v3/event/pebble/web_events'; | |
window.ENVIRONMENT['TREASURE_DATA_WRITE_KEY'] = '4432/0fe3124e45fa5882e919b116d98449f22ab427e8'; | |
</script> | |
<base href="/en_US/"> | |
<meta charset="utf-8"> | |
<title>Pebble Appstore</title> | |
<meta name="description" content=""> | |
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"> | |
<style> | |
input[type=range] { | |
width: 300px | |
} | |
ul[rn-carousel] { | |
overflow: hidden; | |
padding: 0; | |
white-space: nowrap; | |
position: relative; | |
-webkit-perspective: 1000px; | |
-ms-perspective: 1000px; | |
perspective: 1000px; | |
-ms-touch-action: pan-y; | |
touch-action: pan-y | |
} | |
ul[rn-carousel]>li { | |
color: #000; | |
-webkit-backface-visibility: hidden; | |
-ms-backface-visibility: hidden; | |
backface-visibility: hidden; | |
overflow: visible; | |
vertical-align: top; | |
position: absolute; | |
left: 0; | |
right: 0; | |
white-space: normal; | |
padding: 0; | |
margin: 0; | |
list-style-type: none; | |
width: 100%; | |
height: 100%; | |
display: inline-block | |
} | |
ul[rn-carousel-buffered]>li { | |
display: none | |
} | |
ul[rn-carousel-transition=hexagon] { | |
overflow: visible | |
} | |
div.rn-carousel-indicator span { | |
cursor: pointer; | |
color: #666 | |
} | |
div.rn-carousel-indicator span.active { | |
color: #fff | |
} | |
.rn-carousel-control { | |
-webkit-transition: opacity .2s ease-out; | |
transition: opacity .2s ease-out; | |
font-size: 2rem; | |
position: absolute; | |
top: 40%; | |
opacity: .75; | |
cursor: pointer | |
} | |
.rn-carousel-control:hover { | |
opacity: 1 | |
} | |
.rn-carousel-control.rn-carousel-control-prev { | |
left: .5em | |
} | |
.rn-carousel-control.rn-carousel-control-prev:before { | |
content: "<" | |
} | |
.rn-carousel-control.rn-carousel-control-next { | |
right: .5em | |
} | |
.rn-carousel-control.rn-carousel-control-next:before { | |
content: ">" | |
} | |
</style> | |
<style> | |
@font-face { | |
font-family: PFDinDisplayProRegularWebfont; | |
font-style: normal; | |
font-variant: normal; | |
src: url(fonts/PFDinDisplayPro-Regular.woff) format("woff"), url(fonts/PFDinDisplayPro-Regular.ttf) format("truetype") | |
} | |
@font-face { | |
font-family: PFDinDisplayProLightWebfont; | |
font-style: normal; | |
font-variant: normal; | |
src: url(fonts/PFDinDisplayPro-Light.woff) format("woff"), url(fonts/PFDinDisplayPro-Light.ttf) format("truetype") | |
} | |
@font-face { | |
font-family: PFDinDisplayProMediumWebfont; | |
font-style: normal; | |
font-variant: normal; | |
src: url(fonts/PFDinDisplayPro-Medium.woff) format("woff"), url(fonts/PFDinDisplayPro-Medium.ttf) format("truetype") | |
} | |
.img-static-aspect { | |
position: relative; | |
height: 0; | |
padding-top: 100% | |
} | |
.img-static-aspect img { | |
position: absolute; | |
top: 0; | |
left: 0; | |
bottom: 0; | |
right: 0; | |
display: block; | |
max-width: 100%; | |
max-height: 100%; | |
margin: auto | |
} | |
.icon.heart { | |
width: 15px; | |
height: 13px; | |
display: inline-block; | |
vertical-align: top; | |
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAnCAYAAACbgcH8AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAbxJREFUeNrs2NFNwzAQANDEE2SEdIOwAZ2g8MMPQmomACaATBB1gkRC/PBDOgHdgGxQRvAI3FWHZNLYteNrZEs96VSpSs6v19bJJU0M8fH+lsHLDeQKsoDMRw7bQW4hu7v7hx9DrVypdT1yCJ7bK7WkrlZqwD5BPkJmiX20kJWKJ+wL5NqhDoI3UOfVCg2LYEc/NV21XfAZFmyhFkJrxw8+7P4t1Oq1aFgEv77GY5HhgjlDHWxCCfDuCE0d/mICcwfCl38dT5Xf8D5QsApf4B9U0Bt14OCEfPWh0/Tv3ifxxEI4bkUhxFrQZh9TrARd6WKKQiQRxgV9QZ9A7yIzd4LuX2OKraB7YBkJWB46TRPCJhI0DgZSvTX9DvxC0wP4arh7lAH/TCT5RieXEAeBfwOAaUYMBX4ENk3jIcBHwVp0AHAt2HgZpxOW9ABl1l3CBDZ2Wul4Rh0vZgQbd7HUptJMcCuwNXoGuDXYCX1GuBPYGa3gG6YpvgVs6XpSOnU1BvgksBfaEz4Z7I2eCPcCs8yIBKgsD698wSydVjqO3W4Mh+Az5pZjLTb0CTgbmB2tgbOCz4IewNnBGL8CDAAwErTF4SgCKwAAAABJRU5ErkJggg==); | |
background-repeat: no-repeat; | |
background-size: contain | |
} | |
.icon.black { | |
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAnCAYAAACbgcH8AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAdBJREFUeNrs2dFNwzAQANDEXaAjpN/5KRu0ExQ+8t9MAJ0AmKB0gua/HyQTkA3IV38LG2QE7sohmTQ2dnxEttSTTkhVcvc4GicOcaSJLMum8OMWcgU5h0x6DqshK8jycDh8aGolUq1FzyF4biPValW1Yg32AfIechqZRwH5LOMJ+wi5tqiD4B3UeTJCQxOc6KtiqqYNN9CwgFoI3Vr+4t3p30GtRomGJvjn2zs06TZMGOrgEHKAlxdomvAbE5g7EL78mXgsfYdPnoJl+AwvUEEfbD0HR+TbnidNV/cpCidmwnIp8iHWghb7kGIl6E4XUsxFFGBc0Vf0H+g6MHMp6Pk1pKgEPQO3gYDb86Rph7ALBI0bg1Z+NH33/EbTAPimu3rkHn9NWvL17lx83Aj82gDo9oi+wC/Aut24D/BesBLtAVwJ1t7G6YQlvUAZdZXQgbWTliY+pYnPRwRrV7HYpNJIcCOwMXoEuDHYCv2PcCuwNVrC75l28QVgc9uTJkM6HY/HKk3TxHHig8CD0QzwwWAntAPcCeyMluB4bSwMDscX7hvXnhOOyx/gNcA/o+9/T6gC3zG/cPRjQRO80cARXHD1YkNr4KxgdnQPnB2M8SXAAMBTzL/Q2XrQAAAAAElFTkSuQmCC) | |
} | |
.icon.orange { | |
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAnCAYAAACbgcH8AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAb1JREFUeNrs2NFNwzAQAFA7E3SEdAPYAL74BDZIJgAmoJ0g6gTJBqSffJUN8AZlhG5Q7uAiuW1s7Phq2agnnSqh9vx6NInPUlhifydm8PIAeQ95BVmOvO0Dcg3Zy3fxZalVarVuRt6Cn1VarZ2plrRgnyGfIGfCPTrIpY4n7Ctk5VEHwSuos3BCwyLY0TdDV10XfIEFO6iF0Mbzix93/xFqKSMaFsF/XxuwyPGCJUMdbEIN8P4ETR3eMIG5A+G3Q8el9hveJgrW4XO8QAv6Q5M4WJCv+ek0Xd1bkU/MC89bUQpRYac/6cGRSyhE7zPrtLigL+j/hi5oa5lT9AXtX3OKtcxk33Gw/yhoQlhl0mUcDHb61jT1J6MC8PVwIQ5RU/tT/VnUpsklxUHgYACwzYipwE/Atmk8Bfgo2IhOAG4EW9EavI18V1E0fSuvw5qRg5tNJLiiDlvvYtKlUiS4E9gZHQHuDPZCnxHuBfZGa/iWaYrvAFt7DwFTV2OATwIHoQPhk8HB6InwIDALmuAL8Xtw/lcsTQfl0dEEr+jpaQp8ynUs0zjnzdYCZwOzow1wVvDZAuF4nkJfgD2+BRgA25qn0LlEmpIAAAAASUVORK5CYII=) | |
} | |
*, | |
:after, | |
:before { | |
box-sizing: border-box | |
} | |
body { | |
-webkit-font-smoothing: antialiased; | |
-webkit-user-select: none | |
} | |
a { | |
-webkit-touch-callout: none; | |
-webkit-tap-highlight-color: rgba(244, 243, 244, 0) | |
} | |
pre { | |
font-family: inherit; | |
font-size: 1em; | |
line-height: 1.6; | |
text-rendering: auto; | |
white-space: pre-line | |
} | |
.app, | |
article, | |
button, | |
li { | |
-webkit-tap-highlight-color: transparent | |
} | |
.app-attributes .attribute-key, | |
.description-title { | |
color: #aaa5a3; | |
text-transform: uppercase | |
} | |
.description-title { | |
border-bottom: 1px solid #dbd9d8; | |
margin-bottom: 10px; | |
padding-bottom: 10px | |
} | |
img { | |
background-color: transparent | |
} | |
.route-error { | |
z-index: 99999; | |
position: fixed; | |
top: 0; | |
right: 0; | |
bottom: 0; | |
left: 0; | |
height: 100%; | |
width: 100%; | |
background: rgba(255, 255, 255, .95); | |
text-align: center | |
} | |
.route-error.hide { | |
display: none | |
} | |
.loading-dots { | |
width: 1em; | |
height: 1em; | |
border-radius: .5em; | |
background: #ff4700; | |
position: absolute; | |
-webkit-animation-duration: .5s; | |
animation-duration: .5s; | |
-webkit-animation-timing-function: ease; | |
animation-timing-function: ease; | |
-webkit-animation-iteration-count: infinite; | |
animation-iteration-count: infinite | |
} | |
.app-detail .list-loading-dots, | |
.apps-list .list-loading-dots { | |
font-size: .7699em; | |
height: 1.3em; | |
position: relative; | |
width: 3.9em | |
} | |
#loading-dots_1, | |
#loading-dots_2 { | |
left: 0 | |
} | |
#loading-dots_3 { | |
left: 1.5em | |
} | |
#loading-dots_4 { | |
left: 3em | |
} | |
@-webkit-keyframes reveal { | |
from { | |
-webkit-transform: scale(0.001); | |
transform: scale(0.001) | |
} | |
to { | |
-webkit-transform: scale(1); | |
transform: scale(1) | |
} | |
} | |
@keyframes reveal { | |
from { | |
-webkit-transform: scale(0.001); | |
transform: scale(0.001) | |
} | |
to { | |
-webkit-transform: scale(1); | |
transform: scale(1) | |
} | |
} | |
@-webkit-keyframes slide { | |
to { | |
-webkit-transform: translateX(1.5em); | |
transform: translateX(1.5em) | |
} | |
} | |
@keyframes slide { | |
to { | |
-webkit-transform: translateX(1.5em); | |
transform: translateX(1.5em) | |
} | |
} | |
#loading-dots_1 { | |
-webkit-animation-name: reveal; | |
animation-name: reveal | |
} | |
#loading-dots_2, | |
#loading-dots_3 { | |
-webkit-animation-name: slide; | |
animation-name: slide | |
} | |
#loading-dots_4 { | |
-webkit-animation-name: reveal; | |
animation-name: reveal; | |
-webkit-animation-direction: reverse; | |
animation-direction: reverse | |
} | |
.slider-container { | |
display: inline-block; | |
overflow: visible!important; | |
width: 155px; | |
height: 235px; | |
z-index: 9; | |
position: relative; | |
margin: 25px 0 | |
} | |
.slider-container:before { | |
background-image: url(images/screenshot_slider_background_original.png); | |
background-repeat: no-repeat; | |
background-size: 155px; | |
background-position: center; | |
content: ""; | |
width: 155px; | |
height: 235px; | |
z-index: 9; | |
position: absolute; | |
left: 0; | |
top: 0; | |
pointer-events: none | |
} | |
.slider-container .slider { | |
padding-top: 63px; | |
width: 100%; | |
height: 100%; | |
overflow: visible | |
} | |
.slider-container .slider .slide { | |
opacity: .4; | |
-webkit-transition: opacity .35s; | |
transition: opacity .35s | |
} | |
.slider-container .slider .slide:after { | |
content: ""; | |
display: block; | |
position: absolute; | |
width: 9000%; | |
left: -400%; | |
height: 100%; | |
top: -63px | |
} | |
.slider-container .slider .slide.current { | |
opacity: 1 | |
} | |
.slider-container .slider .slide img { | |
width: 96px; | |
text-align: left | |
} | |
.screenshot-frame-time .slider-container, | |
.screenshot-frame-time_steel .slider-container { | |
width: 162px; | |
height: 233px | |
} | |
.screenshot-frame-time .slider-container:before, | |
.screenshot-frame-time_steel .slider-container:before { | |
background-image: url(images/screenshot_slider_background_time.png); | |
background-size: 162px; | |
width: 162px; | |
height: 233px | |
} | |
.screenshot-frame-time .slider-container .slider, | |
.screenshot-frame-time_steel .slider-container .slider { | |
padding-top: 61px | |
} | |
.screenshot-frame-time .slider-container .slider .slide img, | |
.screenshot-frame-time_steel .slider-container .slider .slide img { | |
border-radius: 6px | |
} | |
.screenshot-frame-time .slider-container .slider .slide:after, | |
.screenshot-frame-time_steel .slider-container .slider .slide:after { | |
top: -61px | |
} | |
.screenshot-frame-pebble_2_hr .slider-container, | |
.screenshot-frame-pebble_2_se .slider-container { | |
width: 162px; | |
height: 233px | |
} | |
.screenshot-frame-pebble_2_hr .slider-container:before, | |
.screenshot-frame-pebble_2_se .slider-container:before { | |
background-image: url(images/screenshot_slider_background_pebble2.png); | |
background-size: 154px; | |
width: 162px; | |
height: 231px | |
} | |
.screenshot-frame-pebble_2_hr .slider-container .slider, | |
.screenshot-frame-pebble_2_se .slider-container .slider { | |
padding-top: 61px | |
} | |
.screenshot-frame-pebble_2_hr .slider-container .slider .slide img, | |
.screenshot-frame-pebble_2_se .slider-container .slider .slide img { | |
border-radius: 4px | |
} | |
.screenshot-frame-pebble_2_hr .slider-container .slider .slide:after, | |
.screenshot-frame-pebble_2_se .slider-container .slider .slide:after { | |
top: -61px | |
} | |
.screenshot-frame-time_2 .slider-container { | |
width: 162px; | |
height: 233px | |
} | |
.screenshot-frame-time_2 .slider-container:before { | |
background-image: url(images/screenshot_slider_background_time2.png); | |
background-size: 154px; | |
width: 162px; | |
height: 231px | |
} | |
.screenshot-frame-time_2 .slider-container .slider { | |
padding-top: 50px | |
} | |
.screenshot-frame-time_2 .slider-container .slider .slide img { | |
border-radius: 4px; | |
width: 112px | |
} | |
.screenshot-frame-time_2 .slider-container .slider .slide:after { | |
top: -50px | |
} | |
.screenshot-frame-time_round_14 .slider-container, | |
.screenshot-frame-time_round_20 .slider-container { | |
width: 162px; | |
height: 233px | |
} | |
.screenshot-frame-time_round_14 .slider-container:before, | |
.screenshot-frame-time_round_20 .slider-container:before { | |
background-image: url(images/screenshot_slider_background_time_round_14.png); | |
background-size: 162px; | |
width: 162px; | |
height: 233px; | |
opacity: .8 | |
} | |
.screenshot-frame-time_round_14 .slider-container .slider, | |
.screenshot-frame-time_round_20 .slider-container .slider { | |
padding-top: 59px | |
} | |
.screenshot-frame-time_round_14 .slider-container .slider .slide img, | |
.screenshot-frame-time_round_20 .slider-container .slider .slide img { | |
border-radius: 50%; | |
width: 115px | |
} | |
.screenshot-frame-time_round_14 .slider-container .slider .slide:after, | |
.screenshot-frame-time_round_20 .slider-container .slider .slide:after { | |
top: -59px | |
} | |
.screenshot-frame-time_round_20 .slider-container:before { | |
background-image: url(images/screenshot_slider_background_time_round_20.png) | |
} | |
.featured-slider .slideSelectors { | |
position: absolute; | |
bottom: 10px | |
} | |
.app-preview .slideSelectors { | |
position: absolute; | |
bottom: 25px | |
} | |
.app-preview, | |
.featured-slider { | |
background: #aaa5a3; | |
position: relative; | |
top: 0; | |
left: 0; | |
overflow: hidden; | |
width: 100% | |
} | |
.app-preview ul, | |
.featured-slider ul { | |
position: relative; | |
width: 100%; | |
margin-bottom: 0 | |
} | |
.placeholder .featured-slider-placeholder, | |
pbl-featured-slider { | |
height: 0; | |
padding-top: 44.444%; | |
display: block; | |
position: relative | |
} | |
.app-preview ul li, | |
.featured-slider ul li { | |
float: left; | |
width: 100%; | |
height: auto; | |
position: absolute; | |
top: 0; | |
left: 0; | |
right: 0; | |
bottom: 0 | |
} | |
.featured-slider ul:before { | |
content: ""; | |
position: relative; | |
float: left; | |
display: block; | |
padding-top: 44.44444444445%; | |
padding-top: -webkit-calc(320%/7.2); | |
padding-top: calc(320%/7.2) | |
} | |
@media only screen and (min-width:720px) { | |
.featured-slider ul { | |
height: 320px | |
} | |
.featured-slider ul:before { | |
padding-top: 320px | |
} | |
} | |
.slideSelectors { | |
position: inherit; | |
z-index: 1; | |
margin: 0 44%; | |
height: 1em; | |
width: 100% | |
} | |
.collections { | |
width: 100%; | |
margin-left: auto; | |
margin-right: auto; | |
margin-top: 0; | |
max-width: 62.5em; | |
margin-bottom: 1.5em | |
} | |
.collections:after, | |
.collections:before { | |
content: " "; | |
display: table | |
} | |
.collections:after { | |
clear: both | |
} | |
.collections .collection .collection-header { | |
padding: 3px 3px 3px 4% | |
} | |
.collections .collection .collection-header a { | |
display: block; | |
overflow: auto | |
} | |
.collections .collection .collection-header:after, | |
.collections .collection .collection-header:before { | |
content: " "; | |
display: table | |
} | |
.collections .collection .collection-header:after { | |
clear: both | |
} | |
.collections .collection .collection-header .collection-title { | |
color: #ff4700; | |
float: left; | |
padding-top: 3px; | |
white-space: nowrap | |
} | |
.collections .collection .collection-header .collection-more { | |
white-space: nowrap; | |
float: right; | |
color: #555 | |
} | |
.collections .collection .collection-header .collection-more a, | |
.collections .collection .collection-header .collection-more a:hover { | |
color: #aaa5a3; | |
vertical-align: top | |
} | |
.collections .collection .collection-header .collection-more span { | |
margin: 0; | |
padding-top: 3px; | |
vertical-align: middle; | |
display: inline-block; | |
float: right | |
} | |
.collections .collection .collection-header .collection-more .dark-gray-arrow { | |
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAgCAYAAAAffCjxAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw%2FeHBhY2tldCBiZWdpbj0i77u%2FIiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8%2BIDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpEMzAwQ0M2MDg0RDAxMUUzQTAxOURCQjZDQkFEMTBFMyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpEMzAwQ0M2MTg0RDAxMUUzQTAxOURCQjZDQkFEMTBFMyI%2BIDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkQzMDBDQzVFODREMDExRTNBMDE5REJCNkNCQUQxMEUzIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkQzMDBDQzVGODREMDExRTNBMDE5REJCNkNCQUQxMEUzIi8%2BIDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY%2BIDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8%2BswhXJQAAAZtJREFUeNqklctKw0AUhsdYRXsxbbUtUhcuFF248SV8AQkiIoh4e6mKYqmVIrpQxEURdKEbwSKKVrwsfAIXLqxW%2F4E%2FMIRokuMPH2RC%2BJjkZM7pcBynRyk1B47BqxLGomQMLIOh%2F4jq4AP0giVQlIpeQImyOHc2KBHpPIN10KJsJarMMq6fDFmCsoJEpPMINgzZaliZ5XPvAWyCT5DkzvISkU6Tsi%2BQoiwnEencG7I%2BygYkIp07sEWZzW%2FWLxHp3IKyR5aViHRuQIWyNGUZiUjnmrI2JWuURha5sm0%2FmSU4nw1QpSzL17QtYddo8BQoVnE2JuwY02CU6zewGxNIZsCkUc0aeI8i6mQ3neD6Cuzwl1BhRV1gHoxzfcmdtN0Hwoi6wQIY4foc7INv86EgkZ4wi2CY61Nw6JUEieIcBu5kqXNk%2BeY3UdIzBI7AyV9b9xPZlOT5CgfgLOhDekUZo01oyR64CFNWU5TjTtIsa41lVlFEBbbSFH%2BwKs%2BTiiIqsjoJTo4yu6KKKpqipMVm35TO%2FgonRkkq0fkRYADpyFmMa0zW7wAAAABJRU5ErkJggg%3D%3D); | |
background-repeat: no-repeat; | |
background-size: 7px; | |
height: 14px; | |
float: right; | |
width: 8px; | |
margin-top: 2px; | |
margin-left: 5px | |
} | |
.collections .collection .collection-header .collection-more, | |
.collections .collection .collection-header .collection-title { | |
font-family: PFDinDisplayPro-Medium, PFDinDisplayProMediumWebfont, sans-serif; | |
font-weight: 400; | |
font-size: .875em; | |
margin-top: .8375em; | |
margin-right: .625em; | |
margin-bottom: .425em; | |
text-transform: uppercase | |
} | |
.collections .collection .apps { | |
border-top: 1px solid #dbd9d8; | |
padding-top: 3%; | |
padding-left: 3%; | |
width: 100%; | |
overflow: auto | |
} | |
.collections .collection .apps a { | |
margin-right: 4%; | |
display: inline-block; | |
display: inline-block; | |
width: 46%; | |
margin-bottom: 4%; | |
margin-top: 0; | |
background-color: #fff; | |
padding: 2.2%; | |
float: left | |
} | |
@media only screen and (min-width:720px) { | |
.collections .collection .apps a { | |
width: 29.3% | |
} | |
} | |
.collections .collection .watchfaces a { | |
width: 29.3%; | |
margin-right: 4%; | |
margin-bottom: 4%; | |
margin-top: 0; | |
margin-left: 0; | |
padding: 2%; | |
border-radius: 4px | |
} | |
.collections .collection .apps .app { | |
position: relative; | |
white-space: normal; | |
vertical-align: text-top; | |
cursor: pointer | |
} | |
.collections .collection .apps .app .app-icon { | |
display: block; | |
height: 0; | |
padding-top: 37%; | |
color: #000; | |
width: 37%; | |
float: left; | |
position: relative | |
} | |
.collections .collection .apps .app .app-image { | |
position: absolute; | |
left: 0; | |
top: 0; | |
right: 0; | |
bottom: 0; | |
max-height: 100% | |
} | |
.collections .collection .apps .app.watchface .app-image { | |
float: none; | |
width: auto; | |
position: absolute; | |
left: 0; | |
right: 0; | |
top: 0; | |
bottom: 0; | |
max-width: 100%; | |
max-height: 100%; | |
margin: auto; | |
border-radius: 4px | |
} | |
.collections .collection .apps .app .app-image img { | |
border-radius: 9px; | |
border: 1px solid #dbd9d8 | |
} | |
.collections .collection .apps .app .app-details { | |
position: relative; | |
float: left; | |
margin-left: 5%; | |
width: 58% | |
} | |
.collections .collection .apps .app .app-details .hearts { | |
color: #aaa5a3 | |
} | |
.collections .collection .apps .app .app-details .app-category { | |
color: #009d85; | |
font-size: 1em; | |
margin-bottom: .3125em; | |
text-transform: capitalize; | |
overflow: hidden; | |
text-overflow: ellipsis; | |
white-space: nowrap | |
} | |
.collections .collection .apps .app .app-details .app-title { | |
font-size: 1.125em; | |
line-height: 18px; | |
margin: 0; | |
color: #555; | |
display: inline-block; | |
max-height: 2em; | |
overflow: hidden; | |
text-overflow: ellipsis; | |
word-wrap: break-word; | |
white-space: nowrap; | |
width: 100% | |
} | |
.collections .collection .apps .app.watchface .face-grid-preview { | |
width: 100%; | |
max-width: 144px; | |
position: relative; | |
height: 0; | |
padding-top: 116.666%; | |
margin: auto | |
} | |
@media only screen and (min-width:460px) { | |
.collections .collection .apps .app.watchface .face-grid-preview { | |
padding-top: 100% | |
} | |
} | |
.collections .collection .apps .app.watchface .hearts { | |
color: #aaa5a3; | |
text-align: center; | |
margin-top: 7% | |
} | |
.route-error-message { | |
font-size: 25px; | |
color: #333; | |
text-align: center; | |
width: 75%; | |
display: inline-block; | |
padding-bottom: 1em | |
} | |
.route-error-wrapper { | |
position: relative; | |
top: 20%; | |
height: 100% | |
} | |
.featured-apps { | |
position: absolute | |
} | |
.featured-apps .banner-overlay { | |
z-index: 1; | |
top: 0; | |
height: 100%; | |
width: 100%; | |
background: #fff | |
} | |
.featured-apps .banner-overlay:first-child { | |
z-index: 2 | |
} | |
.featured-apps .banner-overlay a { | |
display: inline-block; | |
-webkit-tap-highlight-color: transparent | |
} | |
.featured-apps>ul { | |
margin-bottom: 0 | |
} | |
.app-detail .app { | |
position: relative; | |
padding-top: 61px | |
} | |
.app-description { | |
font-family: PFDinDisplayPro-Light, PFDinDisplayProLightWebfont, sans-serif; | |
font-weight: 400; | |
position: relative; | |
padding-left: .9375em; | |
padding-right: .9375em; | |
width: 100%; | |
float: left; | |
color: #555 | |
} | |
.app-description .description-body { | |
word-wrap: break-word; | |
padding-bottom: .3125em; | |
margin-bottom: .3125em; | |
-webkit-user-select: all; | |
-moz-user-select: all; | |
-ms-user-select: all; | |
user-select: all | |
} | |
.app-preview { | |
border-bottom: 1px solid #cecece; | |
position: relative | |
} | |
.app-preview .app-image { | |
position: relative; | |
z-index: 9 | |
} | |
.app-preview .app-title { | |
color: #959595 | |
} | |
.app-download { | |
margin-top: 0; | |
margin-bottom: 0; | |
background-color: #303030; | |
width: 100%; | |
min-height: 61px; | |
padding: 15px 0 10px; | |
position: fixed; | |
top: 0; | |
left: 0; | |
min-width: 0; | |
z-index: 1000; | |
max-width: 720px; | |
display: -webkit-flex; | |
display: -webkit-box; | |
display: -ms-flexbox; | |
display: flex; | |
-webkit-justify-content: space-between; | |
-webkit-box-pack: justify; | |
-ms-flex-pack: justify; | |
justify-content: space-between | |
} | |
.app-download:after, | |
.app-download:before { | |
content: " "; | |
display: table | |
} | |
.app-download:after { | |
clear: both | |
} | |
.app-download .app-identity { | |
padding-left: 47px; | |
padding-right: 5px; | |
position: relative; | |
min-width: 0; | |
text-overflow: ellipsis; | |
white-space: nowrap; | |
-webkit-flex: 1; | |
-webkit-box-flex: 1; | |
-ms-flex: 1; | |
flex: 1 | |
} | |
.app-detail.watchface .app-download .app-identity { | |
padding-left: 10px | |
} | |
.app-download .app-identity .app-icon { | |
height: 30px; | |
width: 30px; | |
position: absolute; | |
left: 10px | |
} | |
.app-download .app-identity .app-icon img { | |
border-radius: 5px; | |
width: 100% | |
} | |
.app-download .app-identity .app-title { | |
color: #fff; | |
font-size: 1.0125em; | |
margin: 0; | |
text-transform: uppercase; | |
text-overflow: ellipsis; | |
overflow: hidden; | |
display: block; | |
line-height: 17px | |
} | |
.app-download .app-identity .app-author { | |
color: #aaa5a3; | |
font-size: .75em; | |
margin: 0; | |
text-overflow: ellipsis; | |
overflow: hidden | |
} | |
.app-download .app-download-actions { | |
vertical-align: top; | |
text-align: right | |
} | |
.app-download .app-download-actions .app-install { | |
color: #fff | |
} | |
.app-download .app-download-actions .add-button, | |
.app-download .app-download-actions .app-added, | |
.app-download .app-download-actions .get-button { | |
float: right; | |
min-width: 50px; | |
display: block; | |
margin-right: 10px | |
} | |
.app-download .app-download-actions .get-button { | |
border: 1px solid #0072ff | |
} | |
.app-download .app-download-actions .app-unsupported-platform .companions { | |
height: 32px; | |
margin-left: -15px; | |
position: relative; | |
top: -3px | |
} | |
.app-download .app-download-actions .app-added { | |
color: #303030 | |
} | |
.app-download .app-download-actions .not-available { | |
width: 101px | |
} | |
.app-meta { | |
width: 100%; | |
margin-top: 0; | |
margin-bottom: 0; | |
max-width: 62.5em; | |
background: #dbd9d8; | |
color: #555; | |
padding-top: 10px; | |
padding-bottom: 10px; | |
display: table | |
} | |
.app-meta .app-os { | |
margin: 0; | |
padding: 0 5px; | |
font-size: 1em; | |
text-transform: uppercase; | |
line-height: 24px; | |
text-align: center; | |
vertical-align: middle; | |
display: table-cell; | |
min-width: 90px | |
} | |
.app-meta .app-os .only-app, | |
.app-meta .app-os .only-basalt, | |
.app-meta .app-os .only-companion, | |
.app-meta .app-os .only-face { | |
display: inline-block | |
} | |
.app-meta .app-os .only-app span, | |
.app-meta .app-os .only-basalt span, | |
.app-meta .app-os .only-companion span, | |
.app-meta .app-os .only-face span { | |
min-height: .66em; | |
margin: 0 auto; | |
color: #777; | |
padding-top: 6px; | |
text-align: left; | |
padding-left: 24px; | |
font-size: .66em; | |
line-height: 1em; | |
vertical-align: middle; | |
display: inline-block | |
} | |
.app-meta .app-os .only-app, | |
.app-meta .app-os .only-face { | |
background-image: url(images/icons/watch.png); | |
background-size: 18px; | |
background-position: center left; | |
background-repeat: no-repeat; | |
min-height: 28px | |
} | |
.app-meta .app-os .only-companion { | |
background-image: url(images/icons/companion.png); | |
background-size: 18px; | |
background-position: center left; | |
background-repeat: no-repeat; | |
min-height: 28px | |
} | |
.app-meta .app-os .companion-categorization, | |
.app-meta .app-os .only-basalt { | |
display: inline-block; | |
max-width: 95px; | |
width: 100%; | |
font-size: 0; | |
line-height: 0; | |
position: relative; | |
top: 4px | |
} | |
.app-meta .app-os .companion-categorization>svg, | |
.app-meta .app-os .only-basalt>svg { | |
display: block; | |
width: 100%; | |
height: 100%; | |
min-height: 40px | |
} | |
.app-meta .app-os .companion-categorization .required-text, | |
.app-meta .app-os .only-basalt .required-text { | |
display: block; | |
position: absolute; | |
top: 63%; | |
left: 0; | |
right: 0; | |
color: #fff; | |
font-size: 8px | |
} | |
.app-meta .app-os .companion-categorization img { | |
float: left; | |
width: 31px; | |
margin-right: 0 | |
} | |
.app-meta .app-os .companion-categorization .browser-app { | |
-ms-transform: translateX(-15px); | |
-webkit-transform: translateX(-15px); | |
transform: translateX(-15px) | |
} | |
.app-meta .app-os .companion-type { | |
font-family: PFDinDisplayPro-Light, PFDinDisplayProLightWebfont, sans-serif; | |
font-weight: 400; | |
color: #888; | |
float: left; | |
font-size: 1em; | |
text-transform: uppercase | |
} | |
.app-meta .app-os img.android-ios { | |
width: 4.5em | |
} | |
.app-meta .app-os .icon-android { | |
height: 30px; | |
width: 26px; | |
margin-right: .3125em | |
} | |
.app-meta .app-os button { | |
box-shadow: none; | |
-webkit-transition: none; | |
transition: none; | |
border-style: solid; | |
border-width: 1px; | |
cursor: pointer; | |
font-family: inherit; | |
line-height: normal; | |
margin: 0; | |
position: relative; | |
text-decoration: none; | |
display: inline-block; | |
font-size: .9em; | |
background-color: #dbd9d8; | |
border-color: #0072ff | |
} | |
.app-meta .app-os .companion-app-button { | |
border: 1px solid #0072ff; | |
color: #0072ff; | |
border-radius: 0 5px 5px 0; | |
text-align: center; | |
padding: 5px 6px 1px 9px; | |
font-size: 18px; | |
float: left; | |
margin-left: 2px | |
} | |
.app-meta .app-companion { | |
vertical-align: middle; | |
height: 100%; | |
display: table-cell; | |
padding: 0 5px; | |
white-space: nowrap; | |
text-align: center | |
} | |
.app-meta .app-companion .app-companion-type { | |
text-transform: uppercase; | |
font-size: 1em; | |
color: #888; | |
content: ""; | |
background-size: contain; | |
background-position: 0 0; | |
background-repeat: no-repeat; | |
display: inline-block | |
} | |
.app-meta .app-companion .app-ios-only { | |
background-image: url(images/icons/ios.png); | |
height: 18px; | |
padding-left: 40px; | |
line-height: 22px | |
} | |
.de_DE .app-meta .app-companion .app-ios-only, | |
.nl_NL .app-meta .app-companion .app-ios-only { | |
background-position: right top; | |
padding-left: 0; | |
padding-right: 40px | |
} | |
.app-meta .app-companion .app-android-only { | |
background-image: url(images/icons/android.png); | |
height: 34px; | |
padding-left: 38px; | |
line-height: 36px | |
} | |
.de_DE .app-meta .app-companion .app-android-only, | |
.nl_NL .app-meta .app-companion .app-android-only { | |
background-position: right top; | |
padding-left: 0; | |
padding-right: 38px | |
} | |
.app-meta .app-companion .app-android-ios { | |
background-image: url(images/icons/android_ios.png); | |
height: 34px; | |
width: 85px | |
} | |
.app-meta .app-hearts-container { | |
margin: 0; | |
padding: 0 5px; | |
border-left: 1px solid #bababa; | |
border-right: 1px solid #bababa; | |
text-align: center; | |
display: table-cell; | |
vertical-align: middle | |
} | |
.app-screenshots { | |
background-image: -webkit-linear-gradient(#F4F3F4, #dbd9d8); | |
background-image: linear-gradient(#F4F3F4, #dbd9d8); | |
border-bottom: 1px solid #cecece; | |
border-top: 1px solid #cecece; | |
margin-bottom: .625em; | |
text-align: center; | |
overflow: hidden | |
} | |
.description-title { | |
font-size: 16px; | |
line-height: 16px | |
} | |
.app-attributes { | |
font-family: PFDinDisplayPro-Light, PFDinDisplayProLightWebfont, sans-serif; | |
font-weight: 400; | |
width: 100%; | |
max-width: 62.5em; | |
clear: both; | |
margin: 0 0 10px; | |
padding: 10px 0 0; | |
display: table | |
} | |
.app-attributes:after, | |
.app-attributes:before { | |
content: " "; | |
display: table | |
} | |
.app-attributes:after { | |
clear: both | |
} | |
.app-attributes .app-attribute { | |
position: relative; | |
list-style: none; | |
margin-bottom: 0; | |
display: table-row | |
} | |
.app-attributes .attribute-key { | |
font-family: PFDinDisplayPro-Regular, PFDinDisplayProRegularWebfont, sans-serif; | |
font-weight: 400; | |
font-size: 16px; | |
line-height: 16px; | |
padding-right: 20px; | |
display: table-cell; | |
padding-left: .9375em; | |
text-align: left; | |
white-space: nowrap | |
} | |
.app-attributes .attribute-value { | |
color: #555; | |
display: table-cell; | |
padding-right: .9375em; | |
width: 100% | |
} | |
.app-links { | |
font-family: PFDinDisplayPro-Light, PFDinDisplayProLightWebfont, sans-serif; | |
font-weight: 400; | |
width: 100%; | |
max-width: 62.5em; | |
*zoom: 1; | |
margin: 0; | |
padding: 0 | |
} | |
.app-links:after, | |
.app-links:before { | |
content: " "; | |
display: table | |
} | |
.app-links:after { | |
clear: both | |
} | |
.app-links .app-link { | |
position: relative; | |
width: 100%; | |
float: left; | |
border-bottom: 1px solid #dbd9d8; | |
list-style: none; | |
padding: 4px | |
} | |
.app-links .app-link:first-child { | |
border-top: 1px solid #dbd9d8 | |
} | |
.app-links .app-link a { | |
border: 0; | |
color: #ff4700; | |
-webkit-transition: none; | |
transition: none; | |
text-transform: uppercase; | |
background: 0 0; | |
margin: 0; | |
font-size: 15px; | |
box-shadow: none; | |
font-family: PFDinDisplayPro-Medium, PFDinDisplayProMediumWebfont, sans-serif; | |
font-weight: 400; | |
display: block; | |
width: 100%; | |
height: 100%; | |
line-height: 18px; | |
padding: 14px 24px 12px 14px; | |
position: relative | |
} | |
.app-links .app-link img { | |
float: right; | |
width: 15px | |
} | |
.app-links .app-link a:after { | |
content: ""; | |
background: url(images/icons/app-link-arrow.svg); | |
background-repeat: no-repeat; | |
height: 18px; | |
width: 11px; | |
background-size: 10px; | |
position: absolute; | |
right: 14px; | |
top: 50%; | |
margin-top: -9px | |
} | |
::-webkit-scrollbar { | |
display: none | |
} | |
.open-companion-modal-wrap { | |
position: fixed; | |
top: 0; | |
left: 0; | |
right: 0; | |
bottom: 0; | |
background: rgba(0, 0, 0, .5); | |
z-index: 9999 | |
} | |
.open-companion-modal { | |
border-radius: 8px; | |
position: fixed | |
} | |
.open-companion-modal.reveal-modal { | |
text-align: center; | |
padding: 10px 0 0 | |
} | |
.open-companion-modal .buttons { | |
width: 100%; | |
margin-left: auto; | |
margin-right: auto; | |
margin-top: 0; | |
margin-bottom: 0; | |
max-width: 62.5em; | |
*zoom: 1; | |
border-top: 1px solid #cecece; | |
padding: 0 | |
} | |
.open-companion-modal .buttons:after, | |
.open-companion-modal .buttons:before { | |
content: " "; | |
display: table | |
} | |
.open-companion-modal .buttons:after { | |
clear: both | |
} | |
.open-companion-modal .buttons button { | |
border: 0; | |
color: #555; | |
padding: 0; | |
background: 0 0; | |
margin: 0; | |
width: 100% | |
} | |
.open-companion-modal .buttons .button-wrap:last-child button { | |
color: #ff4700 | |
} | |
.open-companion-modal h4, | |
.open-companion-modal p { | |
padding: 0 20px; | |
color: #000; | |
line-height: 1em; | |
margin-bottom: .4em | |
} | |
.open-companion-modal h4 { | |
padding: 0 20px | |
} | |
.open-companion-modal .product-shots { | |
padding: 2% 5%; | |
overflow: auto | |
} | |
.open-companion-modal .product-shots li { | |
display: block; | |
width: 47.5%; | |
float: left | |
} | |
.open-companion-modal .product-shots li:nth-child(odd) { | |
margin-right: 5% | |
} | |
.open-companion-modal .product-shots li:last-child:nth-child(odd) { | |
margin: 0 auto; | |
float: none | |
} | |
.open-companion-modal .product-shots a { | |
color: #000 | |
} | |
.open-companion-modal .product-shots a span { | |
white-space: nowrap; | |
font-size: .7em | |
} | |
.pill { | |
font-family: PFDinDisplayPro-Light, PFDinDisplayProLightWebfont, sans-serif; | |
font-weight: 400; | |
border: 1px solid; | |
min-width: 61px; | |
border-radius: 17px; | |
display: inline-block; | |
color: #555; | |
padding: 5px 10px 4px; | |
cursor: pointer | |
} | |
[disabled].pill { | |
cursor: default | |
} | |
.pill .hearts { | |
text-align: center; | |
line-height: 14px | |
} | |
.pill.orange { | |
border-color: #ff4700 | |
} | |
.categories { | |
width: 100%; | |
margin-left: auto; | |
margin-right: auto; | |
margin-top: 0; | |
margin-bottom: 0; | |
max-width: 62.5em; | |
background: #333; | |
border-top: 2px solid #ff4700; | |
border-bottom: 2px solid #ff4700 | |
} | |
.categories:after, | |
.categories:before { | |
content: " "; | |
display: table | |
} | |
.categories:after { | |
clear: both | |
} | |
.category { | |
position: relative; | |
width: 50%; | |
float: left; | |
background: #333; | |
border-top: 1px solid #484848; | |
color: #fff; | |
padding: 3px 0 | |
} | |
.category a { | |
overflow: auto; | |
display: table; | |
width: 100%; | |
table-layout: auto; | |
padding: 14px 0 14px 10px; | |
-webkit-tap-highlight-color: rgba(51, 51, 51, 0); | |
color: #fff | |
} | |
.category a:hover { | |
color: #fff | |
} | |
.category-icon { | |
padding-right: 8px; | |
display: table-cell; | |
width: 42px; | |
vertical-align: middle | |
} | |
.category-icon img { | |
width: 34px; | |
height: 34px | |
} | |
.category-meta { | |
display: table-cell; | |
vertical-align: middle | |
} | |
.category-title { | |
color: #fff; | |
font-size: 14px; | |
line-height: 1em; | |
font-family: PFDinDisplayPro-Medium, PFDinDisplayProMediumWebfont, sans-serif; | |
font-weight: 400; | |
text-transform: uppercase; | |
margin: 0 | |
} | |
.zh_CN .category-title, | |
.zh_TW .category-title { | |
font-size: 22px | |
} | |
@media only screen and (min-width:460px) { | |
.category-title { | |
font-size: 12px | |
} | |
.zh_CN .category-title, | |
.zh_TW .category-title { | |
font-size: 20px | |
} | |
} | |
.category-index .ui-slider, | |
.watchface-index .ui-slider { | |
border-bottom: 2px solid #ff4700 | |
} | |
.category-index .tags, | |
.watchface-index .tags { | |
min-height: 56px; | |
max-height: 128px; | |
background: #333; | |
border-bottom: 2px solid #ff4700; | |
border-top: 2px solid #ff4700; | |
overflow-y: scroll; | |
overflow-x: hidden; | |
padding: 3px | |
} | |
.text-center { | |
text-align: center | |
} | |
.filter, | |
.filter:hover { | |
background: 0 0; | |
box-shadow: 0 0 0 #fff inset; | |
-webkit-transition: background-color 0ms ease-out; | |
transition: background-color 0ms ease-out | |
} | |
button { | |
outline: 0 | |
} | |
.add-button, | |
.add-button:hover, | |
.app-added { | |
font-family: PFDinDisplayPro-Regular, PFDinDisplayProRegularWebfont, sans-serif; | |
font-weight: 400; | |
border-radius: 5px; | |
padding: 4px 6px 2px; | |
top: 0; | |
right: 0; | |
text-transform: uppercase; | |
background: 0 0; | |
box-shadow: 0 0 0 #fff inset; | |
-webkit-transition: background-color 0ms ease-out; | |
transition: background-color 0ms ease-out; | |
font-size: 16px; | |
margin: 0; | |
line-height: 1; | |
min-width: 50px; | |
vertical-align: top | |
} | |
.pbl-app-li .add-button, | |
.pbl-app-li .add-button:hover, | |
.pbl-app-li .app-added { | |
font-size: 14px | |
} | |
.add-button, | |
.add-button:hover { | |
border: 1px solid #ff4700; | |
color: #ff4700 | |
} | |
.app-added { | |
color: #fff; | |
border: 1px solid #959595; | |
background-color: #959595 | |
} | |
.get-apps-message { | |
background: #555; | |
color: #fff; | |
text-align: center | |
} | |
.get-apps-message p { | |
padding: .55em .45em; | |
font-size: .875em; | |
line-height: 1.125em; | |
margin-bottom: 0 | |
} | |
.apps-list { | |
color: #555; | |
float: left; | |
width: 100% | |
} | |
.apps-list .hearts { | |
text-align: center; | |
color: #aaa5a3; | |
margin-top: .1em | |
} | |
.apps-list .hearts .counter, | |
.apps-list .hearts .icon { | |
display: inline-block; | |
vertical-align: top | |
} | |
.apps-list .hearts .icon { | |
fill: #aaa5a3 | |
} | |
.apps-list .hearts .counter { | |
line-height: 22px | |
} | |
.apps-list ul { | |
list-style-type: none; | |
padding: 0; | |
margin: 1em 15px 0 | |
} | |
.apps-list ul .watchapp { | |
margin: 0 0 21px; | |
border-bottom: 1px solid #dbd9d8; | |
padding: 0 0 10px; | |
cursor: pointer | |
} | |
.apps-list ul .watchapp .app-image { | |
display: inline-block; | |
width: 72px; | |
vertical-align: top | |
} | |
.apps-list ul .watchapp .app-image img { | |
border: 1px solid #dbd9d8; | |
border-radius: 4px | |
} | |
.apps-list ul .watchapp .app-details { | |
display: inline-block; | |
padding: 0 | |
} | |
.apps-list ul .watchapp .app-details .app-image img, | |
.apps-list ul .watchapp .app-details .app-title img { | |
width: 28px; | |
border-radius: 4px; | |
display: inline-block; | |
vertical-align: top | |
} | |
.apps-list ul .watchapp .app-details .app-header { | |
display: -webkit-flex; | |
display: -webkit-box; | |
display: -ms-flexbox; | |
display: flex; | |
width: 100%; | |
-webkit-flex-wrap: nowrap; | |
-ms-flex-wrap: nowrap; | |
flex-wrap: nowrap; | |
-webkit-flex-direction: row; | |
-webkit-box-orient: horizontal; | |
-webkit-box-direction: normal; | |
-ms-flex-direction: row; | |
flex-direction: row; | |
-webkit-justify-content: space-between; | |
-webkit-box-pack: justify; | |
-ms-flex-pack: justify; | |
justify-content: space-between | |
} | |
.apps-list ul .watchapp .app-details .app-header .app-title, | |
.apps-list ul .watchapp .app-details .app-header pbl-add-btn { | |
display: block; | |
padding: 0; | |
margin: 0; | |
vertical-align: top | |
} | |
.apps-list ul .watchapp .app-details .app-header .app-list-icon { | |
width: 28px; | |
min-height: 28px; | |
margin-right: 8px; | |
float: left | |
} | |
.apps-list ul .watchapp .app-details .app-header .app-title { | |
overflow: hidden; | |
text-overflow: ellipsis; | |
white-space: nowrap; | |
min-width: 0; | |
-webkit-flex: 1; | |
-webkit-box-flex: 1; | |
-ms-flex: 1; | |
flex: 1; | |
margin-bottom: 5px | |
} | |
.apps-list ul .watchapp .app-details .app-header h3 { | |
color: #555; | |
font-family: PFDinDisplayPro-Regular, PFDinDisplayProRegularWebfont, sans-serif; | |
font-weight: 400; | |
font-size: .875em; | |
line-height: 1em; | |
margin: 0 .5em 0 0; | |
display: block; | |
overflow: hidden; | |
text-overflow: ellipsis; | |
height: 17px | |
} | |
.apps-list ul .watchapp .app-details .app-header .app-category { | |
font-family: PFDinDisplayPro-Regular, PFDinDisplayProRegularWebfont, sans-serif; | |
font-weight: 400; | |
color: #aaa5a3; | |
font-size: 14px; | |
line-height: 12px; | |
overflow: hidden; | |
text-overflow: ellipsis; | |
text-transform: capitalize | |
} | |
.apps-list ul .pbl-app-li { | |
display: block; | |
position: relative; | |
overflow: hidden | |
} | |
.apps-list ul .pbl-app-li .app-image { | |
display: block; | |
position: absolute | |
} | |
.apps-list ul .pbl-app-li .app-image .img-static-aspect { | |
padding-top: 115% | |
} | |
.apps-list ul .pbl-app-li.hardware-chalk .app-image .img-static-aspect, | |
.hardware-chalk .apps-list ul .pbl-app-li .app-image .img-static-aspect { | |
padding-top: 100%; | |
border-radius: 50% | |
} | |
.apps-list ul .pbl-app-li .app-details { | |
display: block; | |
padding-left: 82px | |
} | |
.apps-list ul .watchapp .app-details .get-button { | |
color: #0072ff; | |
border: 1px solid #0072ff | |
} | |
.apps-list ul .watchapp .app-details .companion-container { | |
display: inline; | |
width: 100%; | |
float: left; | |
padding-bottom: .2em; | |
line-height: 1 | |
} | |
.apps-list ul .watchapp .app-details .companion-container .companion-app-indicator, | |
.apps-list ul .watchapp .app-details .companion-container .companion-only-indicator { | |
color: #fff; | |
line-height: 14px; | |
font-size: 10px; | |
font-family: PFDinDisplayPro-Medium, PFDinDisplayProMediumWebfont, sans-serif; | |
font-weight: 400; | |
border-radius: 2px; | |
text-align: center; | |
text-rendering: auto; | |
padding: .15em .7em .1em; | |
display: inline-block | |
} | |
.apps-list ul .watchapp .app-details .companion-container .companion-app-indicator { | |
background-color: #ff4700 | |
} | |
.apps-list ul .watchapp .app-details .companion-container .companion-only-indicator { | |
background-color: #0072ff | |
} | |
.apps-list ul .watchapp .app-details .companion-container .companion-only-indicator:before { | |
content: ""; | |
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAUCAYAAAC58NwRAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw%2FeHBhY2tldCBiZWdpbj0i77u%2FIiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8%2BIDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpjN2Y3Mzg1Yy03NDAzLTRmNTMtYjg0OC02MDk2ZWFhNzkyZGMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NkVEMEFFNzA4MjNFMTFFMzgzMDBGN0ZFRTM0NDY2MjIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NkVEMEFFNkY4MjNFMTFFMzgzMDBGN0ZFRTM0NDY2MjIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSI%2BIDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOmQ4OWEzNTIxLTE3NWMtNDAzNS1iMTE0LWY0N2ViODJiMjk4MCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpjN2Y3Mzg1Yy03NDAzLTRmNTMtYjg0OC02MDk2ZWFhNzkyZGMiLz4gPC9yZGY6RGVzY3JpcHRpb24%2BIDwvcmRmOlJERj4gPC94OnhtcG1ldGE%2BIDw%2FeHBhY2tldCBlbmQ9InIiPz52JtmkAAAA2ElEQVR42uyTMQ6CQBBFZxEwxkINjecwNnoHT6SlXsZSrmC08xw2JNpIJML6F2aScQvE3p88mP2ZYTa7g7HW7oloRY0seNKn%2BsBwnBoUvBD02DiDHSh57fw1WPC6DPEowICNCZiDitcBe6JCOmTgwoVjb0s3kIMZSMg2OoDRF1yODaUVuFO7CtkjqVNok9EFnfUv%2BKXAdsitc%2BSmIzBUFyjTW6rkqL49jIczr%2BDEHQNvWitmCaau4KHGW7Tl98bzc7el2DfBUcX6Y7HxflEZsozjxDuQ9C3AAG7dYSDVUbSMAAAAAElFTkSuQmCC); | |
background-repeat: no-repeat; | |
background-size: 6px; | |
height: 10px; | |
width: 12px; | |
display: inline-block; | |
vertical-align: top; | |
margin: 1px 0; | |
float: left | |
} | |
.apps-list ul .watchapp .app-details { | |
height: 6.3em; | |
overflow: hidden | |
} | |
.apps-list ul .watchapp .app-details pre { | |
clear: both; | |
font-family: PFDinDisplayPro-Light, PFDinDisplayProLightWebfont, sans-serif; | |
font-weight: 400; | |
color: #555; | |
font-size: .875em; | |
line-height: 1.125em; | |
padding-top: .28125em; | |
overflow: hidden; | |
position: relative; | |
height: 4.78125em | |
} | |
.apps-list ul .watchapp .app-details:after { | |
width: 100%; | |
position: absolute; | |
content: ""; | |
bottom: 0; | |
height: 1.125em; | |
background: -webkit-linear-gradient(top, rgba(244, 243, 244, 0), #f4f3f4 90%); | |
background: linear-gradient(to bottom, rgba(244, 243, 244, 0), #f4f3f4 90%) | |
} | |
.apps-list ul .watchapp .app-details .ios-android-icon { | |
float: right; | |
max-width: 63px | |
} | |
.apps-list ul .hardware-chalk .app-image img, | |
.apps-list ul .hardware-chalk .screenshot img, | |
.collections .hardware-chalk .app-image { | |
border-radius: 50%!important | |
} | |
.apps-list .watchface { | |
cursor: pointer; | |
width: 33%; | |
padding: 0 15px; | |
margin-bottom: 20px; | |
display: inline-block; | |
float: left | |
} | |
.apps-list .watchface a { | |
display: block | |
} | |
.apps-list .watchface h2 { | |
color: #aaa5a3; | |
margin: 0; | |
text-align: center; | |
font-size: .75em; | |
overflow: hidden; | |
white-space: nowrap; | |
line-height: 24px; | |
font-family: inherit; | |
text-overflow: ellipsis | |
} | |
@media only screen and (min-width:460px) { | |
.apps-list .watchface h2 { | |
font-size: 1em; | |
padding-bottom: .2em | |
} | |
} | |
.apps-list .watchface .screenshot { | |
display: block; | |
width: 100%; | |
overflow: hidden; | |
position: relative; | |
height: 0; | |
padding-top: 116.5% | |
} | |
@media only screen and (min-width:460px) { | |
.apps-list .watchface .screenshot { | |
padding-top: 100% | |
} | |
} | |
@media only screen and (min-width:720px) { | |
.apps-list .watchface .screenshot { | |
padding-top: 86.5% | |
} | |
} | |
.apps-list .watchface .screenshot img { | |
position: absolute; | |
left: 0; | |
right: 0; | |
top: 0; | |
bottom: 0; | |
margin: auto; | |
display: block; | |
max-width: 100%; | |
max-height: 100%; | |
border: 1px solid #dbd9d8; | |
border-radius: 4px | |
} | |
.migrate-apps { | |
background: #F4F3F4; | |
min-height: 100%; | |
padding-bottom: 112px; | |
overflow: auto | |
} | |
.migrate-apps p { | |
font-size: 16px; | |
text-align: center; | |
margin: 0 2em 1em; | |
font-family: PFDinDisplayPro-Light, PFDinDisplayProLightWebfont, sans-serif; | |
font-weight: 400 | |
} | |
.migrate-apps p:nth-child(3) { | |
margin-bottom: 3em | |
} | |
.migrate-apps a { | |
display: block; | |
margin: 0 auto; | |
text-transform: uppercase; | |
text-align: center; | |
color: #ff4700 | |
} | |
.migrate-apps hr { | |
border: solid #aaa5a3; | |
border-width: 1px 0 0; | |
clear: both; | |
margin: 1em; | |
height: 0 | |
} | |
.migrate-apps .footer-button { | |
position: fixed; | |
width: 100%; | |
bottom: 0; | |
padding: .9em 0; | |
background: #F4F3F4 | |
} | |
.migrate-apps .footer-button .checking, | |
.migrate-apps .footer-button button { | |
font-family: PFDinDisplayPro-Light, PFDinDisplayProLightWebfont, sans-serif; | |
font-weight: 400; | |
display: block; | |
margin: 0 auto 1em; | |
padding: .75em 5em; | |
background-color: #ff4700; | |
border-radius: 25px; | |
border: none; | |
text-transform: uppercase; | |
width: 255px | |
} | |
.migrate-apps .footer-button button:hover { | |
background-color: #ff4700 | |
} | |
.migrate-apps .footer-button .checking { | |
font-family: PFDinDisplayPro-Light, PFDinDisplayProLightWebfont, sans-serif; | |
font-weight: 400; | |
background-color: #959595; | |
border-color: #959595; | |
border-color: #959595; | |
width: 255px; | |
cursor: auto | |
} | |
.migrate-apps .footer-button .checking:hover { | |
background-color: #959595 | |
} | |
.migrate-apps .footer-button a:hover { | |
color: #ff4700; | |
outline: 0 | |
} | |
.migrate-apps .migrate-alert { | |
background: #484848; | |
width: 100%; | |
overflow: scroll | |
} | |
.migrate-apps .migrate-alert p { | |
text-align: left; | |
color: #fff; | |
font-size: .96em; | |
padding: 1em 1em 0 0; | |
margin: 0 1em 1em | |
} | |
.migrate-apps .migrate-alert ul { | |
padding: 0 0 0 1em; | |
font-size: 16px; | |
text-transform: uppercase | |
} | |
.migrate-apps .migrate-alert ul li { | |
display: inline-block; | |
color: #fff | |
} | |
.migrate-apps .migrate-alert ul li:after { | |
content: ", " | |
} | |
.migrate-apps .migrate-alert ul li:last-child:after { | |
content: "" | |
} | |
.migrate-apps .load-message { | |
padding-top: 1em | |
} | |
.migrate-apps .load-message p { | |
text-align: left; | |
font-size: 17px; | |
margin: 0 30px 20px | |
} | |
.migrate-apps .upgraded-apps ul { | |
list-style-type: none; | |
padding: 0 5%; | |
float: left; | |
position: relative; | |
width: 100% | |
} | |
.migrate-apps .upgraded-apps ul li { | |
text-align: center; | |
float: left!important; | |
width: 30%; | |
margin-right: 5%; | |
margin-bottom: 5% | |
} | |
.migrate-apps .upgraded-apps ul li:nth-child(3n) { | |
margin-right: 0 | |
} | |
.migrate-apps .upgraded-apps ul li h6 { | |
color: #aaa5a3; | |
font-family: PFDinDisplayPro-Light, PFDinDisplayProLightWebfont, sans-serif; | |
font-weight: 400; | |
white-space: nowrap; | |
overflow: auto; | |
text-overflow: ellipsis | |
} | |
.migrate-apps .upgraded-apps ul img { | |
width: 100% | |
} | |
.search { | |
border: none; | |
font-size: 1.125em; | |
font-family: PFDinDisplayPro-Regular, PFDinDisplayProRegularWebfont, sans-serif; | |
font-weight: 400; | |
margin: 0 auto; | |
margin-bottom: 0!important; | |
padding: 8px 8px 5px 35px; | |
border-radius: 5px!important | |
} | |
.noresults { | |
font-size: 1.625em; | |
margin-top: 1.25em; | |
position: relative; | |
padding-left: .9375em; | |
padding-right: .9375em; | |
width: 100%; | |
float: left | |
} | |
.search-form { | |
padding: 0 .9375em; | |
float: left; | |
width: 100%; | |
margin-top: .625em; | |
margin-right: .3125em; | |
display: table | |
} | |
.search-form input { | |
cursor: pointer; | |
z-index: 1000; | |
-webkit-tap-highlight-color: transparent | |
} | |
.search-form form { | |
display: table; | |
width: 100%; | |
margin-bottom: .5em | |
} | |
.search-form .input-wrap { | |
display: table-cell; | |
vertical-align: middle | |
} | |
input[type=search]::-webkit-search-cancel-button, | |
input[type=search]::-webkit-search-decoration, | |
input[type=search]::-webkit-search-results-button, | |
input[type=search]::-webkit-search-results-decoration { | |
display: none | |
} | |
.search-form button { | |
box-shadow: none; | |
border: none; | |
cursor: pointer; | |
font-family: inherit; | |
line-height: normal; | |
margin: 0; | |
position: relative; | |
text-decoration: none; | |
text-align: center; | |
display: inline-block; | |
padding: 0; | |
font-size: 0; | |
background-color: #ff4700; | |
color: #fff | |
} | |
.search-form button:hover { | |
box-shadow: none; | |
-webkit-transition: none; | |
transition: none; | |
background-color: #ff4700; | |
outline: 0; | |
border: none | |
} | |
.search-cancel { | |
display: block; | |
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8%2BCjxzdmcgd2lkdGg9IjQycHgiIGhlaWdodD0iNDJweCIgdmlld0JveD0iMCAwIDQyIDQyIiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbG5zOnNrZXRjaD0iaHR0cDovL3d3dy5ib2hlbWlhbmNvZGluZy5jb20vc2tldGNoL25zIj4KICAgIDx0aXRsZT5jYW5jZWw8L3RpdGxlPgogICAgPGRlc2NyaXB0aW9uPkNyZWF0ZWQgd2l0aCBTa2V0Y2ggKGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCk8L2Rlc2NyaXB0aW9uPgogICAgPGRlZnM%2BPC9kZWZzPgogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc2tldGNoOnR5cGU9Ik1TUGFnZSI%2BCiAgICAgICAgPGcgaWQ9IkltcG9ydGVkLUxheWVycyIgc2tldGNoOnR5cGU9Ik1TTGF5ZXJHcm91cCIgZmlsbD0iI0ZGRkZGRiI%2BCiAgICAgICAgICAgIDxnIGlkPSJGaWxsLTEtKy1GaWxsLTIiIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPgogICAgICAgICAgICAgICAgPHBhdGggZD0iTTQyLDQgTDQsNDIgTDAsMzggTDM4LDAgTDQyLDQiIGlkPSJGaWxsLTEiPjwvcGF0aD4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik00LDAgTDQyLDM4IEwzOCw0MiBMMCw0IEw0LDAiIGlkPSJGaWxsLTIiPjwvcGF0aD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc%2B); | |
background-repeat: no-repeat; | |
background-size: 21px; | |
width: 21px; | |
height: 35px; | |
background-position: center | |
} | |
.search-cancel-wrap { | |
padding-left: .5em | |
} | |
.search-wrap { | |
width: 100% | |
} | |
.search-header { | |
*zoom: 1; | |
background: #ff4700 | |
} | |
.search-header:after, | |
.search-header:before { | |
content: " "; | |
display: table | |
} | |
.search-header:after { | |
clear: both | |
} | |
.search-header a { | |
padding: 0 | |
} | |
.search-header a img { | |
width: 2em | |
} | |
.search-type { | |
position: relative; | |
padding-left: .9375em; | |
padding-right: .9375em; | |
width: 100%; | |
float: left; | |
margin-top: .9375em | |
} | |
.search-type .search-type-apps, | |
.search-type .search-type-watch { | |
position: relative; | |
width: 50%; | |
float: left; | |
border: 1px solid #ff4700; | |
padding: 3px; | |
margin-bottom: 0 | |
} | |
.search-type .search-type-apps a, | |
.search-type .search-type-watch a { | |
padding: 5px 2px 3px; | |
display: block; | |
overflow: hidden; | |
text-overflow: ellipsis; | |
white-space: nowrap; | |
width: 100%; | |
text-align: center; | |
text-transform: uppercase; | |
font-size: 14px; | |
line-height: 14px; | |
color: #ff4700; | |
-webkit-tap-highlight-color: rgba(255, 71, 0, 0) | |
} | |
@media only screen and (max-width:359px) { | |
.search-type .search-type-apps a, | |
.search-type .search-type-watch a { | |
font-size: 10.5px | |
} | |
} | |
@media only screen and (max-width:390px) and (min-width:360px) { | |
.search-type .search-type-apps a, | |
.search-type .search-type-watch a { | |
font-size: 12px | |
} | |
} | |
.search-type .active { | |
background: #ff4700; | |
font-family: PFDinDisplayPro-Medium, PFDinDisplayProMediumWebfont, sans-serif; | |
font-weight: 400 | |
} | |
.search-type .active a { | |
color: #fff; | |
-webkit-tap-highlight-color: rgba(244, 243, 244, 0) | |
} | |
.search-list em { | |
font-style: normal; | |
color: #ff4700 | |
} | |
html { | |
background: #F4F3F4; | |
position: relative | |
} | |
body, | |
html { | |
font-size: 100%; | |
min-height: 100% | |
} | |
body { | |
background-color: #F4F3F4; | |
color: #222; | |
padding: 0; | |
font-family: PFDinDisplayPro-Regular, PFDinDisplayProRegularWebfont, sans-serif; | |
font-weight: 400; | |
font-style: normal; | |
line-height: 1; | |
position: static; | |
cursor: default; | |
margin: 0 auto; | |
max-width: 720px | |
} | |
a:hover { | |
cursor: pointer | |
} | |
embed, | |
img, | |
object { | |
max-width: 100%; | |
height: auto | |
} | |
embed, | |
object { | |
height: 100% | |
} | |
img { | |
-ms-interpolation-mode: bicubic | |
} | |
.hide { | |
display: none | |
} | |
img { | |
display: inline-block; | |
vertical-align: middle | |
} | |
p.lead { | |
font-size: 1.21875em; | |
line-height: 1.6 | |
} | |
blockquote, | |
dd, | |
div, | |
dl, | |
dt, | |
form, | |
h1, | |
h2, | |
h3, | |
h4, | |
h5, | |
h6, | |
li, | |
ol, | |
p, | |
pre, | |
td, | |
th, | |
ul { | |
margin: 0; | |
padding: 0; | |
direction: ltr | |
} | |
a { | |
color: #ff4700; | |
text-decoration: none; | |
line-height: inherit | |
} | |
a:hover { | |
color: #ff4700 | |
} | |
a img { | |
border: none | |
} | |
p { | |
font-family: inherit; | |
font-size: 1em; | |
line-height: 1.6; | |
margin-bottom: 1.25em; | |
text-rendering: optimizeLegibility | |
} | |
h1, | |
h2, | |
h3, | |
h4, | |
h5, | |
h6 { | |
font-family: PFDinDisplayPro-Regular, PFDinDisplayProRegularWebfont, sans-serif; | |
font-weight: 400; | |
font-style: normal; | |
color: #222; | |
text-rendering: optimizeLegibility; | |
margin-top: .2em; | |
margin-bottom: .5em; | |
line-height: 1.2125em | |
} | |
h1 { | |
font-size: 2.125em | |
} | |
h2 { | |
font-size: 1.6875em | |
} | |
h3 { | |
font-size: 1.375em | |
} | |
h4, | |
h5 { | |
font-size: 1.125em | |
} | |
h6 { | |
font-size: 1em | |
} | |
hr { | |
border: solid #dbd9d8; | |
border-width: 1px 0 0; | |
clear: both; | |
margin: 1.25em 0 1.1875em; | |
height: 0 | |
} | |
em, | |
i { | |
font-style: italic; | |
line-height: inherit | |
} | |
b, | |
strong { | |
font-family: PFDinDisplayPro-Medium, PFDinDisplayProMediumWebfont, sans-serif; | |
font-weight: 400; | |
line-height: inherit | |
} | |
small { | |
font-size: 60%; | |
line-height: inherit | |
} | |
dl, | |
ol, | |
ul { | |
font-size: 1em; | |
line-height: 1.6; | |
margin-bottom: 1.25em; | |
list-style-position: outside; | |
font-family: inherit | |
} | |
ol, | |
ol.no-bullet, | |
ul, | |
ul.no-bullet { | |
margin-left: 0 | |
} | |
ul li ol, | |
ul li ul { | |
margin-left: 1.25em; | |
margin-bottom: 0; | |
font-size: 1em | |
} | |
ul.circle li ul, | |
ul.disc li ul, | |
ul.square li ul { | |
list-style: inherit | |
} | |
ul.square { | |
list-style-type: square | |
} | |
ul.circle { | |
list-style-type: circle | |
} | |
ul.disc { | |
list-style-type: disc | |
} | |
ul.no-bullet { | |
list-style: none | |
} | |
ol li ol, | |
ol li ul { | |
margin-left: 1.25em; | |
margin-bottom: 0 | |
} | |
dl dt { | |
margin-bottom: .3em; | |
font-family: PFDinDisplayPro-Medium, PFDinDisplayProMediumWebfont, sans-serif; | |
font-weight: 400 | |
} | |
dl dd { | |
margin-bottom: .75em | |
} | |
abbr, | |
acronym { | |
text-transform: uppercase; | |
font-size: 90%; | |
color: #222; | |
border-bottom: 1px dotted #dbd9d8; | |
cursor: help | |
} | |
abbr { | |
text-transform: none | |
} | |
.button, | |
button { | |
font-family: PFDinDisplayPro-Medium, PFDinDisplayProMediumWebfont, sans-serif; | |
font-weight: 400; | |
font-size: 1em; | |
color: #fff; | |
cursor: pointer; | |
padding-top: .8125em; | |
padding-bottom: .75em; | |
-webkit-appearance: none | |
} | |
.button.tiny, | |
button.tiny { | |
padding-top: .5em; | |
padding-bottom: .4375em; | |
-webkit-appearance: none | |
} | |
.button.small, | |
button.small { | |
padding-top: .625em; | |
padding-bottom: .5625em; | |
-webkit-appearance: none | |
} | |
.button.large, | |
button.large { | |
padding-top: 1.03125em; | |
padding-bottom: 1.03125em; | |
-webkit-appearance: none | |
} | |
form { | |
margin: 0 0 1em | |
} | |
input:focus { | |
outline: 0 | |
} | |
.input-group.radius>:first-child, | |
.input-group.radius>:first-child * { | |
-moz-border-radius-bottomleft: 3px; | |
-moz-border-radius-topleft: 3px; | |
-webkit-border-bottom-left-radius: 3px; | |
-webkit-border-top-left-radius: 3px; | |
border-bottom-left-radius: 3px; | |
border-top-left-radius: 3px | |
} | |
input[type=date], | |
input[type=datetime-local], | |
input[type=datetime], | |
input[type=email], | |
input[type=month], | |
input[type=number], | |
input[type=password], | |
input[type=search], | |
input[type=tel], | |
input[type=text], | |
input[type=time], | |
input[type=url], | |
input[type=week], | |
textarea { | |
-webkit-appearance: none; | |
border-radius: 0; | |
background-color: #fff; | |
font-family: inherit; | |
border: 1px solid #cecece; | |
box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); | |
color: rgba(0, 0, 0, .75); | |
display: block; | |
font-size: .875em; | |
margin: 0 0 1em; | |
padding: .5em; | |
height: 2.3125em; | |
width: 100%; | |
box-sizing: border-box; | |
-webkit-transition: box-shadow .45s, border-color .45s ease-in-out; | |
transition: box-shadow .45s, border-color .45s ease-in-out | |
} | |
input[type=date][disabled], | |
input[type=datetime-local][disabled], | |
input[type=datetime][disabled], | |
input[type=email][disabled], | |
input[type=month][disabled], | |
input[type=number][disabled], | |
input[type=password][disabled], | |
input[type=search][disabled], | |
input[type=tel][disabled], | |
input[type=text][disabled], | |
input[type=time][disabled], | |
input[type=url][disabled], | |
input[type=week][disabled], | |
textarea[disabled] { | |
background-color: #dbd9d8 | |
} | |
input[type=checkbox], | |
input[type=file], | |
input[type=radio], | |
select { | |
margin: 0 0 1em | |
} | |
input[type=file] { | |
width: 100% | |
} | |
@-webkit-keyframes rotate { | |
from { | |
-webkit-transform: rotate(0deg) | |
} | |
to { | |
-webkit-transform: rotate(360deg) | |
} | |
} | |
@keyframes rotate { | |
from { | |
-webkit-transform: rotate(0deg); | |
transform: rotate(0deg) | |
} | |
to { | |
-webkit-transform: rotate(360deg); | |
transform: rotate(360deg) | |
} | |
} | |
.reveal-modal-bg { | |
position: fixed; | |
height: 100%; | |
width: 100%; | |
background: #000; | |
background: rgba(0, 0, 0, .45); | |
z-index: 98; | |
display: none; | |
top: 0; | |
left: 0 | |
} | |
.reveal-modal { | |
position: fixed; | |
left: 50%; | |
z-index: 99; | |
height: auto; | |
margin-left: -40%; | |
width: 80%; | |
background-color: #fff; | |
padding: 1.25em; | |
border: solid 1px #777; | |
box-shadow: 0 0 10px rgba(0, 0, 0, .4); | |
top: 80px | |
} | |
.reveal-modal .button-wrap { | |
width: 50%; | |
float: left; | |
padding: .7em | |
} | |
.reveal-modal .button-wrap:first-child { | |
border-right: 1px solid #cecece | |
} | |
.reveal-modal .button-wrap:only-child { | |
width: 100%; | |
border-right: none | |
} | |
.reveal-modal>:first-child { | |
margin-top: 0 | |
} | |
.reveal-modal>:last-child { | |
margin-bottom: 0 | |
} | |
.reveal-modal .close-reveal-modal { | |
font-size: 1.375em; | |
line-height: 1; | |
position: absolute; | |
top: .5em; | |
right: .6875em; | |
color: #aaa5a3; | |
font-family: PFDinDisplayPro-Medium, PFDinDisplayProMediumWebfont, sans-serif; | |
font-weight: 400; | |
cursor: pointer | |
} | |
.app-changelog h2 { | |
color: #959595; | |
font-size: 1.0125em; | |
margin: 15px 10px 5px; | |
text-transform: uppercase; | |
text-overflow: ellipsis; | |
overflow: hidden; | |
white-space: nowrap; | |
line-height: 17px | |
} | |
.app-changelog pre { | |
width: 100%; | |
color: #777; | |
background: #fff; | |
padding: 10px; | |
font-size: 1em; | |
font-style: normal; | |
line-height: 1.6 | |
} | |
.changelog-date { | |
font-size: .9em; | |
text-align: right; | |
vertical-align: middle; | |
position: absolute; | |
right: 10px | |
} | |
.pagination { | |
display: table; | |
table-layout: fixed; | |
width: 100%; | |
margin: 1em 0; | |
padding: 0 1em | |
} | |
.pagination div { | |
display: table-cell; | |
padding: 0 .2em; | |
text-align: center | |
} | |
.dev-settings-page .section.submit .dev-settings-button, | |
.pagination a, | |
.refresh-button { | |
font-family: PFDinDisplayPro-Medium, PFDinDisplayProMediumWebfont, sans-serif; | |
font-weight: 400; | |
background-color: #ff4700; | |
border-radius: 5px; | |
border: none; | |
color: #fff; | |
text-align: center; | |
text-transform: uppercase; | |
padding: .75em 0; | |
display: inline-block; | |
width: 100%; | |
max-width: 15em | |
} | |
.dev-settings-page .section.submit .dev-settings-button, | |
.refresh-button { | |
top: 30% | |
} | |
.browser-header { | |
background: #484848; | |
position: relative; | |
z-index: 10000 | |
} | |
.browser-header .title-bar { | |
padding: .7em .5em .85em; | |
display: -webkit-flex; | |
display: -webkit-box; | |
display: -ms-flexbox; | |
display: flex; | |
-webkit-justify-content: space-between; | |
-webkit-box-pack: justify; | |
-ms-flex-pack: justify; | |
justify-content: space-between; | |
-webkit-align-items: center; | |
-webkit-box-align: center; | |
-ms-flex-align: center; | |
align-items: center | |
} | |
.browser-header .title-bar h1 { | |
display: block; | |
width: 25%; | |
min-width: 90px; | |
margin: 0; | |
-webkit-flex: .23 1 0; | |
-webkit-box-flex: .23; | |
-ms-flex: .23 1 0; | |
flex: .23 1 0 | |
} | |
.browser-header .title-bar h1 svg { | |
display: block; | |
max-height: 1em | |
} | |
.browser-header .title-bar h1 svg path { | |
fill: #fff | |
} | |
.browser-header .title-bar h2 { | |
text-align: right; | |
text-transform: uppercase; | |
color: #fff; | |
margin: 0; | |
font-size: 1.1em; | |
overflow: hidden; | |
text-overflow: ellipsis; | |
white-space: nowrap; | |
padding-left: 1em; | |
-webkit-flex: 1; | |
-webkit-box-flex: 1; | |
-ms-flex: 1; | |
flex: 1 | |
} | |
.browser-header .nav-bar { | |
display: -webkit-flex; | |
display: -webkit-box; | |
display: -ms-flexbox; | |
display: flex; | |
-webkit-justify-content: space-between; | |
-webkit-box-pack: justify; | |
-ms-flex-pack: justify; | |
justify-content: space-between; | |
height: 2.2em; | |
margin: 0 | |
} | |
.browser-header .nav-bar li { | |
display: block; | |
position: relative; | |
height: 100%; | |
-webkit-flex: 1; | |
-webkit-box-flex: 1; | |
-ms-flex: 1; | |
flex: 1; | |
padding-bottom: .9em; | |
padding-top: .2em; | |
cursor: pointer; | |
text-align: center; | |
white-space: nowrap | |
} | |
.browser-header .nav-bar li:hover span, | |
.browser-header .nav-bar li:hover svg { | |
opacity: 1 | |
} | |
.browser-header .nav-bar li.active:after { | |
content: ""; | |
background: #ff4700; | |
position: absolute; | |
bottom: 0; | |
left: 0; | |
right: 0; | |
height: 3px | |
} | |
.browser-header .nav-bar li.active span, | |
.browser-header .nav-bar li.active svg { | |
opacity: 1 | |
} | |
.browser-header .nav-bar li svg { | |
display: block; | |
margin: auto; | |
height: 100%; | |
opacity: .6 | |
} | |
@media only screen and (min-width:720px) { | |
.browser-header .nav-bar li svg { | |
display: inline-block; | |
margin: auto .25em auto 0; | |
vertical-align: middle | |
} | |
} | |
.browser-header .nav-bar li svg path, | |
.browser-header .nav-bar li svg polygon { | |
fill: #fff | |
} | |
.browser-header .nav-bar li span { | |
display: none; | |
opacity: .6 | |
} | |
@media only screen and (min-width:720px) { | |
.browser-header .nav-bar li span { | |
color: #fff; | |
display: inline-block; | |
margin: auto 0; | |
vertical-align: middle | |
} | |
} | |
.dev-settings-page { | |
margin: 0; | |
min-height: 100%; | |
padding: 5% 3%; | |
color: #fff; | |
background: #484848 | |
} | |
.dev-settings-page h4 { | |
color: #fff; | |
font-size: 1.2em | |
} | |
.dev-settings-page .section { | |
margin-bottom: 2em | |
} | |
.dev-settings-page .section p { | |
line-height: 1.2; | |
font-size: 1.1em; | |
margin-bottom: .5em; | |
padding-right: 6% | |
} | |
.dev-settings-page .section.locale label { | |
display: block; | |
border-bottom: 1px solid #555; | |
cursor: pointer | |
} | |
.dev-settings-page .section.locale label:first-of-type { | |
border-top: 1px solid #555 | |
} | |
.dev-settings-page .section.locale label input { | |
display: none | |
} | |
.dev-settings-page .section.locale label span { | |
font-size: 1.2em; | |
display: block; | |
padding: .35em .25em .25em .35em; | |
border-left: 3px solid transparent; | |
opacity: .55 | |
} | |
.dev-settings-page .section.locale label span:hover { | |
opacity: 1 | |
} | |
.dev-settings-page .section.locale label input:checked+span { | |
border-color: #ff4700; | |
opacity: 1 | |
} | |
.dev-settings-page .section .controls { | |
display: -webkit-flex; | |
display: -webkit-box; | |
display: -ms-flexbox; | |
display: flex | |
} | |
.dev-settings-page .section .controls label { | |
display: block; | |
padding: 0 .6em; | |
text-align: center; | |
border-left: 1px solid #555; | |
cursor: pointer; | |
-webkit-flex: 1; | |
-webkit-box-flex: 1; | |
-ms-flex: 1; | |
flex: 1 | |
} | |
.dev-settings-page .section .controls label:first-of-type { | |
border-left: none | |
} | |
.dev-settings-page .section .controls label input { | |
display: none | |
} | |
.dev-settings-page .section .controls label .label { | |
border-bottom: 3px solid transparent; | |
opacity: .55; | |
padding: 0 .25em .5em | |
} | |
.dev-settings-page .section .controls label .label:hover { | |
opacity: 1 | |
} | |
.dev-settings-page .section .controls label .label span { | |
font-size: .5em | |
} | |
.dev-settings-page .section .controls label .label .img-wrap { | |
display: block; | |
position: relative; | |
height: 0 | |
} | |
.dev-settings-page .section .controls label .label .img-wrap img { | |
position: absolute; | |
top: 0; | |
right: 0; | |
bottom: 0; | |
left: 0; | |
display: block; | |
margin: auto; | |
max-height: 100%; | |
max-width: 100% | |
} | |
.dev-settings-page .section .controls label input:checked+.label { | |
border-color: #ff4700; | |
opacity: 1 | |
} | |
.dev-settings-page .section.hardware .img-wrap { | |
padding-top: 100% | |
} | |
.dev-settings-page .section.platform .img-wrap { | |
padding-top: 46% | |
} | |
.dev-settings-page .section.submit { | |
text-align: center | |
} | |
#main-view, | |
.placeholder { | |
background-color: #F4F3F4; | |
overflow: auto; | |
width: 100%; | |
min-height: 60vh | |
} | |
.pebble-banner-ad { | |
position: relative; | |
background-color: #ff4700; | |
min-height: 115px; | |
text-transform: uppercase; | |
box-shadow: inset 0 10px 30px -10px #000; | |
display: -webkit-flex; | |
display: -webkit-box; | |
display: -ms-flexbox; | |
display: flex | |
} | |
.banner-ad-content { | |
color: #fff; | |
font-size: 16px; | |
padding-right: 5px | |
} | |
.banner-ad-content p, | |
.pebble-banner-ad .banner-ad-content hr { | |
margin: 0 | |
} | |
.banner-ad-content p:first-child { | |
font-family: PFDinDisplayPro-Medium, PFDinDisplayProMediumWebfont, sans-serif; | |
font-weight: 400 | |
} | |
.banner-ad-content p { | |
padding-top: 10px; | |
padding-left: 10px | |
} | |
.banner-ad-content p.subtitle { | |
padding-top: 0 | |
} | |
.pebble-banner-ad .preview-watch { | |
background-image: url(images/banner-ad.png); | |
background-size: contain; | |
background-position: right center; | |
background-repeat: no-repeat; | |
height: auto; | |
width: auto; | |
border-bottom-right-radius: 5px; | |
margin-left: auto; | |
-webkit-flex: 1 1 100px; | |
-webkit-box-flex: 1; | |
-ms-flex: 1 1 100px; | |
flex: 1 1 100px | |
} | |
@media only screen and (min-width:720px) { | |
.loader, | |
html { | |
background-color: #303030!important | |
} | |
body { | |
position: relative | |
} | |
.is-browser { | |
background-color: #303030!important; | |
padding: 0; | |
top: 40px; | |
margin-bottom: 70px | |
} | |
.is-browser #main-view, | |
.is-browser .pebble-banner-ad, | |
.is-browser .placeholder, | |
.is-browser body { | |
border-radius: 0 0 5px 5px | |
} | |
.is-browser .browser-header { | |
border-radius: 5px 5px 0 0 | |
} | |
.is-browser .browser-header .title-bar { | |
padding: 1em | |
} | |
.is-browser #main-view, | |
.is-browser .placeholder { | |
background-color: #F4F3F4 | |
} | |
} | |
.is-browser .app-download { | |
position: static | |
} | |
.is-browser .app-detail .app { | |
position: relative; | |
padding-top: 0 | |
} | |
.is-browser .search-header { | |
background: #484848; | |
padding-bottom: .3em | |
} | |
.is-browser .search-header .search-cancel { | |
opacity: .6 | |
} | |
.highlight-block { | |
display: block | |
} | |
.ng-cloak, | |
.x-ng-cloak, | |
[data-ng-cloak], | |
[ng-cloak], | |
[ng\:cloak], | |
[x-ng-cloak] { | |
display: none!important | |
} | |
.lock-scroll .platform-android #main-view, | |
.lock-scroll .platform-android .loader, | |
.lock-scroll .platform-android .placeholder { | |
overflow: hidden; | |
height: 0; | |
height: 100vh | |
} | |
.loader { | |
position: fixed; | |
width: 100%; | |
min-height: 100%; | |
top: 0; | |
left: 0; | |
z-index: 9999; | |
pointer-events: none; | |
background-color: #F4F3F4; | |
-webkit-transition-property: opacity; | |
transition-property: opacity; | |
-webkit-transition-timing-function: linear; | |
transition-timing-function: linear; | |
-webkit-transition-duration: 75ms; | |
transition-duration: 75ms; | |
-webkit-transition-delay: 40ms; | |
transition-delay: 40ms; | |
opacity: 0 | |
} | |
.loader.show { | |
opacity: 1; | |
-webkit-transition-delay: 0ms; | |
transition-delay: 0ms; | |
-webkit-transition-duration: 125ms; | |
transition-duration: 125ms | |
} | |
.placeholder-blank .loader { | |
-webkit-transition-delay: 0ms; | |
transition-delay: 0ms | |
} | |
.loading-bar { | |
position: fixed; | |
bottom: 0; | |
left: 0; | |
right: 0; | |
height: .5rem; | |
height: 1.5vh; | |
z-index: 9999; | |
background: #ff4700; | |
-webkit-animation: loader 2s ease-in-out infinite; | |
animation: loader 2s ease-in-out infinite | |
} | |
@-webkit-keyframes loader { | |
0% { | |
-webkit-transform: translate(-100%, 0); | |
transform: translate(-100%, 0); | |
-webkit-transform: translate(-100vw, 0); | |
transform: translate(-100vw, 0) | |
} | |
50% { | |
-webkit-transform: translate(0, 0); | |
transform: translate(0, 0) | |
} | |
100% { | |
-webkit-transform: translate(100%, 0); | |
transform: translate(100%, 0); | |
-webkit-transform: translate(100vw, 0); | |
transform: translate(100vw, 0) | |
} | |
} | |
@keyframes loader { | |
0% { | |
-webkit-transform: translate(-100%, 0); | |
transform: translate(-100%, 0); | |
-webkit-transform: translate(-100vw, 0); | |
transform: translate(-100vw, 0) | |
} | |
50% { | |
-webkit-transform: translate(0, 0); | |
transform: translate(0, 0) | |
} | |
100% { | |
-webkit-transform: translate(100%, 0); | |
transform: translate(100%, 0); | |
-webkit-transform: translate(100vw, 0); | |
transform: translate(100vw, 0) | |
} | |
} | |
.placeholder { | |
letter-spacing: -1px; | |
font-family: sans-serif; | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
min-height: 100%; | |
display: none | |
} | |
.placeholder.active { | |
display: block | |
} | |
.placeholder .text-placeholder-inline { | |
vertical-align: 35%; | |
display: inline-block | |
} | |
.placeholder .text-placeholder-block { | |
position: relative; | |
top: -.1em; | |
display: block | |
} | |
.placeholder .text-placeholder-block.extra { | |
top: -.2em | |
} | |
.placeholder.blank, | |
.placeholder.default { | |
position: fixed; | |
height: 100%; | |
top: 0; | |
left: 0 | |
} | |
.placeholder .featured-slider-placeholder { | |
background: #ddd | |
} | |
.placeholder.placeholder-watchapps .categories, | |
.placeholder.placeholder-watchfaces .categories { | |
border-top: 2px solid #444; | |
border-bottom: 2px solid #444 | |
} | |
.placeholder.placeholder-watchapps .category a, | |
.placeholder.placeholder-watchfaces .category a { | |
display: block | |
} | |
.placeholder.placeholder-watchapps .category-icon:before, | |
.placeholder.placeholder-watchfaces .category-icon:before { | |
content: ''; | |
display: block; | |
height: 34px; | |
width: 34px; | |
background: #444 | |
} | |
.placeholder.placeholder-watchapps .category-title, | |
.placeholder.placeholder-watchfaces .category-title { | |
text-align: left; | |
color: #444; | |
font-family: sans-serif | |
} | |
.placeholder.placeholder-watchapps .app-icon, | |
.placeholder.placeholder-watchfaces .app-icon { | |
background: #eee | |
} | |
.placeholder.placeholder-watchapps .app-category, | |
.placeholder.placeholder-watchapps .app-title, | |
.placeholder.placeholder-watchfaces .app-category, | |
.placeholder.placeholder-watchfaces .app-title { | |
color: #eee!important; | |
font-family: sans-serif!important | |
} | |
.placeholder.placeholder-watchapps .collection-title, | |
.placeholder.placeholder-watchfaces .collection-title { | |
color: #ddd!important; | |
font-family: sans-serif!important | |
} | |
.placeholder.placeholder-watchapps .icon.heart, | |
.placeholder.placeholder-watchfaces .icon.heart { | |
opacity: .2 | |
} | |
.placeholder.placeholder-application .app-icon { | |
background: #444 | |
} | |
.placeholder.placeholder-application .app-detail.watchface .app-icon { | |
display: none | |
} | |
.placeholder.placeholder-application .app-author, | |
.placeholder.placeholder-application .app-title { | |
color: #444!important | |
} | |
.placeholder.placeholder-application .add-button { | |
border-color: #444; | |
color: #444!important | |
} | |
.placeholder.placeholder-application .app-download { | |
position: absolute; | |
text-align: left | |
} | |
.placeholder.placeholder-application .app-meta:before { | |
height: 35px; | |
content: ''; | |
display: inline-block | |
} | |
.placeholder.placeholder-application .app-screenshots .slider-container:before { | |
background-image: none | |
} | |
.placeholder.placeholder-application .description-title { | |
color: #ddd!important | |
} | |
.placeholder.placeholder-category { | |
padding: 0; | |
border: none | |
} | |
.placeholder.placeholder-category .filter { | |
border-color: #ddd; | |
background-color: #eee | |
} | |
.placeholder .apps-list .app-list-icon { | |
background-color: #ddd | |
} | |
.placeholder .apps-list .app-image .img-static-aspect img { | |
background-color: #ddd; | |
width: 144px; | |
height: 168px | |
} | |
.hardware-chalk .placeholder .apps-list .app-image .img-static-aspect img { | |
border-radius: 50%; | |
width: 180px; | |
height: auto | |
} | |
.placeholder .apps-list .app-details pre, | |
.placeholder .apps-list .app-header .app-category, | |
.placeholder .apps-list .app-header h3, | |
.placeholder .apps-list .watchface h2 { | |
color: #ddd!important | |
} | |
.placeholder .apps-list .app-details pre { | |
font-size: .5em | |
} | |
.is-browser .loading-bar, | |
.is-browser .placeholder, | |
.placeholder-blank.active~.loading-bar { | |
display: none | |
} | |
</style> | |
<body ng-app="appstoreApp" ng-class="[ | |
'platform-' + platform, | |
'hardware-' + hardware, | |
'product-variant-' + productVariant, | |
isBrowser ? 'is-browser' : 'not-browser' | |
]"> | |
<pbl-browser-header ng-if="isBrowser"></pbl-browser-header> | |
<div class="route-error hide"> | |
<div class="route-error-wrapper"> | |
<div class="route-error-message">{{ errorMessage }}</div> | |
<button type="button" class="refresh-button" ng-click="tryAgain(errorStatus)"><span>Try Again</span></button> | |
</div> | |
</div> | |
<a id="search-trigger" style="display: none"></a> | |
<div class="loader show"> | |
<div class="placeholder placeholder-watchapps"> | |
<div class="featured-slider-placeholder"></div> | |
<div class="categories" ng-if="showCategories"> | |
<div class="category" ng-repeat="title in [ | |
'▆▆▆', | |
'▆▆ ▆ ▆▆▆▆', | |
'▆▆▆', | |
'▆▆▆▆▆▆', | |
'▆▆ ▆ ▆▆▆', | |
'▆▆▆' | |
] track by $index"> | |
<a> | |
<div class="category-icon"></div> | |
<div class="category-meta"> | |
<h1 class="category-title"> <span class="text-placeholder-inline">{{::title}}</span> </h1> </div> | |
</a> | |
</div> | |
</div> | |
<div class="collections"> | |
<div class="collection" ng-repeat="n in repeat(2)"> | |
<div> | |
<header class="collection-header"> <a><span class="collection-title text-placeholder-block extra">▆▆ ▆▆▆▆▆</span></a> </header> | |
<div class="apps"> | |
<a ng-repeat="n in repeat(homeSectionSize)"> | |
<div class="app"> | |
<div class="app-icon"></div> | |
<div class="app-details"> <span class="app-title text-placeholder-block extra">▆▆▆▆</span> | |
<div class="app-category text-placeholder-block">▆▆</div> | |
<div class="hearts"> | |
<div class="icon heart"></div> | |
</div> | |
</div> | |
</div> | |
</a> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="placeholder placeholder-watchfaces"> | |
<div class="featured-slider-placeholder"></div> | |
<div class="collections"> | |
<div class="collection" ng-repeat="n in repeat(3)"> | |
<div> | |
<header class="collection-header"> <a><span class="collection-title text-placeholder-block extra">▆▆ ▆▆▆▆▆</span></a> </header> | |
<div class="apps watchfaces"> | |
<a ng-repeat="n in repeat(homeSectionSize)"> | |
<div class="app watchface"> | |
<div class="face-grid-preview"></div> | |
<div class="hearts ng-binding"> | |
<div class="icon heart"></div> | |
</div> | |
</div> | |
</a> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="placeholder placeholder-application"> | |
<section class="app-detail" ng-class="section === enums.SECTION.WATCHFACES ? 'watchface' : 'watchapp'"> | |
<article class="app"> | |
<div class="app-download"> | |
<div class="app-identity"> | |
<div class="app-icon"></div> | |
<div class="app-title-author"> | |
<h1 class="app-title text-placeholder-block">▆▆▆▆▆▆</h1> | |
<h2 class="app-author text-placeholder-block">▆▆▆</h2> </div> | |
</div> | |
<div class="app-download-actions"></div> | |
</div> | |
</article> | |
</section> | |
</div> | |
<div class="placeholder placeholder-category"> | |
<div class="featured-slider-placeholder"></div> | |
<div class="search-type"> <span class="filter search-type-apps"><a> </a></span> <span class="filter search-type-apps"><a> </a></span> </div> | |
<div class="apps-list"> | |
<ul> | |
<li ng-repeat="n in repeat(5)" class="watchapp"> | |
<div ng-include data-src="'placeholders/partials/app-li.html'"></div> | |
</li> | |
</ul> | |
</div> | |
</div> | |
<div class="placeholder placeholder-collection"> | |
<div class="apps-list"> | |
<ul ng-if="section == 'watchapps'"> | |
<li ng-repeat="n in repeat(5)" class="watchapp"> | |
<div ng-include data-src="'placeholders/partials/app-li.html'"></div> | |
</li> | |
</ul> | |
<ul ng-if="section == 'watchfaces'"> | |
<li ng-repeat="n in repeat(15)" class="watchface"> | |
<div ng-include data-src="'placeholders/partials/face-li.html'"></div> | |
</li> | |
</ul> | |
</div> | |
</div> | |
<div class="placeholder placeholder-default"></div> | |
<div class="placeholder placeholder-blank"></div> | |
<div class="loading-bar"></div> | |
</div> | |
<div id="main-view" ng-view=""> </div> | |
<script> | |
! function(window, document, undefined) { | |
"use strict"; | |
function minErr(module, ErrorConstructor) { | |
return ErrorConstructor = ErrorConstructor || Error, | |
function() { | |
var paramPrefix, i, SKIP_INDEXES = 2, | |
templateArgs = arguments, | |
code = templateArgs[0], | |
message = "[" + (module ? module + ":" : "") + code + "] ", | |
template = templateArgs[1]; | |
for (message += template.replace(/\{\d+\}/g, function(match) { | |
var index = +match.slice(1, -1), | |
shiftedIndex = index + SKIP_INDEXES; | |
if (shiftedIndex < templateArgs.length) return toDebugString(templateArgs[shiftedIndex]); | |
return match | |
}), message += "\nhttp://errors.angularjs.org/1.4.0-rc.0/" + (module ? module + "/" : "") + code, i = SKIP_INDEXES, paramPrefix = "?"; i < templateArgs.length; i++, paramPrefix = "&") message += paramPrefix + "p" + (i - SKIP_INDEXES) + "=" + encodeURIComponent(toDebugString(templateArgs[i])); | |
return new ErrorConstructor(message) | |
} | |
} | |
var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/, | |
VALIDITY_STATE_PROPERTY = "validity", | |
lowercase = function(string) { | |
return isString(string) ? string.toLowerCase() : string | |
}, | |
hasOwnProperty = Object.prototype.hasOwnProperty, | |
uppercase = function(string) { | |
return isString(string) ? string.toUpperCase() : string | |
}, | |
manualLowercase = function(s) { | |
return isString(s) ? s.replace(/[A-Z]/g, function(ch) { | |
return String.fromCharCode(32 | ch.charCodeAt(0)) | |
}) : s | |
}, | |
manualUppercase = function(s) { | |
return isString(s) ? s.replace(/[a-z]/g, function(ch) { | |
return String.fromCharCode(-33 & ch.charCodeAt(0)) | |
}) : s | |
}; | |
"i" !== "I".toLowerCase() && (lowercase = manualLowercase, uppercase = manualUppercase); | |
var msie, jqLite, jQuery, angularModule, slice = [].slice, | |
splice = [].splice, | |
push = [].push, | |
toString = Object.prototype.toString, | |
ngMinErr = minErr("ng"), | |
angular = window.angular || (window.angular = {}), | |
uid = 0; | |
msie = document.documentMode; | |
function isArrayLike(obj) { | |
if (null == obj || isWindow(obj)) return !1; | |
var length = obj.length; | |
if (obj.nodeType === NODE_TYPE_ELEMENT && length) return !0; | |
return isString(obj) || isArray(obj) || 0 === length || "number" == typeof length && length > 0 && length - 1 in obj | |
} | |
function forEach(obj, iterator, context) { | |
var key, length; | |
if (obj) | |
if (isFunction(obj)) | |
for (key in obj) "prototype" == key || "length" == key || "name" == key || obj.hasOwnProperty && !obj.hasOwnProperty(key) || iterator.call(context, obj[key], key, obj); | |
else if (isArray(obj) || isArrayLike(obj)) { | |
var isPrimitive = "object" != typeof obj; | |
for (key = 0, length = obj.length; length > key; key++)(isPrimitive || key in obj) && iterator.call(context, obj[key], key, obj) | |
} else if (obj.forEach && obj.forEach !== forEach) obj.forEach(iterator, context, obj); | |
else | |
for (key in obj) obj.hasOwnProperty(key) && iterator.call(context, obj[key], key, obj); | |
return obj | |
} | |
function forEachSorted(obj, iterator, context) { | |
for (var keys = Object.keys(obj).sort(), i = 0; i < keys.length; i++) iterator.call(context, obj[keys[i]], keys[i]); | |
return keys | |
} | |
function reverseParams(iteratorFn) { | |
return function(value, key) { | |
iteratorFn(key, value) | |
} | |
} | |
function nextUid() { | |
return ++uid | |
} | |
function setHashKey(obj, h) { | |
h ? obj.$$hashKey = h : delete obj.$$hashKey | |
} | |
function baseExtend(dst, objs, deep) { | |
for (var h = dst.$$hashKey, i = 0, ii = objs.length; ii > i; ++i) { | |
var obj = objs[i]; | |
if (!isObject(obj) && !isFunction(obj)) continue; | |
for (var keys = Object.keys(obj), j = 0, jj = keys.length; jj > j; j++) { | |
var key = keys[j], | |
src = obj[key]; | |
deep && isObject(src) ? (isObject(dst[key]) || (dst[key] = isArray(src) ? [] : {}), baseExtend(dst[key], [src], !0)) : dst[key] = src | |
} | |
} | |
return setHashKey(dst, h), dst | |
} | |
function extend(dst) { | |
return baseExtend(dst, slice.call(arguments, 1), !1) | |
} | |
function merge(dst) { | |
return baseExtend(dst, slice.call(arguments, 1), !0) | |
} | |
function toInt(str) { | |
return parseInt(str, 10) | |
} | |
function inherit(parent, extra) { | |
return extend(Object.create(parent), extra) | |
} | |
function noop() {} | |
noop.$inject = []; | |
function identity($) { | |
return $ | |
} | |
identity.$inject = []; | |
function valueFn(value) { | |
return function() { | |
return value | |
} | |
} | |
function isUndefined(value) { | |
return "undefined" == typeof value | |
} | |
function isDefined(value) { | |
return "undefined" != typeof value | |
} | |
function isObject(value) { | |
return null !== value && "object" == typeof value | |
} | |
function isString(value) { | |
return "string" == typeof value | |
} | |
function isNumber(value) { | |
return "number" == typeof value | |
} | |
function isDate(value) { | |
return "[object Date]" === toString.call(value) | |
} | |
var isArray = Array.isArray; | |
function isFunction(value) { | |
return "function" == typeof value | |
} | |
function isRegExp(value) { | |
return "[object RegExp]" === toString.call(value) | |
} | |
function isWindow(obj) { | |
return obj && obj.window === obj | |
} | |
function isScope(obj) { | |
return obj && obj.$evalAsync && obj.$watch | |
} | |
function isFile(obj) { | |
return "[object File]" === toString.call(obj) | |
} | |
function isFormData(obj) { | |
return "[object FormData]" === toString.call(obj) | |
} | |
function isBlob(obj) { | |
return "[object Blob]" === toString.call(obj) | |
} | |
function isBoolean(value) { | |
return "boolean" == typeof value | |
} | |
function isPromiseLike(obj) { | |
return obj && isFunction(obj.then) | |
} | |
var TYPED_ARRAY_REGEXP = /^\[object (Uint8(Clamped)?)|(Uint16)|(Uint32)|(Int8)|(Int16)|(Int32)|(Float(32)|(64))Array\]$/; | |
function isTypedArray(value) { | |
return TYPED_ARRAY_REGEXP.test(toString.call(value)) | |
} | |
var trim = function(value) { | |
return isString(value) ? value.trim() : value | |
}, | |
escapeForRegexp = function(s) { | |
return s.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, "\\$1").replace(/\x08/g, "\\x08") | |
}; | |
function isElement(node) { | |
return !(!node || !(node.nodeName || node.prop && node.attr && node.find)) | |
} | |
function makeMap(str) { | |
var i, obj = {}, | |
items = str.split(","); | |
for (i = 0; i < items.length; i++) obj[items[i]] = !0; | |
return obj | |
} | |
function nodeName_(element) { | |
return lowercase(element.nodeName || element[0] && element[0].nodeName) | |
} | |
function arrayRemove(array, value) { | |
var index = array.indexOf(value); | |
return index >= 0 && array.splice(index, 1), index | |
} | |
function copy(source, destination, stackSource, stackDest) { | |
if (isWindow(source) || isScope(source)) throw ngMinErr("cpws", "Can't copy! Making copies of Window or Scope instances is not supported."); | |
if (isTypedArray(destination)) throw ngMinErr("cpta", "Can't copy! TypedArray destination cannot be mutated."); | |
if (destination) { | |
if (source === destination) throw ngMinErr("cpi", "Can't copy! Source and destination are identical."); | |
if (stackSource = stackSource || [], stackDest = stackDest || [], isObject(source)) { | |
var index = stackSource.indexOf(source); | |
if (-1 !== index) return stackDest[index]; | |
stackSource.push(source), stackDest.push(destination) | |
} | |
var result; | |
if (isArray(source)) { | |
destination.length = 0; | |
for (var i = 0; i < source.length; i++) result = copy(source[i], null, stackSource, stackDest), isObject(source[i]) && (stackSource.push(source[i]), stackDest.push(result)), destination.push(result) | |
} else { | |
var h = destination.$$hashKey; | |
isArray(destination) ? destination.length = 0 : forEach(destination, function(value, key) { | |
delete destination[key] | |
}); | |
for (var key in source) source.hasOwnProperty(key) && (result = copy(source[key], null, stackSource, stackDest), isObject(source[key]) && (stackSource.push(source[key]), stackDest.push(result)), destination[key] = result); | |
setHashKey(destination, h) | |
} | |
} else if (destination = source, source) | |
if (isArray(source)) destination = copy(source, [], stackSource, stackDest); | |
else if (isTypedArray(source)) destination = new source.constructor(source); | |
else if (isDate(source)) destination = new Date(source.getTime()); | |
else if (isRegExp(source)) destination = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]), destination.lastIndex = source.lastIndex; | |
else if (isObject(source)) { | |
var emptyObject = Object.create(Object.getPrototypeOf(source)); | |
destination = copy(source, emptyObject, stackSource, stackDest) | |
} | |
return destination | |
} | |
function shallowCopy(src, dst) { | |
if (isArray(src)) { | |
dst = dst || []; | |
for (var i = 0, ii = src.length; ii > i; i++) dst[i] = src[i] | |
} else if (isObject(src)) { | |
dst = dst || {}; | |
for (var key in src)("$" !== key.charAt(0) || "$" !== key.charAt(1)) && (dst[key] = src[key]) | |
} | |
return dst || src | |
} | |
function equals(o1, o2) { | |
if (o1 === o2) return !0; | |
if (null === o1 || null === o2) return !1; | |
if (o1 !== o1 && o2 !== o2) return !0; | |
var length, key, keySet, t1 = typeof o1, | |
t2 = typeof o2; | |
if (t1 == t2 && "object" == t1) { | |
if (!isArray(o1)) { | |
if (isDate(o1)) { | |
if (!isDate(o2)) return !1; | |
return equals(o1.getTime(), o2.getTime()) | |
} | |
if (isRegExp(o1)) return isRegExp(o2) ? o1.toString() == o2.toString() : !1; | |
if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || isArray(o2) || isDate(o2) || isRegExp(o2)) return !1; | |
keySet = {}; | |
for (key in o1) { | |
if ("$" === key.charAt(0) || isFunction(o1[key])) continue; | |
if (!equals(o1[key], o2[key])) return !1; | |
keySet[key] = !0 | |
} | |
for (key in o2) | |
if (!keySet.hasOwnProperty(key) && "$" !== key.charAt(0) && o2[key] !== undefined && !isFunction(o2[key])) return !1; | |
return !0 | |
} | |
if (!isArray(o2)) return !1; | |
if ((length = o1.length) == o2.length) { | |
for (key = 0; length > key; key++) | |
if (!equals(o1[key], o2[key])) return !1; | |
return !0 | |
} | |
} | |
return !1 | |
} | |
var csp = function() { | |
if (isDefined(csp.isActive_)) return csp.isActive_; | |
var active = !(!document.querySelector("[ng-csp]") && !document.querySelector("[data-ng-csp]")); | |
if (!active) try { | |
new Function("") | |
} catch (e) { | |
active = !0 | |
} | |
return csp.isActive_ = active | |
}, | |
jq = function() { | |
if (isDefined(jq.name_)) return jq.name_; | |
var el, i, prefix, name, ii = ngAttrPrefixes.length; | |
for (i = 0; ii > i; ++i) | |
if (prefix = ngAttrPrefixes[i], el = document.querySelector("[" + prefix.replace(":", "\\:") + "jq]")) { | |
name = el.getAttribute(prefix + "jq"); | |
break | |
} | |
return jq.name_ = name | |
}; | |
function concat(array1, array2, index) { | |
return array1.concat(slice.call(array2, index)) | |
} | |
function sliceArgs(args, startIndex) { | |
return slice.call(args, startIndex || 0) | |
} | |
function bind(self, fn) { | |
var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : []; | |
return !isFunction(fn) || fn instanceof RegExp ? fn : curryArgs.length ? function() { | |
return arguments.length ? fn.apply(self, concat(curryArgs, arguments, 0)) : fn.apply(self, curryArgs) | |
} : function() { | |
return arguments.length ? fn.apply(self, arguments) : fn.call(self) | |
} | |
} | |
function toJsonReplacer(key, value) { | |
var val = value; | |
return "string" == typeof key && "$" === key.charAt(0) && "$" === key.charAt(1) ? val = undefined : isWindow(value) ? val = "$WINDOW" : value && document === value ? val = "$DOCUMENT" : isScope(value) && (val = "$SCOPE"), val | |
} | |
function toJson(obj, pretty) { | |
if ("undefined" == typeof obj) return undefined; | |
return isNumber(pretty) || (pretty = pretty ? 2 : null), JSON.stringify(obj, toJsonReplacer, pretty) | |
} | |
function fromJson(json) { | |
return isString(json) ? JSON.parse(json) : json | |
} | |
function timezoneToOffset(timezone, fallback) { | |
var requestedTimezoneOffset = Date.parse("Jan 01, 1970 00:00:00 " + timezone) / 6e4; | |
return isNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset | |
} | |
function addDateMinutes(date, minutes) { | |
return date = new Date(date.getTime()), date.setMinutes(date.getMinutes() + minutes), date | |
} | |
function convertTimezoneToLocal(date, timezone, reverse) { | |
reverse = reverse ? -1 : 1; | |
var timezoneOffset = timezoneToOffset(timezone, date.getTimezoneOffset()); | |
return addDateMinutes(date, reverse * (timezoneOffset - date.getTimezoneOffset())) | |
} | |
function startingTag(element) { | |
element = jqLite(element).clone(); | |
try { | |
element.empty() | |
} catch (e) {} | |
var elemHtml = jqLite("<div>").append(element).html(); | |
try { | |
return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) : elemHtml.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/, function(match, nodeName) { | |
return "<" + lowercase(nodeName) | |
}) | |
} catch (e) { | |
return lowercase(elemHtml) | |
} | |
} | |
function tryDecodeURIComponent(value) { | |
try { | |
return decodeURIComponent(value) | |
} catch (e) {} | |
} | |
function parseKeyValue(keyValue) { | |
var key_value, key, obj = {}; | |
return forEach((keyValue || "").split("&"), function(keyValue) { | |
if (keyValue && (key_value = keyValue.replace(/\+/g, "%20").split("="), key = tryDecodeURIComponent(key_value[0]), isDefined(key))) { | |
var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : !0; | |
hasOwnProperty.call(obj, key) ? isArray(obj[key]) ? obj[key].push(val) : obj[key] = [obj[key], val] : obj[key] = val | |
} | |
}), obj | |
} | |
function toKeyValue(obj) { | |
var parts = []; | |
return forEach(obj, function(value, key) { | |
isArray(value) ? forEach(value, function(arrayValue) { | |
parts.push(encodeUriQuery(key, !0) + (arrayValue === !0 ? "" : "=" + encodeUriQuery(arrayValue, !0))) | |
}) : parts.push(encodeUriQuery(key, !0) + (value === !0 ? "" : "=" + encodeUriQuery(value, !0))) | |
}), parts.length ? parts.join("&") : "" | |
} | |
function encodeUriSegment(val) { | |
return encodeUriQuery(val, !0).replace(/%26/gi, "&").replace(/%3D/gi, "=").replace(/%2B/gi, "+") | |
} | |
function encodeUriQuery(val, pctEncodeSpaces) { | |
return encodeURIComponent(val).replace(/%40/gi, "@").replace(/%3A/gi, ":").replace(/%24/g, "$").replace(/%2C/gi, ",").replace(/%3B/gi, ";").replace(/%20/g, pctEncodeSpaces ? "%20" : "+") | |
} | |
var ngAttrPrefixes = ["ng-", "data-ng-", "ng:", "x-ng-"]; | |
function getNgAttribute(element, ngAttr) { | |
var attr, i, ii = ngAttrPrefixes.length; | |
for (i = 0; ii > i; ++i) | |
if (attr = ngAttrPrefixes[i] + ngAttr, isString(attr = element.getAttribute(attr))) return attr; | |
return null | |
} | |
function angularInit(element, bootstrap) { | |
var appElement, module, config = {}; | |
forEach(ngAttrPrefixes, function(prefix) { | |
var name = prefix + "app"; | |
!appElement && element.hasAttribute && element.hasAttribute(name) && (appElement = element, module = element.getAttribute(name)) | |
}), forEach(ngAttrPrefixes, function(prefix) { | |
var candidate, name = prefix + "app"; | |
!appElement && (candidate = element.querySelector("[" + name.replace(":", "\\:") + "]")) && (appElement = candidate, module = candidate.getAttribute(name)) | |
}), appElement && (config.strictDi = null !== getNgAttribute(appElement, "strict-di"), bootstrap(appElement, module ? [module] : [], config)) | |
} | |
function bootstrap(element, modules, config) { | |
isObject(config) || (config = {}); | |
var defaultConfig = { | |
strictDi: !1 | |
}; | |
config = extend(defaultConfig, config); | |
var doBootstrap = function() { | |
if (element = jqLite(element), element.injector()) { | |
var tag = element[0] === document ? "document" : startingTag(element); | |
throw ngMinErr("btstrpd", "App Already Bootstrapped with this Element '{0}'", tag.replace(/</, "<").replace(/>/, ">")) | |
} | |
modules = modules || [], modules.unshift(["$provide", function($provide) { | |
$provide.value("$rootElement", element) | |
}]), config.debugInfoEnabled && modules.push(["$compileProvider", function($compileProvider) { | |
$compileProvider.debugInfoEnabled(!0) | |
}]), modules.unshift("ng"); | |
var injector = createInjector(modules, config.strictDi); | |
return injector.invoke(["$rootScope", "$rootElement", "$compile", "$injector", function(scope, element, compile, injector) { | |
scope.$apply(function() { | |
element.data("$injector", injector), compile(element)(scope) | |
}) | |
}]), injector | |
}, | |
NG_ENABLE_DEBUG_INFO = /^NG_ENABLE_DEBUG_INFO!/, | |
NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/; | |
if (window && NG_ENABLE_DEBUG_INFO.test(window.name) && (config.debugInfoEnabled = !0, window.name = window.name.replace(NG_ENABLE_DEBUG_INFO, "")), window && !NG_DEFER_BOOTSTRAP.test(window.name)) return doBootstrap(); | |
window.name = window.name.replace(NG_DEFER_BOOTSTRAP, ""), angular.resumeBootstrap = function(extraModules) { | |
return forEach(extraModules, function(module) { | |
modules.push(module) | |
}), doBootstrap() | |
}, isFunction(angular.resumeDeferredBootstrap) && angular.resumeDeferredBootstrap() | |
} | |
function reloadWithDebugInfo() { | |
window.name = "NG_ENABLE_DEBUG_INFO!" + window.name, window.location.reload() | |
} | |
function getTestability(rootElement) { | |
var injector = angular.element(rootElement).injector(); | |
if (!injector) throw ngMinErr("test", "no injector found for element argument to getTestability"); | |
return injector.get("$$testability") | |
} | |
var SNAKE_CASE_REGEXP = /[A-Z]/g; | |
function snake_case(name, separator) { | |
return separator = separator || "_", name.replace(SNAKE_CASE_REGEXP, function(letter, pos) { | |
return (pos ? separator : "") + letter.toLowerCase() | |
}) | |
} | |
var skipDestroyOnNextJQueryCleanData, bindJQueryFired = !1; | |
function bindJQuery() { | |
var originalCleanData; | |
if (bindJQueryFired) return; | |
var jqName = jq(); | |
jQuery = window.jQuery, isDefined(jqName) && (jQuery = null === jqName ? undefined : window[jqName]), jQuery && jQuery.fn.on ? (jqLite = jQuery, extend(jQuery.fn, { | |
scope: JQLitePrototype.scope, | |
isolateScope: JQLitePrototype.isolateScope, | |
controller: JQLitePrototype.controller, | |
injector: JQLitePrototype.injector, | |
inheritedData: JQLitePrototype.inheritedData | |
}), originalCleanData = jQuery.cleanData, jQuery.cleanData = function(elems) { | |
var events; | |
if (skipDestroyOnNextJQueryCleanData) skipDestroyOnNextJQueryCleanData = !1; | |
else | |
for (var elem, i = 0; null != (elem = elems[i]); i++) events = jQuery._data(elem, "events"), events && events.$destroy && jQuery(elem).triggerHandler("$destroy"); | |
originalCleanData(elems) | |
}) : jqLite = JQLite, angular.element = jqLite, bindJQueryFired = !0 | |
} | |
function assertArg(arg, name, reason) { | |
if (!arg) throw ngMinErr("areq", "Argument '{0}' is {1}", name || "?", reason || "required"); | |
return arg | |
} | |
function assertArgFn(arg, name, acceptArrayAnnotation) { | |
return acceptArrayAnnotation && isArray(arg) && (arg = arg[arg.length - 1]), assertArg(isFunction(arg), name, "not a function, got " + (arg && "object" == typeof arg ? arg.constructor.name || "Object" : typeof arg)), arg | |
} | |
function assertNotHasOwnProperty(name, context) { | |
if ("hasOwnProperty" === name) throw ngMinErr("badname", "hasOwnProperty is not a valid {0} name", context) | |
} | |
function getter(obj, path, bindFnToScope) { | |
if (!path) return obj; | |
for (var key, keys = path.split("."), lastInstance = obj, len = keys.length, i = 0; len > i; i++) key = keys[i], obj && (obj = (lastInstance = obj)[key]); | |
if (!bindFnToScope && isFunction(obj)) return bind(lastInstance, obj); | |
return obj | |
} | |
function getBlockNodes(nodes) { | |
var node = nodes[0], | |
endNode = nodes[nodes.length - 1], | |
blockNodes = [node]; | |
do { | |
if (node = node.nextSibling, !node) break; | |
blockNodes.push(node) | |
} while (node !== endNode); | |
return jqLite(blockNodes) | |
} | |
function createMap() { | |
return Object.create(null) | |
} | |
var NODE_TYPE_ELEMENT = 1, | |
NODE_TYPE_ATTRIBUTE = 2, | |
NODE_TYPE_TEXT = 3, | |
NODE_TYPE_COMMENT = 8, | |
NODE_TYPE_DOCUMENT = 9, | |
NODE_TYPE_DOCUMENT_FRAGMENT = 11; | |
function setupModuleLoader(window) { | |
var $injectorMinErr = minErr("$injector"), | |
ngMinErr = minErr("ng"); | |
function ensure(obj, name, factory) { | |
return obj[name] || (obj[name] = factory()) | |
} | |
var angular = ensure(window, "angular", Object); | |
return angular.$$minErr = angular.$$minErr || minErr, ensure(angular, "module", function() { | |
var modules = {}; | |
return function(name, requires, configFn) { | |
var assertNotHasOwnProperty = function(name, context) { | |
if ("hasOwnProperty" === name) throw ngMinErr("badname", "hasOwnProperty is not a valid {0} name", context) | |
}; | |
return assertNotHasOwnProperty(name, "module"), requires && modules.hasOwnProperty(name) && (modules[name] = null), ensure(modules, name, function() { | |
if (!requires) throw $injectorMinErr("nomod", "Module '{0}' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.", name); | |
var invokeQueue = [], | |
configBlocks = [], | |
runBlocks = [], | |
config = invokeLater("$injector", "invoke", "push", configBlocks), | |
moduleInstance = { | |
_invokeQueue: invokeQueue, | |
_configBlocks: configBlocks, | |
_runBlocks: runBlocks, | |
requires: requires, | |
name: name, | |
provider: invokeLater("$provide", "provider"), | |
factory: invokeLater("$provide", "factory"), | |
service: invokeLater("$provide", "service"), | |
value: invokeLater("$provide", "value"), | |
constant: invokeLater("$provide", "constant", "unshift"), | |
decorator: invokeLater("$provide", "decorator"), | |
animation: invokeLater("$animateProvider", "register"), | |
filter: invokeLater("$filterProvider", "register"), | |
controller: invokeLater("$controllerProvider", "register"), | |
directive: invokeLater("$compileProvider", "directive"), | |
config: config, | |
run: function(block) { | |
return runBlocks.push(block), this | |
} | |
}; | |
return configFn && config(configFn), moduleInstance; | |
function invokeLater(provider, method, insertMethod, queue) { | |
return queue || (queue = invokeQueue), | |
function() { | |
return queue[insertMethod || "push"]([provider, method, arguments]), moduleInstance | |
} | |
} | |
}) | |
} | |
}) | |
} | |
function serializeObject(obj) { | |
var seen = []; | |
return JSON.stringify(obj, function(key, val) { | |
if (val = toJsonReplacer(key, val), isObject(val)) { | |
if (seen.indexOf(val) >= 0) return "<<already seen>>"; | |
seen.push(val) | |
} | |
return val | |
}) | |
} | |
function toDebugString(obj) { | |
if ("function" == typeof obj) return obj.toString().replace(/ \{[\s\S]*$/, ""); | |
if ("undefined" == typeof obj) return "undefined"; | |
if ("string" != typeof obj) return serializeObject(obj); | |
return obj | |
} | |
var version = { | |
full: "1.4.0-rc.0", | |
major: 1, | |
minor: 4, | |
dot: 0, | |
codeName: "smooth-unwinding" | |
}; | |
function publishExternalAPI(angular) { | |
extend(angular, { | |
bootstrap: bootstrap, | |
copy: copy, | |
extend: extend, | |
merge: merge, | |
equals: equals, | |
element: jqLite, | |
forEach: forEach, | |
injector: createInjector, | |
noop: noop, | |
bind: bind, | |
toJson: toJson, | |
fromJson: fromJson, | |
identity: identity, | |
isUndefined: isUndefined, | |
isDefined: isDefined, | |
isString: isString, | |
isFunction: isFunction, | |
isObject: isObject, | |
isNumber: isNumber, | |
isElement: isElement, | |
isArray: isArray, | |
version: version, | |
isDate: isDate, | |
lowercase: lowercase, | |
uppercase: uppercase, | |
callbacks: { | |
counter: 0 | |
}, | |
getTestability: getTestability, | |
$$minErr: minErr, | |
$$csp: csp, | |
reloadWithDebugInfo: reloadWithDebugInfo | |
}), angularModule = setupModuleLoader(window); | |
try { | |
angularModule("ngLocale") | |
} catch (e) { | |
angularModule("ngLocale", []).provider("$locale", $LocaleProvider) | |
} | |
angularModule("ng", ["ngLocale"], ["$provide", function($provide) { | |
$provide.provider({ | |
$$sanitizeUri: $$SanitizeUriProvider | |
}), $provide.provider("$compile", $CompileProvider).directive({ | |
a: htmlAnchorDirective, | |
input: inputDirective, | |
textarea: inputDirective, | |
form: formDirective, | |
script: scriptDirective, | |
select: selectDirective, | |
style: styleDirective, | |
option: optionDirective, | |
ngBind: ngBindDirective, | |
ngBindHtml: ngBindHtmlDirective, | |
ngBindTemplate: ngBindTemplateDirective, | |
ngClass: ngClassDirective, | |
ngClassEven: ngClassEvenDirective, | |
ngClassOdd: ngClassOddDirective, | |
ngCloak: ngCloakDirective, | |
ngController: ngControllerDirective, | |
ngForm: ngFormDirective, | |
ngHide: ngHideDirective, | |
ngIf: ngIfDirective, | |
ngInclude: ngIncludeDirective, | |
ngInit: ngInitDirective, | |
ngNonBindable: ngNonBindableDirective, | |
ngPluralize: ngPluralizeDirective, | |
ngRepeat: ngRepeatDirective, | |
ngShow: ngShowDirective, | |
ngStyle: ngStyleDirective, | |
ngSwitch: ngSwitchDirective, | |
ngSwitchWhen: ngSwitchWhenDirective, | |
ngSwitchDefault: ngSwitchDefaultDirective, | |
ngOptions: ngOptionsDirective, | |
ngTransclude: ngTranscludeDirective, | |
ngModel: ngModelDirective, | |
ngList: ngListDirective, | |
ngChange: ngChangeDirective, | |
pattern: patternDirective, | |
ngPattern: patternDirective, | |
required: requiredDirective, | |
ngRequired: requiredDirective, | |
minlength: minlengthDirective, | |
ngMinlength: minlengthDirective, | |
maxlength: maxlengthDirective, | |
ngMaxlength: maxlengthDirective, | |
ngValue: ngValueDirective, | |
ngModelOptions: ngModelOptionsDirective | |
}).directive({ | |
ngInclude: ngIncludeFillContentDirective | |
}).directive(ngAttributeAliasDirectives).directive(ngEventDirectives), $provide.provider({ | |
$anchorScroll: $AnchorScrollProvider, | |
$animate: $AnimateProvider, | |
$$animateQueue: $$CoreAnimateQueueProvider, | |
$$AnimateRunner: $$CoreAnimateRunnerProvider, | |
$browser: $BrowserProvider, | |
$cacheFactory: $CacheFactoryProvider, | |
$controller: $ControllerProvider, | |
$document: $DocumentProvider, | |
$exceptionHandler: $ExceptionHandlerProvider, | |
$filter: $FilterProvider, | |
$interpolate: $InterpolateProvider, | |
$interval: $IntervalProvider, | |
$http: $HttpProvider, | |
$httpParamSerializer: $HttpParamSerializerProvider, | |
$httpParamSerializerJQLike: $HttpParamSerializerJQLikeProvider, | |
$httpBackend: $HttpBackendProvider, | |
$location: $LocationProvider, | |
$log: $LogProvider, | |
$parse: $ParseProvider, | |
$rootScope: $RootScopeProvider, | |
$q: $QProvider, | |
$$q: $$QProvider, | |
$sce: $SceProvider, | |
$sceDelegate: $SceDelegateProvider, | |
$sniffer: $SnifferProvider, | |
$templateCache: $TemplateCacheProvider, | |
$templateRequest: $TemplateRequestProvider, | |
$$testability: $$TestabilityProvider, | |
$timeout: $TimeoutProvider, | |
$window: $WindowProvider, | |
$$rAF: $$RAFProvider, | |
$$asyncCallback: $$AsyncCallbackProvider, | |
$$jqLite: $$jqLiteProvider, | |
$$HashMap: $$HashMapProvider, | |
$$cookieReader: $$CookieReaderProvider | |
}) | |
}]) | |
} | |
JQLite.expando = "ng339"; | |
var jqCache = JQLite.cache = {}, | |
jqId = 1, | |
addEventListenerFn = function(element, type, fn) { | |
element.addEventListener(type, fn, !1) | |
}, | |
removeEventListenerFn = function(element, type, fn) { | |
element.removeEventListener(type, fn, !1) | |
}; | |
JQLite._data = function(node) { | |
return this.cache[node[this.expando]] || {} | |
}; | |
function jqNextId() { | |
return ++jqId | |
} | |
var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g, | |
MOZ_HACK_REGEXP = /^moz([A-Z])/, | |
MOUSE_EVENT_MAP = { | |
mouseleave: "mouseout", | |
mouseenter: "mouseover" | |
}, | |
jqLiteMinErr = minErr("jqLite"); | |
function camelCase(name) { | |
return name.replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) { | |
return offset ? letter.toUpperCase() : letter | |
}).replace(MOZ_HACK_REGEXP, "Moz$1") | |
} | |
var SINGLE_TAG_REGEXP = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, | |
HTML_REGEXP = /<|&#?\w+;/, | |
TAG_NAME_REGEXP = /<([\w:]+)/, | |
XHTML_TAG_REGEXP = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, | |
wrapMap = { | |
option: [1, '<select multiple="multiple">', "</select>"], | |
thead: [1, "<table>", "</table>"], | |
col: [2, "<table><colgroup>", "</colgroup></table>"], | |
tr: [2, "<table><tbody>", "</tbody></table>"], | |
td: [3, "<table><tbody><tr>", "</tr></tbody></table>"], | |
_default: [0, "", ""] | |
}; | |
wrapMap.optgroup = wrapMap.option, wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead, wrapMap.th = wrapMap.td; | |
function jqLiteIsTextNode(html) { | |
return !HTML_REGEXP.test(html) | |
} | |
function jqLiteAcceptsData(node) { | |
var nodeType = node.nodeType; | |
return nodeType === NODE_TYPE_ELEMENT || !nodeType || nodeType === NODE_TYPE_DOCUMENT | |
} | |
function jqLiteBuildFragment(html, context) { | |
var tmp, tag, wrap, i, fragment = context.createDocumentFragment(), | |
nodes = []; | |
if (jqLiteIsTextNode(html)) nodes.push(context.createTextNode(html)); | |
else { | |
for (tmp = tmp || fragment.appendChild(context.createElement("div")), tag = (TAG_NAME_REGEXP.exec(html) || ["", ""])[1].toLowerCase(), wrap = wrapMap[tag] || wrapMap._default, tmp.innerHTML = wrap[1] + html.replace(XHTML_TAG_REGEXP, "<$1></$2>") + wrap[2], i = wrap[0]; i--;) tmp = tmp.lastChild; | |
nodes = concat(nodes, tmp.childNodes), tmp = fragment.firstChild, tmp.textContent = "" | |
} | |
return fragment.textContent = "", fragment.innerHTML = "", forEach(nodes, function(node) { | |
fragment.appendChild(node) | |
}), fragment | |
} | |
function jqLiteParseHTML(html, context) { | |
context = context || document; | |
var parsed; | |
if (parsed = SINGLE_TAG_REGEXP.exec(html)) return [context.createElement(parsed[1])]; | |
if (parsed = jqLiteBuildFragment(html, context)) return parsed.childNodes; | |
return [] | |
} | |
function JQLite(element) { | |
if (element instanceof JQLite) return element; | |
var argIsString; | |
if (isString(element) && (element = trim(element), argIsString = !0), !(this instanceof JQLite)) { | |
if (argIsString && "<" != element.charAt(0)) throw jqLiteMinErr("nosel", "Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element"); | |
return new JQLite(element) | |
} | |
argIsString ? jqLiteAddNodes(this, jqLiteParseHTML(element)) : jqLiteAddNodes(this, element) | |
} | |
function jqLiteClone(element) { | |
return element.cloneNode(!0) | |
} | |
function jqLiteDealoc(element, onlyDescendants) { | |
if (onlyDescendants || jqLiteRemoveData(element), element.querySelectorAll) | |
for (var descendants = element.querySelectorAll("*"), i = 0, l = descendants.length; l > i; i++) jqLiteRemoveData(descendants[i]) | |
} | |
function jqLiteOff(element, type, fn, unsupported) { | |
if (isDefined(unsupported)) throw jqLiteMinErr("offargs", "jqLite#off() does not support the `selector` argument"); | |
var expandoStore = jqLiteExpandoStore(element), | |
events = expandoStore && expandoStore.events, | |
handle = expandoStore && expandoStore.handle; | |
if (!handle) return; | |
if (type) forEach(type.split(" "), function(type) { | |
if (isDefined(fn)) { | |
var listenerFns = events[type]; | |
if (arrayRemove(listenerFns || [], fn), listenerFns && listenerFns.length > 0) return | |
} | |
removeEventListenerFn(element, type, handle), delete events[type] | |
}); | |
else | |
for (type in events) "$destroy" !== type && removeEventListenerFn(element, type, handle), delete events[type] | |
} | |
function jqLiteRemoveData(element, name) { | |
var expandoId = element.ng339, | |
expandoStore = expandoId && jqCache[expandoId]; | |
if (expandoStore) { | |
if (name) return void delete expandoStore.data[name]; | |
expandoStore.handle && (expandoStore.events.$destroy && expandoStore.handle({}, "$destroy"), jqLiteOff(element)), delete jqCache[expandoId], element.ng339 = undefined | |
} | |
} | |
function jqLiteExpandoStore(element, createIfNecessary) { | |
var expandoId = element.ng339, | |
expandoStore = expandoId && jqCache[expandoId]; | |
return createIfNecessary && !expandoStore && (element.ng339 = expandoId = jqNextId(), expandoStore = jqCache[expandoId] = { | |
events: {}, | |
data: {}, | |
handle: undefined | |
}), expandoStore | |
} | |
function jqLiteData(element, key, value) { | |
if (jqLiteAcceptsData(element)) { | |
var isSimpleSetter = isDefined(value), | |
isSimpleGetter = !isSimpleSetter && key && !isObject(key), | |
massGetter = !key, | |
expandoStore = jqLiteExpandoStore(element, !isSimpleGetter), | |
data = expandoStore && expandoStore.data; | |
if (isSimpleSetter) data[key] = value; | |
else { | |
if (massGetter) return data; | |
if (isSimpleGetter) return data && data[key]; | |
extend(data, key) | |
} | |
} | |
} | |
function jqLiteHasClass(element, selector) { | |
if (!element.getAttribute) return !1; | |
return (" " + (element.getAttribute("class") || "") + " ").replace(/[\n\t]/g, " ").indexOf(" " + selector + " ") > -1 | |
} | |
function jqLiteRemoveClass(element, cssClasses) { | |
cssClasses && element.setAttribute && forEach(cssClasses.split(" "), function(cssClass) { | |
element.setAttribute("class", trim((" " + (element.getAttribute("class") || "") + " ").replace(/[\n\t]/g, " ").replace(" " + trim(cssClass) + " ", " "))) | |
}) | |
} | |
function jqLiteAddClass(element, cssClasses) { | |
if (cssClasses && element.setAttribute) { | |
var existingClasses = (" " + (element.getAttribute("class") || "") + " ").replace(/[\n\t]/g, " "); | |
forEach(cssClasses.split(" "), function(cssClass) { | |
cssClass = trim(cssClass), -1 === existingClasses.indexOf(" " + cssClass + " ") && (existingClasses += cssClass + " ") | |
}), element.setAttribute("class", trim(existingClasses)) | |
} | |
} | |
function jqLiteAddNodes(root, elements) { | |
if (elements) | |
if (elements.nodeType) root[root.length++] = elements; | |
else { | |
var length = elements.length; | |
if ("number" == typeof length && elements.window !== elements) { | |
if (length) | |
for (var i = 0; length > i; i++) root[root.length++] = elements[i] | |
} else root[root.length++] = elements | |
} | |
} | |
function jqLiteController(element, name) { | |
return jqLiteInheritedData(element, "$" + (name || "ngController") + "Controller") | |
} | |
function jqLiteInheritedData(element, name, value) { | |
element.nodeType == NODE_TYPE_DOCUMENT && (element = element.documentElement); | |
for (var names = isArray(name) ? name : [name]; element;) { | |
for (var i = 0, ii = names.length; ii > i; i++) | |
if ((value = jqLite.data(element, names[i])) !== undefined) return value; | |
element = element.parentNode || element.nodeType === NODE_TYPE_DOCUMENT_FRAGMENT && element.host | |
} | |
} | |
function jqLiteEmpty(element) { | |
for (jqLiteDealoc(element, !0); element.firstChild;) element.removeChild(element.firstChild) | |
} | |
function jqLiteRemove(element, keepData) { | |
keepData || jqLiteDealoc(element); | |
var parent = element.parentNode; | |
parent && parent.removeChild(element) | |
} | |
function jqLiteDocumentLoaded(action, win) { | |
win = win || window, "complete" === win.document.readyState ? win.setTimeout(action) : jqLite(win).on("load", action) | |
} | |
var JQLitePrototype = JQLite.prototype = { | |
ready: function(fn) { | |
var fired = !1; | |
function trigger() { | |
if (fired) return; | |
fired = !0, fn() | |
} | |
"complete" === document.readyState ? setTimeout(trigger) : (this.on("DOMContentLoaded", trigger), JQLite(window).on("load", trigger)) | |
}, | |
toString: function() { | |
var value = []; | |
return forEach(this, function(e) { | |
value.push("" + e) | |
}), "[" + value.join(", ") + "]" | |
}, | |
eq: function(index) { | |
return jqLite(index >= 0 ? this[index] : this[this.length + index]) | |
}, | |
length: 0, | |
push: push, | |
sort: [].sort, | |
splice: [].splice | |
}, | |
BOOLEAN_ATTR = {}; | |
forEach("multiple,selected,checked,disabled,readOnly,required,open".split(","), function(value) { | |
BOOLEAN_ATTR[lowercase(value)] = value | |
}); | |
var BOOLEAN_ELEMENTS = {}; | |
forEach("input,select,option,textarea,button,form,details".split(","), function(value) { | |
BOOLEAN_ELEMENTS[value] = !0 | |
}); | |
var ALIASED_ATTR = { | |
ngMinlength: "minlength", | |
ngMaxlength: "maxlength", | |
ngMin: "min", | |
ngMax: "max", | |
ngPattern: "pattern" | |
}; | |
function getBooleanAttrName(element, name) { | |
var booleanAttr = BOOLEAN_ATTR[name.toLowerCase()]; | |
return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr | |
} | |
function getAliasedAttrName(element, name) { | |
var nodeName = element.nodeName; | |
return ("INPUT" === nodeName || "TEXTAREA" === nodeName) && ALIASED_ATTR[name] | |
} | |
forEach({ | |
data: jqLiteData, | |
removeData: jqLiteRemoveData | |
}, function(fn, name) { | |
JQLite[name] = fn | |
}), forEach({ | |
data: jqLiteData, | |
inheritedData: jqLiteInheritedData, | |
scope: function(element) { | |
return jqLite.data(element, "$scope") || jqLiteInheritedData(element.parentNode || element, ["$isolateScope", "$scope"]) | |
}, | |
isolateScope: function(element) { | |
return jqLite.data(element, "$isolateScope") || jqLite.data(element, "$isolateScopeNoTemplate") | |
}, | |
controller: jqLiteController, | |
injector: function(element) { | |
return jqLiteInheritedData(element, "$injector") | |
}, | |
removeAttr: function(element, name) { | |
element.removeAttribute(name) | |
}, | |
hasClass: jqLiteHasClass, | |
css: function(element, name, value) { | |
if (name = camelCase(name), !isDefined(value)) return element.style[name]; | |
element.style[name] = value | |
}, | |
attr: function(element, name, value) { | |
var nodeType = element.nodeType; | |
if (nodeType === NODE_TYPE_TEXT || nodeType === NODE_TYPE_ATTRIBUTE || nodeType === NODE_TYPE_COMMENT) return; | |
var lowercasedName = lowercase(name); | |
if (BOOLEAN_ATTR[lowercasedName]) { | |
if (!isDefined(value)) return element[name] || (element.attributes.getNamedItem(name) || noop).specified ? lowercasedName : undefined; | |
value ? (element[name] = !0, element.setAttribute(name, lowercasedName)) : (element[name] = !1, element.removeAttribute(lowercasedName)) | |
} else if (isDefined(value)) element.setAttribute(name, value); | |
else if (element.getAttribute) { | |
var ret = element.getAttribute(name, 2); | |
return null === ret ? undefined : ret | |
} | |
}, | |
prop: function(element, name, value) { | |
if (!isDefined(value)) return element[name]; | |
element[name] = value | |
}, | |
text: function() { | |
return getText.$dv = "", getText; | |
function getText(element, value) { | |
if (isUndefined(value)) { | |
var nodeType = element.nodeType; | |
return nodeType === NODE_TYPE_ELEMENT || nodeType === NODE_TYPE_TEXT ? element.textContent : ""; | |
} | |
element.textContent = value | |
} | |
}(), | |
val: function(element, value) { | |
if (isUndefined(value)) { | |
if (element.multiple && "select" === nodeName_(element)) { | |
var result = []; | |
return forEach(element.options, function(option) { | |
option.selected && result.push(option.value || option.text) | |
}), 0 === result.length ? null : result | |
} | |
return element.value | |
} | |
element.value = value | |
}, | |
html: function(element, value) { | |
if (isUndefined(value)) return element.innerHTML; | |
jqLiteDealoc(element, !0), element.innerHTML = value | |
}, | |
empty: jqLiteEmpty | |
}, function(fn, name) { | |
JQLite.prototype[name] = function(arg1, arg2) { | |
var i, key, nodeCount = this.length; | |
if (fn !== jqLiteEmpty && (2 == fn.length && fn !== jqLiteHasClass && fn !== jqLiteController ? arg1 : arg2) === undefined) { | |
if (isObject(arg1)) { | |
for (i = 0; nodeCount > i; i++) | |
if (fn === jqLiteData) fn(this[i], arg1); | |
else | |
for (key in arg1) fn(this[i], key, arg1[key]); | |
return this | |
} | |
for (var value = fn.$dv, jj = value === undefined ? Math.min(nodeCount, 1) : nodeCount, j = 0; jj > j; j++) { | |
var nodeValue = fn(this[j], arg1, arg2); | |
value = value ? value + nodeValue : nodeValue | |
} | |
return value | |
} | |
for (i = 0; nodeCount > i; i++) fn(this[i], arg1, arg2); | |
return this | |
} | |
}); | |
function createEventHandler(element, events) { | |
var eventHandler = function(event, type) { | |
event.isDefaultPrevented = function() { | |
return event.defaultPrevented | |
}; | |
var eventFns = events[type || event.type], | |
eventFnsLength = eventFns ? eventFns.length : 0; | |
if (!eventFnsLength) return; | |
if (isUndefined(event.immediatePropagationStopped)) { | |
var originalStopImmediatePropagation = event.stopImmediatePropagation; | |
event.stopImmediatePropagation = function() { | |
event.immediatePropagationStopped = !0, event.stopPropagation && event.stopPropagation(), originalStopImmediatePropagation && originalStopImmediatePropagation.call(event) | |
} | |
} | |
event.isImmediatePropagationStopped = function() { | |
return event.immediatePropagationStopped === !0 | |
}, eventFnsLength > 1 && (eventFns = shallowCopy(eventFns)); | |
for (var i = 0; eventFnsLength > i; i++) event.isImmediatePropagationStopped() || eventFns[i].call(element, event) | |
}; | |
return eventHandler.elem = element, eventHandler | |
} | |
forEach({ | |
removeData: jqLiteRemoveData, | |
on: function jqLiteOn(element, type, fn, unsupported) { | |
if (isDefined(unsupported)) throw jqLiteMinErr("onargs", "jqLite#on() does not support the `selector` or `eventData` parameters"); | |
if (!jqLiteAcceptsData(element)) return; | |
var expandoStore = jqLiteExpandoStore(element, !0), | |
events = expandoStore.events, | |
handle = expandoStore.handle; | |
handle || (handle = expandoStore.handle = createEventHandler(element, events)); | |
for (var types = type.indexOf(" ") >= 0 ? type.split(" ") : [type], i = types.length; i--;) { | |
type = types[i]; | |
var eventFns = events[type]; | |
eventFns || (events[type] = [], "mouseenter" === type || "mouseleave" === type ? jqLiteOn(element, MOUSE_EVENT_MAP[type], function(event) { | |
var target = this, | |
related = event.relatedTarget; | |
(!related || related !== target && !target.contains(related)) && handle(event, type) | |
}) : "$destroy" !== type && addEventListenerFn(element, type, handle), eventFns = events[type]), eventFns.push(fn) | |
} | |
}, | |
off: jqLiteOff, | |
one: function(element, type, fn) { | |
element = jqLite(element), element.on(type, function onFn() { | |
element.off(type, fn), element.off(type, onFn) | |
}), element.on(type, fn) | |
}, | |
replaceWith: function(element, replaceNode) { | |
var index, parent = element.parentNode; | |
jqLiteDealoc(element), forEach(new JQLite(replaceNode), function(node) { | |
index ? parent.insertBefore(node, index.nextSibling) : parent.replaceChild(node, element), index = node | |
}) | |
}, | |
children: function(element) { | |
var children = []; | |
return forEach(element.childNodes, function(element) { | |
element.nodeType === NODE_TYPE_ELEMENT && children.push(element) | |
}), children | |
}, | |
contents: function(element) { | |
return element.contentDocument || element.childNodes || [] | |
}, | |
append: function(element, node) { | |
var nodeType = element.nodeType; | |
if (nodeType !== NODE_TYPE_ELEMENT && nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT) return; | |
node = new JQLite(node); | |
for (var i = 0, ii = node.length; ii > i; i++) { | |
var child = node[i]; | |
element.appendChild(child) | |
} | |
}, | |
prepend: function(element, node) { | |
if (element.nodeType === NODE_TYPE_ELEMENT) { | |
var index = element.firstChild; | |
forEach(new JQLite(node), function(child) { | |
element.insertBefore(child, index) | |
}) | |
} | |
}, | |
wrap: function(element, wrapNode) { | |
wrapNode = jqLite(wrapNode).eq(0).clone()[0]; | |
var parent = element.parentNode; | |
parent && parent.replaceChild(wrapNode, element), wrapNode.appendChild(element) | |
}, | |
remove: jqLiteRemove, | |
detach: function(element) { | |
jqLiteRemove(element, !0) | |
}, | |
after: function(element, newElement) { | |
var index = element, | |
parent = element.parentNode; | |
newElement = new JQLite(newElement); | |
for (var i = 0, ii = newElement.length; ii > i; i++) { | |
var node = newElement[i]; | |
parent.insertBefore(node, index.nextSibling), index = node | |
} | |
}, | |
addClass: jqLiteAddClass, | |
removeClass: jqLiteRemoveClass, | |
toggleClass: function(element, selector, condition) { | |
selector && forEach(selector.split(" "), function(className) { | |
var classCondition = condition; | |
isUndefined(classCondition) && (classCondition = !jqLiteHasClass(element, className)), (classCondition ? jqLiteAddClass : jqLiteRemoveClass)(element, className) | |
}) | |
}, | |
parent: function(element) { | |
var parent = element.parentNode; | |
return parent && parent.nodeType !== NODE_TYPE_DOCUMENT_FRAGMENT ? parent : null | |
}, | |
next: function(element) { | |
return element.nextElementSibling | |
}, | |
find: function(element, selector) { | |
return element.getElementsByTagName ? element.getElementsByTagName(selector) : [] | |
}, | |
clone: jqLiteClone, | |
triggerHandler: function(element, event, extraParameters) { | |
var dummyEvent, eventFnsCopy, handlerArgs, eventName = event.type || event, | |
expandoStore = jqLiteExpandoStore(element), | |
events = expandoStore && expandoStore.events, | |
eventFns = events && events[eventName]; | |
eventFns && (dummyEvent = { | |
preventDefault: function() { | |
this.defaultPrevented = !0 | |
}, | |
isDefaultPrevented: function() { | |
return this.defaultPrevented === !0 | |
}, | |
stopImmediatePropagation: function() { | |
this.immediatePropagationStopped = !0 | |
}, | |
isImmediatePropagationStopped: function() { | |
return this.immediatePropagationStopped === !0 | |
}, | |
stopPropagation: noop, | |
type: eventName, | |
target: element | |
}, event.type && (dummyEvent = extend(dummyEvent, event)), eventFnsCopy = shallowCopy(eventFns), handlerArgs = extraParameters ? [dummyEvent].concat(extraParameters) : [dummyEvent], forEach(eventFnsCopy, function(fn) { | |
dummyEvent.isImmediatePropagationStopped() || fn.apply(element, handlerArgs) | |
})) | |
} | |
}, function(fn, name) { | |
JQLite.prototype[name] = function(arg1, arg2, arg3) { | |
for (var value, i = 0, ii = this.length; ii > i; i++) isUndefined(value) ? (value = fn(this[i], arg1, arg2, arg3), isDefined(value) && (value = jqLite(value))) : jqLiteAddNodes(value, fn(this[i], arg1, arg2, arg3)); | |
return isDefined(value) ? value : this | |
}, JQLite.prototype.bind = JQLite.prototype.on, JQLite.prototype.unbind = JQLite.prototype.off | |
}); | |
function $$jqLiteProvider() { | |
this.$get = function() { | |
return extend(JQLite, { | |
hasClass: function(node, classes) { | |
return node.attr && (node = node[0]), jqLiteHasClass(node, classes) | |
}, | |
addClass: function(node, classes) { | |
return node.attr && (node = node[0]), jqLiteAddClass(node, classes) | |
}, | |
removeClass: function(node, classes) { | |
return node.attr && (node = node[0]), jqLiteRemoveClass(node, classes) | |
} | |
}) | |
} | |
} | |
function hashKey(obj, nextUidFn) { | |
var key = obj && obj.$$hashKey; | |
if (key) return "function" == typeof key && (key = obj.$$hashKey()), key; | |
var objType = typeof obj; | |
return key = "function" == objType || "object" == objType && null !== obj ? obj.$$hashKey = objType + ":" + (nextUidFn || nextUid)() : objType + ":" + obj | |
} | |
function HashMap(array, isolatedUid) { | |
if (isolatedUid) { | |
var uid = 0; | |
this.nextUid = function() { | |
return ++uid | |
} | |
} | |
forEach(array, this.put, this) | |
} | |
HashMap.prototype = { | |
put: function(key, value) { | |
this[hashKey(key, this.nextUid)] = value | |
}, | |
get: function(key) { | |
return this[hashKey(key, this.nextUid)] | |
}, | |
remove: function(key) { | |
var value = this[key = hashKey(key, this.nextUid)]; | |
return delete this[key], value | |
} | |
}; | |
var $$HashMapProvider = [function() { | |
this.$get = [function() { | |
return HashMap | |
}] | |
}], | |
FN_ARGS = /^function\s*[^\(]*\(\s*([^\)]*)\)/m, | |
FN_ARG_SPLIT = /,/, | |
FN_ARG = /^\s*(_?)(\S+?)\1\s*$/, | |
STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm, | |
$injectorMinErr = minErr("$injector"); | |
function anonFn(fn) { | |
var fnText = fn.toString().replace(STRIP_COMMENTS, ""), | |
args = fnText.match(FN_ARGS); | |
if (args) return "function(" + (args[1] || "").replace(/[\s\r\n]+/, " ") + ")"; | |
return "fn" | |
} | |
function annotate(fn, strictDi, name) { | |
var $inject, fnText, argDecl, last; | |
if ("function" == typeof fn) { | |
if (!($inject = fn.$inject)) { | |
if ($inject = [], fn.length) { | |
if (strictDi) throw isString(name) && name || (name = fn.name || anonFn(fn)), $injectorMinErr("strictdi", "{0} is not using explicit annotation and cannot be invoked in strict mode", name); | |
fnText = fn.toString().replace(STRIP_COMMENTS, ""), argDecl = fnText.match(FN_ARGS), forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) { | |
arg.replace(FN_ARG, function(all, underscore, name) { | |
$inject.push(name) | |
}) | |
}) | |
} | |
fn.$inject = $inject | |
} | |
} else isArray(fn) ? (last = fn.length - 1, assertArgFn(fn[last], "fn"), $inject = fn.slice(0, last)) : assertArgFn(fn, "fn", !0); | |
return $inject | |
} | |
function createInjector(modulesToLoad, strictDi) { | |
strictDi = strictDi === !0; | |
var INSTANTIATING = {}, | |
providerSuffix = "Provider", | |
path = [], | |
loadedModules = new HashMap([], !0), | |
providerCache = { | |
$provide: { | |
provider: supportObject(provider), | |
factory: supportObject(factory), | |
service: supportObject(service), | |
value: supportObject(value), | |
constant: supportObject(constant), | |
decorator: decorator | |
} | |
}, | |
providerInjector = providerCache.$injector = createInternalInjector(providerCache, function(serviceName, caller) { | |
throw angular.isString(caller) && path.push(caller), $injectorMinErr("unpr", "Unknown provider: {0}", path.join(" <- ")) | |
}), | |
instanceCache = {}, | |
instanceInjector = instanceCache.$injector = createInternalInjector(instanceCache, function(serviceName, caller) { | |
var provider = providerInjector.get(serviceName + providerSuffix, caller); | |
return instanceInjector.invoke(provider.$get, provider, undefined, serviceName) | |
}); | |
return forEach(loadModules(modulesToLoad), function(fn) { | |
instanceInjector.invoke(fn || noop) | |
}), instanceInjector; | |
function supportObject(delegate) { | |
return function(key, value) { | |
if (!isObject(key)) return delegate(key, value); | |
forEach(key, reverseParams(delegate)) | |
} | |
} | |
function provider(name, provider_) { | |
if (assertNotHasOwnProperty(name, "service"), (isFunction(provider_) || isArray(provider_)) && (provider_ = providerInjector.instantiate(provider_)), !provider_.$get) throw $injectorMinErr("pget", "Provider '{0}' must define $get factory method.", name); | |
return providerCache[name + providerSuffix] = provider_ | |
} | |
function enforceReturnValue(name, factory) { | |
return function() { | |
var result = instanceInjector.invoke(factory, this); | |
if (isUndefined(result)) throw $injectorMinErr("undef", "Provider '{0}' must return a value from $get factory method.", name); | |
return result | |
} | |
} | |
function factory(name, factoryFn, enforce) { | |
return provider(name, { | |
$get: enforce !== !1 ? enforceReturnValue(name, factoryFn) : factoryFn | |
}) | |
} | |
function service(name, constructor) { | |
return factory(name, ["$injector", function($injector) { | |
return $injector.instantiate(constructor) | |
}]) | |
} | |
function value(name, val) { | |
return factory(name, valueFn(val), !1) | |
} | |
function constant(name, value) { | |
assertNotHasOwnProperty(name, "constant"), providerCache[name] = value, instanceCache[name] = value | |
} | |
function decorator(serviceName, decorFn) { | |
var origProvider = providerInjector.get(serviceName + providerSuffix), | |
orig$get = origProvider.$get; | |
origProvider.$get = function() { | |
var origInstance = instanceInjector.invoke(orig$get, origProvider); | |
return instanceInjector.invoke(decorFn, null, { | |
$delegate: origInstance | |
}) | |
} | |
} | |
function loadModules(modulesToLoad) { | |
var moduleFn, runBlocks = []; | |
return forEach(modulesToLoad, function(module) { | |
if (loadedModules.get(module)) return; | |
loadedModules.put(module, !0); | |
function runInvokeQueue(queue) { | |
var i, ii; | |
for (i = 0, ii = queue.length; ii > i; i++) { | |
var invokeArgs = queue[i], | |
provider = providerInjector.get(invokeArgs[0]); | |
provider[invokeArgs[1]].apply(provider, invokeArgs[2]) | |
} | |
} | |
try { | |
isString(module) ? (moduleFn = angularModule(module), runBlocks = runBlocks.concat(loadModules(moduleFn.requires)).concat(moduleFn._runBlocks), runInvokeQueue(moduleFn._invokeQueue), runInvokeQueue(moduleFn._configBlocks)) : isFunction(module) ? runBlocks.push(providerInjector.invoke(module)) : isArray(module) ? runBlocks.push(providerInjector.invoke(module)) : assertArgFn(module, "module") | |
} catch (e) { | |
throw isArray(module) && (module = module[module.length - 1]), e.message && e.stack && -1 == e.stack.indexOf(e.message) && (e = e.message + "\n" + e.stack), $injectorMinErr("modulerr", "Failed to instantiate module {0} due to:\n{1}", module, e.stack || e.message || e) | |
} | |
}), runBlocks | |
} | |
function createInternalInjector(cache, factory) { | |
function getService(serviceName, caller) { | |
if (cache.hasOwnProperty(serviceName)) { | |
if (cache[serviceName] === INSTANTIATING) throw $injectorMinErr("cdep", "Circular dependency found: {0}", serviceName + " <- " + path.join(" <- ")); | |
return cache[serviceName] | |
} | |
try { | |
return path.unshift(serviceName), cache[serviceName] = INSTANTIATING, cache[serviceName] = factory(serviceName, caller) | |
} catch (err) { | |
throw cache[serviceName] === INSTANTIATING && delete cache[serviceName], err | |
} finally { | |
path.shift() | |
} | |
} | |
function invoke(fn, self, locals, serviceName) { | |
"string" == typeof locals && (serviceName = locals, locals = null); | |
var length, i, key, args = [], | |
$inject = createInjector.$$annotate(fn, strictDi, serviceName); | |
for (i = 0, length = $inject.length; length > i; i++) { | |
if (key = $inject[i], "string" != typeof key) throw $injectorMinErr("itkn", "Incorrect injection token! Expected service name as string, got {0}", key); | |
args.push(locals && locals.hasOwnProperty(key) ? locals[key] : getService(key, serviceName)) | |
} | |
return isArray(fn) && (fn = fn[length]), fn.apply(self, args) | |
} | |
function instantiate(Type, locals, serviceName) { | |
var instance = Object.create((isArray(Type) ? Type[Type.length - 1] : Type).prototype || null), | |
returnedValue = invoke(Type, instance, locals, serviceName); | |
return isObject(returnedValue) || isFunction(returnedValue) ? returnedValue : instance | |
} | |
return { | |
invoke: invoke, | |
instantiate: instantiate, | |
get: getService, | |
annotate: createInjector.$$annotate, | |
has: function(name) { | |
return providerCache.hasOwnProperty(name + providerSuffix) || cache.hasOwnProperty(name) | |
} | |
} | |
} | |
} | |
createInjector.$$annotate = annotate; | |
function $AnchorScrollProvider() { | |
var autoScrollingEnabled = !0; | |
this.disableAutoScrolling = function() { | |
autoScrollingEnabled = !1 | |
}, this.$get = ["$window", "$location", "$rootScope", function($window, $location, $rootScope) { | |
var document = $window.document; | |
function getFirstAnchor(list) { | |
var result = null; | |
return Array.prototype.some.call(list, function(element) { | |
if ("a" === nodeName_(element)) return result = element, !0 | |
}), result | |
} | |
function getYOffset() { | |
var offset = scroll.yOffset; | |
if (isFunction(offset)) offset = offset(); | |
else if (isElement(offset)) { | |
var elem = offset[0], | |
style = $window.getComputedStyle(elem); | |
offset = "fixed" !== style.position ? 0 : elem.getBoundingClientRect().bottom | |
} else isNumber(offset) || (offset = 0); | |
return offset | |
} | |
function scrollTo(elem) { | |
if (elem) { | |
elem.scrollIntoView(); | |
var offset = getYOffset(); | |
if (offset) { | |
var elemTop = elem.getBoundingClientRect().top; | |
$window.scrollBy(0, elemTop - offset) | |
} | |
} else $window.scrollTo(0, 0) | |
} | |
function scroll(hash) { | |
hash = isString(hash) ? hash : $location.hash(); | |
var elm; | |
hash ? (elm = document.getElementById(hash)) ? scrollTo(elm) : (elm = getFirstAnchor(document.getElementsByName(hash))) ? scrollTo(elm) : "top" === hash && scrollTo(null) : scrollTo(null) | |
} | |
return autoScrollingEnabled && $rootScope.$watch(function() { | |
return $location.hash() | |
}, function(newVal, oldVal) { | |
if (newVal === oldVal && "" === newVal) return; | |
jqLiteDocumentLoaded(function() { | |
$rootScope.$evalAsync(scroll) | |
}) | |
}), scroll | |
}] | |
} | |
var $animateMinErr = minErr("$animate"), | |
ELEMENT_NODE = 1; | |
function mergeClasses(a, b) { | |
if (!a && !b) return ""; | |
if (!a) return b; | |
if (!b) return a; | |
return isArray(a) && (a = a.join(" ")), isArray(b) && (b = b.join(" ")), a + " " + b | |
} | |
function extractElementNode(element) { | |
for (var i = 0; i < element.length; i++) { | |
var elm = element[i]; | |
if (elm.nodeType === ELEMENT_NODE) return elm | |
} | |
} | |
function splitClasses(classes) { | |
isString(classes) && (classes = classes.split(" ")); | |
var obj = {}; | |
return forEach(classes, function(klass) { | |
klass.length && (obj[klass] = !0) | |
}), obj | |
} | |
var $$CoreAnimateRunnerProvider = function() { | |
this.$get = ["$q", "$$rAF", function($q, $$rAF) { | |
function AnimateRunner() {} | |
return AnimateRunner.all = noop, AnimateRunner.chain = noop, AnimateRunner.prototype = { | |
end: noop, | |
cancel: noop, | |
resume: noop, | |
pause: noop, | |
complete: noop, | |
then: function(pass, fail) { | |
return $q(function(resolve) { | |
$$rAF(function() { | |
resolve() | |
}) | |
}).then(pass, fail) | |
} | |
}, AnimateRunner | |
}] | |
}, | |
$$CoreAnimateQueueProvider = function() { | |
var postDigestQueue = new HashMap, | |
postDigestElements = []; | |
this.$get = ["$$AnimateRunner", "$rootScope", function($$AnimateRunner, $rootScope) { | |
return { | |
enabled: noop, | |
on: noop, | |
off: noop, | |
push: function(element, event, options, domOperation) { | |
return domOperation && domOperation(), options = options || {}, options.from && element.css(options.from), options.to && element.css(options.to), (options.addClass || options.removeClass) && addRemoveClassesPostDigest(element, options.addClass, options.removeClass), new $$AnimateRunner | |
} | |
}; | |
function addRemoveClassesPostDigest(element, add, remove) { | |
var data = postDigestQueue.get(element); | |
if (data || (postDigestQueue.put(element, data = {}), postDigestElements.push(element)), add && forEach(add.split(" "), function(className) { | |
className && (data[className] = !0) | |
}), remove && forEach(remove.split(" "), function(className) { | |
className && (data[className] = !1) | |
}), postDigestElements.length > 1) return; | |
$rootScope.$$postDigest(function() { | |
forEach(postDigestElements, function(element) { | |
var data = postDigestQueue.get(element); | |
if (data) { | |
var existing = splitClasses(element.attr("class")), | |
toAdd = "", | |
toRemove = ""; | |
forEach(data, function(status, className) { | |
var hasClass = !!existing[className]; | |
status !== hasClass && (status ? toAdd += (toAdd.length ? " " : "") + className : toRemove += (toRemove.length ? " " : "") + className) | |
}), forEach(element, function(elm) { | |
toAdd && jqLiteAddClass(elm, toAdd), toRemove && jqLiteRemoveClass(elm, toRemove) | |
}), postDigestQueue.remove(element) | |
} | |
}), postDigestElements.length = 0 | |
}) | |
} | |
}] | |
}, | |
$AnimateProvider = ["$provide", function($provide) { | |
var provider = this; | |
this.$$registeredAnimations = [], this.register = function(name, factory) { | |
if (name && "." !== name.charAt(0)) throw $animateMinErr("notcsel", "Expecting class selector starting with '.' got '{0}'.", name); | |
var key = name + "-animation"; | |
provider.$$registeredAnimations[name.substr(1)] = key, $provide.factory(key, factory) | |
}, this.classNameFilter = function(expression) { | |
return 1 === arguments.length && (this.$$classNameFilter = expression instanceof RegExp ? expression : null), this.$$classNameFilter | |
}, this.$get = ["$$animateQueue", function($$animateQueue) { | |
function domInsert(element, parentElement, afterElement) { | |
if (afterElement) { | |
var afterNode = extractElementNode(afterElement); | |
!afterNode || afterNode.parentNode || afterNode.previousElementSibling || (afterElement = null) | |
} | |
afterElement ? afterElement.after(element) : parentElement.prepend(element) | |
} | |
return { | |
on: $$animateQueue.on, | |
off: $$animateQueue.off, | |
enabled: $$animateQueue.enabled, | |
cancel: function(runner) { | |
runner.cancel && runner.end() | |
}, | |
enter: function(element, parent, after, options) { | |
return parent = parent || after.parent(), domInsert(element, parent, after), $$animateQueue.push(element, "enter", options) | |
}, | |
move: function(element, parent, after, options) { | |
return parent = parent || after.parent(), domInsert(element, parent, after), $$animateQueue.push(element, "move", options) | |
}, | |
leave: function(element, options) { | |
return $$animateQueue.push(element, "leave", options, function() { | |
element.remove() | |
}) | |
}, | |
addClass: function(element, className, options) { | |
return options = options || {}, options.addClass = mergeClasses(options.addclass, className), $$animateQueue.push(element, "addClass", options) | |
}, | |
removeClass: function(element, className, options) { | |
return options = options || {}, options.removeClass = mergeClasses(options.removeClass, className), $$animateQueue.push(element, "removeClass", options) | |
}, | |
setClass: function(element, add, remove, options) { | |
return options = options || {}, options.addClass = mergeClasses(options.addClass, add), options.removeClass = mergeClasses(options.removeClass, remove), $$animateQueue.push(element, "setClass", options) | |
}, | |
animate: function(element, from, to, className, options) { | |
return options = options || {}, options.from = options.from ? extend(options.from, from) : from, options.to = options.to ? extend(options.to, to) : to, className = className || "ng-inline-animate", options.tempClasses = mergeClasses(options.tempClasses, className), $$animateQueue.push(element, "animate", options) | |
} | |
} | |
}] | |
}]; | |
function $$AsyncCallbackProvider() { | |
this.$get = ["$$rAF", "$timeout", function($$rAF, $timeout) { | |
return $$rAF.supported ? function(fn) { | |
return $$rAF(fn) | |
} : function(fn) { | |
return $timeout(fn, 0, !1) | |
} | |
}] | |
} | |
function Browser(window, document, $log, $sniffer) { | |
var self = this, | |
location = (document[0], window.location), | |
history = window.history, | |
setTimeout = window.setTimeout, | |
clearTimeout = window.clearTimeout, | |
pendingDeferIds = {}; | |
self.isMock = !1; | |
var outstandingRequestCount = 0, | |
outstandingRequestCallbacks = []; | |
self.$$completeOutstandingRequest = completeOutstandingRequest, self.$$incOutstandingRequestCount = function() { | |
outstandingRequestCount++ | |
}; | |
function completeOutstandingRequest(fn) { | |
try { | |
fn.apply(null, sliceArgs(arguments, 1)) | |
} finally { | |
if (outstandingRequestCount--, 0 === outstandingRequestCount) | |
for (; outstandingRequestCallbacks.length;) try { | |
outstandingRequestCallbacks.pop()() | |
} catch (e) { | |
$log.error(e) | |
} | |
} | |
} | |
function getHash(url) { | |
var index = url.indexOf("#"); | |
return -1 === index ? "" : url.substr(index + 1) | |
} | |
self.notifyWhenNoOutstandingRequests = function(callback) { | |
0 === outstandingRequestCount ? callback() : outstandingRequestCallbacks.push(callback) | |
}; | |
var cachedState, lastHistoryState, lastBrowserUrl = location.href, | |
baseElement = document.find("base"), | |
reloadLocation = null; | |
cacheState(), lastHistoryState = cachedState, self.url = function(url, replace, state) { | |
if (isUndefined(state) && (state = null), location !== window.location && (location = window.location), history !== window.history && (history = window.history), url) { | |
var sameState = lastHistoryState === state; | |
if (lastBrowserUrl === url && (!$sniffer.history || sameState)) return self; | |
var sameBase = lastBrowserUrl && stripHash(lastBrowserUrl) === stripHash(url); | |
return lastBrowserUrl = url, lastHistoryState = state, !$sniffer.history || sameBase && sameState ? (sameBase || (reloadLocation = url), replace ? location.replace(url) : sameBase ? location.hash = getHash(url) : location.href = url) : (history[replace ? "replaceState" : "pushState"](state, "", url), cacheState(), lastHistoryState = cachedState), self | |
} | |
return reloadLocation || location.href.replace(/%27/g, "'") | |
}, self.state = function() { | |
return cachedState | |
}; | |
var urlChangeListeners = [], | |
urlChangeInit = !1; | |
function cacheStateAndFireUrlChange() { | |
cacheState(), fireUrlChange() | |
} | |
function getCurrentState() { | |
try { | |
return history.state | |
} catch (e) {} | |
} | |
var lastCachedState = null; | |
function cacheState() { | |
cachedState = getCurrentState(), cachedState = isUndefined(cachedState) ? null : cachedState, equals(cachedState, lastCachedState) && (cachedState = lastCachedState), lastCachedState = cachedState | |
} | |
function fireUrlChange() { | |
if (lastBrowserUrl === self.url() && lastHistoryState === cachedState) return; | |
lastBrowserUrl = self.url(), lastHistoryState = cachedState, forEach(urlChangeListeners, function(listener) { | |
listener(self.url(), cachedState) | |
}) | |
} | |
self.onUrlChange = function(callback) { | |
return urlChangeInit || ($sniffer.history && jqLite(window).on("popstate", cacheStateAndFireUrlChange), jqLite(window).on("hashchange", cacheStateAndFireUrlChange), urlChangeInit = !0), urlChangeListeners.push(callback), callback | |
}, self.$$applicationDestroyed = function() { | |
jqLite(window).off("hashchange popstate", cacheStateAndFireUrlChange) | |
}, self.$$checkUrlChange = fireUrlChange, self.baseHref = function() { | |
var href = baseElement.attr("href"); | |
return href ? href.replace(/^(https?\:)?\/\/[^\/]*/, "") : "" | |
}, self.defer = function(fn, delay) { | |
var timeoutId; | |
return outstandingRequestCount++, timeoutId = setTimeout(function() { | |
delete pendingDeferIds[timeoutId], completeOutstandingRequest(fn) | |
}, delay || 0), pendingDeferIds[timeoutId] = !0, timeoutId | |
}, self.defer.cancel = function(deferId) { | |
if (pendingDeferIds[deferId]) return delete pendingDeferIds[deferId], clearTimeout(deferId), completeOutstandingRequest(noop), !0; | |
return !1 | |
} | |
} | |
function $BrowserProvider() { | |
this.$get = ["$window", "$log", "$sniffer", "$document", function($window, $log, $sniffer, $document) { | |
return new Browser($window, $document, $log, $sniffer) | |
}] | |
} | |
function $CacheFactoryProvider() { | |
this.$get = function() { | |
var caches = {}; | |
function cacheFactory(cacheId, options) { | |
if (cacheId in caches) throw minErr("$cacheFactory")("iid", "CacheId '{0}' is already taken!", cacheId); | |
var size = 0, | |
stats = extend({}, options, { | |
id: cacheId | |
}), | |
data = {}, | |
capacity = options && options.capacity || Number.MAX_VALUE, | |
lruHash = {}, | |
freshEnd = null, | |
staleEnd = null; | |
return caches[cacheId] = { | |
put: function(key, value) { | |
if (isUndefined(value)) return; | |
if (capacity < Number.MAX_VALUE) { | |
var lruEntry = lruHash[key] || (lruHash[key] = { | |
key: key | |
}); | |
refresh(lruEntry) | |
} | |
return key in data || size++, data[key] = value, size > capacity && this.remove(staleEnd.key), value | |
}, | |
get: function(key) { | |
if (capacity < Number.MAX_VALUE) { | |
var lruEntry = lruHash[key]; | |
if (!lruEntry) return; | |
refresh(lruEntry) | |
} | |
return data[key] | |
}, | |
remove: function(key) { | |
if (capacity < Number.MAX_VALUE) { | |
var lruEntry = lruHash[key]; | |
if (!lruEntry) return; | |
lruEntry == freshEnd && (freshEnd = lruEntry.p), lruEntry == staleEnd && (staleEnd = lruEntry.n), link(lruEntry.n, lruEntry.p), delete lruHash[key] | |
} | |
delete data[key], size-- | |
}, | |
removeAll: function() { | |
data = {}, size = 0, lruHash = {}, freshEnd = staleEnd = null | |
}, | |
destroy: function() { | |
data = null, stats = null, lruHash = null, delete caches[cacheId] | |
}, | |
info: function() { | |
return extend({}, stats, { | |
size: size | |
}) | |
} | |
}; | |
function refresh(entry) { | |
entry != freshEnd && (staleEnd ? staleEnd == entry && (staleEnd = entry.n) : staleEnd = entry, link(entry.n, entry.p), link(entry, freshEnd), freshEnd = entry, freshEnd.n = null) | |
} | |
function link(nextEntry, prevEntry) { | |
nextEntry != prevEntry && (nextEntry && (nextEntry.p = prevEntry), prevEntry && (prevEntry.n = nextEntry)) | |
} | |
} | |
return cacheFactory.info = function() { | |
var info = {}; | |
return forEach(caches, function(cache, cacheId) { | |
info[cacheId] = cache.info() | |
}), info | |
}, cacheFactory.get = function(cacheId) { | |
return caches[cacheId] | |
}, cacheFactory | |
} | |
} | |
function $TemplateCacheProvider() { | |
this.$get = ["$cacheFactory", function($cacheFactory) { | |
return $cacheFactory("templates") | |
}] | |
} | |
var $compileMinErr = minErr("$compile"); | |
$CompileProvider.$inject = ["$provide", "$$sanitizeUriProvider"]; | |
function $CompileProvider($provide, $$sanitizeUriProvider) { | |
var hasDirectives = {}, | |
Suffix = "Directive", | |
COMMENT_DIRECTIVE_REGEXP = /^\s*directive\:\s*([\w\-]+)\s+(.*)$/, | |
CLASS_DIRECTIVE_REGEXP = /(([\w\-]+)(?:\:([^;]+))?;?)/, | |
ALL_OR_NOTHING_ATTRS = makeMap("ngSrc,ngSrcset,src,srcset"), | |
REQUIRE_PREFIX_REGEXP = /^(?:(\^\^?)?(\?)?(\^\^?)?)?/, | |
EVENT_HANDLER_ATTR_REGEXP = /^(on[a-z]+|formaction)$/; | |
function parseIsolateBindings(scope, directiveName, isController) { | |
var LOCAL_REGEXP = /^\s*([@&]|=(\*?))(\??)\s*(\w*)\s*$/, | |
bindings = {}; | |
return forEach(scope, function(definition, scopeName) { | |
var match = definition.match(LOCAL_REGEXP); | |
if (!match) throw $compileMinErr("iscp", "Invalid {3} for directive '{0}'. Definition: {... {1}: '{2}' ...}", directiveName, scopeName, definition, isController ? "controller bindings definition" : "isolate scope definition"); | |
bindings[scopeName] = { | |
mode: match[1][0], | |
collection: "*" === match[2], | |
optional: "?" === match[3], | |
attrName: match[4] || scopeName | |
} | |
}), bindings | |
} | |
function parseDirectiveBindings(directive, directiveName) { | |
var bindings = { | |
isolateScope: null, | |
bindToController: null | |
}; | |
if (isObject(directive.scope) && (directive.bindToController === !0 ? (bindings.bindToController = parseIsolateBindings(directive.scope, directiveName, !0), bindings.isolateScope = {}) : bindings.isolateScope = parseIsolateBindings(directive.scope, directiveName, !1)), isObject(directive.bindToController) && (bindings.bindToController = parseIsolateBindings(directive.bindToController, directiveName, !0)), isObject(bindings.bindToController)) { | |
var controller = directive.controller, | |
controllerAs = directive.controllerAs; | |
if (!controller) throw $compileMinErr("noctrl", "Cannot bind to controller without directive '{0}'s controller.", directiveName); | |
if (!identifierForController(controller, controllerAs)) throw $compileMinErr("noident", "Cannot bind to controller without identifier for directive '{0}'.", directiveName) | |
} | |
return bindings | |
} | |
function assertValidDirectiveName(name) { | |
var letter = name.charAt(0); | |
if (!letter || letter !== lowercase(letter)) throw $compileMinErr("baddir", "Directive name '{0}' is invalid. The first character must be a lowercase letter", name) | |
} | |
this.directive = function registerDirective(name, directiveFactory) { | |
return assertNotHasOwnProperty(name, "directive"), isString(name) ? (assertValidDirectiveName(name), assertArg(directiveFactory, "directiveFactory"), hasDirectives.hasOwnProperty(name) || (hasDirectives[name] = [], $provide.factory(name + Suffix, ["$injector", "$exceptionHandler", function($injector, $exceptionHandler) { | |
var directives = []; | |
return forEach(hasDirectives[name], function(directiveFactory, index) { | |
try { | |
var directive = $injector.invoke(directiveFactory); | |
isFunction(directive) ? directive = { | |
compile: valueFn(directive) | |
} : !directive.compile && directive.link && (directive.compile = valueFn(directive.link)), directive.priority = directive.priority || 0, directive.index = index, directive.name = directive.name || name, directive.require = directive.require || directive.controller && directive.name, directive.restrict = directive.restrict || "EA"; | |
var bindings = directive.$$bindings = parseDirectiveBindings(directive, directive.name); | |
isObject(bindings.isolateScope) && (directive.$$isolateBindings = bindings.isolateScope), directives.push(directive) | |
} catch (e) { | |
$exceptionHandler(e) | |
} | |
}), directives | |
}])), hasDirectives[name].push(directiveFactory)) : forEach(name, reverseParams(registerDirective)), this | |
}, this.aHrefSanitizationWhitelist = function(regexp) { | |
return isDefined(regexp) ? ($$sanitizeUriProvider.aHrefSanitizationWhitelist(regexp), this) : $$sanitizeUriProvider.aHrefSanitizationWhitelist() | |
}, this.imgSrcSanitizationWhitelist = function(regexp) { | |
return isDefined(regexp) ? ($$sanitizeUriProvider.imgSrcSanitizationWhitelist(regexp), this) : $$sanitizeUriProvider.imgSrcSanitizationWhitelist() | |
}; | |
var debugInfoEnabled = !0; | |
this.debugInfoEnabled = function(enabled) { | |
if (isDefined(enabled)) return debugInfoEnabled = enabled, this; | |
return debugInfoEnabled | |
}, this.$get = ["$injector", "$interpolate", "$exceptionHandler", "$templateRequest", "$parse", "$controller", "$rootScope", "$document", "$sce", "$animate", "$$sanitizeUri", function($injector, $interpolate, $exceptionHandler, $templateRequest, $parse, $controller, $rootScope, $document, $sce, $animate, $$sanitizeUri) { | |
var Attributes = function(element, attributesToCopy) { | |
if (attributesToCopy) { | |
var i, l, key, keys = Object.keys(attributesToCopy); | |
for (i = 0, l = keys.length; l > i; i++) key = keys[i], this[key] = attributesToCopy[key] | |
} else this.$attr = {}; | |
this.$$element = element | |
}; | |
Attributes.prototype = { | |
$normalize: directiveNormalize, | |
$addClass: function(classVal) { | |
classVal && classVal.length > 0 && $animate.addClass(this.$$element, classVal) | |
}, | |
$removeClass: function(classVal) { | |
classVal && classVal.length > 0 && $animate.removeClass(this.$$element, classVal) | |
}, | |
$updateClass: function(newClasses, oldClasses) { | |
var toAdd = tokenDifference(newClasses, oldClasses); | |
toAdd && toAdd.length && $animate.addClass(this.$$element, toAdd); | |
var toRemove = tokenDifference(oldClasses, newClasses); | |
toRemove && toRemove.length && $animate.removeClass(this.$$element, toRemove) | |
}, | |
$set: function(key, value, writeAttr, attrName) { | |
var nodeName, node = this.$$element[0], | |
booleanKey = getBooleanAttrName(node, key), | |
aliasedKey = getAliasedAttrName(node, key), | |
observer = key; | |
if (booleanKey ? (this.$$element.prop(key, value), attrName = booleanKey) : aliasedKey && (this[aliasedKey] = value, observer = aliasedKey), this[key] = value, attrName ? this.$attr[key] = attrName : (attrName = this.$attr[key], attrName || (this.$attr[key] = attrName = snake_case(key, "-"))), nodeName = nodeName_(this.$$element), "a" === nodeName && "href" === key || "img" === nodeName && "src" === key) this[key] = value = $$sanitizeUri(value, "src" === key); | |
else if ("img" === nodeName && "srcset" === key) { | |
for (var result = "", trimmedSrcset = trim(value), srcPattern = /(\s+\d+x\s*,|\s+\d+w\s*,|\s+,|,\s+)/, pattern = /\s/.test(trimmedSrcset) ? srcPattern : /(,)/, rawUris = trimmedSrcset.split(pattern), nbrUrisWith2parts = Math.floor(rawUris.length / 2), i = 0; nbrUrisWith2parts > i; i++) { | |
var innerIdx = 2 * i; | |
result += $$sanitizeUri(trim(rawUris[innerIdx]), !0), result += " " + trim(rawUris[innerIdx + 1]) | |
} | |
var lastTuple = trim(rawUris[2 * i]).split(/\s/); | |
result += $$sanitizeUri(trim(lastTuple[0]), !0), 2 === lastTuple.length && (result += " " + trim(lastTuple[1])), this[key] = value = result | |
} | |
writeAttr !== !1 && (null === value || value === undefined ? this.$$element.removeAttr(attrName) : this.$$element.attr(attrName, value)); | |
var $$observers = this.$$observers; | |
$$observers && forEach($$observers[observer], function(fn) { | |
try { | |
fn(value) | |
} catch (e) { | |
$exceptionHandler(e) | |
} | |
}) | |
}, | |
$observe: function(key, fn) { | |
var attrs = this, | |
$$observers = attrs.$$observers || (attrs.$$observers = createMap()), | |
listeners = $$observers[key] || ($$observers[key] = []); | |
return listeners.push(fn), $rootScope.$evalAsync(function() { | |
!listeners.$$inter && attrs.hasOwnProperty(key) && fn(attrs[key]) | |
}), | |
function() { | |
arrayRemove(listeners, fn) | |
} | |
} | |
}; | |
function safeAddClass($element, className) { | |
try { | |
$element.addClass(className) | |
} catch (e) {} | |
} | |
var startSymbol = $interpolate.startSymbol(), | |
endSymbol = $interpolate.endSymbol(), | |
denormalizeTemplate = "{{" == startSymbol || "}}" == endSymbol ? identity : function(template) { | |
return template.replace(/\{\{/g, startSymbol).replace(/}}/g, endSymbol); | |
}, | |
NG_ATTR_BINDING = /^ngAttr[A-Z]/; | |
return compile.$$addBindingInfo = debugInfoEnabled ? function($element, binding) { | |
var bindings = $element.data("$binding") || []; | |
isArray(binding) ? bindings = bindings.concat(binding) : bindings.push(binding), $element.data("$binding", bindings) | |
} : noop, compile.$$addBindingClass = debugInfoEnabled ? function($element) { | |
safeAddClass($element, "ng-binding") | |
} : noop, compile.$$addScopeInfo = debugInfoEnabled ? function($element, scope, isolated, noTemplate) { | |
var dataName = isolated ? noTemplate ? "$isolateScopeNoTemplate" : "$isolateScope" : "$scope"; | |
$element.data(dataName, scope) | |
} : noop, compile.$$addScopeClass = debugInfoEnabled ? function($element, isolated) { | |
safeAddClass($element, isolated ? "ng-isolate-scope" : "ng-scope") | |
} : noop, compile; | |
function compile($compileNodes, transcludeFn, maxPriority, ignoreDirective, previousCompileContext) { | |
$compileNodes instanceof jqLite || ($compileNodes = jqLite($compileNodes)), forEach($compileNodes, function(node, index) { | |
node.nodeType == NODE_TYPE_TEXT && node.nodeValue.match(/\S+/) && ($compileNodes[index] = jqLite(node).wrap("<span></span>").parent()[0]) | |
}); | |
var compositeLinkFn = compileNodes($compileNodes, transcludeFn, $compileNodes, maxPriority, ignoreDirective, previousCompileContext); | |
compile.$$addScopeClass($compileNodes); | |
var namespace = null; | |
return function(scope, cloneConnectFn, options) { | |
assertArg(scope, "scope"), options = options || {}; | |
var parentBoundTranscludeFn = options.parentBoundTranscludeFn, | |
transcludeControllers = options.transcludeControllers, | |
futureParentElement = options.futureParentElement; | |
parentBoundTranscludeFn && parentBoundTranscludeFn.$$boundTransclude && (parentBoundTranscludeFn = parentBoundTranscludeFn.$$boundTransclude), namespace || (namespace = detectNamespaceForChildElements(futureParentElement)); | |
var $linkNode; | |
if ($linkNode = "html" !== namespace ? jqLite(wrapTemplate(namespace, jqLite("<div>").append($compileNodes).html())) : cloneConnectFn ? JQLitePrototype.clone.call($compileNodes) : $compileNodes, transcludeControllers) | |
for (var controllerName in transcludeControllers) $linkNode.data("$" + controllerName + "Controller", transcludeControllers[controllerName].instance); | |
return compile.$$addScopeInfo($linkNode, scope), cloneConnectFn && cloneConnectFn($linkNode, scope), compositeLinkFn && compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn), $linkNode | |
} | |
} | |
function detectNamespaceForChildElements(parentElement) { | |
var node = parentElement && parentElement[0]; | |
return node && "foreignobject" !== nodeName_(node) && node.toString().match(/SVG/) ? "svg" : "html" | |
} | |
function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective, previousCompileContext) { | |
for (var attrs, directives, nodeLinkFn, childNodes, childLinkFn, linkFnFound, nodeLinkFnFound, linkFns = [], i = 0; i < nodeList.length; i++) attrs = new Attributes, directives = collectDirectives(nodeList[i], [], attrs, 0 === i ? maxPriority : undefined, ignoreDirective), nodeLinkFn = directives.length ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement, null, [], [], previousCompileContext) : null, nodeLinkFn && nodeLinkFn.scope && compile.$$addScopeClass(attrs.$$element), childLinkFn = nodeLinkFn && nodeLinkFn.terminal || !(childNodes = nodeList[i].childNodes) || !childNodes.length ? null : compileNodes(childNodes, nodeLinkFn ? (nodeLinkFn.transcludeOnThisElement || !nodeLinkFn.templateOnThisElement) && nodeLinkFn.transclude : transcludeFn), (nodeLinkFn || childLinkFn) && (linkFns.push(i, nodeLinkFn, childLinkFn), linkFnFound = !0, nodeLinkFnFound = nodeLinkFnFound || nodeLinkFn), previousCompileContext = null; | |
return linkFnFound ? compositeLinkFn : null; | |
function compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) { | |
var nodeLinkFn, childLinkFn, node, childScope, i, ii, idx, childBoundTranscludeFn, stableNodeList; | |
if (nodeLinkFnFound) { | |
var nodeListLength = nodeList.length; | |
for (stableNodeList = new Array(nodeListLength), i = 0; i < linkFns.length; i += 3) idx = linkFns[i], stableNodeList[idx] = nodeList[idx] | |
} else stableNodeList = nodeList; | |
for (i = 0, ii = linkFns.length; ii > i;) | |
if (node = stableNodeList[linkFns[i++]], nodeLinkFn = linkFns[i++], childLinkFn = linkFns[i++], nodeLinkFn) { | |
if (nodeLinkFn.scope) { | |
childScope = scope.$new(), compile.$$addScopeInfo(jqLite(node), childScope); | |
var destroyBindings = nodeLinkFn.$$destroyBindings; | |
destroyBindings && (nodeLinkFn.$$destroyBindings = null, childScope.$on("$destroyed", destroyBindings)) | |
} else childScope = scope; | |
childBoundTranscludeFn = nodeLinkFn.transcludeOnThisElement ? createBoundTranscludeFn(scope, nodeLinkFn.transclude, parentBoundTranscludeFn, nodeLinkFn.elementTranscludeOnThisElement) : !nodeLinkFn.templateOnThisElement && parentBoundTranscludeFn ? parentBoundTranscludeFn : !parentBoundTranscludeFn && transcludeFn ? createBoundTranscludeFn(scope, transcludeFn) : null, nodeLinkFn(childLinkFn, childScope, node, $rootElement, childBoundTranscludeFn, nodeLinkFn) | |
} else childLinkFn && childLinkFn(scope, node.childNodes, undefined, parentBoundTranscludeFn) | |
} | |
} | |
function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn, elementTransclusion) { | |
var boundTranscludeFn = function(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) { | |
return transcludedScope || (transcludedScope = scope.$new(!1, containingScope), transcludedScope.$$transcluded = !0), transcludeFn(transcludedScope, cloneFn, { | |
parentBoundTranscludeFn: previousBoundTranscludeFn, | |
transcludeControllers: controllers, | |
futureParentElement: futureParentElement | |
}) | |
}; | |
return boundTranscludeFn | |
} | |
function collectDirectives(node, directives, attrs, maxPriority, ignoreDirective) { | |
var match, className, nodeType = node.nodeType, | |
attrsMap = attrs.$attr; | |
switch (nodeType) { | |
case NODE_TYPE_ELEMENT: | |
addDirective(directives, directiveNormalize(nodeName_(node)), "E", maxPriority, ignoreDirective); | |
for (var attr, name, nName, ngAttrName, value, isNgAttr, nAttrs = node.attributes, j = 0, jj = nAttrs && nAttrs.length; jj > j; j++) { | |
var attrStartName = !1, | |
attrEndName = !1; | |
attr = nAttrs[j], name = attr.name, value = trim(attr.value), ngAttrName = directiveNormalize(name), (isNgAttr = NG_ATTR_BINDING.test(ngAttrName)) && (name = name.replace(PREFIX_REGEXP, "").substr(8).replace(/_(.)/g, function(match, letter) { | |
return letter.toUpperCase() | |
})); | |
var directiveNName = ngAttrName.replace(/(Start|End)$/, ""); | |
directiveIsMultiElement(directiveNName) && ngAttrName === directiveNName + "Start" && (attrStartName = name, attrEndName = name.substr(0, name.length - 5) + "end", name = name.substr(0, name.length - 6)), nName = directiveNormalize(name.toLowerCase()), attrsMap[nName] = name, (isNgAttr || !attrs.hasOwnProperty(nName)) && (attrs[nName] = value, getBooleanAttrName(node, nName) && (attrs[nName] = !0)), addAttrInterpolateDirective(node, directives, value, nName, isNgAttr), addDirective(directives, nName, "A", maxPriority, ignoreDirective, attrStartName, attrEndName) | |
} | |
if (className = node.className, isObject(className) && (className = className.animVal), isString(className) && "" !== className) | |
for (; match = CLASS_DIRECTIVE_REGEXP.exec(className);) nName = directiveNormalize(match[2]), addDirective(directives, nName, "C", maxPriority, ignoreDirective) && (attrs[nName] = trim(match[3])), className = className.substr(match.index + match[0].length); | |
break; | |
case NODE_TYPE_TEXT: | |
addTextInterpolateDirective(directives, node.nodeValue); | |
break; | |
case NODE_TYPE_COMMENT: | |
try { | |
match = COMMENT_DIRECTIVE_REGEXP.exec(node.nodeValue), match && (nName = directiveNormalize(match[1]), addDirective(directives, nName, "M", maxPriority, ignoreDirective) && (attrs[nName] = trim(match[2]))) | |
} catch (e) {} | |
} | |
return directives.sort(byPriority), directives | |
} | |
function groupScan(node, attrStart, attrEnd) { | |
var nodes = [], | |
depth = 0; | |
if (attrStart && node.hasAttribute && node.hasAttribute(attrStart)) { | |
do { | |
if (!node) throw $compileMinErr("uterdir", "Unterminated attribute, found '{0}' but no matching '{1}' found.", attrStart, attrEnd); | |
node.nodeType == NODE_TYPE_ELEMENT && (node.hasAttribute(attrStart) && depth++, node.hasAttribute(attrEnd) && depth--), nodes.push(node), node = node.nextSibling | |
} while (depth > 0) | |
} else nodes.push(node); | |
return jqLite(nodes) | |
} | |
function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) { | |
return function(scope, element, attrs, controllers, transcludeFn) { | |
return element = groupScan(element[0], attrStart, attrEnd), linkFn(scope, element, attrs, controllers, transcludeFn) | |
} | |
} | |
function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn, jqCollection, originalReplaceDirective, preLinkFns, postLinkFns, previousCompileContext) { | |
previousCompileContext = previousCompileContext || {}; | |
for (var newScopeDirective, directive, directiveName, $template, linkFn, directiveValue, terminalPriority = -Number.MAX_VALUE, controllerDirectives = previousCompileContext.controllerDirectives, newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective, templateDirective = previousCompileContext.templateDirective, nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective, hasTranscludeDirective = !1, hasTemplate = !1, hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective, $compileNode = templateAttrs.$$element = jqLite(compileNode), replaceDirective = originalReplaceDirective, childTranscludeFn = transcludeFn, i = 0, ii = directives.length; ii > i; i++) { | |
directive = directives[i]; | |
var attrStart = directive.$$start, | |
attrEnd = directive.$$end; | |
if (attrStart && ($compileNode = groupScan(compileNode, attrStart, attrEnd)), $template = undefined, terminalPriority > directive.priority) break; | |
if ((directiveValue = directive.scope) && (directive.templateUrl || (isObject(directiveValue) ? (assertNoDuplicate("new/isolated scope", newIsolateScopeDirective || newScopeDirective, directive, $compileNode), newIsolateScopeDirective = directive) : assertNoDuplicate("new/isolated scope", newIsolateScopeDirective, directive, $compileNode)), newScopeDirective = newScopeDirective || directive), directiveName = directive.name, !directive.templateUrl && directive.controller && (directiveValue = directive.controller, controllerDirectives = controllerDirectives || createMap(), assertNoDuplicate("'" + directiveName + "' controller", controllerDirectives[directiveName], directive, $compileNode), controllerDirectives[directiveName] = directive), (directiveValue = directive.transclude) && (hasTranscludeDirective = !0, directive.$$tlb || (assertNoDuplicate("transclusion", nonTlbTranscludeDirective, directive, $compileNode), nonTlbTranscludeDirective = directive), "element" == directiveValue ? (hasElementTranscludeDirective = !0, terminalPriority = directive.priority, $template = $compileNode, $compileNode = templateAttrs.$$element = jqLite(document.createComment(" " + directiveName + ": " + templateAttrs[directiveName] + " ")), compileNode = $compileNode[0], replaceWith(jqCollection, sliceArgs($template), compileNode), childTranscludeFn = compile($template, transcludeFn, terminalPriority, replaceDirective && replaceDirective.name, { | |
nonTlbTranscludeDirective: nonTlbTranscludeDirective | |
})) : ($template = jqLite(jqLiteClone(compileNode)).contents(), $compileNode.empty(), childTranscludeFn = compile($template, transcludeFn))), directive.template) | |
if (hasTemplate = !0, assertNoDuplicate("template", templateDirective, directive, $compileNode), templateDirective = directive, directiveValue = isFunction(directive.template) ? directive.template($compileNode, templateAttrs) : directive.template, directiveValue = denormalizeTemplate(directiveValue), directive.replace) { | |
if (replaceDirective = directive, $template = jqLiteIsTextNode(directiveValue) ? [] : removeComments(wrapTemplate(directive.templateNamespace, trim(directiveValue))), compileNode = $template[0], 1 != $template.length || compileNode.nodeType !== NODE_TYPE_ELEMENT) throw $compileMinErr("tplrt", "Template for directive '{0}' must have exactly one root element. {1}", directiveName, ""); | |
replaceWith(jqCollection, $compileNode, compileNode); | |
var newTemplateAttrs = { | |
$attr: {} | |
}, | |
templateDirectives = collectDirectives(compileNode, [], newTemplateAttrs), | |
unprocessedDirectives = directives.splice(i + 1, directives.length - (i + 1)); | |
newIsolateScopeDirective && markDirectivesAsIsolate(templateDirectives), directives = directives.concat(templateDirectives).concat(unprocessedDirectives), mergeTemplateAttributes(templateAttrs, newTemplateAttrs), ii = directives.length | |
} else $compileNode.html(directiveValue); | |
if (directive.templateUrl) hasTemplate = !0, assertNoDuplicate("template", templateDirective, directive, $compileNode), templateDirective = directive, directive.replace && (replaceDirective = directive), nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode, templateAttrs, jqCollection, hasTranscludeDirective && childTranscludeFn, preLinkFns, postLinkFns, { | |
controllerDirectives: controllerDirectives, | |
newIsolateScopeDirective: newIsolateScopeDirective, | |
templateDirective: templateDirective, | |
nonTlbTranscludeDirective: nonTlbTranscludeDirective | |
}), ii = directives.length; | |
else if (directive.compile) try { | |
linkFn = directive.compile($compileNode, templateAttrs, childTranscludeFn), isFunction(linkFn) ? addLinkFns(null, linkFn, attrStart, attrEnd) : linkFn && addLinkFns(linkFn.pre, linkFn.post, attrStart, attrEnd) | |
} catch (e) { | |
$exceptionHandler(e, startingTag($compileNode)) | |
} | |
directive.terminal && (nodeLinkFn.terminal = !0, terminalPriority = Math.max(terminalPriority, directive.priority)) | |
} | |
return nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === !0, nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective, nodeLinkFn.elementTranscludeOnThisElement = hasElementTranscludeDirective, nodeLinkFn.templateOnThisElement = hasTemplate, nodeLinkFn.transclude = childTranscludeFn, previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective, nodeLinkFn; | |
function addLinkFns(pre, post, attrStart, attrEnd) { | |
pre && (attrStart && (pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd)), pre.require = directive.require, pre.directiveName = directiveName, (newIsolateScopeDirective === directive || directive.$$isolateScope) && (pre = cloneAndAnnotateFn(pre, { | |
isolateScope: !0 | |
})), preLinkFns.push(pre)), post && (attrStart && (post = groupElementsLinkFnWrapper(post, attrStart, attrEnd)), post.require = directive.require, post.directiveName = directiveName, (newIsolateScopeDirective === directive || directive.$$isolateScope) && (post = cloneAndAnnotateFn(post, { | |
isolateScope: !0 | |
})), postLinkFns.push(post)) | |
} | |
function getControllers(directiveName, require, $element, elementControllers) { | |
var value; | |
if (isString(require)) { | |
var match = require.match(REQUIRE_PREFIX_REGEXP), | |
name = require.substring(match[0].length), | |
inheritType = match[1] || match[3], | |
optional = "?" === match[2]; | |
if ("^^" === inheritType ? $element = $element.parent() : (value = elementControllers && elementControllers[name], value = value && value.instance), !value) { | |
var dataName = "$" + name + "Controller"; | |
value = inheritType ? $element.inheritedData(dataName) : $element.data(dataName) | |
} | |
if (!value && !optional) throw $compileMinErr("ctreq", "Controller '{0}', required by directive '{1}', can't be found!", name, directiveName) | |
} else if (isArray(require)) { | |
value = []; | |
for (var i = 0, ii = require.length; ii > i; i++) value[i] = getControllers(directiveName, require[i], $element, elementControllers) | |
} | |
return value || null | |
} | |
function setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope) { | |
var elementControllers = createMap(); | |
for (var controllerKey in controllerDirectives) { | |
var directive = controllerDirectives[controllerKey], | |
locals = { | |
$scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope, | |
$element: $element, | |
$attrs: attrs, | |
$transclude: transcludeFn | |
}, | |
controller = directive.controller; | |
"@" == controller && (controller = attrs[directive.name]); | |
var controllerInstance = $controller(controller, locals, !0, directive.controllerAs); | |
elementControllers[directive.name] = controllerInstance, hasElementTranscludeDirective || $element.data("$" + directive.name + "Controller", controllerInstance.instance) | |
} | |
return elementControllers | |
} | |
function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn, thisLinkFn) { | |
var i, ii, linkFn, controller, isolateScope, elementControllers, transcludeFn, $element, attrs; | |
if (compileNode === linkNode ? (attrs = templateAttrs, $element = templateAttrs.$$element) : ($element = jqLite(linkNode), attrs = new Attributes($element, templateAttrs)), newIsolateScopeDirective && (isolateScope = scope.$new(!0)), boundTranscludeFn && (transcludeFn = controllersBoundTransclude, transcludeFn.$$boundTransclude = boundTranscludeFn), controllerDirectives && (elementControllers = setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope)), newIsolateScopeDirective && (compile.$$addScopeInfo($element, isolateScope, !0, !(templateDirective && (templateDirective === newIsolateScopeDirective || templateDirective === newIsolateScopeDirective.$$originalDirective))), compile.$$addScopeClass($element, !0), isolateScope.$$isolateBindings = newIsolateScopeDirective.$$isolateBindings, initializeDirectiveBindings(scope, attrs, isolateScope, isolateScope.$$isolateBindings, newIsolateScopeDirective, isolateScope)), elementControllers) { | |
var bindings, controllerForBindings, scopeDirective = newIsolateScopeDirective || newScopeDirective; | |
scopeDirective && elementControllers[scopeDirective.name] && (bindings = scopeDirective.$$bindings.bindToController, controller = elementControllers[scopeDirective.name], controller && controller.identifier && bindings && (controllerForBindings = controller, thisLinkFn.$$destroyBindings = initializeDirectiveBindings(scope, attrs, controller.instance, bindings, scopeDirective))); | |
for (i in elementControllers) { | |
controller = elementControllers[i]; | |
var controllerResult = controller(); | |
controllerResult !== controller.instance && (controller.instance = controllerResult, $element.data("$" + directive.name + "Controller", controllerResult), controller === controllerForBindings && (thisLinkFn.$$destroyBindings(), thisLinkFn.$$destroyBindings = initializeDirectiveBindings(scope, attrs, controllerResult, bindings, scopeDirective))) | |
} | |
} | |
for (i = 0, ii = preLinkFns.length; ii > i; i++) linkFn = preLinkFns[i], invokeLinkFn(linkFn, linkFn.isolateScope ? isolateScope : scope, $element, attrs, linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers), transcludeFn); | |
var scopeToChild = scope; | |
for (newIsolateScopeDirective && (newIsolateScopeDirective.template || null === newIsolateScopeDirective.templateUrl) && (scopeToChild = isolateScope), childLinkFn && childLinkFn(scopeToChild, linkNode.childNodes, undefined, boundTranscludeFn), i = postLinkFns.length - 1; i >= 0; i--) linkFn = postLinkFns[i], invokeLinkFn(linkFn, linkFn.isolateScope ? isolateScope : scope, $element, attrs, linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers), transcludeFn); | |
function controllersBoundTransclude(scope, cloneAttachFn, futureParentElement) { | |
var transcludeControllers; | |
return isScope(scope) || (futureParentElement = cloneAttachFn, cloneAttachFn = scope, scope = undefined), hasElementTranscludeDirective && (transcludeControllers = elementControllers), futureParentElement || (futureParentElement = hasElementTranscludeDirective ? $element.parent() : $element), boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild) | |
} | |
} | |
} | |
function markDirectivesAsIsolate(directives) { | |
for (var j = 0, jj = directives.length; jj > j; j++) directives[j] = inherit(directives[j], { | |
$$isolateScope: !0 | |
}) | |
} | |
function addDirective(tDirectives, name, location, maxPriority, ignoreDirective, startAttrName, endAttrName) { | |
if (name === ignoreDirective) return null; | |
var match = null; | |
if (hasDirectives.hasOwnProperty(name)) | |
for (var directive, directives = $injector.get(name + Suffix), i = 0, ii = directives.length; ii > i; i++) try { | |
directive = directives[i], (maxPriority === undefined || maxPriority > directive.priority) && -1 != directive.restrict.indexOf(location) && (startAttrName && (directive = inherit(directive, { | |
$$start: startAttrName, | |
$$end: endAttrName | |
})), tDirectives.push(directive), match = directive) | |
} catch (e) { | |
$exceptionHandler(e) | |
} | |
return match | |
} | |
function directiveIsMultiElement(name) { | |
if (hasDirectives.hasOwnProperty(name)) | |
for (var directive, directives = $injector.get(name + Suffix), i = 0, ii = directives.length; ii > i; i++) | |
if (directive = directives[i], directive.multiElement) return !0; | |
return !1 | |
} | |
function mergeTemplateAttributes(dst, src) { | |
var srcAttr = src.$attr, | |
dstAttr = dst.$attr, | |
$element = dst.$$element; | |
forEach(dst, function(value, key) { | |
"$" != key.charAt(0) && (src[key] && src[key] !== value && (value += ("style" === key ? ";" : " ") + src[key]), dst.$set(key, value, !0, srcAttr[key])) | |
}), forEach(src, function(value, key) { | |
"class" == key ? (safeAddClass($element, value), dst["class"] = (dst["class"] ? dst["class"] + " " : "") + value) : "style" == key ? ($element.attr("style", $element.attr("style") + ";" + value), dst.style = (dst.style ? dst.style + ";" : "") + value) : "$" == key.charAt(0) || dst.hasOwnProperty(key) || (dst[key] = value, dstAttr[key] = srcAttr[key]) | |
}) | |
} | |
function compileTemplateUrl(directives, $compileNode, tAttrs, $rootElement, childTranscludeFn, preLinkFns, postLinkFns, previousCompileContext) { | |
var afterTemplateNodeLinkFn, afterTemplateChildLinkFn, linkQueue = [], | |
beforeTemplateCompileNode = $compileNode[0], | |
origAsyncDirective = directives.shift(), | |
derivedSyncDirective = inherit(origAsyncDirective, { | |
templateUrl: null, | |
transclude: null, | |
replace: null, | |
$$originalDirective: origAsyncDirective | |
}), | |
templateUrl = isFunction(origAsyncDirective.templateUrl) ? origAsyncDirective.templateUrl($compileNode, tAttrs) : origAsyncDirective.templateUrl, | |
templateNamespace = origAsyncDirective.templateNamespace; | |
return $compileNode.empty(), $templateRequest($sce.getTrustedResourceUrl(templateUrl)).then(function(content) { | |
var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn; | |
if (content = denormalizeTemplate(content), origAsyncDirective.replace) { | |
if ($template = jqLiteIsTextNode(content) ? [] : removeComments(wrapTemplate(templateNamespace, trim(content))), compileNode = $template[0], 1 != $template.length || compileNode.nodeType !== NODE_TYPE_ELEMENT) throw $compileMinErr("tplrt", "Template for directive '{0}' must have exactly one root element. {1}", origAsyncDirective.name, templateUrl); | |
tempTemplateAttrs = { | |
$attr: {} | |
}, replaceWith($rootElement, $compileNode, compileNode); | |
var templateDirectives = collectDirectives(compileNode, [], tempTemplateAttrs); | |
isObject(origAsyncDirective.scope) && markDirectivesAsIsolate(templateDirectives), directives = templateDirectives.concat(directives), mergeTemplateAttributes(tAttrs, tempTemplateAttrs) | |
} else compileNode = beforeTemplateCompileNode, $compileNode.html(content); | |
for (directives.unshift(derivedSyncDirective), afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs, childTranscludeFn, $compileNode, origAsyncDirective, preLinkFns, postLinkFns, previousCompileContext), forEach($rootElement, function(node, i) { | |
node == compileNode && ($rootElement[i] = $compileNode[0]) | |
}), afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn); linkQueue.length;) { | |
var scope = linkQueue.shift(), | |
beforeTemplateLinkNode = linkQueue.shift(), | |
linkRootElement = linkQueue.shift(), | |
boundTranscludeFn = linkQueue.shift(), | |
linkNode = $compileNode[0]; | |
if (scope.$$destroyed) continue; | |
if (beforeTemplateLinkNode !== beforeTemplateCompileNode) { | |
var oldClasses = beforeTemplateLinkNode.className; | |
previousCompileContext.hasElementTranscludeDirective && origAsyncDirective.replace || (linkNode = jqLiteClone(compileNode)), replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode), safeAddClass(jqLite(linkNode), oldClasses) | |
} | |
childBoundTranscludeFn = afterTemplateNodeLinkFn.transcludeOnThisElement ? createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn) : boundTranscludeFn, afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement, childBoundTranscludeFn, afterTemplateNodeLinkFn) | |
} | |
linkQueue = null | |
}), | |
function(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) { | |
var childBoundTranscludeFn = boundTranscludeFn; | |
if (scope.$$destroyed) return; | |
linkQueue ? linkQueue.push(scope, node, rootElement, childBoundTranscludeFn) : (afterTemplateNodeLinkFn.transcludeOnThisElement && (childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn)), afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, childBoundTranscludeFn, afterTemplateNodeLinkFn)) | |
} | |
} | |
function byPriority(a, b) { | |
var diff = b.priority - a.priority; | |
if (0 !== diff) return diff; | |
if (a.name !== b.name) return a.name < b.name ? -1 : 1; | |
return a.index - b.index | |
} | |
function assertNoDuplicate(what, previousDirective, directive, element) { | |
if (previousDirective) throw $compileMinErr("multidir", "Multiple directives [{0}, {1}] asking for {2} on: {3}", previousDirective.name, directive.name, what, startingTag(element)) | |
} | |
function addTextInterpolateDirective(directives, text) { | |
var interpolateFn = $interpolate(text, !0); | |
interpolateFn && directives.push({ | |
priority: 0, | |
compile: function(templateNode) { | |
var templateNodeParent = templateNode.parent(), | |
hasCompileParent = !!templateNodeParent.length; | |
return hasCompileParent && compile.$$addBindingClass(templateNodeParent), | |
function(scope, node) { | |
var parent = node.parent(); | |
hasCompileParent || compile.$$addBindingClass(parent), compile.$$addBindingInfo(parent, interpolateFn.expressions), scope.$watch(interpolateFn, function(value) { | |
node[0].nodeValue = value | |
}) | |
} | |
} | |
}) | |
} | |
function wrapTemplate(type, template) { | |
switch (type = lowercase(type || "html")) { | |
case "svg": | |
case "math": | |
var wrapper = document.createElement("div"); | |
return wrapper.innerHTML = "<" + type + ">" + template + "</" + type + ">", wrapper.childNodes[0].childNodes; | |
default: | |
return template | |
} | |
} | |
function getTrustedContext(node, attrNormalizedName) { | |
if ("srcdoc" == attrNormalizedName) return $sce.HTML; | |
var tag = nodeName_(node); | |
if ("xlinkHref" == attrNormalizedName || "form" == tag && "action" == attrNormalizedName || "img" != tag && ("src" == attrNormalizedName || "ngSrc" == attrNormalizedName)) return $sce.RESOURCE_URL | |
} | |
function addAttrInterpolateDirective(node, directives, value, name, allOrNothing) { | |
var trustedContext = getTrustedContext(node, name); | |
allOrNothing = ALL_OR_NOTHING_ATTRS[name] || allOrNothing; | |
var interpolateFn = $interpolate(value, !0, trustedContext, allOrNothing); | |
if (!interpolateFn) return; | |
if ("multiple" === name && "select" === nodeName_(node)) throw $compileMinErr("selmulti", "Binding to the 'multiple' attribute is not supported. Element: {0}", startingTag(node)); | |
directives.push({ | |
priority: 100, | |
compile: function() { | |
return { | |
pre: function(scope, element, attr) { | |
var $$observers = attr.$$observers || (attr.$$observers = {}); | |
if (EVENT_HANDLER_ATTR_REGEXP.test(name)) throw $compileMinErr("nodomevents", "Interpolations for HTML DOM event attributes are disallowed. Please use the ng- versions (such as ng-click instead of onclick) instead."); | |
var newValue = attr[name]; | |
if (newValue !== value && (interpolateFn = newValue && $interpolate(newValue, !0, trustedContext, allOrNothing), value = newValue), !interpolateFn) return; | |
attr[name] = interpolateFn(scope), ($$observers[name] || ($$observers[name] = [])).$$inter = !0, (attr.$$observers && attr.$$observers[name].$$scope || scope).$watch(interpolateFn, function(newValue, oldValue) { | |
"class" === name && newValue != oldValue ? attr.$updateClass(newValue, oldValue) : attr.$set(name, newValue) | |
}) | |
} | |
} | |
} | |
}) | |
} | |
function replaceWith($rootElement, elementsToRemove, newNode) { | |
var i, ii, firstElementToRemove = elementsToRemove[0], | |
removeCount = elementsToRemove.length, | |
parent = firstElementToRemove.parentNode; | |
if ($rootElement) | |
for (i = 0, ii = $rootElement.length; ii > i; i++) | |
if ($rootElement[i] == firstElementToRemove) { | |
$rootElement[i++] = newNode; | |
for (var j = i, j2 = j + removeCount - 1, jj = $rootElement.length; jj > j; j++, j2++) jj > j2 ? $rootElement[j] = $rootElement[j2] : delete $rootElement[j]; | |
$rootElement.length -= removeCount - 1, $rootElement.context === firstElementToRemove && ($rootElement.context = newNode); | |
break | |
} | |
parent && parent.replaceChild(newNode, firstElementToRemove); | |
var fragment = document.createDocumentFragment(); | |
fragment.appendChild(firstElementToRemove), jqLite(newNode).data(jqLite(firstElementToRemove).data()), jQuery ? (skipDestroyOnNextJQueryCleanData = !0, jQuery.cleanData([firstElementToRemove])) : delete jqLite.cache[firstElementToRemove[jqLite.expando]]; | |
for (var k = 1, kk = elementsToRemove.length; kk > k; k++) { | |
var element = elementsToRemove[k]; | |
jqLite(element).remove(), fragment.appendChild(element), delete elementsToRemove[k] | |
} | |
elementsToRemove[0] = newNode, elementsToRemove.length = 1 | |
} | |
function cloneAndAnnotateFn(fn, annotation) { | |
return extend(function() { | |
return fn.apply(null, arguments) | |
}, fn, annotation) | |
} | |
function invokeLinkFn(linkFn, scope, $element, attrs, controllers, transcludeFn) { | |
try { | |
linkFn(scope, $element, attrs, controllers, transcludeFn) | |
} catch (e) { | |
$exceptionHandler(e, startingTag($element)) | |
} | |
} | |
function initializeDirectiveBindings(scope, attrs, destination, bindings, directive, newScope) { | |
var onNewScopeDestroyed; | |
forEach(bindings, function(definition, scopeName) { | |
var lastValue, parentGet, parentSet, compare, attrName = definition.attrName, | |
optional = definition.optional, | |
mode = definition.mode; | |
switch (mode) { | |
case "@": | |
attrs.$observe(attrName, function(value) { | |
destination[scopeName] = value | |
}), attrs.$$observers[attrName].$$scope = scope, attrs[attrName] && (destination[scopeName] = $interpolate(attrs[attrName])(scope)); | |
break; | |
case "=": | |
if (optional && !attrs[attrName]) return; | |
parentGet = $parse(attrs[attrName]), compare = parentGet.literal ? equals : function(a, b) { | |
return a === b || a !== a && b !== b | |
}, parentSet = parentGet.assign || function() { | |
throw lastValue = destination[scopeName] = parentGet(scope), $compileMinErr("nonassign", "Expression '{0}' used with directive '{1}' is non-assignable!", attrs[attrName], directive.name) | |
}, lastValue = destination[scopeName] = parentGet(scope); | |
var parentValueWatch = function(parentValue) { | |
return compare(parentValue, destination[scopeName]) || (compare(parentValue, lastValue) ? parentSet(scope, parentValue = destination[scopeName]) : destination[scopeName] = parentValue), lastValue = parentValue | |
}; | |
parentValueWatch.$stateful = !0; | |
var unwatch; | |
unwatch = definition.collection ? scope.$watchCollection(attrs[attrName], parentValueWatch) : scope.$watch($parse(attrs[attrName], parentValueWatch), null, parentGet.literal), onNewScopeDestroyed = onNewScopeDestroyed || [], onNewScopeDestroyed.push(unwatch); | |
break; | |
case "&": | |
if (!attrs.hasOwnProperty(attrName) && optional) break; | |
if (parentGet = $parse(attrs[attrName]), parentGet === noop && optional) break; | |
destination[scopeName] = function(locals) { | |
return parentGet(scope, locals) | |
} | |
} | |
}); | |
var destroyBindings = onNewScopeDestroyed ? function() { | |
for (var i = 0, ii = onNewScopeDestroyed.length; ii > i; ++i) onNewScopeDestroyed[i]() | |
} : noop; | |
if (newScope && destroyBindings !== noop) return newScope.$on("$destroy", destroyBindings), noop; | |
return destroyBindings | |
} | |
}] | |
} | |
var PREFIX_REGEXP = /^((?:x|data)[\:\-_])/i; | |
function directiveNormalize(name) { | |
return camelCase(name.replace(PREFIX_REGEXP, "")) | |
} | |
function tokenDifference(str1, str2) { | |
var values = "", | |
tokens1 = str1.split(/\s+/), | |
tokens2 = str2.split(/\s+/); | |
outer: for (var i = 0; i < tokens1.length; i++) { | |
for (var token = tokens1[i], j = 0; j < tokens2.length; j++) | |
if (token == tokens2[j]) continue outer; | |
values += (values.length > 0 ? " " : "") + token | |
} | |
return values | |
} | |
function removeComments(jqNodes) { | |
jqNodes = jqLite(jqNodes); | |
var i = jqNodes.length; | |
if (1 >= i) return jqNodes; | |
for (; i--;) { | |
var node = jqNodes[i]; | |
node.nodeType === NODE_TYPE_COMMENT && splice.call(jqNodes, i, 1) | |
} | |
return jqNodes | |
} | |
var $controllerMinErr = minErr("$controller"), | |
CNTRL_REG = /^(\S+)(\s+as\s+(\w+))?$/; | |
function identifierForController(controller, ident) { | |
if (ident && isString(ident)) return ident; | |
if (isString(controller)) { | |
var match = CNTRL_REG.exec(controller); | |
if (match) return match[3] | |
} | |
} | |
function $ControllerProvider() { | |
var controllers = {}, | |
globals = !1; | |
this.register = function(name, constructor) { | |
assertNotHasOwnProperty(name, "controller"), isObject(name) ? extend(controllers, name) : controllers[name] = constructor | |
}, this.allowGlobals = function() { | |
globals = !0 | |
}, this.$get = ["$injector", "$window", function($injector, $window) { | |
return function(expression, locals, later, ident) { | |
var instance, match, constructor, identifier; | |
if (later = later === !0, ident && isString(ident) && (identifier = ident), isString(expression)) { | |
if (match = expression.match(CNTRL_REG), !match) throw $controllerMinErr("ctrlfmt", "Badly formed controller string '{0}'. Must match `__name__ as __id__` or `__name__`.", expression); | |
constructor = match[1], identifier = identifier || match[3], expression = controllers.hasOwnProperty(constructor) ? controllers[constructor] : getter(locals.$scope, constructor, !0) || (globals ? getter($window, constructor, !0) : undefined), assertArgFn(expression, constructor, !0) | |
} | |
if (later) { | |
var controllerPrototype = (isArray(expression) ? expression[expression.length - 1] : expression).prototype; | |
instance = Object.create(controllerPrototype || null), identifier && addIdentifier(locals, identifier, instance, constructor || expression.name); | |
var instantiate; | |
return instantiate = extend(function() { | |
var result = $injector.invoke(expression, instance, locals, constructor); | |
return result !== instance && (isObject(result) || isFunction(result)) && (instance = result, identifier && addIdentifier(locals, identifier, instance, constructor || expression.name)), instance | |
}, { | |
instance: instance, | |
identifier: identifier | |
}) | |
} | |
return instance = $injector.instantiate(expression, locals, constructor), identifier && addIdentifier(locals, identifier, instance, constructor || expression.name), instance | |
}; | |
function addIdentifier(locals, identifier, instance, name) { | |
if (!locals || !isObject(locals.$scope)) throw minErr("$controller")("noscp", "Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`.", name, identifier); | |
locals.$scope[identifier] = instance | |
} | |
}] | |
} | |
function $DocumentProvider() { | |
this.$get = ["$window", function(window) { | |
return jqLite(window.document) | |
}] | |
} | |
function $ExceptionHandlerProvider() { | |
this.$get = ["$log", function($log) { | |
return function(exception, cause) { | |
$log.error.apply($log, arguments) | |
} | |
}] | |
} | |
var APPLICATION_JSON = "application/json", | |
CONTENT_TYPE_APPLICATION_JSON = { | |
"Content-Type": APPLICATION_JSON + ";charset=utf-8" | |
}, | |
JSON_START = /^\[|^\{(?!\{)/, | |
JSON_ENDS = { | |
"[": /]$/, | |
"{": /}$/ | |
}, | |
JSON_PROTECTION_PREFIX = /^\)\]\}',?\n/; | |
function paramSerializerFactory(jQueryMode) { | |
function serializeValue(v) { | |
if (isObject(v)) return isDate(v) ? v.toISOString() : toJson(v); | |
return v | |
} | |
return function(params) { | |
if (!params) return ""; | |
var parts = []; | |
return forEachSorted(params, function(value, key) { | |
if (null === value || isUndefined(value)) return; | |
isArray(value) || isObject(value) && jQueryMode ? forEach(value, function(v, k) { | |
var keySuffix = jQueryMode ? "[" + (isArray(value) ? "" : k) + "]" : ""; | |
parts.push(encodeUriQuery(key + keySuffix) + "=" + encodeUriQuery(serializeValue(v))) | |
}) : parts.push(encodeUriQuery(key) + "=" + encodeUriQuery(serializeValue(value))) | |
}), parts.length > 0 ? parts.join("&") : "" | |
} | |
} | |
function $HttpParamSerializerProvider() { | |
this.$get = function() { | |
return paramSerializerFactory(!1) | |
} | |
} | |
function $HttpParamSerializerJQLikeProvider() { | |
this.$get = function() { | |
return paramSerializerFactory(!0) | |
} | |
} | |
function defaultHttpResponseTransform(data, headers) { | |
if (isString(data)) { | |
var tempData = data.replace(JSON_PROTECTION_PREFIX, "").trim(); | |
if (tempData) { | |
var contentType = headers("Content-Type"); | |
(contentType && 0 === contentType.indexOf(APPLICATION_JSON) || isJsonLike(tempData)) && (data = fromJson(tempData)) | |
} | |
} | |
return data | |
} | |
function isJsonLike(str) { | |
var jsonStart = str.match(JSON_START); | |
return jsonStart && JSON_ENDS[jsonStart[0]].test(str) | |
} | |
function parseHeaders(headers) { | |
var i, parsed = createMap(); | |
function fillInParsed(key, val) { | |
key && (parsed[key] = parsed[key] ? parsed[key] + ", " + val : val) | |
} | |
return isString(headers) ? forEach(headers.split("\n"), function(line) { | |
i = line.indexOf(":"), fillInParsed(lowercase(trim(line.substr(0, i))), trim(line.substr(i + 1))) | |
}) : isObject(headers) && forEach(headers, function(headerVal, headerKey) { | |
fillInParsed(lowercase(headerKey), trim(headerVal)) | |
}), parsed | |
} | |
function headersGetter(headers) { | |
var headersObj; | |
return function(name) { | |
if (headersObj || (headersObj = parseHeaders(headers)), name) { | |
var value = headersObj[lowercase(name)]; | |
return void 0 === value && (value = null), value | |
} | |
return headersObj | |
} | |
} | |
function transformData(data, headers, status, fns) { | |
if (isFunction(fns)) return fns(data, headers, status); | |
return forEach(fns, function(fn) { | |
data = fn(data, headers, status) | |
}), data | |
} | |
function isSuccess(status) { | |
return status >= 200 && 300 > status | |
} | |
function $HttpProvider() { | |
var defaults = this.defaults = { | |
transformResponse: [defaultHttpResponseTransform], | |
transformRequest: [function(d) { | |
return !isObject(d) || isFile(d) || isBlob(d) || isFormData(d) ? d : toJson(d) | |
}], | |
headers: { | |
common: { | |
Accept: "application/json, text/plain, */*" | |
}, | |
post: shallowCopy(CONTENT_TYPE_APPLICATION_JSON), | |
put: shallowCopy(CONTENT_TYPE_APPLICATION_JSON), | |
patch: shallowCopy(CONTENT_TYPE_APPLICATION_JSON) | |
}, | |
xsrfCookieName: "XSRF-TOKEN", | |
xsrfHeaderName: "X-XSRF-TOKEN", | |
paramSerializer: "$httpParamSerializer" | |
}, | |
useApplyAsync = !1; | |
this.useApplyAsync = function(value) { | |
if (isDefined(value)) return useApplyAsync = !!value, this; | |
return useApplyAsync | |
}; | |
var interceptorFactories = this.interceptors = []; | |
this.$get = ["$httpBackend", "$$cookieReader", "$cacheFactory", "$rootScope", "$q", "$injector", function($httpBackend, $$cookieReader, $cacheFactory, $rootScope, $q, $injector) { | |
var defaultCache = $cacheFactory("$http"); | |
defaults.paramSerializer = isString(defaults.paramSerializer) ? $injector.get(defaults.paramSerializer) : defaults.paramSerializer; | |
var reversedInterceptors = []; | |
forEach(interceptorFactories, function(interceptorFactory) { | |
reversedInterceptors.unshift(isString(interceptorFactory) ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory)) | |
}); | |
function $http(requestConfig) { | |
if (!angular.isObject(requestConfig)) throw minErr("$http")("badreq", "Http request configuration must be an object. Received: {0}", requestConfig); | |
var config = extend({ | |
method: "get", | |
transformRequest: defaults.transformRequest, | |
transformResponse: defaults.transformResponse, | |
paramSerializer: defaults.paramSerializer | |
}, requestConfig); | |
config.headers = mergeHeaders(requestConfig), config.method = uppercase(config.method), config.paramSerializer = isString(config.paramSerializer) ? $injector.get(config.paramSerializer) : config.paramSerializer; | |
var serverRequest = function(config) { | |
var headers = config.headers, | |
reqData = transformData(config.data, headersGetter(headers), undefined, config.transformRequest); | |
return isUndefined(reqData) && forEach(headers, function(value, header) { | |
"content-type" === lowercase(header) && delete headers[header] | |
}), isUndefined(config.withCredentials) && !isUndefined(defaults.withCredentials) && (config.withCredentials = defaults.withCredentials), sendReq(config, reqData).then(transformResponse, transformResponse) | |
}, | |
chain = [serverRequest, undefined], | |
promise = $q.when(config); | |
for (forEach(reversedInterceptors, function(interceptor) { | |
(interceptor.request || interceptor.requestError) && chain.unshift(interceptor.request, interceptor.requestError), (interceptor.response || interceptor.responseError) && chain.push(interceptor.response, interceptor.responseError) | |
}); chain.length;) { | |
var thenFn = chain.shift(), | |
rejectFn = chain.shift(); | |
promise = promise.then(thenFn, rejectFn) | |
} | |
return promise.success = function(fn) { | |
return assertArgFn(fn, "fn"), promise.then(function(response) { | |
fn(response.data, response.status, response.headers, config) | |
}), promise | |
}, promise.error = function(fn) { | |
return assertArgFn(fn, "fn"), promise.then(null, function(response) { | |
fn(response.data, response.status, response.headers, config) | |
}), promise | |
}, promise; | |
function transformResponse(response) { | |
var resp = extend({}, response); | |
return response.data ? resp.data = transformData(response.data, response.headers, response.status, config.transformResponse) : resp.data = response.data, isSuccess(response.status) ? resp : $q.reject(resp) | |
} | |
function executeHeaderFns(headers, config) { | |
var headerContent, processedHeaders = {}; | |
return forEach(headers, function(headerFn, header) { | |
isFunction(headerFn) ? (headerContent = headerFn(config), null != headerContent && (processedHeaders[header] = headerContent)) : processedHeaders[header] = headerFn | |
}), processedHeaders | |
} | |
function mergeHeaders(config) { | |
var defHeaderName, lowercaseDefHeaderName, reqHeaderName, defHeaders = defaults.headers, | |
reqHeaders = extend({}, config.headers); | |
defHeaders = extend({}, defHeaders.common, defHeaders[lowercase(config.method)]); | |
defaultHeadersIteration: for (defHeaderName in defHeaders) { | |
lowercaseDefHeaderName = lowercase(defHeaderName); | |
for (reqHeaderName in reqHeaders) | |
if (lowercase(reqHeaderName) === lowercaseDefHeaderName) continue defaultHeadersIteration; | |
reqHeaders[defHeaderName] = defHeaders[defHeaderName] | |
} | |
return executeHeaderFns(reqHeaders, shallowCopy(config)) | |
} | |
} | |
return $http.pendingRequests = [], createShortMethods("get", "delete", "head", "jsonp"), createShortMethodsWithData("post", "put", "patch"), $http.defaults = defaults, $http; | |
function createShortMethods(names) { | |
forEach(arguments, function(name) { | |
$http[name] = function(url, config) { | |
return $http(extend(config || {}, { | |
method: name, | |
url: url | |
})) | |
} | |
}) | |
} | |
function createShortMethodsWithData(name) { | |
forEach(arguments, function(name) { | |
$http[name] = function(url, data, config) { | |
return $http(extend(config || {}, { | |
method: name, | |
url: url, | |
data: data | |
})) | |
} | |
}) | |
} | |
function sendReq(config, reqData) { | |
var cache, cachedResp, deferred = $q.defer(), | |
promise = deferred.promise, | |
reqHeaders = config.headers, | |
url = buildUrl(config.url, config.paramSerializer(config.params)); | |
if ($http.pendingRequests.push(config), promise.then(removePendingReq, removePendingReq), !config.cache && !defaults.cache || config.cache === !1 || "GET" !== config.method && "JSONP" !== config.method || (cache = isObject(config.cache) ? config.cache : isObject(defaults.cache) ? defaults.cache : defaultCache), cache && (cachedResp = cache.get(url), isDefined(cachedResp) ? isPromiseLike(cachedResp) ? cachedResp.then(resolvePromiseWithResult, resolvePromiseWithResult) : isArray(cachedResp) ? resolvePromise(cachedResp[1], cachedResp[0], shallowCopy(cachedResp[2]), cachedResp[3]) : resolvePromise(cachedResp, 200, {}, "OK") : cache.put(url, promise)), isUndefined(cachedResp)) { | |
var xsrfValue = urlIsSameOrigin(config.url) ? $$cookieReader()[config.xsrfCookieName || defaults.xsrfCookieName] : undefined; | |
xsrfValue && (reqHeaders[config.xsrfHeaderName || defaults.xsrfHeaderName] = xsrfValue), $httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout, config.withCredentials, config.responseType) | |
} | |
return promise; | |
function done(status, response, headersString, statusText) { | |
cache && (isSuccess(status) ? cache.put(url, [status, response, parseHeaders(headersString), statusText]) : cache.remove(url)); | |
function resolveHttpPromise() { | |
resolvePromise(response, status, headersString, statusText) | |
} | |
useApplyAsync ? $rootScope.$applyAsync(resolveHttpPromise) : (resolveHttpPromise(), $rootScope.$$phase || $rootScope.$apply()) | |
} | |
function resolvePromise(response, status, headers, statusText) { | |
status = Math.max(status, 0), (isSuccess(status) ? deferred.resolve : deferred.reject)({ | |
data: response, | |
status: status, | |
headers: headersGetter(headers), | |
config: config, | |
statusText: statusText | |
}) | |
} | |
function resolvePromiseWithResult(result) { | |
resolvePromise(result.data, result.status, shallowCopy(result.headers()), result.statusText) | |
} | |
function removePendingReq() { | |
var idx = $http.pendingRequests.indexOf(config); - 1 !== idx && $http.pendingRequests.splice(idx, 1) | |
} | |
} | |
function buildUrl(url, serializedParams) { | |
return serializedParams.length > 0 && (url += (-1 == url.indexOf("?") ? "?" : "&") + serializedParams), url | |
} | |
}] | |
} | |
function createXhr() { | |
return new window.XMLHttpRequest | |
} | |
function $HttpBackendProvider() { | |
this.$get = ["$browser", "$window", "$document", function($browser, $window, $document) { | |
return createHttpBackend($browser, createXhr, $browser.defer, $window.angular.callbacks, $document[0]) | |
}] | |
} | |
function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) { | |
return function(method, url, post, callback, headers, timeout, withCredentials, responseType) { | |
if ($browser.$$incOutstandingRequestCount(), url = url || $browser.url(), "jsonp" == lowercase(method)) { | |
var callbackId = "_" + (callbacks.counter++).toString(36); | |
callbacks[callbackId] = function(data) { | |
callbacks[callbackId].data = data, callbacks[callbackId].called = !0 | |
}; | |
var jsonpDone = jsonpReq(url.replace("JSON_CALLBACK", "angular.callbacks." + callbackId), callbackId, function(status, text) { | |
completeRequest(callback, status, callbacks[callbackId].data, "", text), callbacks[callbackId] = noop | |
}) | |
} else { | |
var xhr = createXhr(); | |
xhr.open(method, url, !0), forEach(headers, function(value, key) { | |
isDefined(value) && xhr.setRequestHeader(key, value) | |
}), xhr.onload = function() { | |
var statusText = xhr.statusText || "", | |
response = "response" in xhr ? xhr.response : xhr.responseText, | |
status = 1223 === xhr.status ? 204 : xhr.status; | |
0 === status && (status = response ? 200 : "file" == urlResolve(url).protocol ? 404 : 0), completeRequest(callback, status, response, xhr.getAllResponseHeaders(), statusText) | |
}; | |
var requestError = function() { | |
completeRequest(callback, -1, null, null, "") | |
}; | |
if (xhr.onerror = requestError, xhr.onabort = requestError, withCredentials && (xhr.withCredentials = !0), responseType) try { | |
xhr.responseType = responseType | |
} catch (e) { | |
if ("json" !== responseType) throw e | |
} | |
xhr.send(post || null) | |
} | |
if (timeout > 0) var timeoutId = $browserDefer(timeoutRequest, timeout); | |
else isPromiseLike(timeout) && timeout.then(timeoutRequest); | |
function timeoutRequest() { | |
jsonpDone && jsonpDone(), xhr && xhr.abort() | |
} | |
function completeRequest(callback, status, response, headersString, statusText) { | |
timeoutId !== undefined && $browserDefer.cancel(timeoutId), jsonpDone = xhr = null, callback(status, response, headersString, statusText), $browser.$$completeOutstandingRequest(noop) | |
} | |
}; | |
function jsonpReq(url, callbackId, done) { | |
var script = rawDocument.createElement("script"), | |
callback = null; | |
return script.type = "text/javascript", script.src = url, script.async = !0, callback = function(event) { | |
removeEventListenerFn(script, "load", callback), removeEventListenerFn(script, "error", callback), rawDocument.body.removeChild(script), script = null; | |
var status = -1, | |
text = "unknown"; | |
event && ("load" !== event.type || callbacks[callbackId].called || (event = { | |
type: "error" | |
}), text = event.type, status = "error" === event.type ? 404 : 200), done && done(status, text) | |
}, addEventListenerFn(script, "load", callback), addEventListenerFn(script, "error", callback), rawDocument.body.appendChild(script), callback | |
} | |
} | |
var $interpolateMinErr = angular.$interpolateMinErr = minErr("$interpolate"); | |
$interpolateMinErr.throwNoconcat = function(text) { | |
throw $interpolateMinErr("noconcat", "Error while interpolating: {0}\nStrict Contextual Escaping disallows interpolations that concatenate multiple expressions when a trusted value is required. See http://docs.angularjs.org/api/ng.$sce", text) | |
}, $interpolateMinErr.interr = function(text, err) { | |
return $interpolateMinErr("interr", "Can't interpolate: {0}\n{1}", text, err.toString()) | |
}; | |
function $InterpolateProvider() { | |
var startSymbol = "{{", | |
endSymbol = "}}"; | |
this.startSymbol = function(value) { | |
return value ? (startSymbol = value, this) : startSymbol | |
}, this.endSymbol = function(value) { | |
return value ? (endSymbol = value, this) : endSymbol | |
}, this.$get = ["$parse", "$exceptionHandler", "$sce", function($parse, $exceptionHandler, $sce) { | |
var startSymbolLength = startSymbol.length, | |
endSymbolLength = endSymbol.length, | |
escapedStartRegexp = new RegExp(startSymbol.replace(/./g, escape), "g"), | |
escapedEndRegexp = new RegExp(endSymbol.replace(/./g, escape), "g"); | |
function escape(ch) { | |
return "\\\\\\" + ch | |
} | |
function unescapeText(text) { | |
return text.replace(escapedStartRegexp, startSymbol).replace(escapedEndRegexp, endSymbol) | |
} | |
function stringify(value) { | |
if (null == value) return ""; | |
switch (typeof value) { | |
case "string": | |
break; | |
case "number": | |
value = "" + value; | |
break; | |
default: | |
value = toJson(value) | |
} | |
return value | |
} | |
function $interpolate(text, mustHaveExpression, trustedContext, allOrNothing) { | |
allOrNothing = !!allOrNothing; | |
for (var startIndex, endIndex, exp, index = 0, expressions = [], parseFns = [], textLength = text.length, concat = [], expressionPositions = []; textLength > index;) { | |
if (-1 == (startIndex = text.indexOf(startSymbol, index)) || -1 == (endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength))) { | |
index !== textLength && concat.push(unescapeText(text.substring(index))); | |
break | |
} | |
index !== startIndex && concat.push(unescapeText(text.substring(index, startIndex))), exp = text.substring(startIndex + startSymbolLength, endIndex), expressions.push(exp), parseFns.push($parse(exp, parseStringifyInterceptor)), index = endIndex + endSymbolLength, expressionPositions.push(concat.length), concat.push("") | |
} | |
if (trustedContext && concat.length > 1 && $interpolateMinErr.throwNoconcat(text), !mustHaveExpression || expressions.length) { | |
var compute = function(values) { | |
for (var i = 0, ii = expressions.length; ii > i; i++) { | |
if (allOrNothing && isUndefined(values[i])) return; | |
concat[expressionPositions[i]] = values[i] | |
} | |
return concat.join("") | |
}, | |
getValue = function(value) { | |
return trustedContext ? $sce.getTrusted(trustedContext, value) : $sce.valueOf(value) | |
}; | |
return extend(function(context) { | |
var i = 0, | |
ii = expressions.length, | |
values = new Array(ii); | |
try { | |
for (; ii > i; i++) values[i] = parseFns[i](context); | |
return compute(values) | |
} catch (err) { | |
$exceptionHandler($interpolateMinErr.interr(text, err)) | |
} | |
}, { | |
exp: text, | |
expressions: expressions, | |
$$watchDelegate: function(scope, listener) { | |
var lastValue; | |
return scope.$watchGroup(parseFns, function(values, oldValues) { | |
var currValue = compute(values); | |
isFunction(listener) && listener.call(this, currValue, values !== oldValues ? lastValue : currValue, scope), lastValue = currValue | |
}) | |
} | |
}) | |
} | |
function parseStringifyInterceptor(value) { | |
try { | |
return value = getValue(value), allOrNothing && !isDefined(value) ? value : stringify(value) | |
} catch (err) { | |
$exceptionHandler($interpolateMinErr.interr(text, err)) | |
} | |
} | |
} | |
return $interpolate.startSymbol = function() { | |
return startSymbol | |
}, $interpolate.endSymbol = function() { | |
return endSymbol | |
}, $interpolate | |
}] | |
} | |
function $IntervalProvider() { | |
this.$get = ["$rootScope", "$window", "$q", "$$q", function($rootScope, $window, $q, $$q) { | |
var intervals = {}; | |
function interval(fn, delay, count, invokeApply) { | |
var hasParams = arguments.length > 4, | |
args = hasParams ? sliceArgs(arguments, 4) : [], | |
setInterval = $window.setInterval, | |
clearInterval = $window.clearInterval, | |
iteration = 0, | |
skipApply = isDefined(invokeApply) && !invokeApply, | |
deferred = (skipApply ? $$q : $q).defer(), | |
promise = deferred.promise; | |
return count = isDefined(count) ? count : 0, promise.then(null, null, hasParams ? function() { | |
fn.apply(null, args) | |
} : fn), promise.$$intervalId = setInterval(function() { | |
deferred.notify(iteration++), count > 0 && iteration >= count && (deferred.resolve(iteration), clearInterval(promise.$$intervalId), delete intervals[promise.$$intervalId]), skipApply || $rootScope.$apply() | |
}, delay), intervals[promise.$$intervalId] = deferred, promise | |
} | |
return interval.cancel = function(promise) { | |
if (promise && promise.$$intervalId in intervals) return intervals[promise.$$intervalId].reject("canceled"), $window.clearInterval(promise.$$intervalId), delete intervals[promise.$$intervalId], !0; | |
return !1 | |
}, interval | |
}] | |
} | |
function $LocaleProvider() { | |
this.$get = function() { | |
return { | |
id: "en-us", | |
NUMBER_FORMATS: { | |
DECIMAL_SEP: ".", | |
GROUP_SEP: ",", | |
PATTERNS: [{ | |
minInt: 1, | |
minFrac: 0, | |
maxFrac: 3, | |
posPre: "", | |
posSuf: "", | |
negPre: "-", | |
negSuf: "", | |
gSize: 3, | |
lgSize: 3 | |
}, { | |
minInt: 1, | |
minFrac: 2, | |
maxFrac: 2, | |
posPre: "¤", | |
posSuf: "", | |
negPre: "(¤", | |
negSuf: ")", | |
gSize: 3, | |
lgSize: 3 | |
}], | |
CURRENCY_SYM: "$" | |
}, | |
DATETIME_FORMATS: { | |
MONTH: "January,February,March,April,May,June,July,August,September,October,November,December".split(","), | |
SHORTMONTH: "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","), | |
DAY: "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","), | |
SHORTDAY: "Sun,Mon,Tue,Wed,Thu,Fri,Sat".split(","), | |
AMPMS: ["AM", "PM"], | |
medium: "MMM d, y h:mm:ss a", | |
"short": "M/d/yy h:mm a", | |
fullDate: "EEEE, MMMM d, y", | |
longDate: "MMMM d, y", | |
mediumDate: "MMM d, y", | |
shortDate: "M/d/yy", | |
mediumTime: "h:mm:ss a", | |
shortTime: "h:mm a", | |
ERANAMES: ["Before Christ", "Anno Domini"], | |
ERAS: ["BC", "AD"] | |
}, | |
pluralCat: function(num) { | |
if (1 === num) return "one"; | |
return "other" | |
} | |
} | |
} | |
} | |
var PATH_MATCH = /^([^\?#]*)(\?([^#]*))?(#(.*))?$/, | |
DEFAULT_PORTS = { | |
http: 80, | |
https: 443, | |
ftp: 21 | |
}, | |
$locationMinErr = minErr("$location"); | |
function encodePath(path) { | |
for (var segments = path.split("/"), i = segments.length; i--;) segments[i] = encodeUriSegment(segments[i]); | |
return segments.join("/") | |
} | |
function parseAbsoluteUrl(absoluteUrl, locationObj) { | |
var parsedUrl = urlResolve(absoluteUrl); | |
locationObj.$$protocol = parsedUrl.protocol, locationObj.$$host = parsedUrl.hostname, locationObj.$$port = toInt(parsedUrl.port) || DEFAULT_PORTS[parsedUrl.protocol] || null | |
} | |
function parseAppUrl(relativeUrl, locationObj) { | |
var prefixed = "/" !== relativeUrl.charAt(0); | |
prefixed && (relativeUrl = "/" + relativeUrl); | |
var match = urlResolve(relativeUrl); | |
locationObj.$$path = decodeURIComponent(prefixed && "/" === match.pathname.charAt(0) ? match.pathname.substring(1) : match.pathname), locationObj.$$search = parseKeyValue(match.search), locationObj.$$hash = decodeURIComponent(match.hash), locationObj.$$path && "/" != locationObj.$$path.charAt(0) && (locationObj.$$path = "/" + locationObj.$$path) | |
} | |
function beginsWith(begin, whole) { | |
if (0 === whole.indexOf(begin)) return whole.substr(begin.length) | |
} | |
function stripHash(url) { | |
var index = url.indexOf("#"); | |
return -1 == index ? url : url.substr(0, index) | |
} | |
function trimEmptyHash(url) { | |
return url.replace(/(#.+)|#$/, "$1") | |
} | |
function stripFile(url) { | |
return url.substr(0, stripHash(url).lastIndexOf("/") + 1) | |
} | |
function serverBase(url) { | |
return url.substring(0, url.indexOf("/", url.indexOf("//") + 2)) | |
} | |
function LocationHtml5Url(appBase, basePrefix) { | |
this.$$html5 = !0, basePrefix = basePrefix || ""; | |
var appBaseNoFile = stripFile(appBase); | |
parseAbsoluteUrl(appBase, this), this.$$parse = function(url) { | |
var pathUrl = beginsWith(appBaseNoFile, url); | |
if (!isString(pathUrl)) throw $locationMinErr("ipthprfx", 'Invalid url "{0}", missing path prefix "{1}".', url, appBaseNoFile); | |
parseAppUrl(pathUrl, this), this.$$path || (this.$$path = "/"), this.$$compose() | |
}, this.$$compose = function() { | |
var search = toKeyValue(this.$$search), | |
hash = this.$$hash ? "#" + encodeUriSegment(this.$$hash) : ""; | |
this.$$url = encodePath(this.$$path) + (search ? "?" + search : "") + hash, this.$$absUrl = appBaseNoFile + this.$$url.substr(1) | |
}, this.$$parseLinkUrl = function(url, relHref) { | |
if (relHref && "#" === relHref[0]) return this.hash(relHref.slice(1)), !0; | |
var appUrl, prevAppUrl, rewrittenUrl; | |
return (appUrl = beginsWith(appBase, url)) !== undefined ? (prevAppUrl = appUrl, rewrittenUrl = (appUrl = beginsWith(basePrefix, appUrl)) !== undefined ? appBaseNoFile + (beginsWith("/", appUrl) || appUrl) : appBase + prevAppUrl) : (appUrl = beginsWith(appBaseNoFile, url)) !== undefined ? rewrittenUrl = appBaseNoFile + appUrl : appBaseNoFile == url + "/" && (rewrittenUrl = appBaseNoFile), rewrittenUrl && this.$$parse(rewrittenUrl), !!rewrittenUrl | |
} | |
} | |
function LocationHashbangUrl(appBase, hashPrefix) { | |
var appBaseNoFile = stripFile(appBase); | |
parseAbsoluteUrl(appBase, this), this.$$parse = function(url) { | |
var withoutHashUrl, withoutBaseUrl = beginsWith(appBase, url) || beginsWith(appBaseNoFile, url); | |
"#" === withoutBaseUrl.charAt(0) ? (withoutHashUrl = beginsWith(hashPrefix, withoutBaseUrl), isUndefined(withoutHashUrl) && (withoutHashUrl = withoutBaseUrl)) : withoutHashUrl = this.$$html5 ? withoutBaseUrl : "", parseAppUrl(withoutHashUrl, this), this.$$path = removeWindowsDriveName(this.$$path, withoutHashUrl, appBase), this.$$compose(); | |
function removeWindowsDriveName(path, url, base) { | |
var firstPathSegmentMatch, windowsFilePathExp = /^\/[A-Z]:(\/.*)/; | |
if (0 === url.indexOf(base) && (url = url.replace(base, "")), windowsFilePathExp.exec(url)) return path; | |
return firstPathSegmentMatch = windowsFilePathExp.exec(path), firstPathSegmentMatch ? firstPathSegmentMatch[1] : path | |
} | |
}, this.$$compose = function() { | |
var search = toKeyValue(this.$$search), | |
hash = this.$$hash ? "#" + encodeUriSegment(this.$$hash) : ""; | |
this.$$url = encodePath(this.$$path) + (search ? "?" + search : "") + hash, this.$$absUrl = appBase + (this.$$url ? hashPrefix + this.$$url : "") | |
}, this.$$parseLinkUrl = function(url, relHref) { | |
if (stripHash(appBase) == stripHash(url)) return this.$$parse(url), !0; | |
return !1 | |
} | |
} | |
function LocationHashbangInHtml5Url(appBase, hashPrefix) { | |
this.$$html5 = !0, LocationHashbangUrl.apply(this, arguments); | |
var appBaseNoFile = stripFile(appBase); | |
this.$$parseLinkUrl = function(url, relHref) { | |
if (relHref && "#" === relHref[0]) return this.hash(relHref.slice(1)), !0; | |
var rewrittenUrl, appUrl; | |
return appBase == stripHash(url) ? rewrittenUrl = url : (appUrl = beginsWith(appBaseNoFile, url)) ? rewrittenUrl = appBase + hashPrefix + appUrl : appBaseNoFile === url + "/" && (rewrittenUrl = appBaseNoFile), rewrittenUrl && this.$$parse(rewrittenUrl), !!rewrittenUrl | |
}, this.$$compose = function() { | |
var search = toKeyValue(this.$$search), | |
hash = this.$$hash ? "#" + encodeUriSegment(this.$$hash) : ""; | |
this.$$url = encodePath(this.$$path) + (search ? "?" + search : "") + hash, this.$$absUrl = appBase + hashPrefix + this.$$url | |
} | |
} | |
var locationPrototype = { | |
$$html5: !1, | |
$$replace: !1, | |
absUrl: locationGetter("$$absUrl"), | |
url: function(url) { | |
if (isUndefined(url)) return this.$$url; | |
var match = PATH_MATCH.exec(url); | |
return (match[1] || "" === url) && this.path(decodeURIComponent(match[1])), (match[2] || match[1] || "" === url) && this.search(match[3] || ""), this.hash(match[5] || ""), this | |
}, | |
protocol: locationGetter("$$protocol"), | |
host: locationGetter("$$host"), | |
port: locationGetter("$$port"), | |
path: locationGetterSetter("$$path", function(path) { | |
return path = null !== path ? path.toString() : "", "/" == path.charAt(0) ? path : "/" + path | |
}), | |
search: function(search, paramValue) { | |
switch (arguments.length) { | |
case 0: | |
return this.$$search; | |
case 1: | |
if (isString(search) || isNumber(search)) search = search.toString(), this.$$search = parseKeyValue(search); | |
else { | |
if (!isObject(search)) throw $locationMinErr("isrcharg", "The first argument of the `$location#search()` call must be a string or an object."); | |
search = copy(search, {}), forEach(search, function(value, key) { | |
null == value && delete search[key] | |
}), this.$$search = search | |
} | |
break; | |
default: | |
isUndefined(paramValue) || null === paramValue ? delete this.$$search[search] : this.$$search[search] = paramValue | |
} | |
return this.$$compose(), this | |
}, | |
hash: locationGetterSetter("$$hash", function(hash) { | |
return null !== hash ? hash.toString() : "" | |
}), | |
replace: function() { | |
return this.$$replace = !0, this | |
} | |
}; | |
forEach([LocationHashbangInHtml5Url, LocationHashbangUrl, LocationHtml5Url], function(Location) { | |
Location.prototype = Object.create(locationPrototype), Location.prototype.state = function(state) { | |
if (!arguments.length) return this.$$state; | |
if (Location !== LocationHtml5Url || !this.$$html5) throw $locationMinErr("nostate", "History API state support is available only in HTML5 mode and only in browsers supporting HTML5 History API"); | |
return this.$$state = isUndefined(state) ? null : state, this | |
} | |
}); | |
function locationGetter(property) { | |
return function() { | |
return this[property] | |
} | |
} | |
function locationGetterSetter(property, preprocess) { | |
return function(value) { | |
if (isUndefined(value)) return this[property]; | |
return this[property] = preprocess(value), this.$$compose(), this | |
} | |
} | |
function $LocationProvider() { | |
var hashPrefix = "", | |
html5Mode = { | |
enabled: !1, | |
requireBase: !0, | |
rewriteLinks: !0 | |
}; | |
this.hashPrefix = function(prefix) { | |
return isDefined(prefix) ? (hashPrefix = prefix, this) : hashPrefix | |
}, this.html5Mode = function(mode) { | |
return isBoolean(mode) ? (html5Mode.enabled = mode, this) : isObject(mode) ? (isBoolean(mode.enabled) && (html5Mode.enabled = mode.enabled), isBoolean(mode.requireBase) && (html5Mode.requireBase = mode.requireBase), isBoolean(mode.rewriteLinks) && (html5Mode.rewriteLinks = mode.rewriteLinks), this) : html5Mode | |
}, this.$get = ["$rootScope", "$browser", "$sniffer", "$rootElement", "$window", function($rootScope, $browser, $sniffer, $rootElement, $window) { | |
var $location, LocationMode, appBase, baseHref = $browser.baseHref(), | |
initialUrl = $browser.url(); | |
if (html5Mode.enabled) { | |
if (!baseHref && html5Mode.requireBase) throw $locationMinErr("nobase", "$location in HTML5 mode requires a <base> tag to be present!"); | |
appBase = serverBase(initialUrl) + (baseHref || "/"), LocationMode = $sniffer.history ? LocationHtml5Url : LocationHashbangInHtml5Url | |
} else appBase = stripHash(initialUrl), LocationMode = LocationHashbangUrl; | |
$location = new LocationMode(appBase, "#" + hashPrefix), $location.$$parseLinkUrl(initialUrl, initialUrl), $location.$$state = $browser.state(); | |
var IGNORE_URI_REGEXP = /^\s*(javascript|mailto):/i; | |
function setBrowserUrlWithFallback(url, replace, state) { | |
var oldUrl = $location.url(), | |
oldState = $location.$$state; | |
try { | |
$browser.url(url, replace, state), $location.$$state = $browser.state() | |
} catch (e) { | |
throw $location.url(oldUrl), $location.$$state = oldState, e | |
} | |
} | |
$rootElement.on("click", function(event) { | |
if (!html5Mode.rewriteLinks || event.ctrlKey || event.metaKey || event.shiftKey || 2 == event.which || 2 == event.button) return; | |
for (var elm = jqLite(event.target); | |
"a" !== nodeName_(elm[0]);) | |
if (elm[0] === $rootElement[0] || !(elm = elm.parent())[0]) return; | |
var absHref = elm.prop("href"), | |
relHref = elm.attr("href") || elm.attr("xlink:href"); | |
if (isObject(absHref) && "[object SVGAnimatedString]" === absHref.toString() && (absHref = urlResolve(absHref.animVal).href), IGNORE_URI_REGEXP.test(absHref)) return; | |
!absHref || elm.attr("target") || event.isDefaultPrevented() || $location.$$parseLinkUrl(absHref, relHref) && (event.preventDefault(), $location.absUrl() != $browser.url() && ($rootScope.$apply(), $window.angular["ff-684208-preventDefault"] = !0)) | |
}), trimEmptyHash($location.absUrl()) != trimEmptyHash(initialUrl) && $browser.url($location.absUrl(), !0); | |
var initializing = !0; | |
return $browser.onUrlChange(function(newUrl, newState) { | |
$rootScope.$evalAsync(function() { | |
var defaultPrevented, oldUrl = $location.absUrl(), | |
oldState = $location.$$state; | |
if ($location.$$parse(newUrl), $location.$$state = newState, defaultPrevented = $rootScope.$broadcast("$locationChangeStart", newUrl, oldUrl, newState, oldState).defaultPrevented, $location.absUrl() !== newUrl) return; | |
defaultPrevented ? ($location.$$parse(oldUrl), $location.$$state = oldState, setBrowserUrlWithFallback(oldUrl, !1, oldState)) : (initializing = !1, afterLocationChange(oldUrl, oldState)) | |
}), $rootScope.$$phase || $rootScope.$digest() | |
}), $rootScope.$watch(function() { | |
var oldUrl = trimEmptyHash($browser.url()), | |
newUrl = trimEmptyHash($location.absUrl()), | |
oldState = $browser.state(), | |
currentReplace = $location.$$replace, | |
urlOrStateChanged = oldUrl !== newUrl || $location.$$html5 && $sniffer.history && oldState !== $location.$$state; | |
(initializing || urlOrStateChanged) && (initializing = !1, $rootScope.$evalAsync(function() { | |
var newUrl = $location.absUrl(), | |
defaultPrevented = $rootScope.$broadcast("$locationChangeStart", newUrl, oldUrl, $location.$$state, oldState).defaultPrevented; | |
if ($location.absUrl() !== newUrl) return; | |
defaultPrevented ? ($location.$$parse(oldUrl), $location.$$state = oldState) : (urlOrStateChanged && setBrowserUrlWithFallback(newUrl, currentReplace, oldState === $location.$$state ? null : $location.$$state), afterLocationChange(oldUrl, oldState)) | |
})), $location.$$replace = !1 | |
}), $location; | |
function afterLocationChange(oldUrl, oldState) { | |
$rootScope.$broadcast("$locationChangeSuccess", $location.absUrl(), oldUrl, $location.$$state, oldState) | |
} | |
}] | |
} | |
function $LogProvider() { | |
var debug = !0, | |
self = this; | |
this.debugEnabled = function(flag) { | |
return isDefined(flag) ? (debug = flag, this) : debug | |
}, this.$get = ["$window", function($window) { | |
return { | |
log: consoleLog("log"), | |
info: consoleLog("info"), | |
warn: consoleLog("warn"), | |
error: consoleLog("error"), | |
debug: function() { | |
var fn = consoleLog("debug"); | |
return function() { | |
debug && fn.apply(self, arguments) | |
} | |
}() | |
}; | |
function formatError(arg) { | |
return arg instanceof Error && (arg.stack ? arg = arg.message && -1 === arg.stack.indexOf(arg.message) ? "Error: " + arg.message + "\n" + arg.stack : arg.stack : arg.sourceURL && (arg = arg.message + "\n" + arg.sourceURL + ":" + arg.line)), arg | |
} | |
function consoleLog(type) { | |
var console = $window.console || {}, | |
logFn = console[type] || console.log || noop, | |
hasApply = !1; | |
try { | |
hasApply = !!logFn.apply | |
} catch (e) {} | |
if (hasApply) return function() { | |
var args = []; | |
return forEach(arguments, function(arg) { | |
args.push(formatError(arg)) | |
}), logFn.apply(console, args) | |
}; | |
return function(arg1, arg2) { | |
logFn(arg1, null == arg2 ? "" : arg2) | |
} | |
} | |
}] | |
} | |
var $parseMinErr = minErr("$parse"); | |
function ensureSafeMemberName(name, fullExpression) { | |
if ("__defineGetter__" === name || "__defineSetter__" === name || "__lookupGetter__" === name || "__lookupSetter__" === name || "__proto__" === name) throw $parseMinErr("isecfld", "Attempting to access a disallowed field in Angular expressions! Expression: {0}", fullExpression); | |
return name | |
} | |
function ensureSafeObject(obj, fullExpression) { | |
if (obj) { | |
if (obj.constructor === obj) throw $parseMinErr("isecfn", "Referencing Function in Angular expressions is disallowed! Expression: {0}", fullExpression); | |
if (obj.window === obj) throw $parseMinErr("isecwindow", "Referencing the Window in Angular expressions is disallowed! Expression: {0}", fullExpression); | |
if (obj.children && (obj.nodeName || obj.prop && obj.attr && obj.find)) throw $parseMinErr("isecdom", "Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}", fullExpression); | |
if (obj === Object) throw $parseMinErr("isecobj", "Referencing Object in Angular expressions is disallowed! Expression: {0}", fullExpression) | |
} | |
return obj | |
} | |
var CALL = Function.prototype.call, | |
APPLY = Function.prototype.apply, | |
BIND = Function.prototype.bind; | |
function ensureSafeFunction(obj, fullExpression) { | |
if (obj) { | |
if (obj.constructor === obj) throw $parseMinErr("isecfn", "Referencing Function in Angular expressions is disallowed! Expression: {0}", fullExpression); | |
if (obj === CALL || obj === APPLY || obj === BIND) throw $parseMinErr("isecff", "Referencing call, apply or bind in Angular expressions is disallowed! Expression: {0}", fullExpression) | |
} | |
} | |
var OPERATORS = createMap(); | |
forEach("+ - * / % === !== == != < > <= >= && || ! = |".split(" "), function(operator) { | |
OPERATORS[operator] = !0 | |
}); | |
var ESCAPE = { | |
n: "\n", | |
f: "\f", | |
r: "\r", | |
t: " ", | |
v: "", | |
"'": "'", | |
'"': '"' | |
}, | |
Lexer = function(options) { | |
this.options = options | |
}; | |
Lexer.prototype = { | |
constructor: Lexer, | |
lex: function(text) { | |
for (this.text = text, this.index = 0, this.tokens = []; this.index < this.text.length;) { | |
var ch = this.text.charAt(this.index); | |
if ('"' === ch || "'" === ch) this.readString(ch); | |
else if (this.isNumber(ch) || "." === ch && this.isNumber(this.peek())) this.readNumber(); | |
else if (this.isIdent(ch)) this.readIdent(); | |
else if (this.is(ch, "(){}[].,;:?")) this.tokens.push({ | |
index: this.index, | |
text: ch | |
}), this.index++; | |
else if (this.isWhitespace(ch)) this.index++; | |
else { | |
var ch2 = ch + this.peek(), | |
ch3 = ch2 + this.peek(2), | |
op1 = OPERATORS[ch], | |
op2 = OPERATORS[ch2], | |
op3 = OPERATORS[ch3]; | |
if (op1 || op2 || op3) { | |
var token = op3 ? ch3 : op2 ? ch2 : ch; | |
this.tokens.push({ | |
index: this.index, | |
text: token, | |
operator: !0 | |
}), this.index += token.length | |
} else this.throwError("Unexpected next character ", this.index, this.index + 1) | |
} | |
} | |
return this.tokens | |
}, | |
is: function(ch, chars) { | |
return -1 !== chars.indexOf(ch) | |
}, | |
peek: function(i) { | |
var num = i || 1; | |
return this.index + num < this.text.length ? this.text.charAt(this.index + num) : !1 | |
}, | |
isNumber: function(ch) { | |
return ch >= "0" && "9" >= ch && "string" == typeof ch | |
}, | |
isWhitespace: function(ch) { | |
return " " === ch || "\r" === ch || " " === ch || "\n" === ch || "" === ch || " " === ch | |
}, | |
isIdent: function(ch) { | |
return ch >= "a" && "z" >= ch || ch >= "A" && "Z" >= ch || "_" === ch || "$" === ch | |
}, | |
isExpOperator: function(ch) { | |
return "-" === ch || "+" === ch || this.isNumber(ch) | |
}, | |
throwError: function(error, start, end) { | |
end = end || this.index; | |
var colStr = isDefined(start) ? "s " + start + "-" + this.index + " [" + this.text.substring(start, end) + "]" : " " + end; | |
throw $parseMinErr("lexerr", "Lexer Error: {0} at column{1} in expression [{2}].", error, colStr, this.text) | |
}, | |
readNumber: function() { | |
for (var number = "", start = this.index; this.index < this.text.length;) { | |
var ch = lowercase(this.text.charAt(this.index)); | |
if ("." == ch || this.isNumber(ch)) number += ch; | |
else { | |
var peekCh = this.peek(); | |
if ("e" == ch && this.isExpOperator(peekCh)) number += ch; | |
else if (this.isExpOperator(ch) && peekCh && this.isNumber(peekCh) && "e" == number.charAt(number.length - 1)) number += ch; | |
else { | |
if (!this.isExpOperator(ch) || peekCh && this.isNumber(peekCh) || "e" != number.charAt(number.length - 1)) break; | |
this.throwError("Invalid exponent") | |
} | |
} | |
this.index++ | |
} | |
this.tokens.push({ | |
index: start, | |
text: number, | |
constant: !0, | |
value: Number(number) | |
}) | |
}, | |
readIdent: function() { | |
for (var start = this.index; this.index < this.text.length;) { | |
var ch = this.text.charAt(this.index); | |
if (!this.isIdent(ch) && !this.isNumber(ch)) break; | |
this.index++ | |
} | |
this.tokens.push({ | |
index: start, | |
text: this.text.slice(start, this.index), | |
identifier: !0 | |
}) | |
}, | |
readString: function(quote) { | |
var start = this.index; | |
this.index++; | |
for (var string = "", rawString = quote, escape = !1; this.index < this.text.length;) { | |
var ch = this.text.charAt(this.index); | |
if (rawString += ch, escape) { | |
if ("u" === ch) { | |
var hex = this.text.substring(this.index + 1, this.index + 5); | |
hex.match(/[\da-f]{4}/i) || this.throwError("Invalid unicode escape [\\u" + hex + "]"), this.index += 4, string += String.fromCharCode(parseInt(hex, 16)) | |
} else { | |
var rep = ESCAPE[ch]; | |
string += rep || ch | |
} | |
escape = !1 | |
} else if ("\\" === ch) escape = !0; | |
else { | |
if (ch === quote) return this.index++, void this.tokens.push({ | |
index: start, | |
text: rawString, | |
constant: !0, | |
value: string | |
}); | |
string += ch | |
} | |
this.index++ | |
} | |
this.throwError("Unterminated quote", start) | |
} | |
}; | |
var AST = function(lexer, options) { | |
this.lexer = lexer, this.options = options | |
}; | |
AST.Program = "Program", AST.ExpressionStatement = "ExpressionStatement", AST.AssignmentExpression = "AssignmentExpression", AST.ConditionalExpression = "ConditionalExpression", AST.LogicalExpression = "LogicalExpression", AST.BinaryExpression = "BinaryExpression", AST.UnaryExpression = "UnaryExpression", AST.CallExpression = "CallExpression", AST.MemberExpression = "MemberExpression", AST.Identifier = "Identifier", AST.Literal = "Literal", AST.ArrayExpression = "ArrayExpression", AST.Property = "Property", AST.ObjectExpression = "ObjectExpression", AST.ThisExpression = "ThisExpression", AST.NGValueParameter = "NGValueParameter", AST.prototype = { | |
ast: function(text) { | |
this.text = text, this.tokens = this.lexer.lex(text); | |
var value = this.program(); | |
return 0 !== this.tokens.length && this.throwError("is an unexpected token", this.tokens[0]), value | |
}, | |
program: function() { | |
for (var body = [];;) | |
if (this.tokens.length > 0 && !this.peek("}", ")", ";", "]") && body.push(this.expressionStatement()), !this.expect(";")) return { | |
type: AST.Program, | |
body: body | |
} | |
}, | |
expressionStatement: function() { | |
return { | |
type: AST.ExpressionStatement, | |
expression: this.filterChain() | |
} | |
}, | |
filterChain: function() { | |
for (var token, left = this.expression(); token = this.expect("|");) left = this.filter(left); | |
return left | |
}, | |
expression: function() { | |
return this.assignment() | |
}, | |
assignment: function() { | |
var result = this.ternary(); | |
return this.expect("=") && (result = { | |
type: AST.AssignmentExpression, | |
left: result, | |
right: this.assignment(), | |
operator: "=" | |
}), result | |
}, | |
ternary: function() { | |
var alternate, consequent, test = this.logicalOR(); | |
if (this.expect("?") && (alternate = this.expression(), this.consume(":"))) return consequent = this.expression(), { | |
type: AST.ConditionalExpression, | |
test: test, | |
alternate: alternate, | |
consequent: consequent | |
}; | |
return test | |
}, | |
logicalOR: function() { | |
for (var left = this.logicalAND(); this.expect("||");) left = { | |
type: AST.LogicalExpression, | |
operator: "||", | |
left: left, | |
right: this.logicalAND() | |
}; | |
return left | |
}, | |
logicalAND: function() { | |
for (var left = this.equality(); this.expect("&&");) left = { | |
type: AST.LogicalExpression, | |
operator: "&&", | |
left: left, | |
right: this.equality() | |
}; | |
return left | |
}, | |
equality: function() { | |
for (var token, left = this.relational(); token = this.expect("==", "!=", "===", "!==");) left = { | |
type: AST.BinaryExpression, | |
operator: token.text, | |
left: left, | |
right: this.relational() | |
}; | |
return left | |
}, | |
relational: function() { | |
for (var token, left = this.additive(); token = this.expect("<", ">", "<=", ">=");) left = { | |
type: AST.BinaryExpression, | |
operator: token.text, | |
left: left, | |
right: this.additive() | |
}; | |
return left | |
}, | |
additive: function() { | |
for (var token, left = this.multiplicative(); token = this.expect("+", "-");) left = { | |
type: AST.BinaryExpression, | |
operator: token.text, | |
left: left, | |
right: this.multiplicative() | |
}; | |
return left | |
}, | |
multiplicative: function() { | |
for (var token, left = this.unary(); token = this.expect("*", "/", "%");) left = { | |
type: AST.BinaryExpression, | |
operator: token.text, | |
left: left, | |
right: this.unary() | |
}; | |
return left | |
}, | |
unary: function() { | |
var token; | |
return (token = this.expect("+", "-", "!")) ? { | |
type: AST.UnaryExpression, | |
operator: token.text, | |
prefix: !0, | |
argument: this.unary() | |
} : this.primary() | |
}, | |
primary: function() { | |
var primary; | |
this.expect("(") ? (primary = this.filterChain(), this.consume(")")) : this.expect("[") ? primary = this.arrayDeclaration() : this.expect("{") ? primary = this.object() : this.constants.hasOwnProperty(this.peek().text) ? primary = copy(this.constants[this.consume().text]) : this.peek().identifier ? primary = this.identifier() : this.peek().constant ? primary = this.constant() : this.throwError("not a primary expression", this.peek()); | |
for (var next; next = this.expect("(", "[", ".");) "(" === next.text ? (primary = { | |
type: AST.CallExpression, | |
callee: primary, | |
arguments: this.parseArguments() | |
}, this.consume(")")) : "[" === next.text ? (primary = { | |
type: AST.MemberExpression, | |
object: primary, | |
property: this.expression(), | |
computed: !0 | |
}, this.consume("]")) : "." === next.text ? primary = { | |
type: AST.MemberExpression, | |
object: primary, | |
property: this.identifier(), | |
computed: !1 | |
} : this.throwError("IMPOSSIBLE"); | |
return primary | |
}, | |
filter: function(baseExpression) { | |
for (var args = [baseExpression], result = { | |
type: AST.CallExpression, | |
callee: this.identifier(), | |
arguments: args, | |
filter: !0 | |
}; this.expect(":");) args.push(this.expression()); | |
return result | |
}, | |
parseArguments: function() { | |
var args = []; | |
if (")" !== this.peekToken().text) | |
do args.push(this.expression()); while (this.expect(",")); | |
return args | |
}, | |
identifier: function() { | |
var token = this.consume(); | |
return token.identifier || this.throwError("is not a valid identifier", token), { | |
type: AST.Identifier, | |
name: token.text | |
} | |
}, | |
constant: function() { | |
return { | |
type: AST.Literal, | |
value: this.consume().value | |
} | |
}, | |
arrayDeclaration: function() { | |
var elements = []; | |
if ("]" !== this.peekToken().text) | |
do { | |
if (this.peek("]")) break; | |
elements.push(this.expression()) | |
} while (this.expect(",")); | |
return this.consume("]"), { | |
type: AST.ArrayExpression, | |
elements: elements | |
} | |
}, | |
object: function() { | |
var property, properties = []; | |
if ("}" !== this.peekToken().text) | |
do { | |
if (this.peek("}")) break; | |
property = { | |
type: AST.Property, | |
kind: "init" | |
}, this.peek().constant ? property.key = this.constant() : this.peek().identifier ? property.key = this.identifier() : this.throwError("invalid key", this.peek()), this.consume(":"), property.value = this.expression(), properties.push(property) | |
} while (this.expect(",")); | |
return this.consume("}"), { | |
type: AST.ObjectExpression, | |
properties: properties | |
} | |
}, | |
throwError: function(msg, token) { | |
throw $parseMinErr("syntax", "Syntax Error: Token '{0}' {1} at column {2} of the expression [{3}] starting at [{4}].", token.text, msg, token.index + 1, this.text, this.text.substring(token.index)) | |
}, | |
consume: function(e1) { | |
if (0 === this.tokens.length) throw $parseMinErr("ueoe", "Unexpected end of expression: {0}", this.text); | |
var token = this.expect(e1); | |
return token || this.throwError("is unexpected, expecting [" + e1 + "]", this.peek()), token | |
}, | |
peekToken: function() { | |
if (0 === this.tokens.length) throw $parseMinErr("ueoe", "Unexpected end of expression: {0}", this.text); | |
return this.tokens[0] | |
}, | |
peek: function(e1, e2, e3, e4) { | |
return this.peekAhead(0, e1, e2, e3, e4) | |
}, | |
peekAhead: function(i, e1, e2, e3, e4) { | |
if (this.tokens.length > i) { | |
var token = this.tokens[i], | |
t = token.text; | |
if (t === e1 || t === e2 || t === e3 || t === e4 || !e1 && !e2 && !e3 && !e4) return token | |
} | |
return !1 | |
}, | |
expect: function(e1, e2, e3, e4) { | |
var token = this.peek(e1, e2, e3, e4); | |
if (token) return this.tokens.shift(), token; | |
return !1 | |
}, | |
constants: { | |
"true": { | |
type: AST.Literal, | |
value: !0 | |
}, | |
"false": { | |
type: AST.Literal, | |
value: !1 | |
}, | |
"null": { | |
type: AST.Literal, | |
value: null | |
}, | |
undefined: { | |
type: AST.Literal, | |
value: undefined | |
}, | |
"this": { | |
type: AST.ThisExpression | |
} | |
} | |
}; | |
function ifDefined(v, d) { | |
return "undefined" != typeof v ? v : d | |
} | |
function plusFn(l, r) { | |
if ("undefined" == typeof l) return r; | |
if ("undefined" == typeof r) return l; | |
return l + r | |
} | |
function isStateless($filter, filterName) { | |
var fn = $filter(filterName); | |
return !fn.$stateful | |
} | |
function findConstantAndWatchExpressions(ast, $filter) { | |
var allConstants, argsToWatch; | |
switch (ast.type) { | |
case AST.Program: | |
allConstants = !0, forEach(ast.body, function(expr) { | |
findConstantAndWatchExpressions(expr.expression, $filter), allConstants = allConstants && expr.expression.constant | |
}), ast.constant = allConstants; | |
break; | |
case AST.Literal: | |
ast.constant = !0, ast.toWatch = []; | |
break; | |
case AST.UnaryExpression: | |
findConstantAndWatchExpressions(ast.argument, $filter), ast.constant = ast.argument.constant, ast.toWatch = ast.argument.toWatch; | |
break; | |
case AST.BinaryExpression: | |
findConstantAndWatchExpressions(ast.left, $filter), findConstantAndWatchExpressions(ast.right, $filter), ast.constant = ast.left.constant && ast.right.constant, ast.toWatch = ast.left.toWatch.concat(ast.right.toWatch); | |
break; | |
case AST.LogicalExpression: | |
findConstantAndWatchExpressions(ast.left, $filter), findConstantAndWatchExpressions(ast.right, $filter), ast.constant = ast.left.constant && ast.right.constant, ast.toWatch = ast.constant ? [] : [ast]; | |
break; | |
case AST.ConditionalExpression: | |
findConstantAndWatchExpressions(ast.test, $filter), findConstantAndWatchExpressions(ast.alternate, $filter), findConstantAndWatchExpressions(ast.consequent, $filter), ast.constant = ast.test.constant && ast.alternate.constant && ast.consequent.constant, ast.toWatch = ast.constant ? [] : [ast]; | |
break; | |
case AST.Identifier: | |
ast.constant = !1, ast.toWatch = [ast]; | |
break; | |
case AST.MemberExpression: | |
findConstantAndWatchExpressions(ast.object, $filter), ast.computed && findConstantAndWatchExpressions(ast.property, $filter), ast.constant = ast.object.constant && (!ast.computed || ast.property.constant), ast.toWatch = [ast]; | |
break; | |
case AST.CallExpression: | |
allConstants = ast.filter ? isStateless($filter, ast.callee.name) : !1, argsToWatch = [], forEach(ast.arguments, function(expr) { | |
findConstantAndWatchExpressions(expr, $filter), allConstants = allConstants && expr.constant, expr.constant || argsToWatch.push.apply(argsToWatch, expr.toWatch) | |
}), ast.constant = allConstants, ast.toWatch = ast.filter && isStateless($filter, ast.callee.name) ? argsToWatch : [ast]; | |
break; | |
case AST.AssignmentExpression: | |
findConstantAndWatchExpressions(ast.left, $filter), findConstantAndWatchExpressions(ast.right, $filter), ast.constant = ast.left.constant && ast.right.constant, ast.toWatch = [ast]; | |
break; | |
case AST.ArrayExpression: | |
allConstants = !0, argsToWatch = [], forEach(ast.elements, function(expr) { | |
findConstantAndWatchExpressions(expr, $filter), allConstants = allConstants && expr.constant, expr.constant || argsToWatch.push.apply(argsToWatch, expr.toWatch) | |
}), ast.constant = allConstants, ast.toWatch = argsToWatch; | |
break; | |
case AST.ObjectExpression: | |
allConstants = !0, argsToWatch = [], forEach(ast.properties, function(property) { | |
findConstantAndWatchExpressions(property.value, $filter), allConstants = allConstants && property.value.constant, property.value.constant || argsToWatch.push.apply(argsToWatch, property.value.toWatch) | |
}), ast.constant = allConstants, ast.toWatch = argsToWatch; | |
break; | |
case AST.ThisExpression: | |
ast.constant = !1, ast.toWatch = [] | |
} | |
} | |
function getInputs(body) { | |
if (1 != body.length) return; | |
var lastExpression = body[0].expression, | |
candidate = lastExpression.toWatch; | |
if (1 !== candidate.length) return candidate; | |
return candidate[0] !== lastExpression ? candidate : undefined | |
} | |
function isAssignable(ast) { | |
return ast.type === AST.Identifier || ast.type === AST.MemberExpression | |
} | |
function assignableAST(ast) { | |
if (1 === ast.body.length && isAssignable(ast.body[0].expression)) return { | |
type: AST.AssignmentExpression, | |
left: ast.body[0].expression, | |
right: { | |
type: AST.NGValueParameter | |
}, | |
operator: "=" | |
} | |
} | |
function isLiteral(ast) { | |
return 0 === ast.body.length || 1 === ast.body.length && (ast.body[0].expression.type === AST.Literal || ast.body[0].expression.type === AST.ArrayExpression || ast.body[0].expression.type === AST.ObjectExpression) | |
} | |
function isConstant(ast) { | |
return ast.constant | |
} | |
function ASTCompiler(astBuilder, $filter) { | |
this.astBuilder = astBuilder, this.$filter = $filter | |
} | |
ASTCompiler.prototype = { | |
compile: function(expression, expensiveChecks) { | |
var self = this, | |
ast = this.astBuilder.ast(expression); | |
this.state = { | |
nextId: 0, | |
filters: {}, | |
expensiveChecks: expensiveChecks, | |
fn: { | |
vars: [], | |
body: [], | |
own: {} | |
}, | |
assign: { | |
vars: [], | |
body: [], | |
own: {} | |
}, | |
inputs: [] | |
}, findConstantAndWatchExpressions(ast, self.$filter); | |
var assignable, extra = ""; | |
if (this.stage = "assign", assignable = assignableAST(ast)) { | |
this.state.computing = "assign"; | |
var result = this.nextId(); | |
this.recurse(assignable, result), extra = "fn.assign=" + this.generateFunction("assign", "s,v,l") | |
} | |
var toWatch = getInputs(ast.body); | |
self.stage = "inputs", forEach(toWatch, function(watch, key) { | |
var fnKey = "fn" + key; | |
self.state[fnKey] = { | |
vars: [], | |
body: [], | |
own: {} | |
}, self.state.computing = fnKey; | |
var intoId = self.nextId(); | |
self.recurse(watch, intoId), self.return_(intoId), self.state.inputs.push(fnKey), watch.watchId = key | |
}), this.state.computing = "fn", this.stage = "main", this.recurse(ast); | |
var fnString = '"' + this.USE + " " + this.STRICT + '";\n' + this.filterPrefix() + "var fn=" + this.generateFunction("fn", "s,l,a,i") + extra + this.watchFns() + "return fn;", | |
fn = new Function("$filter", "ensureSafeMemberName", "ensureSafeObject", "ensureSafeFunction", "ifDefined", "plus", "text", fnString)(this.$filter, ensureSafeMemberName, ensureSafeObject, ensureSafeFunction, ifDefined, plusFn, expression); | |
return this.state = this.stage = undefined, fn.literal = isLiteral(ast), fn.constant = isConstant(ast), fn | |
}, | |
USE: "use", | |
STRICT: "strict", | |
watchFns: function() { | |
var result = [], | |
fns = this.state.inputs, | |
self = this; | |
return forEach(fns, function(name) { | |
result.push("var " + name + "=" + self.generateFunction(name, "s")) | |
}), fns.length && result.push("fn.inputs=[" + fns.join(",") + "];"), result.join("") | |
}, | |
generateFunction: function(name, params) { | |
return "function(" + params + "){" + this.varsPrefix(name) + this.body(name) + "};" | |
}, | |
filterPrefix: function() { | |
var parts = [], | |
self = this; | |
if (forEach(this.state.filters, function(id, filter) { | |
parts.push(id + "=$filter(" + self.escape(filter) + ")") | |
}), parts.length) return "var " + parts.join(",") + ";"; | |
return "" | |
}, | |
varsPrefix: function(section) { | |
return this.state[section].vars.length ? "var " + this.state[section].vars.join(",") + ";" : "" | |
}, | |
body: function(section) { | |
return this.state[section].body.join("") | |
}, | |
recurse: function(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck) { | |
var left, right, args, expression, self = this; | |
if (recursionFn = recursionFn || noop, !skipWatchIdCheck && isDefined(ast.watchId)) return intoId = intoId || this.nextId(), void this.if_("i", this.lazyAssign(intoId, this.computedMember("i", ast.watchId)), this.lazyRecurse(ast, intoId, nameId, recursionFn, create, !0)); | |
switch (ast.type) { | |
case AST.Program: | |
forEach(ast.body, function(expression, pos) { | |
self.recurse(expression.expression, undefined, undefined, function(expr) { | |
right = expr | |
}), pos !== ast.body.length - 1 ? self.current().body.push(right, ";") : self.return_(right) | |
}); | |
break; | |
case AST.Literal: | |
expression = this.escape(ast.value), this.assign(intoId, expression), recursionFn(expression); | |
break; | |
case AST.UnaryExpression: | |
this.recurse(ast.argument, undefined, undefined, function(expr) { | |
right = expr | |
}), expression = ast.operator + "(" + this.ifDefined(right, 0) + ")", this.assign(intoId, expression), recursionFn(expression); | |
break; | |
case AST.BinaryExpression: | |
this.recurse(ast.left, undefined, undefined, function(expr) { | |
left = expr | |
}), this.recurse(ast.right, undefined, undefined, function(expr) { | |
right = expr | |
}), expression = "+" === ast.operator ? this.plus(left, right) : "-" === ast.operator ? this.ifDefined(left, 0) + ast.operator + this.ifDefined(right, 0) : "(" + left + ")" + ast.operator + "(" + right + ")", this.assign(intoId, expression), recursionFn(expression); | |
break; | |
case AST.LogicalExpression: | |
intoId = intoId || this.nextId(), self.recurse(ast.left, intoId), self.if_("&&" === ast.operator ? intoId : self.not(intoId), self.lazyRecurse(ast.right, intoId)), recursionFn(intoId); | |
break; | |
case AST.ConditionalExpression: | |
intoId = intoId || this.nextId(), self.recurse(ast.test, intoId), self.if_(intoId, self.lazyRecurse(ast.alternate, intoId), self.lazyRecurse(ast.consequent, intoId)), recursionFn(intoId); | |
break; | |
case AST.Identifier: | |
intoId = intoId || this.nextId(), nameId && (nameId.context = "inputs" === self.stage ? "s" : this.assign(this.nextId(), this.getHasOwnProperty("l", ast.name) + "?l:s"), nameId.computed = !1, nameId.name = ast.name), ensureSafeMemberName(ast.name), self.if_("inputs" === self.stage || self.not(self.getHasOwnProperty("l", ast.name)), function() { | |
self.if_("inputs" === self.stage || "s", function() { | |
create && 1 !== create && self.if_(self.not(self.nonComputedMember("s", ast.name)), self.lazyAssign(self.nonComputedMember("s", ast.name), "{}")), self.assign(intoId, self.nonComputedMember("s", ast.name)) | |
}) | |
}, intoId && self.lazyAssign(intoId, self.nonComputedMember("l", ast.name))), (self.state.expensiveChecks || isPossiblyDangerousMemberName(ast.name)) && self.addEnsureSafeObject(intoId), recursionFn(intoId); | |
break; | |
case AST.MemberExpression: | |
left = nameId && (nameId.context = this.nextId()) || this.nextId(), intoId = intoId || this.nextId(), self.recurse(ast.object, left, undefined, function() { | |
self.if_(self.notNull(left), function() { | |
ast.computed ? (right = self.nextId(), self.recurse(ast.property, right), self.addEnsureSafeMemberName(right), create && 1 !== create && self.if_(self.not(self.computedMember(left, right)), self.lazyAssign(self.computedMember(left, right), "{}")), expression = self.ensureSafeObject(self.computedMember(left, right)), self.assign(intoId, expression), nameId && (nameId.computed = !0, nameId.name = right)) : (ensureSafeMemberName(ast.property.name), create && 1 !== create && self.if_(self.not(self.nonComputedMember(left, ast.property.name)), self.lazyAssign(self.nonComputedMember(left, ast.property.name), "{}")), expression = self.nonComputedMember(left, ast.property.name), (self.state.expensiveChecks || isPossiblyDangerousMemberName(ast.property.name)) && (expression = self.ensureSafeObject(expression)), self.assign(intoId, expression), nameId && (nameId.computed = !1, nameId.name = ast.property.name)), recursionFn(intoId) | |
}) | |
}, !!create); | |
break; | |
case AST.CallExpression: | |
intoId = intoId || this.nextId(), ast.filter ? (right = self.filter(ast.callee.name), args = [], forEach(ast.arguments, function(expr) { | |
var argument = self.nextId(); | |
self.recurse(expr, argument), args.push(argument) | |
}), expression = right + "(" + args.join(",") + ")", self.assign(intoId, expression), recursionFn(intoId)) : (right = self.nextId(), left = {}, args = [], self.recurse(ast.callee, right, left, function() { | |
self.if_(self.notNull(right), function() { | |
self.addEnsureSafeFunction(right), forEach(ast.arguments, function(expr) { | |
self.recurse(expr, self.nextId(), undefined, function(argument) { | |
args.push(self.ensureSafeObject(argument)) | |
}) | |
}), left.name ? (self.state.expensiveChecks || self.addEnsureSafeObject(left.context), expression = self.member(left.context, left.name, left.computed) + "(" + args.join(",") + ")") : expression = right + "(" + args.join(",") + ")", expression = self.ensureSafeObject(expression), self.assign(intoId, expression), recursionFn(intoId) | |
}) | |
})); | |
break; | |
case AST.AssignmentExpression: | |
if (right = this.nextId(), left = {}, !isAssignable(ast.left)) throw $parseMinErr("lval", "Trying to assing a value to a non l-value"); | |
this.recurse(ast.left, undefined, left, function() { | |
self.if_(self.notNull(left.context), function() { | |
self.recurse(ast.right, right), self.addEnsureSafeObject(self.member(left.context, left.name, left.computed)), expression = self.member(left.context, left.name, left.computed) + ast.operator + right, self.assign(intoId, expression), recursionFn(intoId || expression) | |
}) | |
}, 1); | |
break; | |
case AST.ArrayExpression: | |
args = [], forEach(ast.elements, function(expr) { | |
self.recurse(expr, self.nextId(), undefined, function(argument) { | |
args.push(argument) | |
}) | |
}), expression = "[" + args.join(",") + "]", this.assign(intoId, expression), recursionFn(expression); | |
break; | |
case AST.ObjectExpression: | |
args = [], forEach(ast.properties, function(property) { | |
self.recurse(property.value, self.nextId(), undefined, function(expr) { | |
args.push(self.escape(property.key.type === AST.Identifier ? property.key.name : "" + property.key.value) + ":" + expr) | |
}) | |
}), expression = "{" + args.join(",") + "}", this.assign(intoId, expression), recursionFn(expression); | |
break; | |
case AST.ThisExpression: | |
this.assign(intoId, "s"), recursionFn("s"); | |
break; | |
case AST.NGValueParameter: | |
this.assign(intoId, "v"), recursionFn("v") | |
} | |
}, | |
getHasOwnProperty: function(element, property) { | |
var key = element + "." + property, | |
own = this.current().own; | |
return own.hasOwnProperty(key) || (own[key] = this.nextId(!1, element + "&&(" + this.escape(property) + " in " + element + ")")), own[key] | |
}, | |
assign: function(id, value) { | |
if (!id) return; | |
return this.current().body.push(id, "=", value, ";"), id | |
}, | |
filter: function(filterName) { | |
return this.state.filters.hasOwnProperty(filterName) || (this.state.filters[filterName] = this.nextId(!0)), this.state.filters[filterName] | |
}, | |
ifDefined: function(id, defaultValue) { | |
return "ifDefined(" + id + "," + this.escape(defaultValue) + ")" | |
}, | |
plus: function(left, right) { | |
return "plus(" + left + "," + right + ")" | |
}, | |
return_: function(id) { | |
this.current().body.push("return ", id, ";") | |
}, | |
if_: function(test, alternate, consequent) { | |
if (test === !0) alternate(); | |
else { | |
var body = this.current().body; | |
body.push("if(", test, "){"), alternate(), body.push("}"), consequent && (body.push("else{"), consequent(), body.push("}")) | |
} | |
}, | |
not: function(expression) { | |
return "!(" + expression + ")" | |
}, | |
notNull: function(expression) { | |
return expression + "!=null" | |
}, | |
nonComputedMember: function(left, right) { | |
return left + "." + right | |
}, | |
computedMember: function(left, right) { | |
return left + "[" + right + "]" | |
}, | |
member: function(left, right, computed) { | |
if (computed) return this.computedMember(left, right); | |
return this.nonComputedMember(left, right) | |
}, | |
addEnsureSafeObject: function(item) { | |
this.current().body.push(this.ensureSafeObject(item), ";") | |
}, | |
addEnsureSafeMemberName: function(item) { | |
this.current().body.push(this.ensureSafeMemberName(item), ";") | |
}, | |
addEnsureSafeFunction: function(item) { | |
this.current().body.push(this.ensureSafeFunction(item), ";") | |
}, | |
ensureSafeObject: function(item) { | |
return "ensureSafeObject(" + item + ",text)" | |
}, | |
ensureSafeMemberName: function(item) { | |
return "ensureSafeMemberName(" + item + ",text)" | |
}, | |
ensureSafeFunction: function(item) { | |
return "ensureSafeFunction(" + item + ",text)" | |
}, | |
lazyRecurse: function(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck) { | |
var self = this; | |
return function() { | |
self.recurse(ast, intoId, nameId, recursionFn, create, skipWatchIdCheck) | |
} | |
}, | |
lazyAssign: function(id, value) { | |
var self = this; | |
return function() { | |
self.assign(id, value) | |
} | |
}, | |
stringEscapeRegex: /[^ a-zA-Z0-9]/g, | |
stringEscapeFn: function(c) { | |
return "\\u" + ("0000" + c.charCodeAt(0).toString(16)).slice(-4) | |
}, | |
escape: function(value) { | |
if (isString(value)) return "'" + value.replace(this.stringEscapeRegex, this.stringEscapeFn) + "'"; | |
if (isNumber(value)) return value.toString(); | |
if (value === !0) return "true"; | |
if (value === !1) return "false"; | |
if (null === value) return "null"; | |
if ("undefined" == typeof value) return "undefined"; | |
throw $parseMinErr("esc", "IMPOSSIBLE") | |
}, | |
nextId: function(skip, init) { | |
var id = "v" + this.state.nextId++; | |
return skip || this.current().vars.push(id + (init ? "=" + init : "")), id | |
}, | |
current: function() { | |
return this.state[this.state.computing] | |
} | |
}; | |
function ASTInterpreter(astBuilder, $filter) { | |
this.astBuilder = astBuilder, this.$filter = $filter | |
} | |
ASTInterpreter.prototype = { | |
compile: function(expression, expensiveChecks) { | |
var self = this, | |
ast = this.astBuilder.ast(expression); | |
this.expression = expression, this.expensiveChecks = expensiveChecks, findConstantAndWatchExpressions(ast, self.$filter); | |
var assignable, assign; | |
(assignable = assignableAST(ast)) && (assign = this.recurse(assignable)); | |
var inputs, toWatch = getInputs(ast.body); | |
toWatch && (inputs = [], forEach(toWatch, function(watch, key) { | |
var input = self.recurse(watch); | |
watch.input = input, inputs.push(input), watch.watchId = key | |
})); | |
var expressions = []; | |
forEach(ast.body, function(expression) { | |
expressions.push(self.recurse(expression.expression)) | |
}); | |
var fn = 0 === ast.body.length ? function() {} : 1 === ast.body.length ? expressions[0] : function(scope, locals) { | |
var lastValue; | |
return forEach(expressions, function(exp) { | |
lastValue = exp(scope, locals) | |
}), lastValue | |
}; | |
return assign && (fn.assign = function(scope, value, locals) { | |
return assign(scope, locals, value) | |
}), inputs && (fn.inputs = inputs), fn.literal = isLiteral(ast), fn.constant = isConstant(ast), fn | |
}, | |
recurse: function(ast, context, create) { | |
var left, right, args, self = this; | |
if (ast.input) return this.inputs(ast.input, ast.watchId); | |
switch (ast.type) { | |
case AST.Literal: | |
return this.value(ast.value, context); | |
case AST.UnaryExpression: | |
return right = this.recurse(ast.argument), this["unary" + ast.operator](right, context); | |
case AST.BinaryExpression: | |
return left = this.recurse(ast.left), right = this.recurse(ast.right), this["binary" + ast.operator](left, right, context); | |
case AST.LogicalExpression: | |
return left = this.recurse(ast.left), right = this.recurse(ast.right), this["binary" + ast.operator](left, right, context); | |
case AST.ConditionalExpression: | |
return this["ternary?:"](this.recurse(ast.test), this.recurse(ast.alternate), this.recurse(ast.consequent), context); | |
case AST.Identifier: | |
return ensureSafeMemberName(ast.name, self.expression), self.identifier(ast.name, self.expensiveChecks || isPossiblyDangerousMemberName(ast.name), context, create, self.expression); | |
case AST.MemberExpression: | |
return left = this.recurse(ast.object, !1, !!create), ast.computed || (ensureSafeMemberName(ast.property.name, self.expression), right = ast.property.name), ast.computed && (right = this.recurse(ast.property)), ast.computed ? this.computedMember(left, right, context, create, self.expression) : this.nonComputedMember(left, right, self.expensiveChecks, context, create, self.expression); | |
case AST.CallExpression: | |
return args = [], forEach(ast.arguments, function(expr) { | |
args.push(self.recurse(expr)) | |
}), ast.filter && (right = this.$filter(ast.callee.name)), ast.filter || (right = this.recurse(ast.callee, !0)), ast.filter ? function(scope, locals, assign, inputs) { | |
for (var values = [], i = 0; i < args.length; ++i) values.push(args[i](scope, locals, assign, inputs)); | |
var value = right.apply(undefined, values, inputs); | |
return context ? { | |
context: undefined, | |
name: undefined, | |
value: value | |
} : value | |
} : function(scope, locals, assign, inputs) { | |
var value, rhs = right(scope, locals, assign, inputs); | |
if (null != rhs.value) { | |
ensureSafeObject(rhs.context, self.expression), ensureSafeFunction(rhs.value, self.expression); | |
for (var values = [], i = 0; i < args.length; ++i) values.push(ensureSafeObject(args[i](scope, locals, assign, inputs), self.expression)); | |
value = ensureSafeObject(rhs.value.apply(rhs.context, values), self.expression) | |
} | |
return context ? { | |
value: value | |
} : value | |
}; | |
case AST.AssignmentExpression: | |
return left = this.recurse(ast.left, !0, 1), right = this.recurse(ast.right), | |
function(scope, locals, assign, inputs) { | |
var lhs = left(scope, locals, assign, inputs), | |
rhs = right(scope, locals, assign, inputs); | |
return ensureSafeObject(lhs.value, self.expression), lhs.context[lhs.name] = rhs, context ? { | |
value: rhs | |
} : rhs | |
}; | |
case AST.ArrayExpression: | |
return args = [], forEach(ast.elements, function(expr) { | |
args.push(self.recurse(expr)) | |
}), | |
function(scope, locals, assign, inputs) { | |
for (var value = [], i = 0; i < args.length; ++i) value.push(args[i](scope, locals, assign, inputs)); | |
return context ? { | |
value: value | |
} : value | |
}; | |
case AST.ObjectExpression: | |
return args = [], forEach(ast.properties, function(property) { | |
args.push({ | |
key: property.key.type === AST.Identifier ? property.key.name : "" + property.key.value, | |
value: self.recurse(property.value) | |
}) | |
}), | |
function(scope, locals, assign, inputs) { | |
for (var value = {}, i = 0; i < args.length; ++i) value[args[i].key] = args[i].value(scope, locals, assign, inputs); | |
return context ? { | |
value: value | |
} : value | |
}; | |
case AST.ThisExpression: | |
return function(scope) { | |
return context ? { | |
value: scope | |
} : scope | |
}; | |
case AST.NGValueParameter: | |
return function(scope, locals, assign, inputs) { | |
return context ? { | |
value: assign | |
} : assign | |
} | |
} | |
}, | |
"unary+": function(argument, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = argument(scope, locals, assign, inputs); | |
return arg = isDefined(arg) ? +arg : 0, context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"unary-": function(argument, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = argument(scope, locals, assign, inputs); | |
return arg = isDefined(arg) ? -arg : 0, context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"unary!": function(argument, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = !argument(scope, locals, assign, inputs); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"binary+": function(left, right, context) { | |
return function(scope, locals, assign, inputs) { | |
var lhs = left(scope, locals, assign, inputs), | |
rhs = right(scope, locals, assign, inputs), | |
arg = plusFn(lhs, rhs); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"binary-": function(left, right, context) { | |
return function(scope, locals, assign, inputs) { | |
var lhs = left(scope, locals, assign, inputs), | |
rhs = right(scope, locals, assign, inputs), | |
arg = (isDefined(lhs) ? lhs : 0) - (isDefined(rhs) ? rhs : 0); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"binary*": function(left, right, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = left(scope, locals, assign, inputs) * right(scope, locals, assign, inputs); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"binary/": function(left, right, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = left(scope, locals, assign, inputs) / right(scope, locals, assign, inputs); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"binary%": function(left, right, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = left(scope, locals, assign, inputs) % right(scope, locals, assign, inputs); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"binary===": function(left, right, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = left(scope, locals, assign, inputs) === right(scope, locals, assign, inputs); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"binary!==": function(left, right, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = left(scope, locals, assign, inputs) !== right(scope, locals, assign, inputs); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"binary==": function(left, right, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = left(scope, locals, assign, inputs) == right(scope, locals, assign, inputs); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"binary!=": function(left, right, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = left(scope, locals, assign, inputs) != right(scope, locals, assign, inputs); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"binary<": function(left, right, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = left(scope, locals, assign, inputs) < right(scope, locals, assign, inputs); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"binary>": function(left, right, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = left(scope, locals, assign, inputs) > right(scope, locals, assign, inputs); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"binary<=": function(left, right, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = left(scope, locals, assign, inputs) <= right(scope, locals, assign, inputs); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"binary>=": function(left, right, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = left(scope, locals, assign, inputs) >= right(scope, locals, assign, inputs); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"binary&&": function(left, right, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = left(scope, locals, assign, inputs) && right(scope, locals, assign, inputs); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"binary||": function(left, right, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = left(scope, locals, assign, inputs) || right(scope, locals, assign, inputs); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
"ternary?:": function(test, alternate, consequent, context) { | |
return function(scope, locals, assign, inputs) { | |
var arg = test(scope, locals, assign, inputs) ? alternate(scope, locals, assign, inputs) : consequent(scope, locals, assign, inputs); | |
return context ? { | |
value: arg | |
} : arg | |
} | |
}, | |
value: function(value, context) { | |
return function() { | |
return context ? { | |
context: undefined, | |
name: undefined, | |
value: value | |
} : value | |
} | |
}, | |
identifier: function(name, expensiveChecks, context, create, expression) { | |
return function(scope, locals, assign, inputs) { | |
var base = locals && name in locals ? locals : scope; | |
create && 1 !== create && base && !base[name] && (base[name] = {}); | |
var value = base ? base[name] : undefined; | |
return expensiveChecks && ensureSafeObject(value, expression), context ? { | |
context: base, | |
name: name, | |
value: value | |
} : value | |
} | |
}, | |
computedMember: function(left, right, context, create, expression) { | |
return function(scope, locals, assign, inputs) { | |
var rhs, value, lhs = left(scope, locals, assign, inputs); | |
return null != lhs && (rhs = right(scope, locals, assign, inputs), ensureSafeMemberName(rhs, expression), create && 1 !== create && lhs && !lhs[rhs] && (lhs[rhs] = {}), value = lhs[rhs], ensureSafeObject(value, expression)), context ? { | |
context: lhs, | |
name: rhs, | |
value: value | |
} : value | |
} | |
}, | |
nonComputedMember: function(left, right, expensiveChecks, context, create, expression) { | |
return function(scope, locals, assign, inputs) { | |
var lhs = left(scope, locals, assign, inputs); | |
create && 1 !== create && lhs && !lhs[right] && (lhs[right] = {}); | |
var value = null != lhs ? lhs[right] : undefined; | |
return (expensiveChecks || isPossiblyDangerousMemberName(right)) && ensureSafeObject(value, expression), context ? { | |
context: lhs, | |
name: right, | |
value: value | |
} : value | |
} | |
}, | |
inputs: function(input, watchId) { | |
return function(scope, value, locals, inputs) { | |
if (inputs) return inputs[watchId]; | |
return input(scope, value, locals) | |
} | |
} | |
}; | |
var Parser = function(lexer, $filter, options) { | |
this.lexer = lexer, this.$filter = $filter, this.options = options, this.ast = new AST(this.lexer), this.astCompiler = options.csp ? new ASTInterpreter(this.ast, $filter) : new ASTCompiler(this.ast, $filter) | |
}; | |
Parser.prototype = { | |
constructor: Parser, | |
parse: function(text) { | |
return this.astCompiler.compile(text, this.options.expensiveChecks) | |
} | |
}; | |
function setter(obj, path, setValue, fullExp) { | |
ensureSafeObject(obj, fullExp); | |
for (var key, element = path.split("."), i = 0; element.length > 1; i++) { | |
key = ensureSafeMemberName(element.shift(), fullExp); | |
var propertyObj = ensureSafeObject(obj[key], fullExp); | |
propertyObj || (propertyObj = {}, obj[key] = propertyObj), obj = propertyObj | |
} | |
return key = ensureSafeMemberName(element.shift(), fullExp), ensureSafeObject(obj[key], fullExp), obj[key] = setValue, setValue | |
} | |
createMap(), createMap(); | |
function isPossiblyDangerousMemberName(name) { | |
return "constructor" == name | |
} | |
var objectValueOf = Object.prototype.valueOf; | |
function getValueOf(value) { | |
return isFunction(value.valueOf) ? value.valueOf() : objectValueOf.call(value) | |
} | |
function $ParseProvider() { | |
var cacheDefault = createMap(), | |
cacheExpensive = createMap(); | |
this.$get = ["$filter", "$sniffer", function($filter, $sniffer) { | |
var $parseOptions = { | |
csp: $sniffer.csp, | |
expensiveChecks: !1 | |
}, | |
$parseOptionsExpensive = { | |
csp: $sniffer.csp, | |
expensiveChecks: !0 | |
}; | |
return function(exp, interceptorFn, expensiveChecks) { | |
var parsedExpression, oneTime, cacheKey; | |
switch (typeof exp) { | |
case "string": | |
exp = exp.trim(), cacheKey = exp; | |
var cache = expensiveChecks ? cacheExpensive : cacheDefault; | |
if (parsedExpression = cache[cacheKey], !parsedExpression) { | |
":" === exp.charAt(0) && ":" === exp.charAt(1) && (oneTime = !0, exp = exp.substring(2)); | |
var parseOptions = expensiveChecks ? $parseOptionsExpensive : $parseOptions, | |
lexer = new Lexer(parseOptions), | |
parser = new Parser(lexer, $filter, parseOptions); | |
parsedExpression = parser.parse(exp), parsedExpression.constant ? parsedExpression.$$watchDelegate = constantWatchDelegate : oneTime ? parsedExpression.$$watchDelegate = parsedExpression.literal ? oneTimeLiteralWatchDelegate : oneTimeWatchDelegate : parsedExpression.inputs && (parsedExpression.$$watchDelegate = inputsWatchDelegate), cache[cacheKey] = parsedExpression | |
} | |
return addInterceptor(parsedExpression, interceptorFn); | |
case "function": | |
return addInterceptor(exp, interceptorFn); | |
default: | |
return noop | |
} | |
}; | |
function expressionInputDirtyCheck(newValue, oldValueOfValue) { | |
if (null == newValue || null == oldValueOfValue) return newValue === oldValueOfValue; | |
if ("object" == typeof newValue && (newValue = getValueOf(newValue), "object" == typeof newValue)) return !1; | |
return newValue === oldValueOfValue || newValue !== newValue && oldValueOfValue !== oldValueOfValue | |
} | |
function inputsWatchDelegate(scope, listener, objectEquality, parsedExpression, prettyPrintExpression) { | |
var lastResult, inputExpressions = parsedExpression.inputs; | |
if (1 === inputExpressions.length) { | |
var oldInputValueOf = expressionInputDirtyCheck; | |
return inputExpressions = inputExpressions[0], scope.$watch(function(scope) { | |
var newInputValue = inputExpressions(scope); | |
return expressionInputDirtyCheck(newInputValue, oldInputValueOf) || (lastResult = parsedExpression(scope, undefined, undefined, [newInputValue]), oldInputValueOf = newInputValue && getValueOf(newInputValue)), lastResult | |
}, listener, objectEquality, prettyPrintExpression) | |
} | |
for (var oldInputValueOfValues = [], oldInputValues = [], i = 0, ii = inputExpressions.length; ii > i; i++) oldInputValueOfValues[i] = expressionInputDirtyCheck, oldInputValues[i] = null; | |
return scope.$watch(function(scope) { | |
for (var changed = !1, i = 0, ii = inputExpressions.length; ii > i; i++) { | |
var newInputValue = inputExpressions[i](scope); | |
(changed || (changed = !expressionInputDirtyCheck(newInputValue, oldInputValueOfValues[i]))) && (oldInputValues[i] = newInputValue, oldInputValueOfValues[i] = newInputValue && getValueOf(newInputValue)) | |
} | |
return changed && (lastResult = parsedExpression(scope, undefined, undefined, oldInputValues)), lastResult | |
}, listener, objectEquality, prettyPrintExpression) | |
} | |
function oneTimeWatchDelegate(scope, listener, objectEquality, parsedExpression) { | |
var unwatch, lastValue; | |
return unwatch = scope.$watch(function(scope) { | |
return parsedExpression(scope) | |
}, function(value, old, scope) { | |
lastValue = value, isFunction(listener) && listener.apply(this, arguments), isDefined(value) && scope.$$postDigest(function() { | |
isDefined(lastValue) && unwatch() | |
}) | |
}, objectEquality) | |
} | |
function oneTimeLiteralWatchDelegate(scope, listener, objectEquality, parsedExpression) { | |
var unwatch, lastValue; | |
return unwatch = scope.$watch(function(scope) { | |
return parsedExpression(scope) | |
}, function(value, old, scope) { | |
lastValue = value, isFunction(listener) && listener.call(this, value, old, scope), isAllDefined(value) && scope.$$postDigest(function() { | |
isAllDefined(lastValue) && unwatch() | |
}) | |
}, objectEquality); | |
function isAllDefined(value) { | |
var allDefined = !0; | |
return forEach(value, function(val) { | |
isDefined(val) || (allDefined = !1) | |
}), allDefined | |
} | |
} | |
function constantWatchDelegate(scope, listener, objectEquality, parsedExpression) { | |
var unwatch; | |
return unwatch = scope.$watch(function(scope) { | |
return parsedExpression(scope) | |
}, function(value, old, scope) { | |
isFunction(listener) && listener.apply(this, arguments), unwatch() | |
}, objectEquality) | |
} | |
function addInterceptor(parsedExpression, interceptorFn) { | |
if (!interceptorFn) return parsedExpression; | |
var watchDelegate = parsedExpression.$$watchDelegate, | |
regularWatch = watchDelegate !== oneTimeLiteralWatchDelegate && watchDelegate !== oneTimeWatchDelegate, | |
fn = regularWatch ? function(scope, locals, assign, inputs) { | |
var value = parsedExpression(scope, locals, assign, inputs); | |
return interceptorFn(value, scope, locals) | |
} : function(scope, locals, assign, inputs) { | |
var value = parsedExpression(scope, locals, assign, inputs), | |
result = interceptorFn(value, scope, locals); | |
return isDefined(value) ? result : value | |
}; | |
return parsedExpression.$$watchDelegate && parsedExpression.$$watchDelegate !== inputsWatchDelegate ? fn.$$watchDelegate = parsedExpression.$$watchDelegate : interceptorFn.$stateful || (fn.$$watchDelegate = inputsWatchDelegate, fn.inputs = parsedExpression.inputs ? parsedExpression.inputs : [parsedExpression]), fn | |
} | |
}] | |
} | |
function $QProvider() { | |
this.$get = ["$rootScope", "$exceptionHandler", function($rootScope, $exceptionHandler) { | |
return qFactory(function(callback) { | |
$rootScope.$evalAsync(callback) | |
}, $exceptionHandler) | |
}] | |
} | |
function $$QProvider() { | |
this.$get = ["$browser", "$exceptionHandler", function($browser, $exceptionHandler) { | |
return qFactory(function(callback) { | |
$browser.defer(callback) | |
}, $exceptionHandler) | |
}] | |
} | |
function qFactory(nextTick, exceptionHandler) { | |
var $qMinErr = minErr("$q", TypeError); | |
function callOnce(self, resolveFn, rejectFn) { | |
var called = !1; | |
function wrap(fn) { | |
return function(value) { | |
if (called) return; | |
called = !0, fn.call(self, value) | |
} | |
} | |
return [wrap(resolveFn), wrap(rejectFn)] | |
} | |
var defer = function() { | |
return new Deferred | |
}; | |
function Promise() { | |
this.$$state = { | |
status: 0 | |
} | |
} | |
Promise.prototype = { | |
then: function(onFulfilled, onRejected, progressBack) { | |
var result = new Deferred; | |
return this.$$state.pending = this.$$state.pending || [], this.$$state.pending.push([result, onFulfilled, onRejected, progressBack]), this.$$state.status > 0 && scheduleProcessQueue(this.$$state), result.promise | |
}, | |
"catch": function(callback) { | |
return this.then(null, callback) | |
}, | |
"finally": function(callback, progressBack) { | |
return this.then(function(value) { | |
return handleCallback(value, !0, callback) | |
}, function(error) { | |
return handleCallback(error, !1, callback) | |
}, progressBack) | |
} | |
}; | |
function simpleBind(context, fn) { | |
return function(value) { | |
fn.call(context, value) | |
} | |
} | |
function processQueue(state) { | |
var fn, deferred, pending; | |
pending = state.pending, state.processScheduled = !1, state.pending = undefined; | |
for (var i = 0, ii = pending.length; ii > i; ++i) { | |
deferred = pending[i][0], fn = pending[i][state.status]; | |
try { | |
isFunction(fn) ? deferred.resolve(fn(state.value)) : 1 === state.status ? deferred.resolve(state.value) : deferred.reject(state.value) | |
} catch (e) { | |
deferred.reject(e), exceptionHandler(e) | |
} | |
} | |
} | |
function scheduleProcessQueue(state) { | |
if (state.processScheduled || !state.pending) return; | |
state.processScheduled = !0, nextTick(function() { | |
processQueue(state) | |
}) | |
} | |
function Deferred() { | |
this.promise = new Promise, this.resolve = simpleBind(this, this.resolve), this.reject = simpleBind(this, this.reject), this.notify = simpleBind(this, this.notify) | |
} | |
Deferred.prototype = { | |
resolve: function(val) { | |
if (this.promise.$$state.status) return; | |
val === this.promise ? this.$$reject($qMinErr("qcycle", "Expected promise to be resolved with value other than itself '{0}'", val)) : this.$$resolve(val) | |
}, | |
$$resolve: function(val) { | |
var then, fns; | |
fns = callOnce(this, this.$$resolve, this.$$reject); | |
try { | |
(isObject(val) || isFunction(val)) && (then = val && val.then), isFunction(then) ? (this.promise.$$state.status = -1, then.call(val, fns[0], fns[1], this.notify)) : (this.promise.$$state.value = val, this.promise.$$state.status = 1, scheduleProcessQueue(this.promise.$$state)) | |
} catch (e) { | |
fns[1](e), exceptionHandler(e) | |
} | |
}, | |
reject: function(reason) { | |
if (this.promise.$$state.status) return; | |
this.$$reject(reason) | |
}, | |
$$reject: function(reason) { | |
this.promise.$$state.value = reason, this.promise.$$state.status = 2, scheduleProcessQueue(this.promise.$$state) | |
}, | |
notify: function(progress) { | |
var callbacks = this.promise.$$state.pending; | |
this.promise.$$state.status <= 0 && callbacks && callbacks.length && nextTick(function() { | |
for (var callback, result, i = 0, ii = callbacks.length; ii > i; i++) { | |
result = callbacks[i][0], callback = callbacks[i][3]; | |
try { | |
result.notify(isFunction(callback) ? callback(progress) : progress) | |
} catch (e) { | |
exceptionHandler(e) | |
} | |
} | |
}) | |
} | |
}; | |
var reject = function(reason) { | |
var result = new Deferred; | |
return result.reject(reason), result.promise | |
}, | |
makePromise = function(value, resolved) { | |
var result = new Deferred; | |
return resolved ? result.resolve(value) : result.reject(value), result.promise | |
}, | |
handleCallback = function(value, isResolved, callback) { | |
var callbackOutput = null; | |
try { | |
isFunction(callback) && (callbackOutput = callback()) | |
} catch (e) { | |
return makePromise(e, !1) | |
} | |
return isPromiseLike(callbackOutput) ? callbackOutput.then(function() { | |
return makePromise(value, isResolved) | |
}, function(error) { | |
return makePromise(error, !1) | |
}) : makePromise(value, isResolved) | |
}, | |
when = function(value, callback, errback, progressBack) { | |
var result = new Deferred; | |
return result.resolve(value), result.promise.then(callback, errback, progressBack) | |
}; | |
function all(promises) { | |
var deferred = new Deferred, | |
counter = 0, | |
results = isArray(promises) ? [] : {}; | |
return forEach(promises, function(promise, key) { | |
counter++, when(promise).then(function(value) { | |
if (results.hasOwnProperty(key)) return; | |
results[key] = value, --counter || deferred.resolve(results) | |
}, function(reason) { | |
if (results.hasOwnProperty(key)) return; | |
deferred.reject(reason) | |
}) | |
}), 0 === counter && deferred.resolve(results), deferred.promise | |
} | |
var $Q = function Q(resolver) { | |
if (!isFunction(resolver)) throw $qMinErr("norslvr", "Expected resolverFn, got '{0}'", resolver); | |
if (!(this instanceof Q)) return new Q(resolver); | |
var deferred = new Deferred; | |
function resolveFn(value) { | |
deferred.resolve(value) | |
} | |
function rejectFn(reason) { | |
deferred.reject(reason) | |
} | |
return resolver(resolveFn, rejectFn), deferred.promise | |
}; | |
return $Q.defer = defer, $Q.reject = reject, $Q.when = when, $Q.all = all, $Q | |
} | |
function $$RAFProvider() { | |
this.$get = ["$window", "$timeout", function($window, $timeout) { | |
var requestAnimationFrame = $window.requestAnimationFrame || $window.webkitRequestAnimationFrame, | |
cancelAnimationFrame = $window.cancelAnimationFrame || $window.webkitCancelAnimationFrame || $window.webkitCancelRequestAnimationFrame, | |
rafSupported = !!requestAnimationFrame, | |
raf = rafSupported ? function(fn) { | |
var id = requestAnimationFrame(fn); | |
return function() { | |
cancelAnimationFrame(id) | |
} | |
} : function(fn) { | |
var timer = $timeout(fn, 16.66, !1); | |
return function() { | |
$timeout.cancel(timer) | |
} | |
}; | |
return raf.supported = rafSupported, raf | |
}] | |
} | |
function $RootScopeProvider() { | |
var TTL = 10, | |
$rootScopeMinErr = minErr("$rootScope"), | |
lastDirtyWatch = null, | |
applyAsyncId = null; | |
this.digestTtl = function(value) { | |
return arguments.length && (TTL = value), TTL | |
}; | |
function createChildScopeClass(parent) { | |
function ChildScope() { | |
this.$$watchers = this.$$nextSibling = this.$$childHead = this.$$childTail = null, this.$$listeners = {}, this.$$listenerCount = {}, this.$$watchersCount = 0, this.$id = nextUid(), this.$$ChildScope = null | |
} | |
return ChildScope.prototype = parent, ChildScope | |
} | |
this.$get = ["$injector", "$exceptionHandler", "$parse", "$browser", function($injector, $exceptionHandler, $parse, $browser) { | |
function destroyChildScope($event) { | |
$event.currentScope.$$destroyed = !0 | |
} | |
function Scope() { | |
this.$id = nextUid(), this.$$phase = this.$parent = this.$$watchers = this.$$nextSibling = this.$$prevSibling = this.$$childHead = this.$$childTail = null, this.$root = this, this.$$destroyed = !1, this.$$listeners = {}, this.$$listenerCount = {}, this.$$watchersCount = 0, this.$$isolateBindings = null | |
} | |
Scope.prototype = { | |
constructor: Scope, | |
$new: function(isolate, parent) { | |
var child; | |
return parent = parent || this, isolate ? (child = new Scope, child.$root = this.$root) : (this.$$ChildScope || (this.$$ChildScope = createChildScopeClass(this)), child = new this.$$ChildScope), child.$parent = parent, child.$$prevSibling = parent.$$childTail, parent.$$childHead ? (parent.$$childTail.$$nextSibling = child, parent.$$childTail = child) : parent.$$childHead = parent.$$childTail = child, (isolate || parent != this) && child.$on("$destroy", destroyChildScope), child | |
}, | |
$watch: function(watchExp, listener, objectEquality, prettyPrintExpression) { | |
var get = $parse(watchExp); | |
if (get.$$watchDelegate) return get.$$watchDelegate(this, listener, objectEquality, get, watchExp); | |
var scope = this, | |
array = scope.$$watchers, | |
watcher = { | |
fn: listener, | |
last: initWatchVal, | |
get: get, | |
exp: prettyPrintExpression || watchExp, | |
eq: !!objectEquality | |
}; | |
return lastDirtyWatch = null, isFunction(listener) || (watcher.fn = noop), array || (array = scope.$$watchers = []), array.unshift(watcher), incrementWatchersCount(this, 1), | |
function() { | |
arrayRemove(array, watcher) >= 0 && incrementWatchersCount(scope, -1), lastDirtyWatch = null | |
} | |
}, | |
$watchGroup: function(watchExpressions, listener) { | |
var oldValues = new Array(watchExpressions.length), | |
newValues = new Array(watchExpressions.length), | |
deregisterFns = [], | |
self = this, | |
changeReactionScheduled = !1, | |
firstRun = !0; | |
if (!watchExpressions.length) { | |
var shouldCall = !0; | |
return self.$evalAsync(function() { | |
shouldCall && listener(newValues, newValues, self) | |
}), | |
function() { | |
shouldCall = !1 | |
} | |
} | |
if (1 === watchExpressions.length) return this.$watch(watchExpressions[0], function(value, oldValue, scope) { | |
newValues[0] = value, oldValues[0] = oldValue, listener(newValues, value === oldValue ? newValues : oldValues, scope) | |
}); | |
forEach(watchExpressions, function(expr, i) { | |
var unwatchFn = self.$watch(expr, function(value, oldValue) { | |
newValues[i] = value, oldValues[i] = oldValue, changeReactionScheduled || (changeReactionScheduled = !0, self.$evalAsync(watchGroupAction)) | |
}); | |
deregisterFns.push(unwatchFn) | |
}); | |
function watchGroupAction() { | |
changeReactionScheduled = !1, firstRun ? (firstRun = !1, listener(newValues, newValues, self)) : listener(newValues, oldValues, self) | |
} | |
return function() { | |
for (; deregisterFns.length;) deregisterFns.shift()() | |
} | |
}, | |
$watchCollection: function(obj, listener) { | |
$watchCollectionInterceptor.$stateful = !0; | |
var newValue, oldValue, veryOldValue, self = this, | |
trackVeryOldValue = listener.length > 1, | |
changeDetected = 0, | |
changeDetector = $parse(obj, $watchCollectionInterceptor), | |
internalArray = [], | |
internalObject = {}, | |
initRun = !0, | |
oldLength = 0; | |
function $watchCollectionInterceptor(_value) { | |
newValue = _value; | |
var newLength, key, bothNaN, newItem, oldItem; | |
if (isUndefined(newValue)) return; | |
if (isObject(newValue)) | |
if (isArrayLike(newValue)) { | |
oldValue !== internalArray && (oldValue = internalArray, oldLength = oldValue.length = 0, changeDetected++), newLength = newValue.length, oldLength !== newLength && (changeDetected++, oldValue.length = oldLength = newLength); | |
for (var i = 0; newLength > i; i++) oldItem = oldValue[i], newItem = newValue[i], bothNaN = oldItem !== oldItem && newItem !== newItem, bothNaN || oldItem === newItem || (changeDetected++, oldValue[i] = newItem) | |
} else { | |
oldValue !== internalObject && (oldValue = internalObject = {}, oldLength = 0, changeDetected++), newLength = 0; | |
for (key in newValue) newValue.hasOwnProperty(key) && (newLength++, newItem = newValue[key], oldItem = oldValue[key], key in oldValue ? (bothNaN = oldItem !== oldItem && newItem !== newItem, bothNaN || oldItem === newItem || (changeDetected++, oldValue[key] = newItem)) : (oldLength++, oldValue[key] = newItem, changeDetected++)); | |
if (oldLength > newLength) { | |
changeDetected++; | |
for (key in oldValue) newValue.hasOwnProperty(key) || (oldLength--, delete oldValue[key]) | |
} | |
} else oldValue !== newValue && (oldValue = newValue, changeDetected++); | |
return changeDetected | |
} | |
function $watchCollectionAction() { | |
if (initRun ? (initRun = !1, listener(newValue, newValue, self)) : listener(newValue, veryOldValue, self), trackVeryOldValue) | |
if (isObject(newValue)) | |
if (isArrayLike(newValue)) { | |
veryOldValue = new Array(newValue.length); | |
for (var i = 0; i < newValue.length; i++) veryOldValue[i] = newValue[i] | |
} else { | |
veryOldValue = {}; | |
for (var key in newValue) hasOwnProperty.call(newValue, key) && (veryOldValue[key] = newValue[key]) | |
} else veryOldValue = newValue | |
} | |
return this.$watch(changeDetector, $watchCollectionAction) | |
}, | |
$digest: function() { | |
var watch, value, last, watchers, length, dirty, next, current, logIdx, asyncTask, ttl = TTL, | |
target = this, | |
watchLog = []; | |
beginPhase("$digest"), $browser.$$checkUrlChange(), this === $rootScope && null !== applyAsyncId && ($browser.defer.cancel(applyAsyncId), flushApplyAsync()), lastDirtyWatch = null; | |
do { | |
for (dirty = !1, current = target; asyncQueue.length;) { | |
try { | |
asyncTask = asyncQueue.shift(), asyncTask.scope.$eval(asyncTask.expression, asyncTask.locals) | |
} catch (e) { | |
$exceptionHandler(e) | |
} | |
lastDirtyWatch = null | |
} | |
traverseScopesLoop: do { | |
if (watchers = current.$$watchers) | |
for (length = watchers.length; length--;) try { | |
if (watch = watchers[length]) | |
if ((value = watch.get(current)) === (last = watch.last) || (watch.eq ? equals(value, last) : "number" == typeof value && "number" == typeof last && isNaN(value) && isNaN(last))) { | |
if (watch === lastDirtyWatch) { | |
dirty = !1; | |
break traverseScopesLoop | |
} | |
} else dirty = !0, lastDirtyWatch = watch, watch.last = watch.eq ? copy(value, null) : value, watch.fn(value, last === initWatchVal ? value : last, current), 5 > ttl && (logIdx = 4 - ttl, watchLog[logIdx] || (watchLog[logIdx] = []), watchLog[logIdx].push({ | |
msg: isFunction(watch.exp) ? "fn: " + (watch.exp.name || watch.exp.toString()) : watch.exp, | |
newVal: value, | |
oldVal: last | |
})) | |
} catch (e) { | |
$exceptionHandler(e) | |
} | |
if (!(next = current.$$watchersCount && current.$$childHead || current !== target && current.$$nextSibling)) | |
for (; current !== target && !(next = current.$$nextSibling);) current = current.$parent | |
} while (current = next); | |
if ((dirty || asyncQueue.length) && !ttl--) throw clearPhase(), $rootScopeMinErr("infdig", "{0} $digest() iterations reached. Aborting!\nWatchers fired in the last 5 iterations: {1}", TTL, watchLog) | |
} while (dirty || asyncQueue.length); | |
for (clearPhase(); postDigestQueue.length;) try { | |
postDigestQueue.shift()() | |
} catch (e) { | |
$exceptionHandler(e) | |
} | |
}, | |
$destroy: function() { | |
if (this.$$destroyed) return; | |
var parent = this.$parent; | |
this.$broadcast("$destroy"), this.$$destroyed = !0, this === $rootScope && $browser.$$applicationDestroyed(), incrementWatchersCount(this, -this.$$watchersCount); | |
for (var eventName in this.$$listenerCount) decrementListenerCount(this, this.$$listenerCount[eventName], eventName); | |
parent && parent.$$childHead == this && (parent.$$childHead = this.$$nextSibling), parent && parent.$$childTail == this && (parent.$$childTail = this.$$prevSibling), this.$$prevSibling && (this.$$prevSibling.$$nextSibling = this.$$nextSibling), this.$$nextSibling && (this.$$nextSibling.$$prevSibling = this.$$prevSibling), this.$destroy = this.$digest = this.$apply = this.$evalAsync = this.$applyAsync = noop, this.$on = this.$watch = this.$watchGroup = function() { | |
return noop | |
}, this.$$listeners = {}, this.$parent = this.$$nextSibling = this.$$prevSibling = this.$$childHead = this.$$childTail = this.$root = this.$$watchers = null | |
}, | |
$eval: function(expr, locals) { | |
return $parse(expr)(this, locals) | |
}, | |
$evalAsync: function(expr, locals) { | |
$rootScope.$$phase || asyncQueue.length || $browser.defer(function() { | |
asyncQueue.length && $rootScope.$digest() | |
}), asyncQueue.push({ | |
scope: this, | |
expression: expr, | |
locals: locals | |
}) | |
}, | |
$$postDigest: function(fn) { | |
postDigestQueue.push(fn) | |
}, | |
$apply: function(expr) { | |
try { | |
return beginPhase("$apply"), this.$eval(expr) | |
} catch (e) { | |
$exceptionHandler(e) | |
} finally { | |
clearPhase(); | |
try { | |
$rootScope.$digest() | |
} catch (e) { | |
throw $exceptionHandler(e), e | |
} | |
} | |
}, | |
$applyAsync: function(expr) { | |
var scope = this; | |
expr && applyAsyncQueue.push($applyAsyncExpression), scheduleApplyAsync(); | |
function $applyAsyncExpression() { | |
scope.$eval(expr) | |
} | |
}, | |
$on: function(name, listener) { | |
var namedListeners = this.$$listeners[name]; | |
namedListeners || (this.$$listeners[name] = namedListeners = []), namedListeners.push(listener); | |
var current = this; | |
do current.$$listenerCount[name] || (current.$$listenerCount[name] = 0), current.$$listenerCount[name]++; while (current = current.$parent); | |
var self = this; | |
return function() { | |
var indexOfListener = namedListeners.indexOf(listener); - 1 !== indexOfListener && (namedListeners[indexOfListener] = null, decrementListenerCount(self, 1, name)) | |
} | |
}, | |
$emit: function(name, args) { | |
var namedListeners, i, length, empty = [], | |
scope = this, | |
stopPropagation = !1, | |
event = { | |
name: name, | |
targetScope: scope, | |
stopPropagation: function() { | |
stopPropagation = !0 | |
}, | |
preventDefault: function() { | |
event.defaultPrevented = !0 | |
}, | |
defaultPrevented: !1 | |
}, | |
listenerArgs = concat([event], arguments, 1); | |
do { | |
for (namedListeners = scope.$$listeners[name] || empty, event.currentScope = scope, i = 0, length = namedListeners.length; length > i; i++) { | |
if (!namedListeners[i]) { | |
namedListeners.splice(i, 1), i--, length--; | |
continue | |
} | |
try { | |
namedListeners[i].apply(null, listenerArgs) | |
} catch (e) { | |
$exceptionHandler(e) | |
} | |
} | |
if (stopPropagation) return event.currentScope = null, event; | |
scope = scope.$parent | |
} while (scope); | |
return event.currentScope = null, event | |
}, | |
$broadcast: function(name, args) { | |
var target = this, | |
current = target, | |
next = target, | |
event = { | |
name: name, | |
targetScope: target, | |
preventDefault: function() { | |
event.defaultPrevented = !0 | |
}, | |
defaultPrevented: !1 | |
}; | |
if (!target.$$listenerCount[name]) return event; | |
for (var listeners, i, length, listenerArgs = concat([event], arguments, 1); current = next;) { | |
for (event.currentScope = current, listeners = current.$$listeners[name] || [], i = 0, length = listeners.length; length > i; i++) { | |
if (!listeners[i]) { | |
listeners.splice(i, 1), i--, length--; | |
continue | |
} | |
try { | |
listeners[i].apply(null, listenerArgs) | |
} catch (e) { | |
$exceptionHandler(e) | |
} | |
} | |
if (!(next = current.$$listenerCount[name] && current.$$childHead || current !== target && current.$$nextSibling)) | |
for (; current !== target && !(next = current.$$nextSibling);) current = current.$parent | |
} | |
return event.currentScope = null, event | |
} | |
}; | |
var $rootScope = new Scope, | |
asyncQueue = $rootScope.$$asyncQueue = [], | |
postDigestQueue = $rootScope.$$postDigestQueue = [], | |
applyAsyncQueue = $rootScope.$$applyAsyncQueue = []; | |
return $rootScope; | |
function beginPhase(phase) { | |
if ($rootScope.$$phase) throw $rootScopeMinErr("inprog", "{0} already in progress", $rootScope.$$phase); | |
$rootScope.$$phase = phase | |
} | |
function clearPhase() { | |
$rootScope.$$phase = null | |
} | |
function incrementWatchersCount(current, count) { | |
do current.$$watchersCount += count; while (current = current.$parent) | |
} | |
function decrementListenerCount(current, count, name) { | |
do current.$$listenerCount[name] -= count, 0 === current.$$listenerCount[name] && delete current.$$listenerCount[name]; while (current = current.$parent) | |
} | |
function initWatchVal() {} | |
function flushApplyAsync() { | |
for (; applyAsyncQueue.length;) try { | |
applyAsyncQueue.shift()() | |
} catch (e) { | |
$exceptionHandler(e) | |
} | |
applyAsyncId = null | |
} | |
function scheduleApplyAsync() { | |
null === applyAsyncId && (applyAsyncId = $browser.defer(function() { | |
$rootScope.$apply(flushApplyAsync) | |
})) | |
} | |
}] | |
} | |
function $$SanitizeUriProvider() { | |
var aHrefSanitizationWhitelist = /^\s*(https?|ftp|mailto|tel|file):/, | |
imgSrcSanitizationWhitelist = /^\s*((https?|ftp|file|blob):|data:image\/)/; | |
this.aHrefSanitizationWhitelist = function(regexp) { | |
if (isDefined(regexp)) return aHrefSanitizationWhitelist = regexp, this; | |
return aHrefSanitizationWhitelist | |
}, this.imgSrcSanitizationWhitelist = function(regexp) { | |
if (isDefined(regexp)) return imgSrcSanitizationWhitelist = regexp, this; | |
return imgSrcSanitizationWhitelist | |
}, this.$get = function() { | |
return function(uri, isImage) { | |
var normalizedVal, regex = isImage ? imgSrcSanitizationWhitelist : aHrefSanitizationWhitelist; | |
if (normalizedVal = urlResolve(uri).href, "" !== normalizedVal && !normalizedVal.match(regex)) return "unsafe:" + normalizedVal; | |
return uri | |
} | |
} | |
} | |
var $sceMinErr = minErr("$sce"), | |
SCE_CONTEXTS = { | |
HTML: "html", | |
CSS: "css", | |
URL: "url", | |
RESOURCE_URL: "resourceUrl", | |
JS: "js" | |
}; | |
function adjustMatcher(matcher) { | |
if ("self" === matcher) return matcher; | |
if (isString(matcher)) { | |
if (matcher.indexOf("***") > -1) throw $sceMinErr("iwcard", "Illegal sequence *** in string matcher. String: {0}", matcher); | |
return matcher = escapeForRegexp(matcher).replace("\\*\\*", ".*").replace("\\*", "[^:/.?&;]*"), new RegExp("^" + matcher + "$") | |
} | |
if (isRegExp(matcher)) return new RegExp("^" + matcher.source + "$"); | |
throw $sceMinErr("imatcher", 'Matchers may only be "self", string patterns or RegExp objects') | |
} | |
function adjustMatchers(matchers) { | |
var adjustedMatchers = []; | |
return isDefined(matchers) && forEach(matchers, function(matcher) { | |
adjustedMatchers.push(adjustMatcher(matcher)) | |
}), adjustedMatchers | |
} | |
function $SceDelegateProvider() { | |
this.SCE_CONTEXTS = SCE_CONTEXTS; | |
var resourceUrlWhitelist = ["self"], | |
resourceUrlBlacklist = []; | |
this.resourceUrlWhitelist = function(value) { | |
return arguments.length && (resourceUrlWhitelist = adjustMatchers(value)), resourceUrlWhitelist | |
}, this.resourceUrlBlacklist = function(value) { | |
return arguments.length && (resourceUrlBlacklist = adjustMatchers(value)), resourceUrlBlacklist | |
}, this.$get = ["$injector", function($injector) { | |
var htmlSanitizer = function(html) { | |
throw $sceMinErr("unsafe", "Attempting to use an unsafe value in a safe context.") | |
}; | |
$injector.has("$sanitize") && (htmlSanitizer = $injector.get("$sanitize")); | |
function matchUrl(matcher, parsedUrl) { | |
return "self" === matcher ? urlIsSameOrigin(parsedUrl) : !!matcher.exec(parsedUrl.href) | |
} | |
function isResourceUrlAllowedByPolicy(url) { | |
var i, n, parsedUrl = urlResolve(url.toString()), | |
allowed = !1; | |
for (i = 0, n = resourceUrlWhitelist.length; n > i; i++) | |
if (matchUrl(resourceUrlWhitelist[i], parsedUrl)) { | |
allowed = !0; | |
break | |
} | |
if (allowed) | |
for (i = 0, n = resourceUrlBlacklist.length; n > i; i++) | |
if (matchUrl(resourceUrlBlacklist[i], parsedUrl)) { | |
allowed = !1; | |
break | |
} | |
return allowed | |
} | |
function generateHolderType(Base) { | |
var holderType = function(trustedValue) { | |
this.$$unwrapTrustedValue = function() { | |
return trustedValue | |
} | |
}; | |
return Base && (holderType.prototype = new Base), holderType.prototype.valueOf = function() { | |
return this.$$unwrapTrustedValue() | |
}, holderType.prototype.toString = function() { | |
return this.$$unwrapTrustedValue().toString() | |
}, holderType | |
} | |
var trustedValueHolderBase = generateHolderType(), | |
byType = {}; | |
byType[SCE_CONTEXTS.HTML] = generateHolderType(trustedValueHolderBase), byType[SCE_CONTEXTS.CSS] = generateHolderType(trustedValueHolderBase), byType[SCE_CONTEXTS.URL] = generateHolderType(trustedValueHolderBase), byType[SCE_CONTEXTS.JS] = generateHolderType(trustedValueHolderBase), byType[SCE_CONTEXTS.RESOURCE_URL] = generateHolderType(byType[SCE_CONTEXTS.URL]); | |
function trustAs(type, trustedValue) { | |
var Constructor = byType.hasOwnProperty(type) ? byType[type] : null; | |
if (!Constructor) throw $sceMinErr("icontext", "Attempted to trust a value in invalid context. Context: {0}; Value: {1}", type, trustedValue); | |
if (null === trustedValue || trustedValue === undefined || "" === trustedValue) return trustedValue; | |
if ("string" != typeof trustedValue) throw $sceMinErr("itype", "Attempted to trust a non-string value in a content requiring a string: Context: {0}", type); | |
return new Constructor(trustedValue) | |
} | |
function valueOf(maybeTrusted) { | |
return maybeTrusted instanceof trustedValueHolderBase ? maybeTrusted.$$unwrapTrustedValue() : maybeTrusted | |
} | |
function getTrusted(type, maybeTrusted) { | |
if (null === maybeTrusted || maybeTrusted === undefined || "" === maybeTrusted) return maybeTrusted; | |
var constructor = byType.hasOwnProperty(type) ? byType[type] : null; | |
if (constructor && maybeTrusted instanceof constructor) return maybeTrusted.$$unwrapTrustedValue(); | |
if (type === SCE_CONTEXTS.RESOURCE_URL) { | |
if (isResourceUrlAllowedByPolicy(maybeTrusted)) return maybeTrusted; | |
throw $sceMinErr("insecurl", "Blocked loading resource from url not allowed by $sceDelegate policy. URL: {0}", maybeTrusted.toString()) | |
} | |
if (type === SCE_CONTEXTS.HTML) return htmlSanitizer(maybeTrusted); | |
throw $sceMinErr("unsafe", "Attempting to use an unsafe value in a safe context.") | |
} | |
return { | |
trustAs: trustAs, | |
getTrusted: getTrusted, | |
valueOf: valueOf | |
} | |
}] | |
} | |
function $SceProvider() { | |
var enabled = !0; | |
this.enabled = function(value) { | |
return arguments.length && (enabled = !!value), enabled | |
}, this.$get = ["$parse", "$sceDelegate", function($parse, $sceDelegate) { | |
if (enabled && 8 > msie) throw $sceMinErr("iequirks", "Strict Contextual Escaping does not support Internet Explorer version < 11 in quirks mode. You can fix this by adding the text <!doctype html> to the top of your HTML document. See http://docs.angularjs.org/api/ng.$sce for more information."); | |
var sce = shallowCopy(SCE_CONTEXTS); | |
sce.isEnabled = function() { | |
return enabled | |
}, sce.trustAs = $sceDelegate.trustAs, sce.getTrusted = $sceDelegate.getTrusted, sce.valueOf = $sceDelegate.valueOf, enabled || (sce.trustAs = sce.getTrusted = function(type, value) { | |
return value | |
}, sce.valueOf = identity), sce.parseAs = function(type, expr) { | |
var parsed = $parse(expr); | |
return parsed.literal && parsed.constant ? parsed : $parse(expr, function(value) { | |
return sce.getTrusted(type, value) | |
}) | |
}; | |
var parse = sce.parseAs, | |
getTrusted = sce.getTrusted, | |
trustAs = sce.trustAs; | |
return forEach(SCE_CONTEXTS, function(enumValue, name) { | |
var lName = lowercase(name); | |
sce[camelCase("parse_as_" + lName)] = function(expr) { | |
return parse(enumValue, expr) | |
}, sce[camelCase("get_trusted_" + lName)] = function(value) { | |
return getTrusted(enumValue, value) | |
}, sce[camelCase("trust_as_" + lName)] = function(value) { | |
return trustAs(enumValue, value) | |
} | |
}), sce | |
}] | |
} | |
function $SnifferProvider() { | |
this.$get = ["$window", "$document", function($window, $document) { | |
var vendorPrefix, match, eventSupport = {}, | |
android = toInt((/android (\d+)/.exec(lowercase(($window.navigator || {}).userAgent)) || [])[1]), | |
boxee = /Boxee/i.test(($window.navigator || {}).userAgent), | |
document = $document[0] || {}, | |
vendorRegex = /^(Moz|webkit|ms)(?=[A-Z])/, | |
bodyStyle = document.body && document.body.style, | |
transitions = !1, | |
animations = !1; | |
if (bodyStyle) { | |
for (var prop in bodyStyle) | |
if (match = vendorRegex.exec(prop)) { | |
vendorPrefix = match[0], vendorPrefix = vendorPrefix.substr(0, 1).toUpperCase() + vendorPrefix.substr(1); | |
break | |
} | |
vendorPrefix || (vendorPrefix = "WebkitOpacity" in bodyStyle && "webkit"), transitions = !!("transition" in bodyStyle || vendorPrefix + "Transition" in bodyStyle), animations = !!("animation" in bodyStyle || vendorPrefix + "Animation" in bodyStyle), !android || transitions && animations || (transitions = isString(bodyStyle.webkitTransition), animations = isString(bodyStyle.webkitAnimation)) | |
} | |
return { | |
history: !(!$window.history || !$window.history.pushState || 4 > android || boxee), | |
hasEvent: function(event) { | |
if ("input" === event && 11 >= msie) return !1; | |
if (isUndefined(eventSupport[event])) { | |
var divElm = document.createElement("div"); | |
eventSupport[event] = "on" + event in divElm | |
} | |
return eventSupport[event] | |
}, | |
csp: csp(), | |
vendorPrefix: vendorPrefix, | |
transitions: transitions, | |
animations: animations, | |
android: android | |
} | |
}] | |
} | |
var $compileMinErr = minErr("$compile"); | |
function $TemplateRequestProvider() { | |
this.$get = ["$templateCache", "$http", "$q", function($templateCache, $http, $q) { | |
function handleRequestFn(tpl, ignoreRequestError) { | |
handleRequestFn.totalPendingRequests++; | |
var transformResponse = $http.defaults && $http.defaults.transformResponse; | |
isArray(transformResponse) ? transformResponse = transformResponse.filter(function(transformer) { | |
return transformer !== defaultHttpResponseTransform | |
}) : transformResponse === defaultHttpResponseTransform && (transformResponse = null); | |
var httpOptions = { | |
cache: $templateCache, | |
transformResponse: transformResponse | |
}; | |
return $http.get(tpl, httpOptions)["finally"](function() { | |
handleRequestFn.totalPendingRequests-- | |
}).then(function(response) { | |
return $templateCache.put(tpl, response.data), response.data | |
}, handleError); | |
function handleError(resp) { | |
if (!ignoreRequestError) throw $compileMinErr("tpload", "Failed to load template: {0} (HTTP status: {1} {2})", tpl, resp.status, resp.statusText); | |
return $q.reject(resp) | |
} | |
} | |
return handleRequestFn.totalPendingRequests = 0, handleRequestFn | |
}] | |
} | |
function $$TestabilityProvider() { | |
this.$get = ["$rootScope", "$browser", "$location", function($rootScope, $browser, $location) { | |
var testability = {}; | |
return testability.findBindings = function(element, expression, opt_exactMatch) { | |
var bindings = element.getElementsByClassName("ng-binding"), | |
matches = []; | |
return forEach(bindings, function(binding) { | |
var dataBinding = angular.element(binding).data("$binding"); | |
dataBinding && forEach(dataBinding, function(bindingName) { | |
if (opt_exactMatch) { | |
var matcher = new RegExp("(^|\\s)" + escapeForRegexp(expression) + "(\\s|\\||$)"); | |
matcher.test(bindingName) && matches.push(binding) | |
} else -1 != bindingName.indexOf(expression) && matches.push(binding) | |
}) | |
}), matches | |
}, testability.findModels = function(element, expression, opt_exactMatch) { | |
for (var prefixes = ["ng-", "data-ng-", "ng\\:"], p = 0; p < prefixes.length; ++p) { | |
var attributeEquals = opt_exactMatch ? "=" : "*=", | |
selector = "[" + prefixes[p] + "model" + attributeEquals + '"' + expression + '"]', | |
elements = element.querySelectorAll(selector); | |
if (elements.length) return elements | |
} | |
}, testability.getLocation = function() { | |
return $location.url() | |
}, testability.setLocation = function(url) { | |
url !== $location.url() && ($location.url(url), $rootScope.$digest()) | |
}, testability.whenStable = function(callback) { | |
$browser.notifyWhenNoOutstandingRequests(callback) | |
}, testability | |
}] | |
} | |
function $TimeoutProvider() { | |
this.$get = ["$rootScope", "$browser", "$q", "$$q", "$exceptionHandler", function($rootScope, $browser, $q, $$q, $exceptionHandler) { | |
var deferreds = {}; | |
function timeout(fn, delay, invokeApply) { | |
isFunction(fn) || (invokeApply = delay, delay = fn, fn = noop); | |
var timeoutId, args = sliceArgs(arguments, 3), | |
skipApply = isDefined(invokeApply) && !invokeApply, | |
deferred = (skipApply ? $$q : $q).defer(), | |
promise = deferred.promise; | |
return timeoutId = $browser.defer(function() { | |
try { | |
deferred.resolve(fn.apply(null, args)) | |
} catch (e) { | |
deferred.reject(e), $exceptionHandler(e) | |
} finally { | |
delete deferreds[promise.$$timeoutId] | |
} | |
skipApply || $rootScope.$apply() | |
}, delay), promise.$$timeoutId = timeoutId, deferreds[timeoutId] = deferred, promise | |
} | |
return timeout.cancel = function(promise) { | |
if (promise && promise.$$timeoutId in deferreds) return deferreds[promise.$$timeoutId].reject("canceled"), delete deferreds[promise.$$timeoutId], $browser.defer.cancel(promise.$$timeoutId); | |
return !1 | |
}, timeout | |
}] | |
} | |
var urlParsingNode = document.createElement("a"), | |
originUrl = urlResolve(window.location.href); | |
function urlResolve(url) { | |
var href = url; | |
return msie && (urlParsingNode.setAttribute("href", href), href = urlParsingNode.href), urlParsingNode.setAttribute("href", href), { | |
href: urlParsingNode.href, | |
protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, "") : "", | |
host: urlParsingNode.host, | |
search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, "") : "", | |
hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, "") : "", | |
hostname: urlParsingNode.hostname, | |
port: urlParsingNode.port, | |
pathname: "/" === urlParsingNode.pathname.charAt(0) ? urlParsingNode.pathname : "/" + urlParsingNode.pathname | |
} | |
} | |
function urlIsSameOrigin(requestUrl) { | |
var parsed = isString(requestUrl) ? urlResolve(requestUrl) : requestUrl; | |
return parsed.protocol === originUrl.protocol && parsed.host === originUrl.host | |
} | |
function $WindowProvider() { | |
this.$get = valueFn(window) | |
} | |
function $$CookieReader($document) { | |
var rawDocument = $document[0] || {}, | |
lastCookies = {}, | |
lastCookieString = ""; | |
function safeDecodeURIComponent(str) { | |
try { | |
return decodeURIComponent(str) | |
} catch (e) { | |
return str | |
} | |
} | |
return function() { | |
var cookieArray, cookie, i, index, name, currentCookieString = rawDocument.cookie || ""; | |
if (currentCookieString !== lastCookieString) | |
for (lastCookieString = currentCookieString, cookieArray = lastCookieString.split("; "), lastCookies = {}, i = 0; i < cookieArray.length; i++) cookie = cookieArray[i], index = cookie.indexOf("="), index > 0 && (name = safeDecodeURIComponent(cookie.substring(0, index)), lastCookies[name] === undefined && (lastCookies[name] = safeDecodeURIComponent(cookie.substring(index + 1)))); | |
return lastCookies | |
} | |
} | |
$$CookieReader.$inject = ["$document"]; | |
function $$CookieReaderProvider() { | |
this.$get = $$CookieReader | |
} | |
$FilterProvider.$inject = ["$provide"]; | |
function $FilterProvider($provide) { | |
var suffix = "Filter"; | |
function register(name, factory) { | |
if (isObject(name)) { | |
var filters = {}; | |
return forEach(name, function(filter, key) { | |
filters[key] = register(key, filter) | |
}), filters | |
} | |
return $provide.factory(name + suffix, factory) | |
} | |
this.register = register, this.$get = ["$injector", function($injector) { | |
return function(name) { | |
return $injector.get(name + suffix) | |
} | |
}], register("currency", currencyFilter), register("date", dateFilter), register("filter", filterFilter), register("json", jsonFilter), register("limitTo", limitToFilter), register("lowercase", lowercaseFilter), register("number", numberFilter), register("orderBy", orderByFilter), register("uppercase", uppercaseFilter) | |
} | |
function filterFilter() { | |
return function(array, expression, comparator) { | |
if (!isArray(array)) { | |
if (null == array) return array; | |
throw minErr("filter")("notarray", "Expected array but received: {0}", array) | |
} | |
var predicateFn, matchAgainstAnyProp, expressionType = getTypeForFilter(expression); | |
switch (expressionType) { | |
case "function": | |
predicateFn = expression; | |
break; | |
case "boolean": | |
case "null": | |
case "number": | |
case "string": | |
matchAgainstAnyProp = !0; | |
case "object": | |
predicateFn = createPredicateFn(expression, comparator, matchAgainstAnyProp); | |
break; | |
default: | |
return array | |
} | |
return array.filter(predicateFn) | |
} | |
} | |
function hasCustomToString(obj) { | |
return isFunction(obj.toString) && obj.toString !== Object.prototype.toString | |
} | |
function createPredicateFn(expression, comparator, matchAgainstAnyProp) { | |
var predicateFn, shouldMatchPrimitives = isObject(expression) && "$" in expression; | |
return comparator === !0 ? comparator = equals : isFunction(comparator) || (comparator = function(actual, expected) { | |
if (isUndefined(actual)) return !1; | |
if (null === actual || null === expected) return actual === expected; | |
if (isObject(expected) || isObject(actual) && !hasCustomToString(actual)) return !1; | |
return actual = lowercase("" + actual), expected = lowercase("" + expected), -1 !== actual.indexOf(expected) | |
}), predicateFn = function(item) { | |
if (shouldMatchPrimitives && !isObject(item)) return deepCompare(item, expression.$, comparator, !1); | |
return deepCompare(item, expression, comparator, matchAgainstAnyProp) | |
} | |
} | |
function deepCompare(actual, expected, comparator, matchAgainstAnyProp, dontMatchWholeObject) { | |
var actualType = getTypeForFilter(actual), | |
expectedType = getTypeForFilter(expected); | |
if ("string" === expectedType && "!" === expected.charAt(0)) return !deepCompare(actual, expected.substring(1), comparator, matchAgainstAnyProp); | |
if (isArray(actual)) return actual.some(function(item) { | |
return deepCompare(item, expected, comparator, matchAgainstAnyProp) | |
}); | |
switch (actualType) { | |
case "object": | |
var key; | |
if (matchAgainstAnyProp) { | |
for (key in actual) | |
if ("$" !== key.charAt(0) && deepCompare(actual[key], expected, comparator, !0)) return !0; | |
return dontMatchWholeObject ? !1 : deepCompare(actual, expected, comparator, !1) | |
} | |
if ("object" === expectedType) { | |
for (key in expected) { | |
var expectedVal = expected[key]; | |
if (isFunction(expectedVal) || isUndefined(expectedVal)) continue; | |
var matchAnyProperty = "$" === key, | |
actualVal = matchAnyProperty ? actual : actual[key]; | |
if (!deepCompare(actualVal, expectedVal, comparator, matchAnyProperty, matchAnyProperty)) return !1 | |
} | |
return !0 | |
} | |
return comparator(actual, expected); | |
case "function": | |
return !1; | |
default: | |
return comparator(actual, expected) | |
} | |
} | |
function getTypeForFilter(val) { | |
return null === val ? "null" : typeof val | |
} | |
currencyFilter.$inject = ["$locale"]; | |
function currencyFilter($locale) { | |
var formats = $locale.NUMBER_FORMATS; | |
return function(amount, currencySymbol, fractionSize) { | |
return isUndefined(currencySymbol) && (currencySymbol = formats.CURRENCY_SYM), isUndefined(fractionSize) && (fractionSize = formats.PATTERNS[1].maxFrac), null == amount ? amount : formatNumber(amount, formats.PATTERNS[1], formats.GROUP_SEP, formats.DECIMAL_SEP, fractionSize).replace(/\u00A4/g, currencySymbol) | |
} | |
} | |
numberFilter.$inject = ["$locale"]; | |
function numberFilter($locale) { | |
var formats = $locale.NUMBER_FORMATS; | |
return function(number, fractionSize) { | |
return null == number ? number : formatNumber(number, formats.PATTERNS[0], formats.GROUP_SEP, formats.DECIMAL_SEP, fractionSize) | |
} | |
} | |
var DECIMAL_SEP = "."; | |
function formatNumber(number, pattern, groupSep, decimalSep, fractionSize) { | |
if (isObject(number)) return ""; | |
var isNegative = 0 > number; | |
number = Math.abs(number); | |
var isInfinity = number === 1 / 0; | |
if (!isInfinity && !isFinite(number)) return ""; | |
var numStr = number + "", | |
formatedText = "", | |
hasExponent = !1, | |
parts = []; | |
if (isInfinity && (formatedText = "∞"), !isInfinity && -1 !== numStr.indexOf("e")) { | |
var match = numStr.match(/([\d\.]+)e(-?)(\d+)/); | |
match && "-" == match[2] && match[3] > fractionSize + 1 ? number = 0 : (formatedText = numStr, hasExponent = !0) | |
} | |
if (isInfinity || hasExponent) fractionSize > 0 && 1 > number && (formatedText = number.toFixed(fractionSize), number = parseFloat(formatedText)); | |
else { | |
var fractionLen = (numStr.split(DECIMAL_SEP)[1] || "").length; | |
isUndefined(fractionSize) && (fractionSize = Math.min(Math.max(pattern.minFrac, fractionLen), pattern.maxFrac)), number = +(Math.round(+(number.toString() + "e" + fractionSize)).toString() + "e" + -fractionSize); | |
var fraction = ("" + number).split(DECIMAL_SEP), | |
whole = fraction[0]; | |
fraction = fraction[1] || ""; | |
var i, pos = 0, | |
lgroup = pattern.lgSize, | |
group = pattern.gSize; | |
if (whole.length >= lgroup + group) | |
for (pos = whole.length - lgroup, i = 0; pos > i; i++)(pos - i) % group === 0 && 0 !== i && (formatedText += groupSep), formatedText += whole.charAt(i); | |
for (i = pos; i < whole.length; i++)(whole.length - i) % lgroup === 0 && 0 !== i && (formatedText += groupSep), formatedText += whole.charAt(i); | |
for (; fraction.length < fractionSize;) fraction += "0"; | |
fractionSize && "0" !== fractionSize && (formatedText += decimalSep + fraction.substr(0, fractionSize)) | |
} | |
return 0 === number && (isNegative = !1), parts.push(isNegative ? pattern.negPre : pattern.posPre, formatedText, isNegative ? pattern.negSuf : pattern.posSuf), parts.join("") | |
} | |
function padNumber(num, digits, trim) { | |
var neg = ""; | |
for (0 > num && (neg = "-", num = -num), num = "" + num; num.length < digits;) num = "0" + num; | |
return trim && (num = num.substr(num.length - digits)), neg + num | |
} | |
function dateGetter(name, size, offset, trim) { | |
return offset = offset || 0, | |
function(date) { | |
var value = date["get" + name](); | |
return (offset > 0 || value > -offset) && (value += offset), 0 === value && -12 == offset && (value = 12), padNumber(value, size, trim) | |
} | |
} | |
function dateStrGetter(name, shortForm) { | |
return function(date, formats) { | |
var value = date["get" + name](), | |
get = uppercase(shortForm ? "SHORT" + name : name); | |
return formats[get][value] | |
} | |
} | |
function timeZoneGetter(date, formats, offset) { | |
var zone = -1 * offset, | |
paddedZone = zone >= 0 ? "+" : ""; | |
return paddedZone += padNumber(Math[zone > 0 ? "floor" : "ceil"](zone / 60), 2) + padNumber(Math.abs(zone % 60), 2) | |
} | |
function getFirstThursdayOfYear(year) { | |
var dayOfWeekOnFirst = new Date(year, 0, 1).getDay(); | |
return new Date(year, 0, (4 >= dayOfWeekOnFirst ? 5 : 12) - dayOfWeekOnFirst) | |
} | |
function getThursdayThisWeek(datetime) { | |
return new Date(datetime.getFullYear(), datetime.getMonth(), datetime.getDate() + (4 - datetime.getDay())) | |
} | |
function weekGetter(size) { | |
return function(date) { | |
var firstThurs = getFirstThursdayOfYear(date.getFullYear()), | |
thisThurs = getThursdayThisWeek(date), | |
diff = +thisThurs - +firstThurs, | |
result = 1 + Math.round(diff / 6048e5); | |
return padNumber(result, size) | |
} | |
} | |
function ampmGetter(date, formats) { | |
return date.getHours() < 12 ? formats.AMPMS[0] : formats.AMPMS[1] | |
} | |
function eraGetter(date, formats) { | |
return date.getFullYear() <= 0 ? formats.ERAS[0] : formats.ERAS[1] | |
} | |
function longEraGetter(date, formats) { | |
return date.getFullYear() <= 0 ? formats.ERANAMES[0] : formats.ERANAMES[1] | |
} | |
var DATE_FORMATS = { | |
yyyy: dateGetter("FullYear", 4), | |
yy: dateGetter("FullYear", 2, 0, !0), | |
y: dateGetter("FullYear", 1), | |
MMMM: dateStrGetter("Month"), | |
MMM: dateStrGetter("Month", !0), | |
MM: dateGetter("Month", 2, 1), | |
M: dateGetter("Month", 1, 1), | |
dd: dateGetter("Date", 2), | |
d: dateGetter("Date", 1), | |
HH: dateGetter("Hours", 2), | |
H: dateGetter("Hours", 1), | |
hh: dateGetter("Hours", 2, -12), | |
h: dateGetter("Hours", 1, -12), | |
mm: dateGetter("Minutes", 2), | |
m: dateGetter("Minutes", 1), | |
ss: dateGetter("Seconds", 2), | |
s: dateGetter("Seconds", 1), | |
sss: dateGetter("Milliseconds", 3), | |
EEEE: dateStrGetter("Day"), | |
EEE: dateStrGetter("Day", !0), | |
a: ampmGetter, | |
Z: timeZoneGetter, | |
ww: weekGetter(2), | |
w: weekGetter(1), | |
G: eraGetter, | |
GG: eraGetter, | |
GGG: eraGetter, | |
GGGG: longEraGetter | |
}, | |
DATE_FORMATS_SPLIT = /((?:[^yMdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/, | |
NUMBER_STRING = /^\-?\d+$/; | |
dateFilter.$inject = ["$locale"]; | |
function dateFilter($locale) { | |
var R_ISO8601_STR = /^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/; | |
function jsonStringToDate(string) { | |
var match; | |
if (match = string.match(R_ISO8601_STR)) { | |
var date = new Date(0), | |
tzHour = 0, | |
tzMin = 0, | |
dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear, | |
timeSetter = match[8] ? date.setUTCHours : date.setHours; | |
match[9] && (tzHour = toInt(match[9] + match[10]), tzMin = toInt(match[9] + match[11])), dateSetter.call(date, toInt(match[1]), toInt(match[2]) - 1, toInt(match[3])); | |
var h = toInt(match[4] || 0) - tzHour, | |
m = toInt(match[5] || 0) - tzMin, | |
s = toInt(match[6] || 0), | |
ms = Math.round(1e3 * parseFloat("0." + (match[7] || 0))); | |
return timeSetter.call(date, h, m, s, ms), date | |
} | |
return string | |
} | |
return function(date, format, timezone) { | |
var fn, match, text = "", | |
parts = []; | |
if (format = format || "mediumDate", format = $locale.DATETIME_FORMATS[format] || format, isString(date) && (date = NUMBER_STRING.test(date) ? toInt(date) : jsonStringToDate(date)), isNumber(date) && (date = new Date(date)), !isDate(date) || !isFinite(date.getTime())) return date; | |
for (; format;) match = DATE_FORMATS_SPLIT.exec(format), match ? (parts = concat(parts, match, 1), format = parts.pop()) : (parts.push(format), format = null); | |
var dateTimezoneOffset = date.getTimezoneOffset(); | |
return timezone && (dateTimezoneOffset = timezoneToOffset(timezone, date.getTimezoneOffset()), date = convertTimezoneToLocal(date, timezone, !0)), forEach(parts, function(value) { | |
fn = DATE_FORMATS[value], text += fn ? fn(date, $locale.DATETIME_FORMATS, dateTimezoneOffset) : value.replace(/(^'|'$)/g, "").replace(/''/g, "'") | |
}), text | |
} | |
} | |
function jsonFilter() { | |
return function(object, spacing) { | |
return isUndefined(spacing) && (spacing = 2), toJson(object, spacing) | |
} | |
} | |
var lowercaseFilter = valueFn(lowercase), | |
uppercaseFilter = valueFn(uppercase); | |
function limitToFilter() { | |
return function(input, limit, begin) { | |
if (limit = Math.abs(Number(limit)) === 1 / 0 ? Number(limit) : toInt(limit), isNaN(limit)) return input; | |
if (isNumber(input) && (input = input.toString()), !isArray(input) && !isString(input)) return input; | |
return begin = !begin || isNaN(begin) ? 0 : toInt(begin), begin = 0 > begin && begin >= -input.length ? input.length + begin : begin, limit >= 0 ? input.slice(begin, begin + limit) : 0 === begin ? input.slice(limit, input.length) : input.slice(Math.max(0, begin + limit), begin) | |
} | |
} | |
orderByFilter.$inject = ["$parse"]; | |
function orderByFilter($parse) { | |
return function(array, sortPredicate, reverseOrder) { | |
if (!isArrayLike(array)) return array; | |
return sortPredicate = isArray(sortPredicate) ? sortPredicate : [sortPredicate], 0 === sortPredicate.length && (sortPredicate = ["+"]), sortPredicate = sortPredicate.map(function(predicate) { | |
var descending = !1, | |
get = predicate || identity; | |
if (isString(predicate)) { | |
if (("+" == predicate.charAt(0) || "-" == predicate.charAt(0)) && (descending = "-" == predicate.charAt(0), predicate = predicate.substring(1)), "" === predicate) return reverseComparator(compare, descending); | |
if (get = $parse(predicate), get.constant) { | |
var key = get(); | |
return reverseComparator(function(a, b) { | |
return compare(a[key], b[key]) | |
}, descending) | |
} | |
} | |
return reverseComparator(function(a, b) { | |
return compare(get(a), get(b)) | |
}, descending) | |
}), slice.call(array).sort(reverseComparator(comparator, reverseOrder)); | |
function comparator(o1, o2) { | |
for (var i = 0; i < sortPredicate.length; i++) { | |
var comp = sortPredicate[i](o1, o2); | |
if (0 !== comp) return comp | |
} | |
return 0 | |
} | |
function reverseComparator(comp, descending) { | |
return descending ? function(a, b) { | |
return comp(b, a) | |
} : comp | |
} | |
function isPrimitive(value) { | |
switch (typeof value) { | |
case "number": | |
case "boolean": | |
case "string": | |
return !0; | |
default: | |
return !1 | |
} | |
} | |
function objectToString(value) { | |
if (null === value) return "null"; | |
if ("function" == typeof value.valueOf && (value = value.valueOf(), isPrimitive(value))) return value; | |
if ("function" == typeof value.toString && (value = value.toString(), isPrimitive(value))) return value; | |
return "" | |
} | |
function compare(v1, v2) { | |
var t1 = typeof v1, | |
t2 = typeof v2; | |
if (t1 === t2 && "object" === t1 && (v1 = objectToString(v1), v2 = objectToString(v2)), t1 === t2) { | |
if ("string" === t1 && (v1 = v1.toLowerCase(), v2 = v2.toLowerCase()), v1 === v2) return 0; | |
return v2 > v1 ? -1 : 1 | |
} | |
return t2 > t1 ? -1 : 1 | |
} | |
} | |
} | |
function ngDirective(directive) { | |
return isFunction(directive) && (directive = { | |
link: directive | |
}), directive.restrict = directive.restrict || "AC", valueFn(directive) | |
} | |
var htmlAnchorDirective = valueFn({ | |
restrict: "E", | |
compile: function(element, attr) { | |
if (!attr.href && !attr.xlinkHref) return function(scope, element) { | |
if ("a" !== element[0].nodeName.toLowerCase()) return; | |
var href = "[object SVGAnimatedString]" === toString.call(element.prop("href")) ? "xlink:href" : "href"; | |
element.on("click", function(event) { | |
element.attr(href) || event.preventDefault() | |
}) | |
} | |
} | |
}), | |
ngAttributeAliasDirectives = {}; | |
forEach(BOOLEAN_ATTR, function(propName, attrName) { | |
if ("multiple" == propName) return; | |
function defaultLinkFn(scope, element, attr) { | |
scope.$watch(attr[normalized], function(value) { | |
attr.$set(attrName, !!value) | |
}) | |
} | |
var normalized = directiveNormalize("ng-" + attrName), | |
linkFn = defaultLinkFn; | |
"checked" === propName && (linkFn = function(scope, element, attr) { | |
attr.ngModel !== attr[normalized] && defaultLinkFn(scope, element, attr) | |
}), ngAttributeAliasDirectives[normalized] = function() { | |
return { | |
restrict: "A", | |
priority: 100, | |
link: linkFn | |
} | |
} | |
}), forEach(ALIASED_ATTR, function(htmlAttr, ngAttr) { | |
ngAttributeAliasDirectives[ngAttr] = function() { | |
return { | |
priority: 100, | |
link: function(scope, element, attr) { | |
if ("ngPattern" === ngAttr && "/" == attr.ngPattern.charAt(0)) { | |
var match = attr.ngPattern.match(REGEX_STRING_REGEXP); | |
if (match) return void attr.$set("ngPattern", new RegExp(match[1], match[2])) | |
} | |
scope.$watch(attr[ngAttr], function(value) { | |
attr.$set(ngAttr, value) | |
}) | |
} | |
} | |
} | |
}), forEach(["src", "srcset", "href"], function(attrName) { | |
var normalized = directiveNormalize("ng-" + attrName); | |
ngAttributeAliasDirectives[normalized] = function() { | |
return { | |
priority: 99, | |
link: function(scope, element, attr) { | |
var propName = attrName, | |
name = attrName; | |
"href" === attrName && "[object SVGAnimatedString]" === toString.call(element.prop("href")) && (name = "xlinkHref", attr.$attr[name] = "xlink:href", propName = null), attr.$observe(normalized, function(value) { | |
if (!value) return void("href" === attrName && attr.$set(name, null)); | |
attr.$set(name, value), msie && propName && element.prop(propName, attr[name]) | |
}) | |
} | |
} | |
} | |
}); | |
var nullFormCtrl = { | |
$addControl: noop, | |
$$renameControl: nullFormRenameControl, | |
$removeControl: noop, | |
$setValidity: noop, | |
$setDirty: noop, | |
$setPristine: noop, | |
$setSubmitted: noop | |
}, | |
SUBMITTED_CLASS = "ng-submitted"; | |
function nullFormRenameControl(control, name) { | |
control.$name = name | |
} | |
FormController.$inject = ["$element", "$attrs", "$scope", "$animate", "$interpolate"]; | |
function FormController(element, attrs, $scope, $animate, $interpolate) { | |
var form = this, | |
controls = [], | |
parentForm = form.$$parentForm = element.parent().controller("form") || nullFormCtrl; | |
form.$error = {}, form.$$success = {}, form.$pending = undefined, form.$name = $interpolate(attrs.name || attrs.ngForm || "")($scope), form.$dirty = !1, form.$pristine = !0, form.$valid = !0, form.$invalid = !1, form.$submitted = !1, parentForm.$addControl(form), form.$rollbackViewValue = function() { | |
forEach(controls, function(control) { | |
control.$rollbackViewValue() | |
}) | |
}, form.$commitViewValue = function() { | |
forEach(controls, function(control) { | |
control.$commitViewValue() | |
}) | |
}, form.$addControl = function(control) { | |
assertNotHasOwnProperty(control.$name, "input"), controls.push(control), control.$name && (form[control.$name] = control) | |
}, form.$$renameControl = function(control, newName) { | |
var oldName = control.$name; | |
form[oldName] === control && delete form[oldName], form[newName] = control, control.$name = newName | |
}, form.$removeControl = function(control) { | |
control.$name && form[control.$name] === control && delete form[control.$name], forEach(form.$pending, function(value, name) { | |
form.$setValidity(name, null, control) | |
}), forEach(form.$error, function(value, name) { | |
form.$setValidity(name, null, control) | |
}), forEach(form.$$success, function(value, name) { | |
form.$setValidity(name, null, control) | |
}), arrayRemove(controls, control) | |
}, addSetValidityMethod({ | |
ctrl: this, | |
$element: element, | |
set: function(object, property, controller) { | |
var list = object[property]; | |
if (list) { | |
var index = list.indexOf(controller); - 1 === index && list.push(controller) | |
} else object[property] = [controller] | |
}, | |
unset: function(object, property, controller) { | |
var list = object[property]; | |
if (!list) return; | |
arrayRemove(list, controller), 0 === list.length && delete object[property] | |
}, | |
parentForm: parentForm, | |
$animate: $animate | |
}), form.$setDirty = function() { | |
$animate.removeClass(element, PRISTINE_CLASS), $animate.addClass(element, DIRTY_CLASS), form.$dirty = !0, form.$pristine = !1, parentForm.$setDirty() | |
}, form.$setPristine = function() { | |
$animate.setClass(element, PRISTINE_CLASS, DIRTY_CLASS + " " + SUBMITTED_CLASS), form.$dirty = !1, form.$pristine = !0, form.$submitted = !1, forEach(controls, function(control) { | |
control.$setPristine() | |
}) | |
}, form.$setUntouched = function() { | |
forEach(controls, function(control) { | |
control.$setUntouched() | |
}) | |
}, form.$setSubmitted = function() { | |
$animate.addClass(element, SUBMITTED_CLASS), form.$submitted = !0, parentForm.$setSubmitted() | |
} | |
} | |
var formDirectiveFactory = function(isNgForm) { | |
return ["$timeout", function($timeout) { | |
var formDirective = { | |
name: "form", | |
restrict: isNgForm ? "EAC" : "E", | |
controller: FormController, | |
compile: function(formElement, attr) { | |
formElement.addClass(PRISTINE_CLASS).addClass(VALID_CLASS); | |
var nameAttr = attr.name ? "name" : isNgForm && attr.ngForm ? "ngForm" : !1; | |
return { | |
pre: function(scope, formElement, attr, controller) { | |
if (!("action" in attr)) { | |
var handleFormSubmission = function(event) { | |
scope.$apply(function() { | |
controller.$commitViewValue(), controller.$setSubmitted() | |
}), event.preventDefault() | |
}; | |
addEventListenerFn(formElement[0], "submit", handleFormSubmission), formElement.on("$destroy", function() { | |
$timeout(function() { | |
removeEventListenerFn(formElement[0], "submit", handleFormSubmission) | |
}, 0, !1) | |
}) | |
} | |
var parentFormCtrl = controller.$$parentForm; | |
nameAttr && (setter(scope, controller.$name, controller, controller.$name), attr.$observe(nameAttr, function(newValue) { | |
if (controller.$name === newValue) return; | |
setter(scope, controller.$name, undefined, controller.$name), parentFormCtrl.$$renameControl(controller, newValue), setter(scope, controller.$name, controller, controller.$name) | |
})), formElement.on("$destroy", function() { | |
parentFormCtrl.$removeControl(controller), nameAttr && setter(scope, attr[nameAttr], undefined, controller.$name), extend(controller, nullFormCtrl) | |
}) | |
} | |
} | |
} | |
}; | |
return formDirective | |
}] | |
}, | |
formDirective = formDirectiveFactory(), | |
ngFormDirective = formDirectiveFactory(!0), | |
ISO_DATE_REGEXP = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/, | |
URL_REGEXP = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/, | |
EMAIL_REGEXP = /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i, | |
NUMBER_REGEXP = /^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/, | |
DATE_REGEXP = /^(\d{4})-(\d{2})-(\d{2})$/, | |
DATETIMELOCAL_REGEXP = /^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/, | |
WEEK_REGEXP = /^(\d{4})-W(\d\d)$/, | |
MONTH_REGEXP = /^(\d{4})-(\d\d)$/, | |
TIME_REGEXP = /^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/, | |
inputType = { | |
text: textInputType, | |
date: createDateInputType("date", DATE_REGEXP, createDateParser(DATE_REGEXP, ["yyyy", "MM", "dd"]), "yyyy-MM-dd"), | |
"datetime-local": createDateInputType("datetimelocal", DATETIMELOCAL_REGEXP, createDateParser(DATETIMELOCAL_REGEXP, ["yyyy", "MM", "dd", "HH", "mm", "ss", "sss"]), "yyyy-MM-ddTHH:mm:ss.sss"), | |
time: createDateInputType("time", TIME_REGEXP, createDateParser(TIME_REGEXP, ["HH", "mm", "ss", "sss"]), "HH:mm:ss.sss"), | |
week: createDateInputType("week", WEEK_REGEXP, weekParser, "yyyy-Www"), | |
month: createDateInputType("month", MONTH_REGEXP, createDateParser(MONTH_REGEXP, ["yyyy", "MM"]), "yyyy-MM"), | |
number: numberInputType, | |
url: urlInputType, | |
email: emailInputType, | |
radio: radioInputType, | |
checkbox: checkboxInputType, | |
hidden: noop, | |
button: noop, | |
submit: noop, | |
reset: noop, | |
file: noop | |
}; | |
function stringBasedInputType(ctrl) { | |
ctrl.$formatters.push(function(value) { | |
return ctrl.$isEmpty(value) ? value : value.toString() | |
}) | |
} | |
function textInputType(scope, element, attr, ctrl, $sniffer, $browser) { | |
baseInputType(scope, element, attr, ctrl, $sniffer, $browser), stringBasedInputType(ctrl) | |
} | |
function baseInputType(scope, element, attr, ctrl, $sniffer, $browser) { | |
var type = lowercase(element[0].type); | |
if (!$sniffer.android) { | |
var composing = !1; | |
element.on("compositionstart", function(data) { | |
composing = !0 | |
}), element.on("compositionend", function() { | |
composing = !1, listener() | |
}) | |
} | |
var listener = function(ev) { | |
if (timeout && ($browser.defer.cancel(timeout), timeout = null), composing) return; | |
var value = element.val(), | |
event = ev && ev.type; | |
"password" === type || attr.ngTrim && "false" === attr.ngTrim || (value = trim(value)), (ctrl.$viewValue !== value || "" === value && ctrl.$$hasNativeValidators) && ctrl.$setViewValue(value, event) | |
}; | |
if ($sniffer.hasEvent("input")) element.on("input", listener); | |
else { | |
var timeout, deferListener = function(ev, input, origValue) { | |
timeout || (timeout = $browser.defer(function() { | |
timeout = null, input && input.value === origValue || listener(ev) | |
})) | |
}; | |
element.on("keydown", function(event) { | |
var key = event.keyCode; | |
if (91 === key || key > 15 && 19 > key || key >= 37 && 40 >= key) return; | |
deferListener(event, this, this.value) | |
}), $sniffer.hasEvent("paste") && element.on("paste cut", deferListener) | |
} | |
element.on("change", listener), ctrl.$render = function() { | |
element.val(ctrl.$isEmpty(ctrl.$viewValue) ? "" : ctrl.$viewValue) | |
} | |
} | |
function weekParser(isoWeek, existingDate) { | |
if (isDate(isoWeek)) return isoWeek; | |
if (isString(isoWeek)) { | |
WEEK_REGEXP.lastIndex = 0; | |
var parts = WEEK_REGEXP.exec(isoWeek); | |
if (parts) { | |
var year = +parts[1], | |
week = +parts[2], | |
hours = 0, | |
minutes = 0, | |
seconds = 0, | |
milliseconds = 0, | |
firstThurs = getFirstThursdayOfYear(year), | |
addDays = 7 * (week - 1); | |
return existingDate && (hours = existingDate.getHours(), minutes = existingDate.getMinutes(), seconds = existingDate.getSeconds(), milliseconds = existingDate.getMilliseconds()), new Date(year, 0, firstThurs.getDate() + addDays, hours, minutes, seconds, milliseconds) | |
} | |
} | |
return NaN | |
} | |
function createDateParser(regexp, mapping) { | |
return function(iso, date) { | |
var parts, map; | |
if (isDate(iso)) return iso; | |
if (isString(iso)) { | |
if ('"' == iso.charAt(0) && '"' == iso.charAt(iso.length - 1) && (iso = iso.substring(1, iso.length - 1)), ISO_DATE_REGEXP.test(iso)) return new Date(iso); | |
if (regexp.lastIndex = 0, parts = regexp.exec(iso)) return parts.shift(), map = date ? { | |
yyyy: date.getFullYear(), | |
MM: date.getMonth() + 1, | |
dd: date.getDate(), | |
HH: date.getHours(), | |
mm: date.getMinutes(), | |
ss: date.getSeconds(), | |
sss: date.getMilliseconds() / 1e3 | |
} : { | |
yyyy: 1970, | |
MM: 1, | |
dd: 1, | |
HH: 0, | |
mm: 0, | |
ss: 0, | |
sss: 0 | |
}, forEach(parts, function(part, index) { | |
index < mapping.length && (map[mapping[index]] = +part) | |
}), new Date(map.yyyy, map.MM - 1, map.dd, map.HH, map.mm, map.ss || 0, 1e3 * map.sss || 0) | |
} | |
return NaN | |
} | |
} | |
function createDateInputType(type, regexp, parseDate, format) { | |
return function(scope, element, attr, ctrl, $sniffer, $browser, $filter) { | |
badInputChecker(scope, element, attr, ctrl), baseInputType(scope, element, attr, ctrl, $sniffer, $browser); | |
var previousDate, timezone = ctrl && ctrl.$options && ctrl.$options.timezone; | |
if (ctrl.$$parserName = type, ctrl.$parsers.push(function(value) { | |
if (ctrl.$isEmpty(value)) return null; | |
if (regexp.test(value)) { | |
var parsedDate = parseDate(value, previousDate); | |
return timezone && (parsedDate = convertTimezoneToLocal(parsedDate, timezone)), parsedDate | |
} | |
return undefined | |
}), ctrl.$formatters.push(function(value) { | |
if (value && !isDate(value)) throw $ngModelMinErr("datefmt", "Expected `{0}` to be a date", value); | |
return isValidDate(value) ? (previousDate = value, previousDate && timezone && (previousDate = convertTimezoneToLocal(previousDate, timezone, !0)), $filter("date")(value, format, timezone)) : (previousDate = null, "") | |
}), isDefined(attr.min) || attr.ngMin) { | |
var minVal; | |
ctrl.$validators.min = function(value) { | |
return !isValidDate(value) || isUndefined(minVal) || parseDate(value) >= minVal | |
}, attr.$observe("min", function(val) { | |
minVal = parseObservedDateValue(val), ctrl.$validate() | |
}) | |
} | |
if (isDefined(attr.max) || attr.ngMax) { | |
var maxVal; | |
ctrl.$validators.max = function(value) { | |
return !isValidDate(value) || isUndefined(maxVal) || parseDate(value) <= maxVal | |
}, attr.$observe("max", function(val) { | |
maxVal = parseObservedDateValue(val), ctrl.$validate() | |
}) | |
} | |
function isValidDate(value) { | |
return value && !(value.getTime && value.getTime() !== value.getTime()) | |
} | |
function parseObservedDateValue(val) { | |
return isDefined(val) ? isDate(val) ? val : parseDate(val) : undefined | |
} | |
} | |
} | |
function badInputChecker(scope, element, attr, ctrl) { | |
var node = element[0], | |
nativeValidation = ctrl.$$hasNativeValidators = isObject(node.validity); | |
nativeValidation && ctrl.$parsers.push(function(value) { | |
var validity = element.prop(VALIDITY_STATE_PROPERTY) || {}; | |
return validity.badInput && !validity.typeMismatch ? undefined : value | |
}) | |
} | |
function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { | |
if (badInputChecker(scope, element, attr, ctrl), baseInputType(scope, element, attr, ctrl, $sniffer, $browser), ctrl.$$parserName = "number", ctrl.$parsers.push(function(value) { | |
if (ctrl.$isEmpty(value)) return null; | |
if (NUMBER_REGEXP.test(value)) return parseFloat(value); | |
return undefined | |
}), ctrl.$formatters.push(function(value) { | |
if (!ctrl.$isEmpty(value)) { | |
if (!isNumber(value)) throw $ngModelMinErr("numfmt", "Expected `{0}` to be a number", value); | |
value = value.toString() | |
} | |
return value | |
}), isDefined(attr.min) || attr.ngMin) { | |
var minVal; | |
ctrl.$validators.min = function(value) { | |
return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal | |
}, attr.$observe("min", function(val) { | |
isDefined(val) && !isNumber(val) && (val = parseFloat(val, 10)), minVal = isNumber(val) && !isNaN(val) ? val : undefined, ctrl.$validate() | |
}) | |
} | |
if (isDefined(attr.max) || attr.ngMax) { | |
var maxVal; | |
ctrl.$validators.max = function(value) { | |
return ctrl.$isEmpty(value) || isUndefined(maxVal) || maxVal >= value | |
}, attr.$observe("max", function(val) { | |
isDefined(val) && !isNumber(val) && (val = parseFloat(val, 10)), maxVal = isNumber(val) && !isNaN(val) ? val : undefined, ctrl.$validate() | |
}) | |
} | |
} | |
function urlInputType(scope, element, attr, ctrl, $sniffer, $browser) { | |
baseInputType(scope, element, attr, ctrl, $sniffer, $browser), stringBasedInputType(ctrl), ctrl.$$parserName = "url", ctrl.$validators.url = function(modelValue, viewValue) { | |
var value = modelValue || viewValue; | |
return ctrl.$isEmpty(value) || URL_REGEXP.test(value) | |
} | |
} | |
function emailInputType(scope, element, attr, ctrl, $sniffer, $browser) { | |
baseInputType(scope, element, attr, ctrl, $sniffer, $browser), stringBasedInputType(ctrl), ctrl.$$parserName = "email", ctrl.$validators.email = function(modelValue, viewValue) { | |
var value = modelValue || viewValue; | |
return ctrl.$isEmpty(value) || EMAIL_REGEXP.test(value) | |
} | |
} | |
function radioInputType(scope, element, attr, ctrl) { | |
isUndefined(attr.name) && element.attr("name", nextUid()); | |
var listener = function(ev) { | |
element[0].checked && ctrl.$setViewValue(attr.value, ev && ev.type) | |
}; | |
element.on("click", listener), ctrl.$render = function() { | |
var value = attr.value; | |
element[0].checked = value == ctrl.$viewValue | |
}, attr.$observe("value", ctrl.$render) | |
} | |
function parseConstantExpr($parse, context, name, expression, fallback) { | |
var parseFn; | |
if (isDefined(expression)) { | |
if (parseFn = $parse(expression), !parseFn.constant) throw minErr("ngModel")("constexpr", "Expected constant expression for `{0}`, but saw `{1}`.", name, expression); | |
return parseFn(context) | |
} | |
return fallback | |
} | |
function checkboxInputType(scope, element, attr, ctrl, $sniffer, $browser, $filter, $parse) { | |
var trueValue = parseConstantExpr($parse, scope, "ngTrueValue", attr.ngTrueValue, !0), | |
falseValue = parseConstantExpr($parse, scope, "ngFalseValue", attr.ngFalseValue, !1), | |
listener = function(ev) { | |
ctrl.$setViewValue(element[0].checked, ev && ev.type) | |
}; | |
element.on("click", listener), ctrl.$render = function() { | |
element[0].checked = ctrl.$viewValue | |
}, ctrl.$isEmpty = function(value) { | |
return value === !1 | |
}, ctrl.$formatters.push(function(value) { | |
return equals(value, trueValue) | |
}), ctrl.$parsers.push(function(value) { | |
return value ? trueValue : falseValue | |
}) | |
} | |
var inputDirective = ["$browser", "$sniffer", "$filter", "$parse", function($browser, $sniffer, $filter, $parse) { | |
return { | |
restrict: "E", | |
require: ["?ngModel"], | |
link: { | |
pre: function(scope, element, attr, ctrls) { | |
ctrls[0] && (inputType[lowercase(attr.type)] || inputType.text)(scope, element, attr, ctrls[0], $sniffer, $browser, $filter, $parse) | |
} | |
} | |
} | |
}], | |
CONSTANT_VALUE_REGEXP = /^(true|false|\d+)$/, | |
ngValueDirective = function() { | |
return { | |
restrict: "A", | |
priority: 100, | |
compile: function(tpl, tplAttr) { | |
return CONSTANT_VALUE_REGEXP.test(tplAttr.ngValue) ? function(scope, elm, attr) { | |
attr.$set("value", scope.$eval(attr.ngValue)) | |
} : function(scope, elm, attr) { | |
scope.$watch(attr.ngValue, function(value) { | |
attr.$set("value", value) | |
}) | |
} | |
} | |
} | |
}, | |
ngBindDirective = ["$compile", function($compile) { | |
return { | |
restrict: "AC", | |
compile: function(templateElement) { | |
return $compile.$$addBindingClass(templateElement), | |
function(scope, element, attr) { | |
$compile.$$addBindingInfo(element, attr.ngBind), element = element[0], scope.$watch(attr.ngBind, function(value) { | |
element.textContent = value === undefined ? "" : value | |
}) | |
} | |
} | |
} | |
}], | |
ngBindTemplateDirective = ["$interpolate", "$compile", function($interpolate, $compile) { | |
return { | |
compile: function(templateElement) { | |
return $compile.$$addBindingClass(templateElement), | |
function(scope, element, attr) { | |
var interpolateFn = $interpolate(element.attr(attr.$attr.ngBindTemplate)); | |
$compile.$$addBindingInfo(element, interpolateFn.expressions), element = element[0], attr.$observe("ngBindTemplate", function(value) { | |
element.textContent = value === undefined ? "" : value | |
}) | |
} | |
} | |
} | |
}], | |
ngBindHtmlDirective = ["$sce", "$parse", "$compile", function($sce, $parse, $compile) { | |
return { | |
restrict: "A", | |
compile: function(tElement, tAttrs) { | |
var ngBindHtmlGetter = $parse(tAttrs.ngBindHtml), | |
ngBindHtmlWatch = $parse(tAttrs.ngBindHtml, function(value) { | |
return (value || "").toString() | |
}); | |
return $compile.$$addBindingClass(tElement), | |
function(scope, element, attr) { | |
$compile.$$addBindingInfo(element, attr.ngBindHtml), scope.$watch(ngBindHtmlWatch, function() { | |
element.html($sce.getTrustedHtml(ngBindHtmlGetter(scope)) || ""); | |
}) | |
} | |
} | |
} | |
}], | |
ngChangeDirective = valueFn({ | |
restrict: "A", | |
require: "ngModel", | |
link: function(scope, element, attr, ctrl) { | |
ctrl.$viewChangeListeners.push(function() { | |
scope.$eval(attr.ngChange) | |
}) | |
} | |
}); | |
function classDirective(name, selector) { | |
return name = "ngClass" + name, ["$animate", function($animate) { | |
return { | |
restrict: "AC", | |
link: function(scope, element, attr) { | |
var oldVal; | |
scope.$watch(attr[name], ngClassWatchAction, !0), attr.$observe("class", function(value) { | |
ngClassWatchAction(scope.$eval(attr[name])) | |
}), "ngClass" !== name && scope.$watch("$index", function($index, old$index) { | |
var mod = 1 & $index; | |
if (mod !== (1 & old$index)) { | |
var classes = arrayClasses(scope.$eval(attr[name])); | |
mod === selector ? addClasses(classes) : removeClasses(classes) | |
} | |
}); | |
function addClasses(classes) { | |
var newClasses = digestClassCounts(classes, 1); | |
attr.$addClass(newClasses) | |
} | |
function removeClasses(classes) { | |
var newClasses = digestClassCounts(classes, -1); | |
attr.$removeClass(newClasses) | |
} | |
function digestClassCounts(classes, count) { | |
var classCounts = element.data("$classCounts") || {}, | |
classesToUpdate = []; | |
return forEach(classes, function(className) { | |
(count > 0 || classCounts[className]) && (classCounts[className] = (classCounts[className] || 0) + count, classCounts[className] === +(count > 0) && classesToUpdate.push(className)) | |
}), element.data("$classCounts", classCounts), classesToUpdate.join(" ") | |
} | |
function updateClasses(oldClasses, newClasses) { | |
var toAdd = arrayDifference(newClasses, oldClasses), | |
toRemove = arrayDifference(oldClasses, newClasses); | |
toAdd = digestClassCounts(toAdd, 1), toRemove = digestClassCounts(toRemove, -1), toAdd && toAdd.length && $animate.addClass(element, toAdd), toRemove && toRemove.length && $animate.removeClass(element, toRemove) | |
} | |
function ngClassWatchAction(newVal) { | |
if (selector === !0 || scope.$index % 2 === selector) { | |
var newClasses = arrayClasses(newVal || []); | |
if (oldVal) { | |
if (!equals(newVal, oldVal)) { | |
var oldClasses = arrayClasses(oldVal); | |
updateClasses(oldClasses, newClasses) | |
} | |
} else addClasses(newClasses) | |
} | |
oldVal = shallowCopy(newVal) | |
} | |
} | |
}; | |
function arrayDifference(tokens1, tokens2) { | |
var values = []; | |
outer: for (var i = 0; i < tokens1.length; i++) { | |
for (var token = tokens1[i], j = 0; j < tokens2.length; j++) | |
if (token == tokens2[j]) continue outer; | |
values.push(token) | |
} | |
return values | |
} | |
function arrayClasses(classVal) { | |
var classes = []; | |
if (isArray(classVal)) return forEach(classVal, function(v) { | |
classes = classes.concat(arrayClasses(v)) | |
}), classes; | |
if (isString(classVal)) return classVal.split(" "); | |
if (isObject(classVal)) return forEach(classVal, function(v, k) { | |
v && (classes = classes.concat(k.split(" "))) | |
}), classes; | |
return classVal | |
} | |
}] | |
} | |
var ngClassDirective = classDirective("", !0), | |
ngClassOddDirective = classDirective("Odd", 0), | |
ngClassEvenDirective = classDirective("Even", 1), | |
ngCloakDirective = ngDirective({ | |
compile: function(element, attr) { | |
attr.$set("ngCloak", undefined), element.removeClass("ng-cloak") | |
} | |
}), | |
ngControllerDirective = [function() { | |
return { | |
restrict: "A", | |
scope: !0, | |
controller: "@", | |
priority: 500 | |
} | |
}], | |
ngEventDirectives = {}, | |
forceAsyncEvents = { | |
blur: !0, | |
focus: !0 | |
}; | |
forEach("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "), function(eventName) { | |
var directiveName = directiveNormalize("ng-" + eventName); | |
ngEventDirectives[directiveName] = ["$parse", "$rootScope", function($parse, $rootScope) { | |
return { | |
restrict: "A", | |
compile: function($element, attr) { | |
var fn = $parse(attr[directiveName], null, !0); | |
return function(scope, element) { | |
element.on(eventName, function(event) { | |
var callback = function() { | |
fn(scope, { | |
$event: event | |
}) | |
}; | |
forceAsyncEvents[eventName] && $rootScope.$$phase ? scope.$evalAsync(callback) : scope.$apply(callback) | |
}) | |
} | |
} | |
} | |
}] | |
}); | |
var ngIfDirective = ["$animate", function($animate) { | |
return { | |
multiElement: !0, | |
transclude: "element", | |
priority: 600, | |
terminal: !0, | |
restrict: "A", | |
$$tlb: !0, | |
link: function($scope, $element, $attr, ctrl, $transclude) { | |
var block, childScope, previousElements; | |
$scope.$watch($attr.ngIf, function(value) { | |
value ? childScope || $transclude(function(clone, newScope) { | |
childScope = newScope, clone[clone.length++] = document.createComment(" end ngIf: " + $attr.ngIf + " "), block = { | |
clone: clone | |
}, $animate.enter(clone, $element.parent(), $element) | |
}) : (previousElements && (previousElements.remove(), previousElements = null), childScope && (childScope.$destroy(), childScope = null), block && (previousElements = getBlockNodes(block.clone), $animate.leave(previousElements).then(function() { | |
previousElements = null | |
}), block = null)) | |
}) | |
} | |
} | |
}], | |
ngIncludeDirective = ["$templateRequest", "$anchorScroll", "$animate", "$sce", function($templateRequest, $anchorScroll, $animate, $sce) { | |
return { | |
restrict: "ECA", | |
priority: 400, | |
terminal: !0, | |
transclude: "element", | |
controller: angular.noop, | |
compile: function(element, attr) { | |
var srcExp = attr.ngInclude || attr.src, | |
onloadExp = attr.onload || "", | |
autoScrollExp = attr.autoscroll; | |
return function(scope, $element, $attr, ctrl, $transclude) { | |
var currentScope, previousElement, currentElement, changeCounter = 0, | |
cleanupLastIncludeContent = function() { | |
previousElement && (previousElement.remove(), previousElement = null), currentScope && (currentScope.$destroy(), currentScope = null), currentElement && ($animate.leave(currentElement).then(function() { | |
previousElement = null | |
}), previousElement = currentElement, currentElement = null) | |
}; | |
scope.$watch($sce.parseAsResourceUrl(srcExp), function(src) { | |
var afterAnimation = function() { | |
!isDefined(autoScrollExp) || autoScrollExp && !scope.$eval(autoScrollExp) || $anchorScroll() | |
}, | |
thisChangeId = ++changeCounter; | |
src ? ($templateRequest(src, !0).then(function(response) { | |
if (thisChangeId !== changeCounter) return; | |
var newScope = scope.$new(); | |
ctrl.template = response; | |
var clone = $transclude(newScope, function(clone) { | |
cleanupLastIncludeContent(), $animate.enter(clone, null, $element).then(afterAnimation) | |
}); | |
currentScope = newScope, currentElement = clone, currentScope.$emit("$includeContentLoaded", src), scope.$eval(onloadExp) | |
}, function() { | |
thisChangeId === changeCounter && (cleanupLastIncludeContent(), scope.$emit("$includeContentError", src)) | |
}), scope.$emit("$includeContentRequested", src)) : (cleanupLastIncludeContent(), ctrl.template = null) | |
}) | |
} | |
} | |
} | |
}], | |
ngIncludeFillContentDirective = ["$compile", function($compile) { | |
return { | |
restrict: "ECA", | |
priority: -400, | |
require: "ngInclude", | |
link: function(scope, $element, $attr, ctrl) { | |
if (/SVG/.test($element[0].toString())) return $element.empty(), void $compile(jqLiteBuildFragment(ctrl.template, document).childNodes)(scope, function(clone) { | |
$element.append(clone) | |
}, { | |
futureParentElement: $element | |
}); | |
$element.html(ctrl.template), $compile($element.contents())(scope) | |
} | |
} | |
}], | |
ngInitDirective = ngDirective({ | |
priority: 450, | |
compile: function() { | |
return { | |
pre: function(scope, element, attrs) { | |
scope.$eval(attrs.ngInit) | |
} | |
} | |
} | |
}), | |
ngListDirective = function() { | |
return { | |
restrict: "A", | |
priority: 100, | |
require: "ngModel", | |
link: function(scope, element, attr, ctrl) { | |
var ngList = element.attr(attr.$attr.ngList) || ", ", | |
trimValues = "false" !== attr.ngTrim, | |
separator = trimValues ? trim(ngList) : ngList, | |
parse = function(viewValue) { | |
if (isUndefined(viewValue)) return; | |
var list = []; | |
return viewValue && forEach(viewValue.split(separator), function(value) { | |
value && list.push(trimValues ? trim(value) : value) | |
}), list | |
}; | |
ctrl.$parsers.push(parse), ctrl.$formatters.push(function(value) { | |
if (isArray(value)) return value.join(ngList); | |
return undefined | |
}), ctrl.$isEmpty = function(value) { | |
return !value || !value.length | |
} | |
} | |
} | |
}, | |
VALID_CLASS = "ng-valid", | |
INVALID_CLASS = "ng-invalid", | |
PRISTINE_CLASS = "ng-pristine", | |
DIRTY_CLASS = "ng-dirty", | |
UNTOUCHED_CLASS = "ng-untouched", | |
TOUCHED_CLASS = "ng-touched", | |
PENDING_CLASS = "ng-pending", | |
$ngModelMinErr = new minErr("ngModel"), | |
NgModelController = ["$scope", "$exceptionHandler", "$attrs", "$element", "$parse", "$animate", "$timeout", "$rootScope", "$q", "$interpolate", function($scope, $exceptionHandler, $attr, $element, $parse, $animate, $timeout, $rootScope, $q, $interpolate) { | |
this.$viewValue = Number.NaN, this.$modelValue = Number.NaN, this.$$rawModelValue = undefined, this.$validators = {}, this.$asyncValidators = {}, this.$parsers = [], this.$formatters = [], this.$viewChangeListeners = [], this.$untouched = !0, this.$touched = !1, this.$pristine = !0, this.$dirty = !1, this.$valid = !0, this.$invalid = !1, this.$error = {}, this.$$success = {}, this.$pending = undefined, this.$name = $interpolate($attr.name || "", !1)($scope); | |
var parserValid, parsedNgModel = $parse($attr.ngModel), | |
parsedNgModelAssign = parsedNgModel.assign, | |
ngModelGet = parsedNgModel, | |
ngModelSet = parsedNgModelAssign, | |
pendingDebounce = null, | |
ctrl = this; | |
this.$$setOptions = function(options) { | |
if (ctrl.$options = options, options && options.getterSetter) { | |
var invokeModelGetter = $parse($attr.ngModel + "()"), | |
invokeModelSetter = $parse($attr.ngModel + "($$$p)"); | |
ngModelGet = function($scope) { | |
var modelValue = parsedNgModel($scope); | |
return isFunction(modelValue) && (modelValue = invokeModelGetter($scope)), modelValue | |
}, ngModelSet = function($scope, newValue) { | |
isFunction(parsedNgModel($scope)) ? invokeModelSetter($scope, { | |
$$$p: ctrl.$modelValue | |
}) : parsedNgModelAssign($scope, ctrl.$modelValue) | |
} | |
} else if (!parsedNgModel.assign) throw $ngModelMinErr("nonassign", "Expression '{0}' is non-assignable. Element: {1}", $attr.ngModel, startingTag($element)) | |
}, this.$render = noop, this.$isEmpty = function(value) { | |
return isUndefined(value) || "" === value || null === value || value !== value | |
}; | |
var parentForm = $element.inheritedData("$formController") || nullFormCtrl, | |
currentValidationRunId = 0; | |
addSetValidityMethod({ | |
ctrl: this, | |
$element: $element, | |
set: function(object, property) { | |
object[property] = !0 | |
}, | |
unset: function(object, property) { | |
delete object[property] | |
}, | |
parentForm: parentForm, | |
$animate: $animate | |
}), this.$setPristine = function() { | |
ctrl.$dirty = !1, ctrl.$pristine = !0, $animate.removeClass($element, DIRTY_CLASS), $animate.addClass($element, PRISTINE_CLASS) | |
}, this.$setDirty = function() { | |
ctrl.$dirty = !0, ctrl.$pristine = !1, $animate.removeClass($element, PRISTINE_CLASS), $animate.addClass($element, DIRTY_CLASS), parentForm.$setDirty() | |
}, this.$setUntouched = function() { | |
ctrl.$touched = !1, ctrl.$untouched = !0, $animate.setClass($element, UNTOUCHED_CLASS, TOUCHED_CLASS) | |
}, this.$setTouched = function() { | |
ctrl.$touched = !0, ctrl.$untouched = !1, $animate.setClass($element, TOUCHED_CLASS, UNTOUCHED_CLASS) | |
}, this.$rollbackViewValue = function() { | |
$timeout.cancel(pendingDebounce), ctrl.$viewValue = ctrl.$$lastCommittedViewValue, ctrl.$render() | |
}, this.$validate = function() { | |
if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) return; | |
var viewValue = ctrl.$$lastCommittedViewValue, | |
modelValue = ctrl.$$rawModelValue, | |
prevValid = ctrl.$valid, | |
prevModelValue = ctrl.$modelValue, | |
allowInvalid = ctrl.$options && ctrl.$options.allowInvalid; | |
ctrl.$$runValidators(modelValue, viewValue, function(allValid) { | |
allowInvalid || prevValid === allValid || (ctrl.$modelValue = allValid ? modelValue : undefined, ctrl.$modelValue !== prevModelValue && ctrl.$$writeModelToScope()) | |
}) | |
}, this.$$runValidators = function(modelValue, viewValue, doneCallback) { | |
currentValidationRunId++; | |
var localValidationRunId = currentValidationRunId; | |
if (!processParseErrors()) return void validationDone(!1); | |
if (!processSyncValidators()) return void validationDone(!1); | |
processAsyncValidators(); | |
function processParseErrors() { | |
var errorKey = ctrl.$$parserName || "parse"; | |
if (parserValid !== undefined) return parserValid || (forEach(ctrl.$validators, function(v, name) { | |
setValidity(name, null) | |
}), forEach(ctrl.$asyncValidators, function(v, name) { | |
setValidity(name, null) | |
})), setValidity(errorKey, parserValid), parserValid; | |
return setValidity(errorKey, null), !0 | |
} | |
function processSyncValidators() { | |
var syncValidatorsValid = !0; | |
if (forEach(ctrl.$validators, function(validator, name) { | |
var result = validator(modelValue, viewValue); | |
syncValidatorsValid = syncValidatorsValid && result, setValidity(name, result) | |
}), !syncValidatorsValid) return forEach(ctrl.$asyncValidators, function(v, name) { | |
setValidity(name, null) | |
}), !1; | |
return !0 | |
} | |
function processAsyncValidators() { | |
var validatorPromises = [], | |
allValid = !0; | |
forEach(ctrl.$asyncValidators, function(validator, name) { | |
var promise = validator(modelValue, viewValue); | |
if (!isPromiseLike(promise)) throw $ngModelMinErr("$asyncValidators", "Expected asynchronous validator to return a promise but got '{0}' instead.", promise); | |
setValidity(name, undefined), validatorPromises.push(promise.then(function() { | |
setValidity(name, !0) | |
}, function(error) { | |
allValid = !1, setValidity(name, !1) | |
})) | |
}), validatorPromises.length ? $q.all(validatorPromises).then(function() { | |
validationDone(allValid) | |
}, noop) : validationDone(!0) | |
} | |
function setValidity(name, isValid) { | |
localValidationRunId === currentValidationRunId && ctrl.$setValidity(name, isValid) | |
} | |
function validationDone(allValid) { | |
localValidationRunId === currentValidationRunId && doneCallback(allValid) | |
} | |
}, this.$commitViewValue = function() { | |
var viewValue = ctrl.$viewValue; | |
if ($timeout.cancel(pendingDebounce), ctrl.$$lastCommittedViewValue === viewValue && ("" !== viewValue || !ctrl.$$hasNativeValidators)) return; | |
ctrl.$$lastCommittedViewValue = viewValue, ctrl.$pristine && this.$setDirty(), this.$$parseAndValidate() | |
}, this.$$parseAndValidate = function() { | |
var viewValue = ctrl.$$lastCommittedViewValue, | |
modelValue = viewValue; | |
if (parserValid = isUndefined(modelValue) ? undefined : !0) | |
for (var i = 0; i < ctrl.$parsers.length; i++) | |
if (modelValue = ctrl.$parsers[i](modelValue), isUndefined(modelValue)) { | |
parserValid = !1; | |
break | |
} | |
isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue) && (ctrl.$modelValue = ngModelGet($scope)); | |
var prevModelValue = ctrl.$modelValue, | |
allowInvalid = ctrl.$options && ctrl.$options.allowInvalid; | |
ctrl.$$rawModelValue = modelValue, allowInvalid && (ctrl.$modelValue = modelValue, writeToModelIfNeeded()), ctrl.$$runValidators(modelValue, ctrl.$$lastCommittedViewValue, function(allValid) { | |
allowInvalid || (ctrl.$modelValue = allValid ? modelValue : undefined, writeToModelIfNeeded()) | |
}); | |
function writeToModelIfNeeded() { | |
ctrl.$modelValue !== prevModelValue && ctrl.$$writeModelToScope() | |
} | |
}, this.$$writeModelToScope = function() { | |
ngModelSet($scope, ctrl.$modelValue), forEach(ctrl.$viewChangeListeners, function(listener) { | |
try { | |
listener() | |
} catch (e) { | |
$exceptionHandler(e) | |
} | |
}) | |
}, this.$setViewValue = function(value, trigger) { | |
ctrl.$viewValue = value, (!ctrl.$options || ctrl.$options.updateOnDefault) && ctrl.$$debounceViewValueCommit(trigger) | |
}, this.$$debounceViewValueCommit = function(trigger) { | |
var debounce, debounceDelay = 0, | |
options = ctrl.$options; | |
options && isDefined(options.debounce) && (debounce = options.debounce, isNumber(debounce) ? debounceDelay = debounce : isNumber(debounce[trigger]) ? debounceDelay = debounce[trigger] : isNumber(debounce["default"]) && (debounceDelay = debounce["default"])), $timeout.cancel(pendingDebounce), debounceDelay ? pendingDebounce = $timeout(function() { | |
ctrl.$commitViewValue() | |
}, debounceDelay) : $rootScope.$$phase ? ctrl.$commitViewValue() : $scope.$apply(function() { | |
ctrl.$commitViewValue() | |
}) | |
}, $scope.$watch(function() { | |
var modelValue = ngModelGet($scope); | |
if (modelValue !== ctrl.$modelValue && (ctrl.$modelValue === ctrl.$modelValue || modelValue === modelValue)) { | |
ctrl.$modelValue = ctrl.$$rawModelValue = modelValue, parserValid = undefined; | |
for (var formatters = ctrl.$formatters, idx = formatters.length, viewValue = modelValue; idx--;) viewValue = formatters[idx](viewValue); | |
ctrl.$viewValue !== viewValue && (ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue, ctrl.$render(), ctrl.$$runValidators(modelValue, viewValue, noop)) | |
} | |
return modelValue | |
}) | |
}], | |
ngModelDirective = ["$rootScope", function($rootScope) { | |
return { | |
restrict: "A", | |
require: ["ngModel", "^?form", "^?ngModelOptions"], | |
controller: NgModelController, | |
priority: 1, | |
compile: function(element) { | |
return element.addClass(PRISTINE_CLASS).addClass(UNTOUCHED_CLASS).addClass(VALID_CLASS), { | |
pre: function(scope, element, attr, ctrls) { | |
var modelCtrl = ctrls[0], | |
formCtrl = ctrls[1] || nullFormCtrl; | |
modelCtrl.$$setOptions(ctrls[2] && ctrls[2].$options), formCtrl.$addControl(modelCtrl), attr.$observe("name", function(newValue) { | |
modelCtrl.$name !== newValue && formCtrl.$$renameControl(modelCtrl, newValue) | |
}), scope.$on("$destroy", function() { | |
formCtrl.$removeControl(modelCtrl) | |
}) | |
}, | |
post: function(scope, element, attr, ctrls) { | |
var modelCtrl = ctrls[0]; | |
modelCtrl.$options && modelCtrl.$options.updateOn && element.on(modelCtrl.$options.updateOn, function(ev) { | |
modelCtrl.$$debounceViewValueCommit(ev && ev.type) | |
}), element.on("blur", function(ev) { | |
if (modelCtrl.$touched) return; | |
$rootScope.$$phase ? scope.$evalAsync(modelCtrl.$setTouched) : scope.$apply(modelCtrl.$setTouched) | |
}) | |
} | |
} | |
} | |
} | |
}], | |
DEFAULT_REGEXP = /(\s+|^)default(\s+|$)/, | |
ngModelOptionsDirective = function() { | |
return { | |
restrict: "A", | |
controller: ["$scope", "$attrs", function($scope, $attrs) { | |
var that = this; | |
this.$options = copy($scope.$eval($attrs.ngModelOptions)), this.$options.updateOn !== undefined ? (this.$options.updateOnDefault = !1, this.$options.updateOn = trim(this.$options.updateOn.replace(DEFAULT_REGEXP, function() { | |
return that.$options.updateOnDefault = !0, " " | |
}))) : this.$options.updateOnDefault = !0 | |
}] | |
} | |
}; | |
function addSetValidityMethod(context) { | |
var ctrl = context.ctrl, | |
$element = context.$element, | |
classCache = {}, | |
set = context.set, | |
unset = context.unset, | |
parentForm = context.parentForm, | |
$animate = context.$animate; | |
classCache[INVALID_CLASS] = !(classCache[VALID_CLASS] = $element.hasClass(VALID_CLASS)), ctrl.$setValidity = setValidity; | |
function setValidity(validationErrorKey, state, controller) { | |
state === undefined ? createAndSet("$pending", validationErrorKey, controller) : unsetAndCleanup("$pending", validationErrorKey, controller), isBoolean(state) ? state ? (unset(ctrl.$error, validationErrorKey, controller), set(ctrl.$$success, validationErrorKey, controller)) : (set(ctrl.$error, validationErrorKey, controller), unset(ctrl.$$success, validationErrorKey, controller)) : (unset(ctrl.$error, validationErrorKey, controller), unset(ctrl.$$success, validationErrorKey, controller)), ctrl.$pending ? (cachedToggleClass(PENDING_CLASS, !0), ctrl.$valid = ctrl.$invalid = undefined, toggleValidationCss("", null)) : (cachedToggleClass(PENDING_CLASS, !1), ctrl.$valid = isObjectEmpty(ctrl.$error), ctrl.$invalid = !ctrl.$valid, toggleValidationCss("", ctrl.$valid)); | |
var combinedState; | |
combinedState = ctrl.$pending && ctrl.$pending[validationErrorKey] ? undefined : ctrl.$error[validationErrorKey] ? !1 : ctrl.$$success[validationErrorKey] ? !0 : null, toggleValidationCss(validationErrorKey, combinedState), parentForm.$setValidity(validationErrorKey, combinedState, ctrl) | |
} | |
function createAndSet(name, value, controller) { | |
ctrl[name] || (ctrl[name] = {}), set(ctrl[name], value, controller) | |
} | |
function unsetAndCleanup(name, value, controller) { | |
ctrl[name] && unset(ctrl[name], value, controller), isObjectEmpty(ctrl[name]) && (ctrl[name] = undefined) | |
} | |
function cachedToggleClass(className, switchValue) { | |
switchValue && !classCache[className] ? ($animate.addClass($element, className), classCache[className] = !0) : !switchValue && classCache[className] && ($animate.removeClass($element, className), classCache[className] = !1) | |
} | |
function toggleValidationCss(validationErrorKey, isValid) { | |
validationErrorKey = validationErrorKey ? "-" + snake_case(validationErrorKey, "-") : "", cachedToggleClass(VALID_CLASS + validationErrorKey, isValid === !0), cachedToggleClass(INVALID_CLASS + validationErrorKey, isValid === !1) | |
} | |
} | |
function isObjectEmpty(obj) { | |
if (obj) | |
for (var prop in obj) return !1; | |
return !0 | |
} | |
var ngNonBindableDirective = ngDirective({ | |
terminal: !0, | |
priority: 1e3 | |
}), | |
ngOptionsMinErr = minErr("ngOptions"), | |
NG_OPTIONS_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+group\s+by\s+([\s\S]+?))?(?:\s+disable\s+when\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?$/, | |
ngOptionsDirective = ["$compile", "$parse", function($compile, $parse) { | |
function parseOptionsExpression(optionsExp, selectElement, scope) { | |
var match = optionsExp.match(NG_OPTIONS_REGEXP); | |
if (!match) throw ngOptionsMinErr("iexp", "Expected expression in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_' but got '{0}'. Element: {1}", optionsExp, startingTag(selectElement)); | |
var valueName = match[5] || match[7], | |
keyName = match[6], | |
selectAs = / as /.test(match[0]) && match[1], | |
trackBy = match[9], | |
valueFn = $parse(match[2] ? match[1] : valueName), | |
selectAsFn = selectAs && $parse(selectAs), | |
viewValueFn = selectAsFn || valueFn, | |
trackByFn = trackBy && $parse(trackBy), | |
getTrackByValue = trackBy ? function(viewValue, locals) { | |
return trackByFn(scope, locals) | |
} : function(viewValue) { | |
return hashKey(viewValue) | |
}, | |
displayFn = $parse(match[2] || match[1]), | |
groupByFn = $parse(match[3] || ""), | |
disableWhenFn = $parse(match[4] || ""), | |
valuesFn = $parse(match[8]), | |
locals = {}, | |
getLocals = keyName ? function(value, key) { | |
return locals[keyName] = key, locals[valueName] = value, locals | |
} : function(value) { | |
return locals[valueName] = value, locals | |
}; | |
function Option(selectValue, viewValue, label, group, disabled) { | |
this.selectValue = selectValue, this.viewValue = viewValue, this.label = label, this.group = group, this.disabled = disabled | |
} | |
return { | |
trackBy: trackBy, | |
getWatchables: $parse(valuesFn, function(values) { | |
var watchedArray = []; | |
return values = values || [], Object.keys(values).forEach(function(key) { | |
var locals = getLocals(values[key], key), | |
selectValue = getTrackByValue(values[key], locals); | |
if (watchedArray.push(selectValue), match[2]) { | |
var label = displayFn(scope, locals); | |
watchedArray.push(label) | |
} | |
if (match[4]) { | |
var disableWhen = disableWhenFn(scope, locals); | |
watchedArray.push(disableWhen) | |
} | |
}), watchedArray | |
}), | |
getOptions: function() { | |
var optionItems = [], | |
selectValueMap = {}, | |
optionValues = valuesFn(scope) || [], | |
keys = Object.keys(optionValues); | |
return keys.forEach(function(key) { | |
if ("$" === key.charAt(0)) return; | |
var value = optionValues[key], | |
locals = getLocals(value, key), | |
viewValue = viewValueFn(scope, locals), | |
selectValue = getTrackByValue(viewValue, locals), | |
label = displayFn(scope, locals), | |
group = groupByFn(scope, locals), | |
disabled = disableWhenFn(scope, locals), | |
optionItem = new Option(selectValue, viewValue, label, group, disabled); | |
optionItems.push(optionItem), selectValueMap[selectValue] = optionItem | |
}), { | |
items: optionItems, | |
selectValueMap: selectValueMap, | |
getOptionFromViewValue: function(value) { | |
return selectValueMap[getTrackByValue(value, getLocals(value))] | |
}, | |
getViewValueFromOption: function(option) { | |
return trackBy ? angular.copy(option.viewValue) : option.viewValue | |
} | |
} | |
} | |
} | |
} | |
var optionTemplate = document.createElement("option"), | |
optGroupTemplate = document.createElement("optgroup"); | |
return { | |
restrict: "A", | |
terminal: !0, | |
require: ["select", "?ngModel"], | |
link: function(scope, selectElement, attr, ctrls) { | |
var ngModelCtrl = ctrls[1]; | |
if (!ngModelCtrl) return; | |
var selectCtrl = ctrls[0], | |
multiple = attr.multiple, | |
emptyOption = selectCtrl.emptyOption, | |
providedEmptyOption = !!emptyOption, | |
unknownOption = jqLite(optionTemplate.cloneNode(!1)); | |
unknownOption.val("?"); | |
var options, ngOptions = parseOptionsExpression(attr.ngOptions, selectElement, scope), | |
renderEmptyOption = function() { | |
providedEmptyOption || selectElement.prepend(emptyOption), selectElement.val(""), emptyOption.prop("selected", !0), emptyOption.attr("selected", !0) | |
}, | |
removeEmptyOption = function() { | |
providedEmptyOption || emptyOption.remove() | |
}, | |
renderUnknownOption = function() { | |
selectElement.prepend(unknownOption), selectElement.val("?"), unknownOption.prop("selected", !0), unknownOption.attr("selected", !0) | |
}, | |
removeUnknownOption = function() { | |
unknownOption.remove() | |
}; | |
selectCtrl.writeValue = function(value) { | |
var option = options.getOptionFromViewValue(value); | |
option && !option.disabled ? selectElement[0].value !== option.selectValue && (removeUnknownOption(), removeEmptyOption(), selectElement[0].value = option.selectValue, option.element.selected = !0, option.element.setAttribute("selected", "selected")) : null === value || providedEmptyOption ? (removeUnknownOption(), renderEmptyOption()) : (removeEmptyOption(), renderUnknownOption()) | |
}, selectCtrl.readValue = function() { | |
var selectedOption = options.selectValueMap[selectElement.val()]; | |
if (selectedOption && !selectedOption.disabled) return removeEmptyOption(), removeUnknownOption(), options.getViewValueFromOption(selectedOption); | |
return null | |
}, multiple && (ngModelCtrl.$isEmpty = function(value) { | |
return !value || 0 === value.length | |
}, selectCtrl.writeValue = function(value) { | |
options.items.forEach(function(option) { | |
option.element.selected = !1 | |
}), value && value.forEach(function(item) { | |
var option = options.getOptionFromViewValue(item); | |
option && !option.disabled && (option.element.selected = !0) | |
}) | |
}, selectCtrl.readValue = function() { | |
var selectedValues = selectElement.val() || [], | |
selections = []; | |
return forEach(selectedValues, function(value) { | |
var option = options.selectValueMap[value]; | |
option.disabled || selections.push(options.getViewValueFromOption(option)) | |
}), selections | |
}), providedEmptyOption ? (emptyOption.remove(), $compile(emptyOption)(scope), emptyOption.removeClass("ng-scope")) : emptyOption = jqLite(optionTemplate.cloneNode(!1)), updateOptions(), scope.$watchCollection(ngOptions.getWatchables, updateOptions), ngOptions.trackBy && scope.$watch(attr.ngModel, function() { | |
ngModelCtrl.$render() | |
}, !0); | |
function updateOptionElement(option, element) { | |
option.element = element, element.disabled = option.disabled, option.value !== element.value && (element.value = option.selectValue), option.label !== element.label && (element.label = option.label, element.textContent = option.label) | |
} | |
function addOrReuseElement(parent, current, type, templateElement) { | |
var element; | |
return current && lowercase(current.nodeName) === type ? element = current : (element = templateElement.cloneNode(!1), current ? parent.insertBefore(element, current) : parent.appendChild(element)), element | |
} | |
function removeExcessElements(current) { | |
for (var next; current;) next = current.nextSibling, jqLiteRemove(current), current = next | |
} | |
function skipEmptyAndUnknownOptions(current) { | |
var emptyOption_ = emptyOption && emptyOption[0], | |
unknownOption_ = unknownOption && unknownOption[0]; | |
if (emptyOption_ || unknownOption_) | |
for (; current && (current === emptyOption_ || current === unknownOption_);) current = current.nextSibling; | |
return current | |
} | |
function updateOptions() { | |
var previousValue = options && selectCtrl.readValue(); | |
options = ngOptions.getOptions(); | |
var groupMap = {}, | |
currentElement = selectElement[0].firstChild; | |
if (providedEmptyOption && selectElement.prepend(emptyOption), currentElement = skipEmptyAndUnknownOptions(currentElement), options.items.forEach(function(option) { | |
var group, groupElement, optionElement; | |
option.group ? (group = groupMap[option.group], group || (groupElement = addOrReuseElement(selectElement[0], currentElement, "optgroup", optGroupTemplate), currentElement = groupElement.nextSibling, groupElement.label = option.group, group = groupMap[option.group] = { | |
groupElement: groupElement, | |
currentOptionElement: groupElement.firstChild | |
}), optionElement = addOrReuseElement(group.groupElement, group.currentOptionElement, "option", optionTemplate), updateOptionElement(option, optionElement), group.currentOptionElement = optionElement.nextSibling) : (optionElement = addOrReuseElement(selectElement[0], currentElement, "option", optionTemplate), updateOptionElement(option, optionElement), currentElement = optionElement.nextSibling) | |
}), Object.keys(groupMap).forEach(function(key) { | |
removeExcessElements(groupMap[key].currentOptionElement) | |
}), removeExcessElements(currentElement), ngModelCtrl.$render(), !ngModelCtrl.$isEmpty(previousValue)) { | |
var nextValue = selectCtrl.readValue(); | |
(ngOptions.trackBy && !equals(previousValue, nextValue) || previousValue !== nextValue) && (ngModelCtrl.$setViewValue(nextValue), ngModelCtrl.$render()) | |
} | |
} | |
} | |
} | |
}], | |
ngPluralizeDirective = ["$locale", "$interpolate", "$log", function($locale, $interpolate, $log) { | |
var BRACE = /{}/g, | |
IS_WHEN = /^when(Minus)?(.+)$/; | |
return { | |
link: function(scope, element, attr) { | |
var lastCount, numberExp = attr.count, | |
whenExp = attr.$attr.when && element.attr(attr.$attr.when), | |
offset = attr.offset || 0, | |
whens = scope.$eval(whenExp) || {}, | |
whensExpFns = {}, | |
startSymbol = $interpolate.startSymbol(), | |
endSymbol = $interpolate.endSymbol(), | |
braceReplacement = startSymbol + numberExp + "-" + offset + endSymbol, | |
watchRemover = angular.noop; | |
forEach(attr, function(expression, attributeName) { | |
var tmpMatch = IS_WHEN.exec(attributeName); | |
if (tmpMatch) { | |
var whenKey = (tmpMatch[1] ? "-" : "") + lowercase(tmpMatch[2]); | |
whens[whenKey] = element.attr(attr.$attr[attributeName]) | |
} | |
}), forEach(whens, function(expression, key) { | |
whensExpFns[key] = $interpolate(expression.replace(BRACE, braceReplacement)) | |
}), scope.$watch(numberExp, function(newVal) { | |
var count = parseFloat(newVal), | |
countIsNaN = isNaN(count); | |
if (countIsNaN || count in whens || (count = $locale.pluralCat(count - offset)), count !== lastCount && !(countIsNaN && isNumber(lastCount) && isNaN(lastCount))) { | |
watchRemover(); | |
var whenExpFn = whensExpFns[count]; | |
isUndefined(whenExpFn) ? (null != newVal && $log.debug("ngPluralize: no rule defined for '" + count + "' in " + whenExp), watchRemover = noop, updateElementText()) : watchRemover = scope.$watch(whenExpFn, updateElementText), lastCount = count | |
} | |
}); | |
function updateElementText(newText) { | |
element.text(newText || "") | |
} | |
} | |
} | |
}], | |
ngRepeatDirective = ["$parse", "$animate", function($parse, $animate) { | |
var NG_REMOVED = "$$NG_REMOVED", | |
ngRepeatMinErr = minErr("ngRepeat"), | |
updateScope = function(scope, index, valueIdentifier, value, keyIdentifier, key, arrayLength) { | |
scope[valueIdentifier] = value, keyIdentifier && (scope[keyIdentifier] = key), scope.$index = index, scope.$first = 0 === index, scope.$last = index === arrayLength - 1, scope.$middle = !(scope.$first || scope.$last), scope.$odd = !(scope.$even = 0 === (1 & index)) | |
}, | |
getBlockStart = function(block) { | |
return block.clone[0] | |
}, | |
getBlockEnd = function(block) { | |
return block.clone[block.clone.length - 1] | |
}; | |
return { | |
restrict: "A", | |
multiElement: !0, | |
transclude: "element", | |
priority: 1e3, | |
terminal: !0, | |
$$tlb: !0, | |
compile: function($element, $attr) { | |
var expression = $attr.ngRepeat, | |
ngRepeatEndComment = document.createComment(" end ngRepeat: " + expression + " "), | |
match = expression.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+as\s+([\s\S]+?))?(?:\s+track\s+by\s+([\s\S]+?))?\s*$/); | |
if (!match) throw ngRepeatMinErr("iexp", "Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'.", expression); | |
var lhs = match[1], | |
rhs = match[2], | |
aliasAs = match[3], | |
trackByExp = match[4]; | |
if (match = lhs.match(/^(?:(\s*[\$\w]+)|\(\s*([\$\w]+)\s*,\s*([\$\w]+)\s*\))$/), !match) throw ngRepeatMinErr("iidexp", "'_item_' in '_item_ in _collection_' should be an identifier or '(_key_, _value_)' expression, but got '{0}'.", lhs); | |
var valueIdentifier = match[3] || match[1], | |
keyIdentifier = match[2]; | |
if (aliasAs && (!/^[$a-zA-Z_][$a-zA-Z0-9_]*$/.test(aliasAs) || /^(null|undefined|this|\$index|\$first|\$middle|\$last|\$even|\$odd|\$parent|\$root|\$id)$/.test(aliasAs))) throw ngRepeatMinErr("badident", "alias '{0}' is invalid --- must be a valid JS identifier which is not a reserved name.", aliasAs); | |
var trackByExpGetter, trackByIdExpFn, trackByIdArrayFn, trackByIdObjFn, hashFnLocals = { | |
$id: hashKey | |
}; | |
return trackByExp ? trackByExpGetter = $parse(trackByExp) : (trackByIdArrayFn = function(key, value) { | |
return hashKey(value) | |
}, trackByIdObjFn = function(key) { | |
return key | |
}), | |
function($scope, $element, $attr, ctrl, $transclude) { | |
trackByExpGetter && (trackByIdExpFn = function(key, value, index) { | |
return keyIdentifier && (hashFnLocals[keyIdentifier] = key), hashFnLocals[valueIdentifier] = value, hashFnLocals.$index = index, trackByExpGetter($scope, hashFnLocals) | |
}); | |
var lastBlockMap = createMap(); | |
$scope.$watchCollection(rhs, function(collection) { | |
var index, length, nextNode, collectionLength, key, value, trackById, trackByIdFn, collectionKeys, block, nextBlockOrder, elementsToRemove, previousNode = $element[0], | |
nextBlockMap = createMap(); | |
if (aliasAs && ($scope[aliasAs] = collection), isArrayLike(collection)) collectionKeys = collection, trackByIdFn = trackByIdExpFn || trackByIdArrayFn; | |
else { | |
trackByIdFn = trackByIdExpFn || trackByIdObjFn, collectionKeys = []; | |
for (var itemKey in collection) collection.hasOwnProperty(itemKey) && "$" !== itemKey.charAt(0) && collectionKeys.push(itemKey) | |
} | |
for (collectionLength = collectionKeys.length, nextBlockOrder = new Array(collectionLength), index = 0; collectionLength > index; index++) | |
if (key = collection === collectionKeys ? index : collectionKeys[index], value = collection[key], trackById = trackByIdFn(key, value, index), lastBlockMap[trackById]) block = lastBlockMap[trackById], delete lastBlockMap[trackById], nextBlockMap[trackById] = block, nextBlockOrder[index] = block; | |
else { | |
if (nextBlockMap[trackById]) throw forEach(nextBlockOrder, function(block) { | |
block && block.scope && (lastBlockMap[block.id] = block) | |
}), ngRepeatMinErr("dupes", "Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}, Duplicate value: {2}", expression, trackById, value); | |
nextBlockOrder[index] = { | |
id: trackById, | |
scope: undefined, | |
clone: undefined | |
}, nextBlockMap[trackById] = !0 | |
} | |
for (var blockKey in lastBlockMap) { | |
if (block = lastBlockMap[blockKey], elementsToRemove = getBlockNodes(block.clone), $animate.leave(elementsToRemove), elementsToRemove[0].parentNode) | |
for (index = 0, length = elementsToRemove.length; length > index; index++) elementsToRemove[index][NG_REMOVED] = !0; | |
block.scope.$destroy() | |
} | |
for (index = 0; collectionLength > index; index++) | |
if (key = collection === collectionKeys ? index : collectionKeys[index], value = collection[key], block = nextBlockOrder[index], block.scope) { | |
nextNode = previousNode; | |
do nextNode = nextNode.nextSibling; while (nextNode && nextNode[NG_REMOVED]); | |
getBlockStart(block) != nextNode && $animate.move(getBlockNodes(block.clone), null, jqLite(previousNode)), previousNode = getBlockEnd(block), updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength) | |
} else $transclude(function(clone, scope) { | |
block.scope = scope; | |
var endNode = ngRepeatEndComment.cloneNode(!1); | |
clone[clone.length++] = endNode, $animate.enter(clone, null, jqLite(previousNode)), previousNode = endNode, block.clone = clone, nextBlockMap[block.id] = block, updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength) | |
}); | |
lastBlockMap = nextBlockMap | |
}) | |
} | |
} | |
} | |
}], | |
NG_HIDE_CLASS = "ng-hide", | |
NG_HIDE_IN_PROGRESS_CLASS = "ng-hide-animate", | |
ngShowDirective = ["$animate", function($animate) { | |
return { | |
restrict: "A", | |
multiElement: !0, | |
link: function(scope, element, attr) { | |
scope.$watch(attr.ngShow, function(value) { | |
$animate[value ? "removeClass" : "addClass"](element, NG_HIDE_CLASS, { | |
tempClasses: NG_HIDE_IN_PROGRESS_CLASS | |
}) | |
}) | |
} | |
} | |
}], | |
ngHideDirective = ["$animate", function($animate) { | |
return { | |
restrict: "A", | |
multiElement: !0, | |
link: function(scope, element, attr) { | |
scope.$watch(attr.ngHide, function(value) { | |
$animate[value ? "addClass" : "removeClass"](element, NG_HIDE_CLASS, { | |
tempClasses: NG_HIDE_IN_PROGRESS_CLASS | |
}) | |
}) | |
} | |
} | |
}], | |
ngStyleDirective = ngDirective(function(scope, element, attr) { | |
scope.$watch(attr.ngStyle, function(newStyles, oldStyles) { | |
oldStyles && newStyles !== oldStyles && forEach(oldStyles, function(val, style) { | |
element.css(style, "") | |
}), newStyles && element.css(newStyles) | |
}, !0) | |
}), | |
ngSwitchDirective = ["$animate", function($animate) { | |
return { | |
require: "ngSwitch", | |
controller: ["$scope", function() { | |
this.cases = {} | |
}], | |
link: function(scope, element, attr, ngSwitchController) { | |
var watchExpr = attr.ngSwitch || attr.on, | |
selectedTranscludes = [], | |
selectedElements = [], | |
previousLeaveAnimations = [], | |
selectedScopes = [], | |
spliceFactory = function(array, index) { | |
return function() { | |
array.splice(index, 1) | |
} | |
}; | |
scope.$watch(watchExpr, function(value) { | |
var i, ii; | |
for (i = 0, ii = previousLeaveAnimations.length; ii > i; ++i) $animate.cancel(previousLeaveAnimations[i]); | |
for (previousLeaveAnimations.length = 0, i = 0, ii = selectedScopes.length; ii > i; ++i) { | |
var selected = getBlockNodes(selectedElements[i].clone); | |
selectedScopes[i].$destroy(); | |
var promise = previousLeaveAnimations[i] = $animate.leave(selected); | |
promise.then(spliceFactory(previousLeaveAnimations, i)) | |
} | |
selectedElements.length = 0, selectedScopes.length = 0, (selectedTranscludes = ngSwitchController.cases["!" + value] || ngSwitchController.cases["?"]) && forEach(selectedTranscludes, function(selectedTransclude) { | |
selectedTransclude.transclude(function(caseElement, selectedScope) { | |
selectedScopes.push(selectedScope); | |
var anchor = selectedTransclude.element; | |
caseElement[caseElement.length++] = document.createComment(" end ngSwitchWhen: "); | |
var block = { | |
clone: caseElement | |
}; | |
selectedElements.push(block), $animate.enter(caseElement, anchor.parent(), anchor) | |
}) | |
}) | |
}) | |
} | |
} | |
}], | |
ngSwitchWhenDirective = ngDirective({ | |
transclude: "element", | |
priority: 1200, | |
require: "^ngSwitch", | |
multiElement: !0, | |
link: function(scope, element, attrs, ctrl, $transclude) { | |
ctrl.cases["!" + attrs.ngSwitchWhen] = ctrl.cases["!" + attrs.ngSwitchWhen] || [], ctrl.cases["!" + attrs.ngSwitchWhen].push({ | |
transclude: $transclude, | |
element: element | |
}) | |
} | |
}), | |
ngSwitchDefaultDirective = ngDirective({ | |
transclude: "element", | |
priority: 1200, | |
require: "^ngSwitch", | |
multiElement: !0, | |
link: function(scope, element, attr, ctrl, $transclude) { | |
ctrl.cases["?"] = ctrl.cases["?"] || [], ctrl.cases["?"].push({ | |
transclude: $transclude, | |
element: element | |
}) | |
} | |
}), | |
ngTranscludeDirective = ngDirective({ | |
restrict: "EAC", | |
link: function($scope, $element, $attrs, controller, $transclude) { | |
if (!$transclude) throw minErr("ngTransclude")("orphan", "Illegal use of ngTransclude directive in the template! No parent directive that requires a transclusion found. Element: {0}", startingTag($element)); | |
$transclude(function(clone) { | |
$element.empty(), $element.append(clone) | |
}) | |
} | |
}), | |
scriptDirective = ["$templateCache", function($templateCache) { | |
return { | |
restrict: "E", | |
terminal: !0, | |
compile: function(element, attr) { | |
if ("text/ng-template" == attr.type) { | |
var templateUrl = attr.id, | |
text = element[0].text; | |
$templateCache.put(templateUrl, text) | |
} | |
} | |
} | |
}], | |
noopNgModelController = { | |
$setViewValue: noop, | |
$render: noop | |
}, | |
SelectController = ["$element", "$scope", "$attrs", function($element, $scope, $attrs) { | |
var self = this, | |
optionsMap = new HashMap; | |
self.ngModelCtrl = noopNgModelController, self.unknownOption = jqLite(document.createElement("option")), self.renderUnknownOption = function(val) { | |
var unknownVal = "? " + hashKey(val) + " ?"; | |
self.unknownOption.val(unknownVal), $element.prepend(self.unknownOption), $element.val(unknownVal) | |
}, $scope.$on("$destroy", function() { | |
self.renderUnknownOption = noop | |
}), self.removeUnknownOption = function() { | |
self.unknownOption.parent() && self.unknownOption.remove() | |
}; | |
for (var i = 0, children = $element.children(), ii = children.length; ii > i; i++) | |
if ("" === children[i].value) { | |
self.emptyOption = children.eq(i); | |
break | |
} | |
self.readValue = function() { | |
return self.removeUnknownOption(), $element.val() | |
}, self.writeValue = function(value) { | |
self.hasOption(value) ? (self.removeUnknownOption(), $element.val(value), "" === value && self.emptyOption.prop("selected", !0)) : isUndefined(value) && self.emptyOption ? (self.removeUnknownOption(), $element.val("")) : self.renderUnknownOption(value) | |
}, self.addOption = function(value) { | |
assertNotHasOwnProperty(value, '"option value"'); | |
var count = optionsMap.get(value) || 0; | |
optionsMap.put(value, count + 1) | |
}, self.removeOption = function(value) { | |
var count = optionsMap.get(value); | |
count && (1 === count ? optionsMap.remove(value) : optionsMap.put(value, count - 1)) | |
}, self.hasOption = function(value) { | |
return !!optionsMap.get(value) | |
} | |
}], | |
selectDirective = function() { | |
return { | |
restrict: "E", | |
require: ["select", "?ngModel"], | |
controller: SelectController, | |
link: function(scope, element, attr, ctrls) { | |
var ngModelCtrl = ctrls[1]; | |
if (!ngModelCtrl) return; | |
var selectCtrl = ctrls[0]; | |
if (selectCtrl.ngModelCtrl = ngModelCtrl, ngModelCtrl.$render = function() { | |
selectCtrl.writeValue(ngModelCtrl.$viewValue) | |
}, element.on("change", function() { | |
scope.$apply(function() { | |
ngModelCtrl.$setViewValue(selectCtrl.readValue()) | |
}) | |
}), attr.multiple) { | |
selectCtrl.readValue = function() { | |
var array = []; | |
return forEach(element.find("option"), function(option) { | |
option.selected && array.push(option.value) | |
}), array | |
}, selectCtrl.writeValue = function(value) { | |
var items = new HashMap(value); | |
forEach(element.find("option"), function(option) { | |
option.selected = isDefined(items.get(option.value)) | |
}) | |
}; | |
var lastView, lastViewRef = NaN; | |
scope.$watch(function() { | |
lastViewRef !== ngModelCtrl.$viewValue || equals(lastView, ngModelCtrl.$viewValue) || (lastView = shallowCopy(ngModelCtrl.$viewValue), ngModelCtrl.$render()), lastViewRef = ngModelCtrl.$viewValue | |
}), ngModelCtrl.$isEmpty = function(value) { | |
return !value || 0 === value.length | |
} | |
} | |
} | |
} | |
}, | |
optionDirective = ["$interpolate", function($interpolate) { | |
function chromeHack(optionElement) { | |
optionElement[0].hasAttribute("selected") && (optionElement[0].selected = !0) | |
} | |
return { | |
restrict: "E", | |
priority: 100, | |
compile: function(element, attr) { | |
if (isUndefined(attr.value)) { | |
var interpolateFn = $interpolate(element.text(), !0); | |
interpolateFn || attr.$set("value", element.text()) | |
} | |
return function(scope, element, attr) { | |
var selectCtrlName = "$selectController", | |
parent = element.parent(), | |
selectCtrl = parent.data(selectCtrlName) || parent.parent().data(selectCtrlName); | |
selectCtrl && selectCtrl.ngModelCtrl && (interpolateFn ? scope.$watch(interpolateFn, function(newVal, oldVal) { | |
attr.$set("value", newVal), oldVal !== newVal && selectCtrl.removeOption(oldVal), selectCtrl.addOption(newVal, element), selectCtrl.ngModelCtrl.$render(), chromeHack(element) | |
}) : (selectCtrl.addOption(attr.value, element), selectCtrl.ngModelCtrl.$render(), chromeHack(element)), element.on("$destroy", function() { | |
selectCtrl.removeOption(attr.value), selectCtrl.ngModelCtrl.$render() | |
})) | |
} | |
} | |
} | |
}], | |
styleDirective = valueFn({ | |
restrict: "E", | |
terminal: !1 | |
}), | |
requiredDirective = function() { | |
return { | |
restrict: "A", | |
require: "?ngModel", | |
link: function(scope, elm, attr, ctrl) { | |
if (!ctrl) return; | |
attr.required = !0, ctrl.$validators.required = function(modelValue, viewValue) { | |
return !attr.required || !ctrl.$isEmpty(viewValue) | |
}, attr.$observe("required", function() { | |
ctrl.$validate() | |
}) | |
} | |
} | |
}, | |
patternDirective = function() { | |
return { | |
restrict: "A", | |
require: "?ngModel", | |
link: function(scope, elm, attr, ctrl) { | |
if (!ctrl) return; | |
var regexp, patternExp = attr.ngPattern || attr.pattern; | |
attr.$observe("pattern", function(regex) { | |
if (isString(regex) && regex.length > 0 && (regex = new RegExp("^" + regex + "$")), regex && !regex.test) throw minErr("ngPattern")("noregexp", "Expected {0} to be a RegExp but was {1}. Element: {2}", patternExp, regex, startingTag(elm)); | |
regexp = regex || undefined, ctrl.$validate() | |
}), ctrl.$validators.pattern = function(value) { | |
return ctrl.$isEmpty(value) || isUndefined(regexp) || regexp.test(value) | |
} | |
} | |
} | |
}, | |
maxlengthDirective = function() { | |
return { | |
restrict: "A", | |
require: "?ngModel", | |
link: function(scope, elm, attr, ctrl) { | |
if (!ctrl) return; | |
var maxlength = -1; | |
attr.$observe("maxlength", function(value) { | |
var intVal = toInt(value); | |
maxlength = isNaN(intVal) ? -1 : intVal, ctrl.$validate() | |
}), ctrl.$validators.maxlength = function(modelValue, viewValue) { | |
return 0 > maxlength || ctrl.$isEmpty(viewValue) || viewValue.length <= maxlength | |
} | |
} | |
} | |
}, | |
minlengthDirective = function() { | |
return { | |
restrict: "A", | |
require: "?ngModel", | |
link: function(scope, elm, attr, ctrl) { | |
if (!ctrl) return; | |
var minlength = 0; | |
attr.$observe("minlength", function(value) { | |
minlength = toInt(value) || 0, ctrl.$validate() | |
}), ctrl.$validators.minlength = function(modelValue, viewValue) { | |
return ctrl.$isEmpty(viewValue) || viewValue.length >= minlength | |
} | |
} | |
} | |
}; | |
if (window.angular.bootstrap) return void console.log("WARNING: Tried to load angular more than once."); | |
bindJQuery(), publishExternalAPI(angular), jqLite(document).ready(function() { | |
angularInit(document, bootstrap) | |
}) | |
}(window, document), !window.angular.$$csp() && window.angular.element(document).find("head").prepend('<style type="text/css">@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide:not(.ng-hide-animate){display:none !important;}ng\\:form{display:block;}.ng-animate-shim{visibility:hidden;}.ng-animate-anchor{position:absolute;}</style>'), | |
function(window, angular, undefined) { | |
"use strict"; | |
var ngTouch = angular.module("ngTouch", []); | |
ngTouch.factory("$swipe", [function() { | |
var MOVE_BUFFER_RADIUS = 10, | |
POINTER_EVENTS = { | |
mouse: { | |
start: "mousedown", | |
move: "mousemove", | |
end: "mouseup" | |
}, | |
touch: { | |
start: "touchstart", | |
move: "touchmove", | |
end: "touchend", | |
cancel: "touchcancel" | |
} | |
}; | |
function getCoordinates(event) { | |
var originalEvent = event.originalEvent || event, | |
touches = originalEvent.touches && originalEvent.touches.length ? originalEvent.touches : [originalEvent], | |
e = originalEvent.changedTouches && originalEvent.changedTouches[0] || touches[0]; | |
return { | |
x: e.clientX, | |
y: e.clientY | |
} | |
} | |
function getEvents(pointerTypes, eventType) { | |
var res = []; | |
return angular.forEach(pointerTypes, function(pointerType) { | |
var eventName = POINTER_EVENTS[pointerType][eventType]; | |
eventName && res.push(eventName) | |
}), res.join(" ") | |
} | |
return { | |
bind: function(element, eventHandlers, pointerTypes) { | |
var totalX, totalY, startCoords, lastPos, active = !1; | |
pointerTypes = pointerTypes || ["mouse", "touch"], element.on(getEvents(pointerTypes, "start"), function(event) { | |
startCoords = getCoordinates(event), active = !0, totalX = 0, totalY = 0, lastPos = startCoords, eventHandlers.start && eventHandlers.start(startCoords, event) | |
}); | |
var events = getEvents(pointerTypes, "cancel"); | |
events && element.on(events, function(event) { | |
active = !1, eventHandlers.cancel && eventHandlers.cancel(event) | |
}), element.on(getEvents(pointerTypes, "move"), function(event) { | |
if (!active) return; | |
if (!startCoords) return; | |
var coords = getCoordinates(event); | |
if (totalX += Math.abs(coords.x - lastPos.x), totalY += Math.abs(coords.y - lastPos.y), lastPos = coords, MOVE_BUFFER_RADIUS > totalX && MOVE_BUFFER_RADIUS > totalY) return; | |
if (totalY > totalX) return active = !1, void(eventHandlers.cancel && eventHandlers.cancel(event)); | |
event.preventDefault(), eventHandlers.move && eventHandlers.move(coords, event) | |
}), element.on(getEvents(pointerTypes, "end"), function(event) { | |
if (!active) return; | |
active = !1, eventHandlers.end && eventHandlers.end(getCoordinates(event), event) | |
}) | |
} | |
} | |
}]), ngTouch.config(["$provide", function($provide) { | |
$provide.decorator("ngClickDirective", ["$delegate", function($delegate) { | |
return $delegate.shift(), $delegate | |
}]) | |
}]), ngTouch.directive("ngClick", ["$parse", "$timeout", "$rootElement", function($parse, $timeout, $rootElement) { | |
var lastPreventedTime, touchCoordinates, lastLabelClickCoordinates, TAP_DURATION = 750, | |
MOVE_TOLERANCE = 12, | |
PREVENT_DURATION = 2500, | |
CLICKBUSTER_THRESHOLD = 25, | |
ACTIVE_CLASS_NAME = "ng-click-active"; | |
function hit(x1, y1, x2, y2) { | |
return Math.abs(x1 - x2) < CLICKBUSTER_THRESHOLD && Math.abs(y1 - y2) < CLICKBUSTER_THRESHOLD | |
} | |
function checkAllowableRegions(touchCoordinates, x, y) { | |
for (var i = 0; i < touchCoordinates.length; i += 2) | |
if (hit(touchCoordinates[i], touchCoordinates[i + 1], x, y)) return touchCoordinates.splice(i, i + 2), !0; | |
return !1 | |
} | |
function onClick(event) { | |
if (Date.now() - lastPreventedTime > PREVENT_DURATION) return; | |
var touches = event.touches && event.touches.length ? event.touches : [event], | |
x = touches[0].clientX, | |
y = touches[0].clientY; | |
if (1 > x && 1 > y) return; | |
if (lastLabelClickCoordinates && lastLabelClickCoordinates[0] === x && lastLabelClickCoordinates[1] === y) return; | |
if (lastLabelClickCoordinates && (lastLabelClickCoordinates = null), "label" === event.target.tagName.toLowerCase() && (lastLabelClickCoordinates = [x, y]), checkAllowableRegions(touchCoordinates, x, y)) return; | |
event.stopPropagation(), event.preventDefault(), event.target && event.target.blur() | |
} | |
function onTouchStart(event) { | |
var touches = event.touches && event.touches.length ? event.touches : [event], | |
x = touches[0].clientX, | |
y = touches[0].clientY; | |
touchCoordinates.push(x, y), $timeout(function() { | |
for (var i = 0; i < touchCoordinates.length; i += 2) | |
if (touchCoordinates[i] == x && touchCoordinates[i + 1] == y) return void touchCoordinates.splice(i, i + 2) | |
}, PREVENT_DURATION, !1) | |
} | |
function preventGhostClick(x, y) { | |
touchCoordinates || ($rootElement[0].addEventListener("click", onClick, !0), $rootElement[0].addEventListener("touchstart", onTouchStart, !0), touchCoordinates = []), lastPreventedTime = Date.now(), checkAllowableRegions(touchCoordinates, x, y) | |
} | |
return function(scope, element, attr) { | |
var tapElement, startTime, touchStartX, touchStartY, clickHandler = $parse(attr.ngClick), | |
tapping = !1; | |
function resetState() { | |
tapping = !1, element.removeClass(ACTIVE_CLASS_NAME) | |
} | |
element.on("touchstart", function(event) { | |
tapping = !0, tapElement = event.target ? event.target : event.srcElement, 3 == tapElement.nodeType && (tapElement = tapElement.parentNode), element.addClass(ACTIVE_CLASS_NAME), startTime = Date.now(); | |
var originalEvent = event.originalEvent || event, | |
touches = originalEvent.touches && originalEvent.touches.length ? originalEvent.touches : [originalEvent], | |
e = touches[0]; | |
touchStartX = e.clientX, touchStartY = e.clientY | |
}), element.on("touchmove", function(event) { | |
resetState() | |
}), element.on("touchcancel", function(event) { | |
resetState() | |
}), element.on("touchend", function(event) { | |
var diff = Date.now() - startTime, | |
originalEvent = event.originalEvent || event, | |
touches = originalEvent.changedTouches && originalEvent.changedTouches.length ? originalEvent.changedTouches : originalEvent.touches && originalEvent.touches.length ? originalEvent.touches : [originalEvent], | |
e = touches[0], | |
x = e.clientX, | |
y = e.clientY, | |
dist = Math.sqrt(Math.pow(x - touchStartX, 2) + Math.pow(y - touchStartY, 2)); | |
tapping && TAP_DURATION > diff && MOVE_TOLERANCE > dist && (preventGhostClick(x, y), tapElement && tapElement.blur(), angular.isDefined(attr.disabled) && attr.disabled !== !1 || element.triggerHandler("click", [event])), resetState() | |
}), element.onclick = function(event) {}, element.on("click", function(event, touchend) { | |
scope.$apply(function() { | |
clickHandler(scope, { | |
$event: touchend || event | |
}) | |
}) | |
}), element.on("mousedown", function(event) { | |
element.addClass(ACTIVE_CLASS_NAME) | |
}), element.on("mousemove mouseup", function(event) { | |
element.removeClass(ACTIVE_CLASS_NAME) | |
}) | |
} | |
}]); | |
function makeSwipeDirective(directiveName, direction, eventName) { | |
ngTouch.directive(directiveName, ["$parse", "$swipe", function($parse, $swipe) { | |
var MAX_VERTICAL_DISTANCE = 75, | |
MAX_VERTICAL_RATIO = .3, | |
MIN_HORIZONTAL_DISTANCE = 30; | |
return function(scope, element, attr) { | |
var startCoords, valid, swipeHandler = $parse(attr[directiveName]); | |
function validSwipe(coords) { | |
if (!startCoords) return !1; | |
var deltaY = Math.abs(coords.y - startCoords.y), | |
deltaX = (coords.x - startCoords.x) * direction; | |
return valid && MAX_VERTICAL_DISTANCE > deltaY && deltaX > 0 && deltaX > MIN_HORIZONTAL_DISTANCE && MAX_VERTICAL_RATIO > deltaY / deltaX | |
} | |
var pointerTypes = ["touch"]; | |
angular.isDefined(attr.ngSwipeDisableMouse) || pointerTypes.push("mouse"), $swipe.bind(element, { | |
start: function(coords, event) { | |
startCoords = coords, valid = !0 | |
}, | |
cancel: function(event) { | |
valid = !1 | |
}, | |
end: function(coords, event) { | |
validSwipe(coords) && scope.$apply(function() { | |
element.triggerHandler(eventName), swipeHandler(scope, { | |
$event: event | |
}) | |
}) | |
} | |
}, pointerTypes) | |
} | |
}]) | |
} | |
makeSwipeDirective("ngSwipeLeft", -1, "swipeleft"), makeSwipeDirective("ngSwipeRight", 1, "swiperight") | |
}(window, window.angular), | |
function(window, angular, undefined) { | |
"use strict"; | |
var ngRouteModule = angular.module("ngRoute", ["ng"]).provider("$route", $RouteProvider), | |
$routeMinErr = angular.$$minErr("ngRoute"); | |
function $RouteProvider() { | |
function inherit(parent, extra) { | |
return angular.extend(Object.create(parent), extra) | |
} | |
var routes = {}; | |
this.when = function(path, route) { | |
var routeCopy = angular.copy(route); | |
if (angular.isUndefined(routeCopy.reloadOnSearch) && (routeCopy.reloadOnSearch = !0), angular.isUndefined(routeCopy.caseInsensitiveMatch) && (routeCopy.caseInsensitiveMatch = this.caseInsensitiveMatch), routes[path] = angular.extend(routeCopy, path && pathRegExp(path, routeCopy)), path) { | |
var redirectPath = "/" == path[path.length - 1] ? path.substr(0, path.length - 1) : path + "/"; | |
routes[redirectPath] = angular.extend({ | |
redirectTo: path | |
}, pathRegExp(redirectPath, routeCopy)) | |
} | |
return this | |
}, this.caseInsensitiveMatch = !1; | |
function pathRegExp(path, opts) { | |
var insensitive = opts.caseInsensitiveMatch, | |
ret = { | |
originalPath: path, | |
regexp: path | |
}, | |
keys = ret.keys = []; | |
return path = path.replace(/([().])/g, "\\$1").replace(/(\/)?:(\w+)([\?\*])?/g, function(_, slash, key, option) { | |
var optional = "?" === option ? option : null, | |
star = "*" === option ? option : null; | |
return keys.push({ | |
name: key, | |
optional: !!optional | |
}), slash = slash || "", "" + (optional ? "" : slash) + "(?:" + (optional ? slash : "") + (star && "(.+?)" || "([^/]+)") + (optional || "") + ")" + (optional || "") | |
}).replace(/([\/$\*])/g, "\\$1"), ret.regexp = new RegExp("^" + path + "$", insensitive ? "i" : ""), ret | |
} | |
this.otherwise = function(params) { | |
return "string" == typeof params && (params = { | |
redirectTo: params | |
}), this.when(null, params), this | |
}, this.$get = ["$rootScope", "$location", "$routeParams", "$q", "$injector", "$templateRequest", "$sce", function($rootScope, $location, $routeParams, $q, $injector, $templateRequest, $sce) { | |
var preparedRoute, preparedRouteIsUpdateOnly, forceReload = !1, | |
$route = { | |
routes: routes, | |
reload: function() { | |
forceReload = !0, $rootScope.$evalAsync(function() { | |
prepareRoute(), commitRoute() | |
}) | |
}, | |
updateParams: function(newParams) { | |
if (!this.current || !this.current.$$route) throw $routeMinErr("norout", "Tried updating route when with no current route"); | |
newParams = angular.extend({}, this.current.params, newParams), $location.path(interpolate(this.current.$$route.originalPath, newParams)), $location.search(newParams) | |
} | |
}; | |
return $rootScope.$on("$locationChangeStart", prepareRoute), $rootScope.$on("$locationChangeSuccess", commitRoute), $route; | |
function switchRouteMatcher(on, route) { | |
var keys = route.keys, | |
params = {}; | |
if (!route.regexp) return null; | |
var m = route.regexp.exec(on); | |
if (!m) return null; | |
for (var i = 1, len = m.length; len > i; ++i) { | |
var key = keys[i - 1], | |
val = m[i]; | |
key && val && (params[key.name] = val) | |
} | |
return params | |
} | |
function prepareRoute($locationEvent) { | |
var lastRoute = $route.current; | |
preparedRoute = parseRoute(), preparedRouteIsUpdateOnly = preparedRoute && lastRoute && preparedRoute.$$route === lastRoute.$$route && angular.equals(preparedRoute.pathParams, lastRoute.pathParams) && !preparedRoute.reloadOnSearch && !forceReload, preparedRouteIsUpdateOnly || !lastRoute && !preparedRoute || $rootScope.$broadcast("$routeChangeStart", preparedRoute, lastRoute).defaultPrevented && $locationEvent && $locationEvent.preventDefault() | |
} | |
function commitRoute() { | |
var lastRoute = $route.current, | |
nextRoute = preparedRoute; | |
preparedRouteIsUpdateOnly ? (lastRoute.params = nextRoute.params, angular.copy(lastRoute.params, $routeParams), $rootScope.$broadcast("$routeUpdate", lastRoute)) : (nextRoute || lastRoute) && (forceReload = !1, $route.current = nextRoute, nextRoute && nextRoute.redirectTo && (angular.isString(nextRoute.redirectTo) ? $location.path(interpolate(nextRoute.redirectTo, nextRoute.params)).search(nextRoute.params).replace() : $location.url(nextRoute.redirectTo(nextRoute.pathParams, $location.path(), $location.search())).replace()), $q.when(nextRoute).then(function() { | |
if (nextRoute) { | |
var template, templateUrl, locals = angular.extend({}, nextRoute.resolve); | |
return angular.forEach(locals, function(value, key) { | |
locals[key] = angular.isString(value) ? $injector.get(value) : $injector.invoke(value, null, null, key) | |
}), angular.isDefined(template = nextRoute.template) ? angular.isFunction(template) && (template = template(nextRoute.params)) : angular.isDefined(templateUrl = nextRoute.templateUrl) && (angular.isFunction(templateUrl) && (templateUrl = templateUrl(nextRoute.params)), templateUrl = $sce.getTrustedResourceUrl(templateUrl), angular.isDefined(templateUrl) && (nextRoute.loadedTemplateUrl = templateUrl, template = $templateRequest(templateUrl))), angular.isDefined(template) && (locals.$template = template), $q.all(locals) | |
} | |
}).then(function(locals) { | |
nextRoute == $route.current && (nextRoute && (nextRoute.locals = locals, angular.copy(nextRoute.params, $routeParams)), $rootScope.$broadcast("$routeChangeSuccess", nextRoute, lastRoute)) | |
}, function(error) { | |
nextRoute == $route.current && $rootScope.$broadcast("$routeChangeError", nextRoute, lastRoute, error) | |
})) | |
} | |
function parseRoute() { | |
var params, match; | |
return angular.forEach(routes, function(route, path) { | |
!match && (params = switchRouteMatcher($location.path(), route)) && (match = inherit(route, { | |
params: angular.extend({}, $location.search(), params), | |
pathParams: params | |
}), match.$$route = route) | |
}), match || routes[null] && inherit(routes[null], { | |
params: {}, | |
pathParams: {} | |
}) | |
} | |
function interpolate(string, params) { | |
var result = []; | |
return angular.forEach((string || "").split(":"), function(segment, i) { | |
if (0 === i) result.push(segment); | |
else { | |
var segmentMatch = segment.match(/(\w+)(?:[?*])?(.*)/), | |
key = segmentMatch[1]; | |
result.push(params[key]), result.push(segmentMatch[2] || ""), delete params[key] | |
} | |
}), result.join("") | |
} | |
}] | |
} | |
ngRouteModule.provider("$routeParams", $RouteParamsProvider); | |
function $RouteParamsProvider() { | |
this.$get = function() { | |
return {} | |
} | |
} | |
ngRouteModule.directive("ngView", ngViewFactory), ngRouteModule.directive("ngView", ngViewFillContentFactory), ngViewFactory.$inject = ["$route", "$anchorScroll", "$animate"]; | |
function ngViewFactory($route, $anchorScroll, $animate) { | |
return { | |
restrict: "ECA", | |
terminal: !0, | |
priority: 400, | |
transclude: "element", | |
link: function(scope, $element, attr, ctrl, $transclude) { | |
var currentScope, currentElement, previousLeaveAnimation, autoScrollExp = attr.autoscroll, | |
onloadExp = attr.onload || ""; | |
scope.$on("$routeChangeSuccess", update), update(); | |
function cleanupLastView() { | |
previousLeaveAnimation && ($animate.cancel(previousLeaveAnimation), previousLeaveAnimation = null), currentScope && (currentScope.$destroy(), currentScope = null), currentElement && (previousLeaveAnimation = $animate.leave(currentElement), previousLeaveAnimation.then(function() { | |
previousLeaveAnimation = null | |
}), currentElement = null) | |
} | |
function update() { | |
var locals = $route.current && $route.current.locals, | |
template = locals && locals.$template; | |
if (angular.isDefined(template)) { | |
var newScope = scope.$new(), | |
current = $route.current, | |
clone = $transclude(newScope, function(clone) { | |
$animate.enter(clone, null, currentElement || $element).then(function() { | |
!angular.isDefined(autoScrollExp) || autoScrollExp && !scope.$eval(autoScrollExp) || $anchorScroll() | |
}), cleanupLastView() | |
}); | |
currentElement = clone, currentScope = current.scope = newScope, currentScope.$emit("$viewContentLoaded"), currentScope.$eval(onloadExp) | |
} else cleanupLastView() | |
} | |
} | |
} | |
} | |
ngViewFillContentFactory.$inject = ["$compile", "$controller", "$route"]; | |
function ngViewFillContentFactory($compile, $controller, $route) { | |
return { | |
restrict: "ECA", | |
priority: -400, | |
link: function(scope, $element) { | |
var current = $route.current, | |
locals = current.locals; | |
$element.html(locals.$template); | |
var link = $compile($element.contents()); | |
if (current.controller) { | |
locals.$scope = scope; | |
var controller = $controller(current.controller, locals); | |
current.controllerAs && (scope[current.controllerAs] = controller), $element.data("$ngControllerController", controller), $element.children().data("$ngControllerController", controller) | |
} | |
link(scope) | |
} | |
} | |
} | |
}(window, window.angular), | |
function(window, angular, undefined) { | |
"use strict"; | |
var noop = angular.noop, | |
extend = angular.extend, | |
jqLite = angular.element, | |
forEach = angular.forEach, | |
isArray = angular.isArray, | |
isString = angular.isString, | |
isObject = angular.isObject, | |
isUndefined = angular.isUndefined, | |
isDefined = angular.isDefined, | |
isFunction = angular.isFunction, | |
isElement = angular.isElement, | |
ELEMENT_NODE = 1, | |
NG_ANIMATE_CHILDREN_DATA = "$$ngAnimateChildren"; | |
function mergeClasses(a, b) { | |
if (!a && !b) return ""; | |
if (!a) return b; | |
if (!b) return a; | |
return isArray(a) && (a = a.join(" ")), isArray(b) && (b = b.join(" ")), a + " " + b | |
} | |
function packageStyles(options) { | |
var styles = {}; | |
return options && (options.to || options.from) && (styles.to = options.to, styles.from = options.from), styles | |
} | |
function pendClasses(classes, fix, isPrefix) { | |
var className = ""; | |
return classes = isArray(classes) ? classes : classes && isString(classes) && classes.length ? classes.split(/\s+/) : [], forEach(classes, function(klass, i) { | |
klass && klass.length > 0 && (className += i > 0 ? " " : "", className += isPrefix ? fix + klass : klass + fix) | |
}), className | |
} | |
function removeFromArray(arr, val) { | |
var index = arr.indexOf(val); | |
val >= 0 && arr.splice(index, 1) | |
} | |
function stripCommentsFromElement(element) { | |
if (element.nodeType === ELEMENT_NODE) return jqLite(element); | |
if (0 === element.length) return []; | |
return 1 === element.length ? element[0].nodeType === ELEMENT_NODE && element : jqLite(extractElementNode(element)) | |
} | |
function extractElementNode(element) { | |
if (!element[0]) return element; | |
for (var i = 0; i < element.length; i++) { | |
var elm = element[i]; | |
if (elm.nodeType == ELEMENT_NODE) return elm | |
} | |
} | |
function $$addClass($$jqLite, element, className) { | |
forEach(element, function(elm) { | |
$$jqLite.addClass(elm, className) | |
}) | |
} | |
function $$removeClass($$jqLite, element, className) { | |
forEach(element, function(elm) { | |
$$jqLite.removeClass(elm, className) | |
}) | |
} | |
function applyAnimationClassesFactory($$jqLite) { | |
return function(element, options) { | |
options.addClass && ($$addClass($$jqLite, element, options.addClass), options.addClass = null), options.removeClass && ($$removeClass($$jqLite, element, options.removeClass), element.removeClass(options.removeClass), options.removeClass = null) | |
} | |
} | |
function prepareAnimationOptions(options) { | |
if (options = options || {}, !options.$$prepared) { | |
var domOperation = options.domOperation || noop; | |
options.domOperation = function() { | |
options.$$domOperationFired = !0, domOperation(), domOperation = noop | |
}, options.$$prepared = !0 | |
} | |
return options | |
} | |
function applyAnimationStyles(element, options) { | |
applyAnimationFromStyles(element, options), applyAnimationToStyles(element, options) | |
} | |
function applyAnimationFromStyles(element, options) { | |
options.from && (element.css(options.from), options.from = null) | |
} | |
function applyAnimationToStyles(element, options) { | |
options.to && (element.css(options.to), options.to = null) | |
} | |
function mergeAnimationOptions(element, target, newOptions) { | |
var toAdd = (target.addClass || "") + " " + (newOptions.addClass || ""), | |
toRemove = (target.removeClass || "") + " " + (newOptions.removeClass || ""), | |
classes = resolveElementClasses(element.attr("class"), toAdd, toRemove); | |
return extend(target, newOptions), classes.addClass ? target.addClass = classes.addClass : target.addClass = null, classes.removeClass ? target.removeClass = classes.removeClass : target.removeClass = null, target | |
} | |
function resolveElementClasses(existing, toAdd, toRemove) { | |
var ADD_CLASS = 1, | |
REMOVE_CLASS = -1, | |
flags = {}; | |
existing = splitClassesToLookup(existing), toAdd = splitClassesToLookup(toAdd), forEach(toAdd, function(value, key) { | |
flags[key] = ADD_CLASS | |
}), toRemove = splitClassesToLookup(toRemove), forEach(toRemove, function(value, key) { | |
flags[key] = flags[key] === ADD_CLASS ? null : REMOVE_CLASS | |
}); | |
var classes = { | |
addClass: "", | |
removeClass: "" | |
}; | |
forEach(flags, function(val, klass) { | |
var prop, allow; | |
val === ADD_CLASS ? (prop = "addClass", allow = !existing[klass]) : val === REMOVE_CLASS && (prop = "removeClass", allow = existing[klass]), allow && (classes[prop].length && (classes[prop] += " "), classes[prop] += klass) | |
}); | |
function splitClassesToLookup(classes) { | |
isString(classes) && (classes = classes.split(" ")); | |
var obj = {}; | |
return forEach(classes, function(klass) { | |
klass.length && (obj[klass] = !0) | |
}), obj | |
} | |
return classes | |
} | |
var TRANSITION_PROP, TRANSITIONEND_EVENT, ANIMATION_PROP, ANIMATIONEND_EVENT, $$AnimateChildrenDirective = [function() { | |
return function(scope, element, attrs) { | |
var val = attrs.ngAnimateChildren; | |
angular.isString(val) && 0 === val.length ? element.data(NG_ANIMATE_CHILDREN_DATA, !0) : attrs.$observe("ngAnimateChildren", function(value) { | |
value = "on" === value || "true" === value, element.data(NG_ANIMATE_CHILDREN_DATA, value) | |
}) | |
} | |
}], | |
CSS_PREFIX = ""; | |
window.ontransitionend === undefined && window.onwebkittransitionend !== undefined ? (CSS_PREFIX = "-webkit-", TRANSITION_PROP = "WebkitTransition", TRANSITIONEND_EVENT = "webkitTransitionEnd transitionend") : (TRANSITION_PROP = "transition", TRANSITIONEND_EVENT = "transitionend"), window.onanimationend === undefined && window.onwebkitanimationend !== undefined ? (CSS_PREFIX = "-webkit-", ANIMATION_PROP = "WebkitAnimation", ANIMATIONEND_EVENT = "webkitAnimationEnd animationend") : (ANIMATION_PROP = "animation", ANIMATIONEND_EVENT = "animationend"); | |
var DURATION_KEY = "Duration", | |
PROPERTY_KEY = "Property", | |
DELAY_KEY = "Delay", | |
TIMING_KEY = "TimingFunction", | |
ANIMATION_ITERATION_COUNT_KEY = "IterationCount", | |
ANIMATION_PLAYSTATE_KEY = "PlayState", | |
ELAPSED_TIME_MAX_DECIMAL_PLACES = 3, | |
CLOSING_TIME_BUFFER = 1.5, | |
ONE_SECOND = 1e3, | |
SAFE_FAST_FORWARD_DURATION_VALUE = 9999, | |
ANIMATION_DELAY_PROP = ANIMATION_PROP + DELAY_KEY, | |
ANIMATION_DURATION_PROP = ANIMATION_PROP + DURATION_KEY, | |
TRANSITION_DELAY_PROP = TRANSITION_PROP + DELAY_KEY, | |
TRANSITION_DURATION_PROP = TRANSITION_PROP + DURATION_KEY, | |
DETECT_CSS_PROPERTIES = { | |
transitionDuration: TRANSITION_DURATION_PROP, | |
transitionDelay: TRANSITION_DELAY_PROP, | |
transitionProperty: TRANSITION_PROP + PROPERTY_KEY, | |
animationDuration: ANIMATION_DURATION_PROP, | |
animationDelay: ANIMATION_DELAY_PROP, | |
animationIterationCount: ANIMATION_PROP + ANIMATION_ITERATION_COUNT_KEY | |
}, | |
DETECT_STAGGER_CSS_PROPERTIES = { | |
transitionDuration: TRANSITION_DURATION_PROP, | |
transitionDelay: TRANSITION_DELAY_PROP, | |
animationDuration: ANIMATION_DURATION_PROP, | |
animationDelay: ANIMATION_DELAY_PROP | |
}; | |
function computeCssStyles($window, element, properties) { | |
var styles = Object.create(null), | |
detectedStyles = $window.getComputedStyle(element) || {}; | |
return forEach(properties, function(formalStyleName, actualStyleName) { | |
var val = detectedStyles[formalStyleName]; | |
if (val) { | |
var c = val.charAt(0); | |
("-" === c || "+" === c || c >= 0) && (val = parseMaxTime(val)), 0 === val && (val = null), styles[actualStyleName] = val | |
} | |
}), styles | |
} | |
function parseMaxTime(str) { | |
var maxValue = 0, | |
values = str.split(/\s*,\s*/); | |
return forEach(values, function(value) { | |
"s" == value.charAt(value.length - 1) && (value = value.substring(0, value.length - 1)), value = parseFloat(value) || 0, maxValue = maxValue ? Math.max(value, maxValue) : value | |
}), maxValue | |
} | |
function truthyTimingValue(val) { | |
return 0 === val || null != val | |
} | |
function getCssTransitionDurationStyle(duration, applyOnlyDuration) { | |
var style = TRANSITION_PROP, | |
value = duration + "s"; | |
return applyOnlyDuration ? style += DURATION_KEY : value += " linear all", [style, value] | |
} | |
function getCssKeyframeDurationStyle(duration) { | |
return [ANIMATION_DURATION_PROP, duration + "s"] | |
} | |
function getCssDelayStyle(delay, isKeyframeAnimation) { | |
var prop = isKeyframeAnimation ? ANIMATION_DELAY_PROP : TRANSITION_DELAY_PROP; | |
return [prop, delay + "s"] | |
} | |
function blockTransitions(node, duration) { | |
var value = duration ? "-" + duration + "s" : ""; | |
return applyInlineStyle(node, [TRANSITION_DELAY_PROP, value]), [TRANSITION_DELAY_PROP, value] | |
} | |
function blockKeyframeAnimations(node, applyBlock) { | |
var value = applyBlock ? "paused" : "", | |
key = ANIMATION_PROP + ANIMATION_PLAYSTATE_KEY; | |
return applyInlineStyle(node, [key, value]), [key, value] | |
} | |
function applyInlineStyle(node, styleTuple) { | |
var prop = styleTuple[0], | |
value = styleTuple[1]; | |
node.style[prop] = value | |
} | |
function createLocalCacheLookup() { | |
var cache = Object.create(null); | |
return { | |
flush: function() { | |
cache = Object.create(null) | |
}, | |
count: function(key) { | |
var entry = cache[key]; | |
return entry ? entry.total : 0 | |
}, | |
get: function(key) { | |
var entry = cache[key]; | |
return entry && entry.value | |
}, | |
put: function(key, value) { | |
cache[key] ? cache[key].total++ : cache[key] = { | |
total: 1, | |
value: value | |
} | |
} | |
} | |
} | |
var $AnimateCssProvider = ["$animateProvider", function($animateProvider) { | |
var gcsLookup = createLocalCacheLookup(), | |
gcsStaggerLookup = createLocalCacheLookup(); | |
this.$get = ["$window", "$$jqLite", "$$AnimateRunner", "$timeout", "$document", "$sniffer", "$$rAF", function($window, $$jqLite, $$AnimateRunner, $timeout, $document, $sniffer, $$rAF) { | |
var applyAnimationClasses = applyAnimationClassesFactory($$jqLite), | |
parentCounter = 0; | |
function gcsHashFn(node, extraClasses) { | |
var KEY = "$$ngAnimateParentKey", | |
parentNode = node.parentNode, | |
parentID = parentNode[KEY] || (parentNode[KEY] = ++parentCounter); | |
return parentID + "-" + node.getAttribute("class") + "-" + extraClasses | |
} | |
function computeCachedCssStyles(node, className, cacheKey, properties) { | |
var timings = gcsLookup.get(cacheKey); | |
return timings || (timings = computeCssStyles($window, node, properties), "infinite" === timings.animationIterationCount && (timings.animationIterationCount = 1)), gcsLookup.put(cacheKey, timings), timings | |
} | |
function computeCachedCssStaggerStyles(node, className, cacheKey, properties) { | |
var stagger; | |
if (gcsLookup.count(cacheKey) > 0 && (stagger = gcsStaggerLookup.get(cacheKey), !stagger)) { | |
var staggerClassName = pendClasses(className, "-stagger"); | |
$$jqLite.addClass(node, staggerClassName), stagger = computeCssStyles($window, node, properties), stagger.animationDuration = Math.max(stagger.animationDuration, 0), stagger.transitionDuration = Math.max(stagger.transitionDuration, 0), $$jqLite.removeClass(node, staggerClassName), gcsStaggerLookup.put(cacheKey, stagger) | |
} | |
return stagger || {} | |
} | |
var cancelLastRAFRequest, bod = $document[0].body, | |
rafWaitQueue = []; | |
function waitUntilQuiet(callback) { | |
cancelLastRAFRequest && cancelLastRAFRequest(), rafWaitQueue.push(callback), cancelLastRAFRequest = $$rAF(function() { | |
cancelLastRAFRequest = null, gcsLookup.flush(), gcsStaggerLookup.flush(); | |
var width = bod.offsetWidth + 1; | |
forEach(rafWaitQueue, function(cb) { | |
cb(width) | |
}), rafWaitQueue.length = 0 | |
}) | |
} | |
return init; | |
function computeTimings(node, className, cacheKey) { | |
var timings = computeCachedCssStyles(node, className, cacheKey, DETECT_CSS_PROPERTIES), | |
aD = timings.animationDelay, | |
tD = timings.transitionDelay; | |
return timings.maxDelay = aD && tD ? Math.max(aD, tD) : aD || tD, timings.maxDuration = Math.max(timings.animationDuration * timings.animationIterationCount, timings.transitionDuration), timings | |
} | |
function init(element, options) { | |
var node = element[0]; | |
options = prepareAnimationOptions(options); | |
var animationClosed, animationPaused, animationCompleted, runner, runnerHost, maxDelay, maxDelayTime, maxDuration, maxDurationTime, temporaryStyles = [], | |
classes = element.attr("class"), | |
styles = packageStyles(options); | |
if (0 === options.duration || !$sniffer.animations && !$sniffer.transitions) return void close(); | |
var method = options.event && isArray(options.event) ? options.event.join(" ") : options.event, | |
isStructural = method && options.structural, | |
structuralClassName = "", | |
addRemoveClassName = ""; | |
isStructural ? structuralClassName = pendClasses(method, "ng-", !0) : method && (structuralClassName = method), options.addClass && (addRemoveClassName += pendClasses(options.addClass, "-add")), options.removeClass && (addRemoveClassName.length && (addRemoveClassName += " "), addRemoveClassName += pendClasses(options.removeClass, "-remove")); | |
var setupClasses = [structuralClassName, addRemoveClassName].join(" ").trim(), | |
fullClassName = classes + " " + setupClasses, | |
activeClasses = pendClasses(setupClasses, "-active"), | |
hasToStyles = styles.to && Object.keys(styles.to).length > 0; | |
if (!hasToStyles && !setupClasses) return close(), !1; | |
var cacheKey, stagger; | |
if (options.stagger > 0) { | |
var staggerVal = parseFloat(options.stagger); | |
stagger = { | |
transitionDelay: staggerVal, | |
animationDelay: staggerVal, | |
transitionDuration: 0, | |
animationDuration: 0 | |
} | |
} else cacheKey = gcsHashFn(node, fullClassName), stagger = computeCachedCssStaggerStyles(node, setupClasses, cacheKey, DETECT_STAGGER_CSS_PROPERTIES); | |
$$jqLite.addClass(element, setupClasses); | |
var applyOnlyDuration; | |
if (options.transitionStyle) { | |
var transitionStyle = [TRANSITION_PROP, options.transitionStyle]; | |
applyInlineStyle(node, transitionStyle), temporaryStyles.push(transitionStyle) | |
} | |
if (options.duration >= 0) { | |
applyOnlyDuration = node.style[TRANSITION_PROP].length > 0; | |
var durationStyle = getCssTransitionDurationStyle(options.duration, applyOnlyDuration); | |
applyInlineStyle(node, durationStyle), temporaryStyles.push(durationStyle) | |
} | |
if (options.keyframeStyle) { | |
var keyframeStyle = [ANIMATION_PROP, options.keyframeStyle]; | |
applyInlineStyle(node, keyframeStyle), temporaryStyles.push(keyframeStyle) | |
} | |
var itemIndex = stagger ? options.staggerIndex >= 0 ? options.staggerIndex : gcsLookup.count(cacheKey) : 0, | |
isFirst = 0 === itemIndex; | |
isFirst && blockTransitions(node, SAFE_FAST_FORWARD_DURATION_VALUE); | |
var timings = computeTimings(node, fullClassName, cacheKey), | |
relativeDelay = timings.maxDelay; | |
maxDelay = Math.max(relativeDelay, 0), maxDuration = timings.maxDuration; | |
var flags = {}; | |
flags.hasTransitions = timings.transitionDuration > 0, flags.hasAnimations = timings.animationDuration > 0, flags.hasTransitionAll = flags.hasTransitions && "all" == timings.transitionProperty, flags.applyTransitionDuration = hasToStyles && (flags.hasTransitions && !flags.hasTransitionAll || flags.hasAnimations && !flags.hasTransitions), flags.applyAnimationDuration = options.duration && flags.hasAnimations, flags.applyTransitionDelay = truthyTimingValue(options.delay) && (flags.applyTransitionDuration || flags.hasTransitions), flags.applyAnimationDelay = truthyTimingValue(options.delay) && flags.hasAnimations, flags.recalculateTimingStyles = addRemoveClassName.length > 0, (flags.applyTransitionDuration || flags.applyAnimationDuration) && (maxDuration = options.duration ? parseFloat(options.duration) : maxDuration, flags.applyTransitionDuration && (flags.hasTransitions = !0, timings.transitionDuration = maxDuration, applyOnlyDuration = node.style[TRANSITION_PROP + PROPERTY_KEY].length > 0, temporaryStyles.push(getCssTransitionDurationStyle(maxDuration, applyOnlyDuration))), flags.applyAnimationDuration && (flags.hasAnimations = !0, timings.animationDuration = maxDuration, temporaryStyles.push(getCssKeyframeDurationStyle(maxDuration)))), flags.transitionClassBlock = "none" === timings.transitionProperty && 0 === timings.transitionDuration; | |
var applyClassesEarly = 0 === maxDuration && isStructural && addRemoveClassName.length > 0 && !flags.transitionClassBlock; | |
if (!applyClassesEarly && 0 === maxDuration && !flags.recalculateTimingStyles) return close(), !1; | |
if (applyClassesEarly && (applyAnimationClasses(element, options), flags.recalculateTimingStyles = !1, fullClassName = node.className + " " + setupClasses, cacheKey = gcsHashFn(node, fullClassName), timings = computeTimings(node, fullClassName, cacheKey), relativeDelay = timings.maxDelay, maxDelay = Math.max(relativeDelay, 0), maxDuration = timings.maxDuration), 0 === maxDuration && !flags.recalculateTimingStyles) return close(), !1; | |
return timings.transitionDuration > 0 && (flags.recalculateTimingStyles = flags.recalculateTimingStyles || isFirst), maxDelayTime = maxDelay * ONE_SECOND, maxDurationTime = maxDuration * ONE_SECOND, options.skipBlocking || (flags.blockTransition = timings.transitionDuration > 0, flags.blockKeyframeAnimation = timings.animationDuration > 0 && stagger.animationDelay > 0 && 0 === stagger.animationDuration), flags.blockTransition ? applyAnimationFromStyles(element, options) : blockTransitions(node, !1), applyBlocking(maxDuration), { | |
end: endFn, | |
start: function() { | |
if (animationClosed) return; | |
return runnerHost = { | |
end: endFn, | |
cancel: cancelFn, | |
resume: null, | |
pause: null | |
}, runner = new $$AnimateRunner(runnerHost), waitUntilQuiet(start), runner | |
} | |
}; | |
function endFn() { | |
close() | |
} | |
function cancelFn() { | |
close(!0) | |
} | |
function close(rejected) { | |
if (animationClosed || animationCompleted && animationPaused) return; | |
animationClosed = !0, animationPaused = !1, $$jqLite.removeClass(element, setupClasses), $$jqLite.removeClass(element, activeClasses), blockKeyframeAnimations(node, !1), blockTransitions(node, !1), forEach(temporaryStyles, function(entry) { | |
node.style[entry[0]] = "" | |
}), applyAnimationClasses(element, options), applyAnimationStyles(element, options), options.onDone && options.onDone(), runner && runner.complete(!rejected) | |
} | |
function applyBlocking(duration) { | |
flags.blockTransition && blockTransitions(node, duration), flags.blockKeyframeAnimation && blockKeyframeAnimations(node, !!duration) | |
} | |
function start() { | |
if (animationClosed) return; | |
var startTime, events = [], | |
playPause = function(playAnimation) { | |
if (animationCompleted) animationPaused && playAnimation && (animationPaused = !1, close()); | |
else if (animationPaused = !playAnimation, timings.animationDuration) { | |
var value = blockKeyframeAnimations(node, animationPaused); | |
animationPaused ? temporaryStyles.push(value) : removeFromArray(temporaryStyles, value) | |
} | |
}, | |
maxStagger = itemIndex > 0 && (timings.transitionDuration && 0 === stagger.transitionDuration || timings.animationDuration && 0 === stagger.animationDuration) && Math.max(stagger.animationDelay, stagger.transitionDelay); | |
maxStagger ? $timeout(triggerAnimationStart, Math.floor(maxStagger * itemIndex * ONE_SECOND), !1) : triggerAnimationStart(), runnerHost.resume = function() { | |
playPause(!0) | |
}, runnerHost.pause = function() { | |
playPause(!1) | |
}; | |
function triggerAnimationStart() { | |
if (animationClosed) return; | |
if (applyBlocking(!1), forEach(temporaryStyles, function(entry) { | |
var key = entry[0], | |
value = entry[1]; | |
node.style[key] = value | |
}), applyAnimationClasses(element, options), $$jqLite.addClass(element, activeClasses), flags.recalculateTimingStyles) { | |
if (fullClassName = node.className + " " + setupClasses, cacheKey = gcsHashFn(node, fullClassName), timings = computeTimings(node, fullClassName, cacheKey), relativeDelay = timings.maxDelay, maxDelay = Math.max(relativeDelay, 0), maxDuration = timings.maxDuration, 0 === maxDuration) return void close(); | |
flags.hasTransitions = timings.transitionDuration > 0, flags.hasAnimations = timings.animationDuration > 0 | |
} | |
if (flags.applyTransitionDelay || flags.applyAnimationDelay) { | |
relativeDelay = "boolean" != typeof options.delay && truthyTimingValue(options.delay) ? parseFloat(options.delay) : relativeDelay, maxDelay = Math.max(relativeDelay, 0); | |
var delayStyle; | |
flags.applyTransitionDelay && (timings.transitionDelay = relativeDelay, delayStyle = getCssDelayStyle(relativeDelay), temporaryStyles.push(delayStyle), node.style[delayStyle[0]] = delayStyle[1]), flags.applyAnimationDelay && (timings.animationDelay = relativeDelay, delayStyle = getCssDelayStyle(relativeDelay, !0), temporaryStyles.push(delayStyle), node.style[delayStyle[0]] = delayStyle[1]) | |
} | |
if (maxDelayTime = maxDelay * ONE_SECOND, maxDurationTime = maxDuration * ONE_SECOND, options.easing) { | |
var easeProp, easeVal = options.easing; | |
flags.hasTransitions && (easeProp = TRANSITION_PROP + TIMING_KEY, temporaryStyles.push([easeProp, easeVal]), node.style[easeProp] = easeVal), flags.hasAnimations && (easeProp = ANIMATION_PROP + TIMING_KEY, temporaryStyles.push([easeProp, easeVal]), node.style[easeProp] = easeVal) | |
} | |
timings.transitionDuration && events.push(TRANSITIONEND_EVENT), timings.animationDuration && events.push(ANIMATIONEND_EVENT), startTime = Date.now(), element.on(events.join(" "), onAnimationProgress), $timeout(onAnimationExpired, maxDelayTime + CLOSING_TIME_BUFFER * maxDurationTime), applyAnimationToStyles(element, options) | |
} | |
function onAnimationExpired() { | |
close() | |
} | |
function onAnimationProgress(event) { | |
event.stopPropagation(); | |
var ev = event.originalEvent || event, | |
timeStamp = ev.$manualTimeStamp || ev.timeStamp || Date.now(), | |
elapsedTime = parseFloat(ev.elapsedTime.toFixed(ELAPSED_TIME_MAX_DECIMAL_PLACES)); | |
Math.max(timeStamp - startTime, 0) >= maxDelayTime && elapsedTime >= maxDuration && (animationCompleted = !0, close()) | |
} | |
} | |
} | |
}] | |
}], | |
$$AnimateCssDriverProvider = ["$$animationProvider", function($$animationProvider) { | |
$$animationProvider.drivers.push("$$animateCssDriver"); | |
var NG_ANIMATE_SHIM_CLASS_NAME = "ng-animate-shim", | |
NG_ANIMATE_ANCHOR_CLASS_NAME = "ng-animate-anchor", | |
NG_ANIMATE_ANCHOR_SUFFIX = "-anchor", | |
NG_OUT_ANCHOR_CLASS_NAME = "ng-anchor-out", | |
NG_IN_ANCHOR_CLASS_NAME = "ng-anchor-in"; | |
this.$get = ["$animateCss", "$rootScope", "$$AnimateRunner", "$rootElement", "$document", "$sniffer", function($animateCss, $rootScope, $$AnimateRunner, $rootElement, $document, $sniffer) { | |
if (!$sniffer.animations && !$sniffer.transitions) return noop; | |
var bodyNode = $document[0].body, | |
rootNode = $rootElement[0], | |
rootBodyElement = jqLite(bodyNode.parentNode === rootNode ? bodyNode : rootNode); | |
return function(animationDetails) { | |
return animationDetails.from && animationDetails.to ? prepareFromToAnchorAnimation(animationDetails.from, animationDetails.to, animationDetails.classes, animationDetails.anchors) : prepareRegularAnimation(animationDetails) | |
}; | |
function filterCssClasses(classes) { | |
return classes.replace(/\bng-\S+\b/g, "") | |
} | |
function getUniqueValues(a, b) { | |
return isString(a) && (a = a.split(" ")), isString(b) && (b = b.split(" ")), a.filter(function(val) { | |
return -1 === b.indexOf(val) | |
}).join(" ") | |
} | |
function prepareAnchoredAnimation(classes, outAnchor, inAnchor) { | |
var clone = jqLite(outAnchor[0].cloneNode(!0)), | |
startingClasses = filterCssClasses(clone.attr("class") || ""), | |
anchorClasses = pendClasses(classes, NG_ANIMATE_ANCHOR_SUFFIX); | |
outAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME), inAnchor.addClass(NG_ANIMATE_SHIM_CLASS_NAME), clone.addClass(NG_ANIMATE_ANCHOR_CLASS_NAME), clone.addClass(anchorClasses), rootBodyElement.append(clone); | |
var animatorOut = prepareOutAnimation(); | |
if (!animatorOut) return end(); | |
return { | |
start: function() { | |
var runner, currentAnimation = animatorOut.start(); | |
return currentAnimation.done(function() { | |
currentAnimation = null; | |
var animatorIn = prepareInAnimation(); | |
if (animatorIn) return currentAnimation = animatorIn.start(), currentAnimation.done(function() { | |
currentAnimation = null, end(), runner.complete() | |
}), currentAnimation; | |
end(), runner.complete() | |
}), runner = new $$AnimateRunner({ | |
end: endFn, | |
cancel: endFn | |
}); | |
function endFn() { | |
currentAnimation && currentAnimation.end() | |
} | |
} | |
}; | |
function calculateAnchorStyles(anchor) { | |
var styles = {}, | |
coords = anchor[0].getBoundingClientRect(); | |
return forEach(["width", "height", "top", "left"], function(key) { | |
var value = coords[key]; | |
switch (key) { | |
case "top": | |
value += bodyNode.scrollTop; | |
break; | |
case "left": | |
value += bodyNode.scrollLeft | |
} | |
styles[key] = Math.floor(value) + "px" | |
}), styles | |
} | |
function prepareOutAnimation() { | |
return $animateCss(clone, { | |
addClass: NG_OUT_ANCHOR_CLASS_NAME, | |
delay: !0, | |
from: calculateAnchorStyles(outAnchor) | |
}) | |
} | |
function prepareInAnimation() { | |
var endingClasses = filterCssClasses(inAnchor.attr("class")), | |
classes = getUniqueValues(endingClasses, startingClasses); | |
return $animateCss(clone, { | |
to: calculateAnchorStyles(inAnchor), | |
addClass: NG_IN_ANCHOR_CLASS_NAME + " " + classes, | |
removeClass: NG_OUT_ANCHOR_CLASS_NAME + " " + startingClasses, | |
delay: !0 | |
}) | |
} | |
function end() { | |
clone.remove(), outAnchor.removeClass(NG_ANIMATE_SHIM_CLASS_NAME), inAnchor.removeClass(NG_ANIMATE_SHIM_CLASS_NAME) | |
} | |
} | |
function prepareFromToAnchorAnimation(from, to, classes, anchors) { | |
var fromAnimation = prepareRegularAnimation(from), | |
toAnimation = prepareRegularAnimation(to), | |
anchorAnimations = []; | |
if (forEach(anchors, function(anchor) { | |
var outElement = anchor.out, | |
inElement = anchor["in"], | |
animator = prepareAnchoredAnimation(classes, outElement, inElement); | |
animator && anchorAnimations.push(animator) | |
}), !fromAnimation && !toAnimation && 0 === anchorAnimations.length) return; | |
return { | |
start: function() { | |
var animationRunners = []; | |
fromAnimation && animationRunners.push(fromAnimation.start()), toAnimation && animationRunners.push(toAnimation.start()), forEach(anchorAnimations, function(animation) { | |
animationRunners.push(animation.start()) | |
}); | |
var runner = new $$AnimateRunner({ | |
end: endFn, | |
cancel: endFn | |
}); | |
return $$AnimateRunner.all(animationRunners, function(status) { | |
runner.complete(status) | |
}), runner; | |
function endFn() { | |
forEach(animationRunners, function(runner) { | |
runner.end() | |
}) | |
} | |
} | |
} | |
} | |
function prepareRegularAnimation(animationDetails) { | |
var element = animationDetails.element, | |
options = animationDetails.options || {}; | |
return options.structural = animationDetails.structural, options.event = animationDetails.event, "leave" === options.event && animationDetails.domOperation && (options.onDone = animationDetails.domOperation), $animateCss(element, options) | |
} | |
}] | |
}], | |
$$AnimateJsProvider = ["$animateProvider", function($animateProvider) { | |
this.$get = ["$injector", "$$AnimateRunner", "$$rAFMutex", "$$jqLite", function($injector, $$AnimateRunner, $$rAFMutex, $$jqLite) { | |
var applyAnimationClasses = applyAnimationClassesFactory($$jqLite); | |
return function(element, event, classes, options) { | |
3 === arguments.length && isObject(classes) && (options = classes, classes = null), options = prepareAnimationOptions(options), classes || (classes = element.attr("class") || "", options.addClass && (classes += " " + options.addClass), options.removeClass && (classes += " " + options.removeClass)); | |
var before, after, classesToAdd = options.addClass, | |
classesToRemove = options.removeClass, | |
animations = lookupAnimations(classes); | |
if (animations.length) { | |
var afterFn, beforeFn; | |
"leave" == event ? (beforeFn = "leave", afterFn = "afterLeave") : (beforeFn = "before" + event.charAt(0).toUpperCase() + event.substr(1), afterFn = event), "enter" !== event && "move" !== event && (before = packageAnimations(element, event, options, animations, beforeFn)), after = packageAnimations(element, event, options, animations, afterFn) | |
} | |
if (!before && !after) return; | |
function applyOptions() { | |
options.domOperation(), applyAnimationClasses(element, options) | |
} | |
return { | |
start: function() { | |
var closeActiveAnimations, chain = []; | |
before && chain.push(function(fn) { | |
closeActiveAnimations = before(fn) | |
}), chain.length ? chain.push(function(fn) { | |
applyOptions(), fn(!0) | |
}) : applyOptions(), after && chain.push(function(fn) { | |
closeActiveAnimations = after(fn) | |
}); | |
var animationClosed = !1, | |
runner = new $$AnimateRunner({ | |
end: function() { | |
endAnimations() | |
}, | |
cancel: function() { | |
endAnimations(!0) | |
} | |
}); | |
return $$AnimateRunner.chain(chain, onComplete), runner; | |
function onComplete(success) { | |
animationClosed = !0, applyOptions(), applyAnimationStyles(element, options), runner.complete(success) | |
} | |
function endAnimations(cancelled) { | |
animationClosed || ((closeActiveAnimations || noop)(cancelled), onComplete(cancelled)) | |
} | |
} | |
}; | |
function executeAnimationFn(fn, element, event, options, onDone) { | |
var args; | |
switch (event) { | |
case "animate": | |
args = [element, options.from, options.to, onDone]; | |
break; | |
case "setClass": | |
args = [element, classesToAdd, classesToRemove, onDone]; | |
break; | |
case "addClass": | |
args = [element, classesToAdd, onDone]; | |
break; | |
case "removeClass": | |
args = [element, classesToRemove, onDone]; | |
break; | |
default: | |
args = [element, onDone] | |
} | |
args.push(options); | |
var value = fn.apply(fn, args); | |
return isFunction(value) ? value : noop | |
} | |
function groupEventedAnimations(element, event, options, animations, fnName) { | |
var operations = []; | |
return forEach(animations, function(ani) { | |
var animation = ani[fnName]; | |
if (!animation) return; | |
operations.push(function() { | |
var runner, endProgressCb, resolved = !1, | |
onAnimationComplete = function(rejected) { | |
resolved || (resolved = !0, (endProgressCb || noop)(rejected), runner.complete(!rejected)) | |
}; | |
return runner = new $$AnimateRunner({ | |
end: function() { | |
onAnimationComplete() | |
}, | |
cancel: function() { | |
onAnimationComplete(!0) | |
} | |
}), endProgressCb = executeAnimationFn(animation, element, event, options, function(result) { | |
var cancelled = result === !1; | |
onAnimationComplete(cancelled) | |
}), runner | |
}) | |
}), operations | |
} | |
function packageAnimations(element, event, options, animations, fnName) { | |
var operations = groupEventedAnimations(element, event, options, animations, fnName); | |
if (0 === operations.length) { | |
var a, b; | |
"beforeSetClass" === fnName ? (a = groupEventedAnimations(element, "removeClass", options, animations, "beforeRemoveClass"), b = groupEventedAnimations(element, "addClass", options, animations, "beforeAddClass")) : "setClass" === fnName && (a = groupEventedAnimations(element, "removeClass", options, animations, "removeClass"), b = groupEventedAnimations(element, "addClass", options, animations, "addClass")), a && (operations = operations.concat(a)), b && (operations = operations.concat(b)) | |
} | |
if (0 === operations.length) return; | |
return function(callback) { | |
var runners = []; | |
return operations.length && forEach(operations, function(animateFn) { | |
runners.push(animateFn()) | |
}), runners.length ? $$AnimateRunner.all(runners, callback) : callback(), | |
function(reject) { | |
forEach(runners, function(runner) { | |
reject ? runner.cancel() : runner.end() | |
}) | |
} | |
} | |
} | |
}; | |
function lookupAnimations(classes) { | |
classes = isArray(classes) ? classes : classes.split(" "); | |
for (var matches = [], flagMap = {}, i = 0; i < classes.length; i++) { | |
var klass = classes[i], | |
animationFactory = $animateProvider.$$registeredAnimations[klass]; | |
animationFactory && !flagMap[klass] && (matches.push($injector.get(animationFactory)), flagMap[klass] = !0) | |
} | |
return matches | |
} | |
}] | |
}], | |
$$AnimateJsDriverProvider = ["$$animationProvider", function($$animationProvider) { | |
$$animationProvider.drivers.push("$$animateJsDriver"), this.$get = ["$$animateJs", "$$AnimateRunner", function($$animateJs, $$AnimateRunner) { | |
return function(animationDetails) { | |
if (animationDetails.from && animationDetails.to) { | |
var fromAnimation = prepareAnimation(animationDetails.from), | |
toAnimation = prepareAnimation(animationDetails.to); | |
if (!fromAnimation && !toAnimation) return; | |
return { | |
start: function() { | |
var animationRunners = []; | |
fromAnimation && animationRunners.push(fromAnimation.start()), toAnimation && animationRunners.push(toAnimation.start()), $$AnimateRunner.all(animationRunners, done); | |
var runner = new $$AnimateRunner({ | |
end: endFnFactory(), | |
cancel: endFnFactory() | |
}); | |
return runner; | |
function endFnFactory() { | |
return function() { | |
forEach(animationRunners, function(runner) { | |
runner.end() | |
}) | |
} | |
} | |
function done(status) { | |
runner.complete(status) | |
} | |
} | |
} | |
} | |
return prepareAnimation(animationDetails) | |
}; | |
function prepareAnimation(animationDetails) { | |
var element = animationDetails.element, | |
event = animationDetails.event, | |
options = animationDetails.options, | |
classes = animationDetails.classes; | |
return $$animateJs(element, event, classes, options) | |
} | |
}] | |
}], | |
NG_ANIMATE_ATTR_NAME = "data-ng-animate", | |
$$AnimateQueueProvider = ["$animateProvider", function($animateProvider) { | |
var PRE_DIGEST_STATE = 1, | |
RUNNING_STATE = 2, | |
rules = this.rules = { | |
skip: [], | |
cancel: [], | |
join: [] | |
}; | |
function isAllowed(ruleType, element, currentAnimation, previousAnimation) { | |
return rules[ruleType].some(function(fn) { | |
return fn(element, currentAnimation, previousAnimation) | |
}) | |
} | |
function hasAnimationClasses(options, and) { | |
options = options || {}; | |
var a = (options.addClass || "").length > 0, | |
b = (options.removeClass || "").length > 0; | |
return and ? a && b : a || b | |
} | |
rules.join.push(function(element, newAnimation, currentAnimation) { | |
return !newAnimation.structural && hasAnimationClasses(newAnimation.options) | |
}), rules.skip.push(function(element, newAnimation, currentAnimation) { | |
return !newAnimation.structural && !hasAnimationClasses(newAnimation.options) | |
}), rules.skip.push(function(element, newAnimation, currentAnimation) { | |
return "leave" == currentAnimation.event && newAnimation.structural | |
}), rules.skip.push(function(element, newAnimation, currentAnimation) { | |
return currentAnimation.structural && !newAnimation.structural | |
}), rules.cancel.push(function(element, newAnimation, currentAnimation) { | |
return currentAnimation.structural && newAnimation.structural | |
}), rules.cancel.push(function(element, newAnimation, currentAnimation) { | |
return currentAnimation.state === RUNNING_STATE && newAnimation.structural | |
}), this.$get = ["$$rAF", "$rootScope", "$rootElement", "$document", "$$HashMap", "$$animation", "$$AnimateRunner", "$templateRequest", "$$jqLite", function($$rAF, $rootScope, $rootElement, $document, $$HashMap, $$animation, $$AnimateRunner, $templateRequest, $$jqLite) { | |
var activeAnimationsLookup = new $$HashMap, | |
disabledElementsLookup = new $$HashMap, | |
animationsEnabled = null, | |
deregisterWatch = $rootScope.$watch(function() { | |
return 0 === $templateRequest.totalPendingRequests | |
}, function(isEmpty) { | |
if (!isEmpty) return; | |
deregisterWatch(), $rootScope.$$postDigest(function() { | |
$rootScope.$$postDigest(function() { | |
null === animationsEnabled && (animationsEnabled = !0) | |
}) | |
}) | |
}), | |
bodyElement = jqLite($document[0].body), | |
callbackRegistry = {}, | |
classNameFilter = $animateProvider.classNameFilter(), | |
isAnimatableClassName = classNameFilter ? function(className) { | |
return classNameFilter.test(className) | |
} : function() { | |
return !0 | |
}, | |
applyAnimationClasses = applyAnimationClassesFactory($$jqLite); | |
function normalizeAnimationOptions(element, options) { | |
return mergeAnimationOptions(element, options, {}) | |
} | |
function findCallbacks(element, event) { | |
var targetNode = element[0], | |
matches = [], | |
entries = callbackRegistry[event]; | |
return entries && forEach(entries, function(entry) { | |
entry.node.contains(targetNode) && matches.push(entry.callback) | |
}), matches | |
} | |
function triggerCallback(event, element, phase, data) { | |
$$rAF(function() { | |
forEach(findCallbacks(element, event), function(callback) { | |
callback(element, phase, data) | |
}) | |
}) | |
} | |
return { | |
on: function(event, container, callback) { | |
var node = extractElementNode(container); | |
callbackRegistry[event] = callbackRegistry[event] || [], callbackRegistry[event].push({ | |
node: node, | |
callback: callback | |
}) | |
}, | |
off: function(event, container, callback) { | |
var entries = callbackRegistry[event]; | |
if (!entries) return; | |
callbackRegistry[event] = 1 === arguments.length ? null : filterFromRegistry(entries, container, callback); | |
function filterFromRegistry(list, matchContainer, matchCallback) { | |
var containerNode = extractElementNode(matchContainer); | |
return list.filter(function(entry) { | |
var isMatch = entry.node === containerNode && (!matchCallback || entry.callback === matchCallback); | |
return !isMatch | |
}) | |
} | |
}, | |
push: function(element, event, options, domOperation) { | |
return options = options || {}, options.domOperation = domOperation, queueAnimation(element, event, options) | |
}, | |
enabled: function(element, bool) { | |
var argCount = arguments.length; | |
if (0 === argCount) bool = !!animationsEnabled; | |
else { | |
var hasElement = isElement(element); | |
if (hasElement) { | |
var node = element.length ? element[0] : element, | |
recordExists = disabledElementsLookup.get(node); | |
1 === argCount ? bool = !recordExists : (bool = !!bool, bool ? recordExists && disabledElementsLookup.remove(node) : disabledElementsLookup.put(node, !0)) | |
} else bool = animationsEnabled = !!element | |
} | |
return bool | |
} | |
}; | |
function queueAnimation(element, event, options) { | |
element = stripCommentsFromElement(element); | |
var node = element[0]; | |
options = prepareAnimationOptions(options); | |
var parent = element.parent(), | |
runner = new $$AnimateRunner; | |
if (!node) return runner.end(), runner; | |
isArray(options.addClass) && (options.addClass = options.addClass.join(" ")), isArray(options.removeClass) && (options.removeClass = options.removeClass.join(" ")), options.from && !isObject(options.from) && (options.from = null), options.to && !isObject(options.to) && (options.to = null); | |
var className = [node.className, options.addClass, options.removeClass].join(" "); | |
if (!isAnimatableClassName(className)) return runner.end(), runner; | |
var isStructural = ["enter", "move", "leave"].indexOf(event) >= 0, | |
skipAnimations = !animationsEnabled || disabledElementsLookup.get(node), | |
existingAnimation = !skipAnimations && activeAnimationsLookup.get(node) || {}, | |
hasExistingAnimation = !!existingAnimation.state; | |
if (skipAnimations || hasExistingAnimation && existingAnimation.state == PRE_DIGEST_STATE || (skipAnimations = !areAnimationsAllowed(element, parent, event)), skipAnimations) return close(), runner; | |
isStructural && closeChildAnimations(element); | |
var newAnimation = { | |
structural: isStructural, | |
element: element, | |
event: event, | |
options: options, | |
runner: runner | |
}; | |
if (hasExistingAnimation) { | |
var skipAnimationFlag = isAllowed("skip", element, newAnimation, existingAnimation); | |
if (skipAnimationFlag) return existingAnimation.state === RUNNING_STATE ? (close(), runner) : (mergeAnimationOptions(element, existingAnimation.options, options), existingAnimation.runner); | |
var cancelAnimationFlag = isAllowed("cancel", element, newAnimation, existingAnimation); | |
if (cancelAnimationFlag) existingAnimation.state === RUNNING_STATE ? existingAnimation.runner.end() : mergeAnimationOptions(element, newAnimation.options, existingAnimation.options); | |
else { | |
var joinAnimationFlag = isAllowed("join", element, newAnimation, existingAnimation); | |
if (joinAnimationFlag) { | |
if (existingAnimation.state !== RUNNING_STATE) return event = newAnimation.event = existingAnimation.event, options = mergeAnimationOptions(element, existingAnimation.options, newAnimation.options), runner; | |
normalizeAnimationOptions(element, options) | |
} | |
} | |
} else normalizeAnimationOptions(element, options); | |
var isValidAnimation = newAnimation.structural; | |
if (isValidAnimation || (isValidAnimation = "animate" === newAnimation.event && Object.keys(newAnimation.options.to || {}).length > 0 || hasAnimationClasses(newAnimation.options)), !isValidAnimation) return close(), runner; | |
closeParentClassBasedAnimations(parent); | |
var counter = (existingAnimation.counter || 0) + 1; | |
return newAnimation.counter = counter, markElementAnimationState(element, PRE_DIGEST_STATE, newAnimation), $rootScope.$$postDigest(function() { | |
var animationDetails = activeAnimationsLookup.get(node), | |
animationCancelled = !animationDetails; | |
animationDetails = animationDetails || {}; | |
var parentElement = element.parent() || [], | |
isValidAnimation = parentElement.length > 0 && ("animate" === animationDetails.event || animationDetails.structural || hasAnimationClasses(animationDetails.options)); | |
if (animationCancelled || animationDetails.counter !== counter || !isValidAnimation) return animationCancelled && (applyAnimationClasses(element, options), applyAnimationStyles(element, options)), void((animationCancelled || isStructural && animationDetails.event !== event) && options.domOperation()); | |
event = !animationDetails.structural && hasAnimationClasses(animationDetails.options, !0) ? "setClass" : animationDetails.event, closeParentClassBasedAnimations(parentElement), markElementAnimationState(element, RUNNING_STATE); | |
var realRunner = $$animation(element, event, animationDetails.options); | |
realRunner.done(function(status) { | |
close(!status); | |
var animationDetails = activeAnimationsLookup.get(node); | |
animationDetails && animationDetails.counter === counter && clearElementAnimationState(element), notifyProgress(runner, event, "close", {}) | |
}), runner.setHost(realRunner), notifyProgress(runner, event, "start", {}) | |
}), runner; | |
function notifyProgress(runner, event, phase, data) { | |
triggerCallback(event, element, phase, data), runner.progress(event, phase, data) | |
} | |
function close(reject) { | |
applyAnimationClasses(element, options), applyAnimationStyles(element, options), options.domOperation(), runner.complete(!reject) | |
} | |
} | |
function closeChildAnimations(element) { | |
var node = element[0], | |
children = node.querySelectorAll("[" + NG_ANIMATE_ATTR_NAME + "]"); | |
forEach(children, function(child) { | |
var state = parseInt(child.getAttribute(NG_ANIMATE_ATTR_NAME)), | |
animationDetails = activeAnimationsLookup.get(child); | |
switch (state) { | |
case RUNNING_STATE: | |
animationDetails.runner.end(); | |
case PRE_DIGEST_STATE: | |
animationDetails && activeAnimationsLookup.remove(child) | |
} | |
}) | |
} | |
function clearElementAnimationState(element) { | |
element = element.length ? element[0] : element, element.removeAttribute(NG_ANIMATE_ATTR_NAME), activeAnimationsLookup.remove(element) | |
} | |
function isMatchingElement(a, b) { | |
return a = a.length ? a[0] : a, b = b.length ? b[0] : b, a === b | |
} | |
function closeParentClassBasedAnimations(startingElement) { | |
for (var parentNode = startingElement[0];;) { | |
if (!parentNode || parentNode.nodeType !== ELEMENT_NODE) break; | |
var animationDetails = activeAnimationsLookup.get(parentNode); | |
animationDetails && examineParentAnimation(parentNode, animationDetails), parentNode = parentNode.parentNode | |
} | |
function examineParentAnimation(node, animationDetails) { | |
if (animationDetails.structural) return; | |
animationDetails.state === RUNNING_STATE && animationDetails.runner.end(), clearElementAnimationState(node) | |
} | |
} | |
function areAnimationsAllowed(element, parent, event) { | |
for (var animateChildren, bodyElementDetected = !1, rootElementDetected = !1, parentAnimationDetected = !1; parent && parent.length;) { | |
var parentNode = parent[0]; | |
if (parentNode.nodeType !== ELEMENT_NODE) break; | |
var details = activeAnimationsLookup.get(parentNode) || {}; | |
if (parentAnimationDetected || (parentAnimationDetected = details.structural || disabledElementsLookup.get(parentNode)), isUndefined(animateChildren) || animateChildren === !0) { | |
var value = parent.data(NG_ANIMATE_CHILDREN_DATA); | |
isDefined(value) && (animateChildren = value) | |
} | |
if (parentAnimationDetected && animateChildren === !1) break; | |
rootElementDetected || (rootElementDetected = isMatchingElement(parent, $rootElement)), bodyElementDetected || (bodyElementDetected = isMatchingElement(parent, bodyElement)), parent = parent.parent() | |
} | |
var allowAnimation = !parentAnimationDetected || animateChildren; | |
return allowAnimation && rootElementDetected && bodyElementDetected | |
} | |
function markElementAnimationState(element, state, details) { | |
details = details || {}, details.state = state, element = element.length ? element[0] : element, element.setAttribute(NG_ANIMATE_ATTR_NAME, state); | |
var oldValue = activeAnimationsLookup.get(element), | |
newValue = oldValue ? extend(oldValue, details) : details; | |
activeAnimationsLookup.put(element, newValue) | |
} | |
}] | |
}], | |
$$rAFMutexFactory = ["$$rAF", function($$rAF) { | |
return function() { | |
var passed = !1; | |
return $$rAF(function() { | |
passed = !0 | |
}), | |
function(fn) { | |
passed ? fn() : $$rAF(fn) | |
} | |
} | |
}], | |
$$AnimateRunnerFactory = ["$q", "$$rAFMutex", function($q, $$rAFMutex) { | |
var INITIAL_STATE = 0, | |
DONE_PENDING_STATE = 1, | |
DONE_COMPLETE_STATE = 2; | |
AnimateRunner.chain = function(chain, callback) { | |
var index = 0; | |
next(); | |
function next() { | |
if (index === chain.length) return void callback(!0); | |
chain[index](function(response) { | |
if (response === !1) return void callback(!1); | |
index++, next() | |
}) | |
} | |
}, AnimateRunner.all = function(runners, callback) { | |
var count = 0, | |
status = !0; | |
forEach(runners, function(runner) { | |
runner.done(onProgress) | |
}); | |
function onProgress(response) { | |
status = status && response, ++count === runners.length && callback(status) | |
} | |
}; | |
function AnimateRunner(host) { | |
this.setHost(host), this._doneCallbacks = [], this._runInAnimationFrame = $$rAFMutex(), this._state = 0 | |
} | |
return AnimateRunner.prototype = { | |
setHost: function(host) { | |
this.host = host || {} | |
}, | |
done: function(fn) { | |
this._state === DONE_COMPLETE_STATE ? fn() : this._doneCallbacks.push(fn) | |
}, | |
progress: noop, | |
getPromise: function() { | |
if (!this.promise) { | |
var self = this; | |
this.promise = $q(function(resolve, reject) { | |
self.done(function(status) { | |
status === !1 ? reject() : resolve() | |
}) | |
}) | |
} | |
return this.promise | |
}, | |
then: function(resolveHandler, rejectHandler) { | |
return this.getPromise().then(resolveHandler, rejectHandler) | |
}, | |
"catch": function(handler) { | |
return this.getPromise()["catch"](handler) | |
}, | |
"finally": function(handler) { | |
return this.getPromise()["finally"](handler) | |
}, | |
pause: function() { | |
this.host.pause && this.host.pause(); | |
}, | |
resume: function() { | |
this.host.resume && this.host.resume() | |
}, | |
end: function() { | |
this.host.end && this.host.end(), this._resolve(!0) | |
}, | |
cancel: function() { | |
this.host.cancel && this.host.cancel(), this._resolve(!1) | |
}, | |
complete: function(response) { | |
var self = this; | |
self._state === INITIAL_STATE && (self._state = DONE_PENDING_STATE, self._runInAnimationFrame(function() { | |
self._resolve(response) | |
})) | |
}, | |
_resolve: function(response) { | |
this._state !== DONE_COMPLETE_STATE && (forEach(this._doneCallbacks, function(fn) { | |
fn(response) | |
}), this._doneCallbacks.length = 0, this._state = DONE_COMPLETE_STATE) | |
} | |
}, AnimateRunner | |
}], | |
$$AnimationProvider = ["$animateProvider", function($animateProvider) { | |
var NG_ANIMATE_CLASSNAME = "ng-animate", | |
NG_ANIMATE_REF_ATTR = "ng-animate-ref", | |
drivers = this.drivers = [], | |
RUNNER_STORAGE_KEY = "$$animationRunner"; | |
function setRunner(element, runner) { | |
element.data(RUNNER_STORAGE_KEY, runner) | |
} | |
function removeRunner(element) { | |
element.removeData(RUNNER_STORAGE_KEY) | |
} | |
function getRunner(element) { | |
return element.data(RUNNER_STORAGE_KEY) | |
} | |
this.$get = ["$$jqLite", "$rootScope", "$injector", "$$AnimateRunner", function($$jqLite, $rootScope, $injector, $$AnimateRunner) { | |
var animationQueue = [], | |
applyAnimationClasses = applyAnimationClassesFactory($$jqLite); | |
return function(element, event, options) { | |
options = prepareAnimationOptions(options); | |
var isStructural = ["enter", "move", "leave"].indexOf(event) >= 0, | |
runner = new $$AnimateRunner({ | |
end: function() { | |
close() | |
}, | |
cancel: function() { | |
close(!0) | |
} | |
}); | |
if (!drivers.length) return close(), runner; | |
setRunner(element, runner); | |
var classes = mergeClasses(element.attr("class"), mergeClasses(options.addClass, options.removeClass)), | |
tempClasses = options.tempClasses; | |
if (tempClasses && (classes += " " + tempClasses, options.tempClasses = null), animationQueue.push({ | |
element: element, | |
classes: classes, | |
event: event, | |
structural: isStructural, | |
options: options, | |
start: start, | |
close: close | |
}), element.on("$destroy", handleDestroyedElement), animationQueue.length > 1) return runner; | |
return $rootScope.$$postDigest(function() { | |
var animations = []; | |
forEach(animationQueue, function(entry) { | |
getRunner(entry.element) && animations.push(entry) | |
}), animationQueue.length = 0, forEach(groupAnimations(animations), function(animationEntry) { | |
var startFn = animationEntry.start, | |
closeFn = animationEntry.close, | |
operation = invokeFirstDriver(animationEntry), | |
startAnimation = operation && operation.start; | |
if (startAnimation) { | |
startFn(); | |
var animationRunner = startAnimation(); | |
animationRunner.done(function(status) { | |
closeFn(!status) | |
}), updateAnimationRunners(animationEntry, animationRunner) | |
} else closeFn() | |
}) | |
}), runner; | |
function getAnchorNodes(node) { | |
var SELECTOR = "[" + NG_ANIMATE_REF_ATTR + "]", | |
items = node.hasAttribute(NG_ANIMATE_REF_ATTR) ? [node] : node.querySelectorAll(SELECTOR), | |
anchors = []; | |
return forEach(items, function(node) { | |
var attr = node.getAttribute(NG_ANIMATE_REF_ATTR); | |
attr && attr.length && anchors.push(node) | |
}), anchors | |
} | |
function groupAnimations(animations) { | |
var preparedAnimations = [], | |
refLookup = {}; | |
forEach(animations, function(animation, index) { | |
var element = animation.element, | |
node = element[0], | |
event = animation.event, | |
enterOrMove = ["enter", "move"].indexOf(event) >= 0, | |
anchorNodes = animation.structural ? getAnchorNodes(node) : []; | |
if (anchorNodes.length) { | |
var direction = enterOrMove ? "to" : "from"; | |
forEach(anchorNodes, function(anchor) { | |
var key = anchor.getAttribute(NG_ANIMATE_REF_ATTR); | |
refLookup[key] = refLookup[key] || {}, refLookup[key][direction] = { | |
animationID: index, | |
element: jqLite(anchor) | |
} | |
}) | |
} else preparedAnimations.push(animation) | |
}); | |
var usedIndicesLookup = {}, | |
anchorGroups = {}; | |
return forEach(refLookup, function(operations, key) { | |
var from = operations.from, | |
to = operations.to; | |
if (!from || !to) { | |
var index = from ? from.animationID : to.animationID, | |
indexKey = index.toString(); | |
return void(usedIndicesLookup[indexKey] || (usedIndicesLookup[indexKey] = !0, preparedAnimations.push(animations[index]))) | |
} | |
var fromAnimation = animations[from.animationID], | |
toAnimation = animations[to.animationID], | |
lookupKey = from.animationID.toString(); | |
if (!anchorGroups[lookupKey]) { | |
var group = anchorGroups[lookupKey] = { | |
start: function() { | |
fromAnimation.start(), toAnimation.start() | |
}, | |
close: function() { | |
fromAnimation.close(), toAnimation.close() | |
}, | |
classes: cssClassesIntersection(fromAnimation.classes, toAnimation.classes), | |
from: fromAnimation, | |
to: toAnimation, | |
anchors: [] | |
}; | |
group.classes.length ? preparedAnimations.push(group) : (preparedAnimations.push(fromAnimation), preparedAnimations.push(toAnimation)) | |
} | |
anchorGroups[lookupKey].anchors.push({ | |
out: from.element, | |
"in": to.element | |
}) | |
}), preparedAnimations | |
} | |
function cssClassesIntersection(a, b) { | |
a = a.split(" "), b = b.split(" "); | |
for (var matches = [], i = 0; i < a.length; i++) { | |
var aa = a[i]; | |
if ("ng-" === aa.substring(0, 3)) continue; | |
for (var j = 0; j < b.length; j++) | |
if (aa === b[j]) { | |
matches.push(aa); | |
break | |
} | |
} | |
return matches.join(" ") | |
} | |
function invokeFirstDriver(animationDetails) { | |
for (var i = drivers.length - 1; i >= 0; i--) { | |
var driverName = drivers[i]; | |
if (!$injector.has(driverName)) continue; | |
var factory = $injector.get(driverName), | |
driver = factory(animationDetails); | |
if (driver) return driver | |
} | |
} | |
function start() { | |
element.addClass(NG_ANIMATE_CLASSNAME), tempClasses && $$jqLite.addClass(element, tempClasses) | |
} | |
function updateAnimationRunners(animation, newRunner) { | |
animation.from && animation.to ? (update(animation.from.element), update(animation.to.element)) : update(animation.element); | |
function update(element) { | |
getRunner(element).setHost(newRunner) | |
} | |
} | |
function handleDestroyedElement() { | |
var runner = getRunner(element); | |
!runner || "leave" === event && options.$$domOperationFired || runner.end() | |
} | |
function close(rejected) { | |
element.off("$destroy", handleDestroyedElement), removeRunner(element), applyAnimationClasses(element, options), applyAnimationStyles(element, options), options.domOperation(), tempClasses && $$jqLite.removeClass(element, tempClasses), element.removeClass(NG_ANIMATE_CLASSNAME), runner.complete(!rejected) | |
} | |
} | |
}] | |
}]; | |
angular.module("ngAnimate", []).directive("ngAnimateChildren", $$AnimateChildrenDirective).factory("$$rAFMutex", $$rAFMutexFactory).factory("$$AnimateRunner", $$AnimateRunnerFactory).provider("$$animateQueue", $$AnimateQueueProvider).provider("$$animation", $$AnimationProvider).provider("$animateCss", $AnimateCssProvider).provider("$$animateCssDriver", $$AnimateCssDriverProvider).provider("$$animateJs", $$AnimateJsProvider).provider("$$animateJsDriver", $$AnimateJsDriverProvider) | |
}(window, window.angular), angular.module("angular-carousel", ["ngTouch", "angular-carousel.shifty"]), angular.module("angular-carousel").directive("rnCarouselAutoSlide", ["$timeout", function($timeout) { | |
return { | |
restrict: "A", | |
link: function(scope, element, attrs) { | |
var delay = Math.round(1e3 * parseFloat(attrs.rnCarouselAutoSlide)), | |
timer = increment = !1, | |
slidesCount = element.children().length; | |
scope.carouselExposedIndex || (scope.carouselExposedIndex = 0), stopAutoplay = function() { | |
angular.isDefined(timer) && $timeout.cancel(timer), timer = void 0 | |
}, increment = function() { | |
scope.carouselExposedIndex < slidesCount - 1 ? scope.carouselExposedIndex = scope.carouselExposedIndex + 1 : scope.carouselExposedIndex = 0 | |
}, restartTimer = function() { | |
stopAutoplay(), timer = $timeout(increment, delay) | |
}, scope.$watch("carouselIndex", function() { | |
restartTimer() | |
}), restartTimer(), attrs.rnCarouselPauseOnHover && "false" != attrs.rnCarouselPauseOnHover && (element.on("mouseenter", stopAutoplay), element.on("mouseleave", restartTimer)), scope.$on("$destroy", function() { | |
stopAutoplay(), element.off("mouseenter", stopAutoplay), element.off("mouseleave", restartTimer) | |
}) | |
} | |
} | |
}]), angular.module("angular-carousel").directive("rnCarouselIndicators", ["$parse", function($parse) { | |
return { | |
restrict: "A", | |
scope: { | |
slides: "=", | |
index: "=rnCarouselIndex" | |
}, | |
templateUrl: "carousel-indicators.html", | |
link: function(scope, iElement, iAttributes) { | |
var indexModel = $parse(iAttributes.rnCarouselIndex); | |
scope.goToSlide = function(index) { | |
indexModel.assign(scope.$parent.$parent, index) | |
} | |
} | |
} | |
}]), angular.module("angular-carousel").run(["$templateCache", function($templateCache) { | |
$templateCache.put("carousel-indicators.html", '<div class="rn-carousel-indicator">\n<span ng-repeat="slide in slides" ng-class="{active: $index==index}" ng-click="goToSlide($index)">●</span></div>') | |
}]), | |
function() { | |
"use strict"; | |
angular.module("angular-carousel").service("DeviceCapabilities", function() { | |
function detectTransformProperty() { | |
var transformProperty = "transform", | |
safariPropertyHack = "webkitTransform"; | |
return "undefined" != typeof document.body.style[transformProperty] ? ["webkit", "moz", "o", "ms"].every(function(prefix) { | |
var e = "-" + prefix + "-transform"; | |
if ("undefined" != typeof document.body.style[e]) return transformProperty = e, !1; | |
return !0 | |
}) : transformProperty = "undefined" != typeof document.body.style[safariPropertyHack] ? "-webkit-transform" : void 0, transformProperty | |
} | |
function detect3dSupport() { | |
var has3d, el = document.createElement("p"), | |
transforms = { | |
webkitTransform: "-webkit-transform", | |
msTransform: "-ms-transform", | |
transform: "transform" | |
}; | |
document.body.insertBefore(el, null); | |
for (var t in transforms) void 0 !== el.style[t] && (el.style[t] = "translate3d(1px,1px,1px)", has3d = window.getComputedStyle(el).getPropertyValue(transforms[t])); | |
return document.body.removeChild(el), void 0 !== has3d && has3d.length > 0 && "none" !== has3d | |
} | |
return { | |
has3d: detect3dSupport(), | |
transformProperty: detectTransformProperty() | |
} | |
}).service("computeCarouselSlideStyle", ["DeviceCapabilities", function(DeviceCapabilities) { | |
return function(slideIndex, offset, transitionType) { | |
var opacity, style = { | |
display: "inline-block" | |
}, | |
absoluteLeft = 100 * slideIndex + offset, | |
slideTransformValue = DeviceCapabilities.has3d ? "translate3d(" + absoluteLeft + "%, 0, 0)" : "translate3d(" + absoluteLeft + "%, 0)", | |
distance = (100 - Math.abs(absoluteLeft)) / 100; | |
if (DeviceCapabilities.transformProperty) | |
if ("fadeAndSlide" == transitionType) style[DeviceCapabilities.transformProperty] = slideTransformValue, opacity = 0, Math.abs(absoluteLeft) < 100 && (opacity = .3 + .7 * distance), style.opacity = opacity; | |
else if ("hexagon" == transitionType) { | |
var transformFrom = 100, | |
degrees = 0, | |
maxDegrees = 60 * (distance - 1); | |
transformFrom = -100 * slideIndex > offset ? 100 : 0, degrees = -100 * slideIndex > offset ? maxDegrees : -maxDegrees, style[DeviceCapabilities.transformProperty] = slideTransformValue + " rotateY(" + degrees + "deg)", style[DeviceCapabilities.transformProperty + "-origin"] = transformFrom + "% 50%" | |
} else if ("zoom" == transitionType) { | |
style[DeviceCapabilities.transformProperty] = slideTransformValue; | |
var scale = 1; | |
Math.abs(absoluteLeft) < 100 && (scale = 1 + 2 * (1 - distance)), style[DeviceCapabilities.transformProperty] += " scale(" + scale + ")", style[DeviceCapabilities.transformProperty + "-origin"] = "50% 50%", opacity = 0, Math.abs(absoluteLeft) < 100 && (opacity = .3 + .7 * distance), style.opacity = opacity | |
} else style[DeviceCapabilities.transformProperty] = slideTransformValue; | |
else style["margin-left"] = absoluteLeft + "%"; | |
return style | |
} | |
}]).service("createStyleString", function() { | |
return function(object) { | |
var styles = []; | |
return angular.forEach(object, function(value, key) { | |
styles.push(key + ":" + value) | |
}), styles.join(";") | |
} | |
}).directive("rnCarousel", ["$swipe", "$window", "$document", "$parse", "$compile", "$timeout", "$interval", "computeCarouselSlideStyle", "createStyleString", "Tweenable", function($swipe, $window, $document, $parse, $compile, $timeout, $interval, computeCarouselSlideStyle, createStyleString, Tweenable) { | |
var carouselId = 0; | |
$window.requestAnimationFrame || $window.webkitRequestAnimationFrame || $window.mozRequestAnimationFrame; | |
function getItemIndex(collection, target, defaultIndex) { | |
var result = defaultIndex; | |
return collection.every(function(item, index) { | |
if (angular.equals(item, target)) return result = index, !1; | |
return !0 | |
}), result | |
} | |
return { | |
restrict: "A", | |
scope: !0, | |
compile: function(tElement, tAttributes) { | |
var repeatItem, repeatCollection, firstChild = tElement[0].querySelector("li"), | |
firstChildAttributes = firstChild ? firstChild.attributes : [], | |
isRepeatBased = !1, | |
isBuffered = !1; | |
return ["ng-repeat", "data-ng-repeat", "ng:repeat", "x-ng-repeat"].every(function(attr) { | |
var repeatAttribute = firstChildAttributes[attr]; | |
if (angular.isDefined(repeatAttribute)) { | |
var exprMatch = repeatAttribute.value.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/), | |
trackProperty = exprMatch[3]; | |
if (repeatItem = exprMatch[1], repeatCollection = exprMatch[2], repeatItem) return angular.isDefined(tAttributes.rnCarouselBuffered) && (isBuffered = !0, repeatAttribute.value = repeatItem + " in " + repeatCollection + "|carouselSlice:carouselBufferIndex:carouselBufferSize", trackProperty && (repeatAttribute.value += " track by " + trackProperty)), isRepeatBased = !0, !1 | |
} | |
return !0 | |
}), | |
function(scope, iElement, iAttributes, containerCtrl) { | |
carouselId++; | |
var pressed, startX, destination, currentSlides, defaultOptions = { | |
transitionType: iAttributes.rnCarouselTransition || "slide", | |
transitionEasing: "easeTo", | |
transitionDuration: 300, | |
isSequential: !0, | |
autoSlideDuration: 3, | |
bufferSize: 5, | |
moveTreshold: .1 | |
}, | |
options = angular.extend({}, defaultOptions), | |
isIndexBound = !1, | |
offset = 0, | |
swipeMoved = !1, | |
elWidth = null, | |
elX = null, | |
locked = !1; | |
if (void 0 !== iAttributes.rnCarouselControls) { | |
var tpl = '<div class="rn-carousel-controls">\n <span class="rn-carousel-control rn-carousel-control-prev" ng-click="prevSlide()" ng-if="carouselIndex > 0"></span>\n <span class="rn-carousel-control rn-carousel-control-next" ng-click="nextSlide()" ng-if="carouselIndex < ' + repeatCollection + '.length - 1"></span>\n</div>'; | |
iElement.append($compile(angular.element(tpl))(scope)) | |
} | |
$swipe.bind(iElement, { | |
start: swipeStart, | |
move: swipeMove, | |
end: swipeEnd, | |
cancel: function(event) { | |
swipeEnd({}, event) | |
} | |
}); | |
function getSlidesDOM() { | |
return iElement[0].querySelectorAll("ul[rn-carousel] > li") | |
} | |
function documentMouseUpEvent(event) { | |
swipeMoved = !0, swipeEnd({ | |
x: event.clientX, | |
y: event.clientY | |
}, event) | |
} | |
function updateSlidesPosition(offset) { | |
var x = 100 * scope.carouselBufferIndex + offset; | |
angular.forEach(getSlidesDOM(), function(child, index) { | |
child.style.cssText = createStyleString(computeCarouselSlideStyle(index, x, options.transitionType)) | |
}) | |
} | |
scope.nextSlide = function(slideOptions) { | |
var index = scope.carouselIndex + 1; | |
index > currentSlides.length - 1 && (index = 0), locked || goToSlide(index, slideOptions) | |
}, scope.prevSlide = function(slideOptions) { | |
var index = scope.carouselIndex - 1; | |
0 > index && (index = currentSlides.length - 1), goToSlide(index, slideOptions) | |
}; | |
function goToSlide(index, slideOptions) { | |
if (void 0 === index && (index = scope.carouselIndex), slideOptions = slideOptions || {}, slideOptions.animate === !1 || "none" === options.transitionType) return locked = !1, offset = -100 * index, scope.carouselIndex = index, void updateBufferIndex(); | |
locked = !0; | |
var tweenable = new Tweenable; | |
tweenable.tween({ | |
from: { | |
x: offset | |
}, | |
to: { | |
x: -100 * index | |
}, | |
duration: options.transitionDuration, | |
easing: options.transitionEasing, | |
step: function(state) { | |
updateSlidesPosition(state.x) | |
}, | |
finish: function() { | |
locked = !1, scope.$apply(function() { | |
scope.carouselIndex = index, offset = -100 * index, updateBufferIndex() | |
}) | |
} | |
}) | |
} | |
function getContainerWidth() { | |
var rect = iElement[0].getBoundingClientRect(); | |
return rect.width ? rect.width : rect.right - rect.left | |
} | |
function updateContainerWidth() { | |
elWidth = getContainerWidth() | |
} | |
function swipeStart(coords, event) { | |
return $document.bind("mouseup", documentMouseUpEvent), updateContainerWidth(), elX = iElement[0].querySelector("li").getBoundingClientRect().left, pressed = !0, startX = coords.x, !1 | |
} | |
function swipeMove(coords, event) { | |
if (locked) return; | |
var x, delta; | |
if (pressed && (x = coords.x, delta = startX - x, delta > 2 || -2 > delta)) { | |
swipeMoved = !0; | |
var moveOffset = offset + 100 * -delta / elWidth; | |
updateSlidesPosition(moveOffset) | |
} | |
return !1 | |
} | |
var init = !0; | |
scope.carouselIndex = 0, isRepeatBased || (currentSlides = [], angular.forEach(getSlidesDOM(), function(node, index) { | |
currentSlides.push({ | |
id: index | |
}) | |
})); | |
var autoSlider; | |
if (void 0 !== iAttributes.rnCarouselAutoSlide) { | |
var duration = parseInt(iAttributes.rnCarouselAutoSlide, 10) || options.autoSlideDuration; | |
autoSlider = $interval(function() { | |
locked || pressed || scope.nextSlide() | |
}, 1e3 * duration) | |
} | |
if (iAttributes.rnCarouselIndex) { | |
var updateParentIndex = function(value) { | |
indexModel.assign(scope.$parent, value) | |
}, | |
indexModel = $parse(iAttributes.rnCarouselIndex); | |
angular.isFunction(indexModel.assign) ? (scope.$watch("carouselIndex", function(newValue) { | |
locked || updateParentIndex(newValue) | |
}), scope.$parent.$watch(indexModel, function(newValue, oldValue) { | |
void 0 !== newValue && null !== newValue && (currentSlides && newValue >= currentSlides.length ? (newValue = currentSlides.length - 1, updateParentIndex(newValue)) : currentSlides && 0 > newValue && (newValue = 0, updateParentIndex(newValue)), locked || goToSlide(newValue, { | |
animate: !init | |
}), init = !1) | |
}), isIndexBound = !0) : isNaN(iAttributes.rnCarouselIndex) || goToSlide(parseInt(iAttributes.rnCarouselIndex, 10), { | |
animate: !1 | |
}) | |
} else goToSlide(0, { | |
animate: !init | |
}), init = !1; | |
if (iAttributes.rnCarouselLocked && scope.$watch(iAttributes.rnCarouselLocked, function(newValue, oldValue) { | |
locked = newValue === !0 ? !0 : !1 | |
}), isRepeatBased) { | |
var deepWatch = void 0 !== iAttributes.rnCarouselDeepWatch; | |
scope[deepWatch ? "$watch" : "$watchCollection"](repeatCollection, function(newValue, oldValue) { | |
(currentSlides || newValue).slice(); | |
if (currentSlides = newValue, deepWatch && angular.isArray(newValue)) { | |
var activeElement = oldValue[scope.carouselIndex], | |
newIndex = getItemIndex(newValue, activeElement, scope.carouselIndex); | |
goToSlide(newIndex, { | |
animate: !1 | |
}) | |
} else goToSlide(scope.carouselIndex, { | |
animate: !1 | |
}) | |
}, !0) | |
} | |
function swipeEnd(coords, event, forceAnimation) { | |
if (event && !swipeMoved) return; | |
if ($document.unbind("mouseup", documentMouseUpEvent), pressed = !1, swipeMoved = !1, destination = startX - coords.x, 0 === destination) return; | |
if (locked) return; | |
if (offset += 100 * -destination / elWidth, options.isSequential) { | |
var minMove = options.moveTreshold * elWidth, | |
absMove = -destination, | |
slidesMove = -Math[absMove >= 0 ? "ceil" : "floor"](absMove / elWidth), | |
shouldMove = Math.abs(absMove) > minMove; | |
currentSlides && slidesMove + scope.carouselIndex >= currentSlides.length && (slidesMove = currentSlides.length - 1 - scope.carouselIndex), slidesMove + scope.carouselIndex < 0 && (slidesMove = -scope.carouselIndex); | |
var moveOffset = shouldMove ? slidesMove : 0; | |
destination = scope.carouselIndex + moveOffset, goToSlide(destination) | |
} else scope.$apply(function() { | |
scope.carouselIndex = parseInt(-offset / 100, 10), updateBufferIndex() | |
}) | |
} | |
scope.$on("$destroy", function() { | |
$document.unbind("mouseup", documentMouseUpEvent) | |
}), scope.carouselBufferIndex = 0, scope.carouselBufferSize = options.bufferSize; | |
function updateBufferIndex() { | |
var bufferIndex = 0, | |
bufferEdgeSize = (scope.carouselBufferSize - 1) / 2; | |
isBuffered ? (bufferIndex = scope.carouselIndex <= bufferEdgeSize ? 0 : currentSlides && currentSlides.length < scope.carouselBufferSize ? 0 : currentSlides && scope.carouselIndex > currentSlides.length - scope.carouselBufferSize ? currentSlides.length - scope.carouselBufferSize : scope.carouselIndex - bufferEdgeSize, scope.carouselBufferIndex = bufferIndex, $timeout(function() { | |
updateSlidesPosition(offset) | |
}, 0, !1)) : $timeout(function() { | |
updateSlidesPosition(offset) | |
}, 0, !1) | |
} | |
function onOrientationChange() { | |
updateContainerWidth(), goToSlide() | |
} | |
var winEl = angular.element($window); | |
winEl.bind("orientationchange", onOrientationChange), winEl.bind("resize", onOrientationChange), scope.$on("$destroy", function() { | |
$document.unbind("mouseup", documentMouseUpEvent), winEl.unbind("orientationchange", onOrientationChange), winEl.unbind("resize", onOrientationChange) | |
}) | |
} | |
} | |
} | |
}]) | |
}(), angular.module("angular-carousel.shifty", []).factory("Tweenable", function() { | |
return function(root) { | |
var Tweenable = function() { | |
"use strict"; | |
var formula, DEFAULT_SCHEDULE_FUNCTION, DEFAULT_EASING = "linear", | |
DEFAULT_DURATION = 500, | |
UPDATE_TIME = 1e3 / 60, | |
_now = Date.now ? Date.now : function() { | |
return +new Date | |
}, | |
now = "undefined" != typeof SHIFTY_DEBUG_NOW ? SHIFTY_DEBUG_NOW : _now; | |
DEFAULT_SCHEDULE_FUNCTION = "undefined" != typeof window ? window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || window.mozCancelRequestAnimationFrame && window.mozRequestAnimationFrame || setTimeout : setTimeout; | |
function noop() {} | |
function each(obj, fn) { | |
var key; | |
for (key in obj) Object.hasOwnProperty.call(obj, key) && fn(key) | |
} | |
function shallowCopy(targetObj, srcObj) { | |
return each(srcObj, function(prop) { | |
targetObj[prop] = srcObj[prop] | |
}), targetObj | |
} | |
function defaults(target, src) { | |
each(src, function(prop) { | |
"undefined" == typeof target[prop] && (target[prop] = src[prop]) | |
}) | |
} | |
function tweenProps(forPosition, currentState, originalState, targetState, duration, timestamp, easing) { | |
var prop, normalizedPosition = (forPosition - timestamp) / duration; | |
for (prop in currentState) currentState.hasOwnProperty(prop) && (currentState[prop] = tweenProp(originalState[prop], targetState[prop], formula[easing[prop]], normalizedPosition)); | |
return currentState | |
} | |
function tweenProp(start, end, easingFunc, position) { | |
return start + (end - start) * easingFunc(position) | |
} | |
function applyFilter(tweenable, filterName) { | |
var filters = Tweenable.prototype.filter, | |
args = tweenable._filterArgs; | |
each(filters, function(name) { | |
"undefined" != typeof filters[name][filterName] && filters[name][filterName].apply(tweenable, args) | |
}) | |
} | |
var timeoutHandler_endTime, timeoutHandler_currentTime, timeoutHandler_isEnded, timeoutHandler_offset; | |
function timeoutHandler(tweenable, timestamp, duration, currentState, originalState, targetState, easing, step, schedule) { | |
timeoutHandler_endTime = timestamp + duration, timeoutHandler_currentTime = Math.min(now(), timeoutHandler_endTime), timeoutHandler_isEnded = timeoutHandler_currentTime >= timeoutHandler_endTime, timeoutHandler_offset = duration - (timeoutHandler_endTime - timeoutHandler_currentTime), tweenable.isPlaying() && !timeoutHandler_isEnded ? (tweenable._scheduleId = schedule(tweenable._timeoutHandler, UPDATE_TIME), applyFilter(tweenable, "beforeTween"), tweenProps(timeoutHandler_currentTime, currentState, originalState, targetState, duration, timestamp, easing), applyFilter(tweenable, "afterTween"), step(currentState, tweenable._attachment, timeoutHandler_offset)) : timeoutHandler_isEnded && (step(targetState, tweenable._attachment, timeoutHandler_offset), tweenable.stop(!0)) | |
} | |
function composeEasingObject(fromTweenParams, easing) { | |
var composedEasing = {}; | |
return "string" == typeof easing ? each(fromTweenParams, function(prop) { | |
composedEasing[prop] = easing | |
}) : each(fromTweenParams, function(prop) { | |
composedEasing[prop] || (composedEasing[prop] = easing[prop] || DEFAULT_EASING) | |
}), composedEasing | |
} | |
function Tweenable(opt_initialState, opt_config) { | |
this._currentState = opt_initialState || {}, this._configured = !1, this._scheduleFunction = DEFAULT_SCHEDULE_FUNCTION, "undefined" != typeof opt_config && this.setConfig(opt_config) | |
} | |
return Tweenable.prototype.tween = function(opt_config) { | |
if (this._isTweening) return this; | |
return void 0 === opt_config && this._configured || this.setConfig(opt_config), this._timestamp = now(), this._start(this.get(), this._attachment), this.resume() | |
}, Tweenable.prototype.setConfig = function(config) { | |
config = config || {}, this._configured = !0, this._attachment = config.attachment, this._pausedAtTime = null, this._scheduleId = null, this._start = config.start || noop, this._step = config.step || noop, this._finish = config.finish || noop, this._duration = config.duration || DEFAULT_DURATION, this._currentState = config.from || this.get(), this._originalState = this.get(), this._targetState = config.to || this.get(); | |
var currentState = this._currentState, | |
targetState = this._targetState; | |
return defaults(targetState, currentState), this._easing = composeEasingObject(currentState, config.easing || DEFAULT_EASING), this._filterArgs = [currentState, this._originalState, targetState, this._easing], applyFilter(this, "tweenCreated"), this | |
}, Tweenable.prototype.get = function() { | |
return shallowCopy({}, this._currentState) | |
}, Tweenable.prototype.set = function(state) { | |
this._currentState = state | |
}, Tweenable.prototype.pause = function() { | |
return this._pausedAtTime = now(), this._isPaused = !0, this | |
}, Tweenable.prototype.resume = function() { | |
this._isPaused && (this._timestamp += now() - this._pausedAtTime), this._isPaused = !1, this._isTweening = !0; | |
var self = this; | |
return this._timeoutHandler = function() { | |
timeoutHandler(self, self._timestamp, self._duration, self._currentState, self._originalState, self._targetState, self._easing, self._step, self._scheduleFunction) | |
}, this._timeoutHandler(), this | |
}, Tweenable.prototype.seek = function(millisecond) { | |
return this._timestamp = now() - millisecond, this.isPlaying() || (this._isTweening = !0, this._isPaused = !1, timeoutHandler(this, this._timestamp, this._duration, this._currentState, this._originalState, this._targetState, this._easing, this._step, this._scheduleFunction), this._timeoutHandler(), this.pause()), this | |
}, Tweenable.prototype.stop = function(gotoEnd) { | |
return this._isTweening = !1, this._isPaused = !1, this._timeoutHandler = noop, (root.cancelAnimationFrame || root.webkitCancelAnimationFrame || root.oCancelAnimationFrame || root.msCancelAnimationFrame || root.mozCancelRequestAnimationFrame || root.clearTimeout)(this._scheduleId), gotoEnd && (shallowCopy(this._currentState, this._targetState), applyFilter(this, "afterTweenEnd"), this._finish.call(this, this._currentState, this._attachment)), this | |
}, Tweenable.prototype.isPlaying = function() { | |
return this._isTweening && !this._isPaused | |
}, Tweenable.prototype.setScheduleFunction = function(scheduleFunction) { | |
this._scheduleFunction = scheduleFunction | |
}, Tweenable.prototype.dispose = function() { | |
var prop; | |
for (prop in this) this.hasOwnProperty(prop) && delete this[prop] | |
}, Tweenable.prototype.filter = {}, Tweenable.prototype.formula = { | |
linear: function(pos) { | |
return pos | |
} | |
}, formula = Tweenable.prototype.formula, shallowCopy(Tweenable, { | |
now: now, | |
each: each, | |
tweenProps: tweenProps, | |
tweenProp: tweenProp, | |
applyFilter: applyFilter, | |
shallowCopy: shallowCopy, | |
defaults: defaults, | |
composeEasingObject: composeEasingObject | |
}), "function" == typeof SHIFTY_DEBUG_NOW && (root.timeoutHandler = timeoutHandler), "object" == typeof exports ? module.exports = Tweenable : "function" == typeof define && define.amd ? define(function() { | |
return Tweenable | |
}) : "undefined" == typeof root.Tweenable && (root.Tweenable = Tweenable), Tweenable | |
}(); | |
! function() { | |
Tweenable.shallowCopy(Tweenable.prototype.formula, { | |
easeInQuad: function(pos) { | |
return Math.pow(pos, 2) | |
}, | |
easeOutQuad: function(pos) { | |
return -(Math.pow(pos - 1, 2) - 1) | |
}, | |
easeInOutQuad: function(pos) { | |
if ((pos /= .5) < 1) return .5 * Math.pow(pos, 2); | |
return -.5 * ((pos -= 2) * pos - 2) | |
}, | |
easeInCubic: function(pos) { | |
return Math.pow(pos, 3) | |
}, | |
easeOutCubic: function(pos) { | |
return Math.pow(pos - 1, 3) + 1 | |
}, | |
easeInOutCubic: function(pos) { | |
if ((pos /= .5) < 1) return .5 * Math.pow(pos, 3); | |
return .5 * (Math.pow(pos - 2, 3) + 2) | |
}, | |
easeInQuart: function(pos) { | |
return Math.pow(pos, 4) | |
}, | |
easeOutQuart: function(pos) { | |
return -(Math.pow(pos - 1, 4) - 1) | |
}, | |
easeInOutQuart: function(pos) { | |
if ((pos /= .5) < 1) return .5 * Math.pow(pos, 4); | |
return -.5 * ((pos -= 2) * Math.pow(pos, 3) - 2) | |
}, | |
easeInQuint: function(pos) { | |
return Math.pow(pos, 5) | |
}, | |
easeOutQuint: function(pos) { | |
return Math.pow(pos - 1, 5) + 1 | |
}, | |
easeInOutQuint: function(pos) { | |
if ((pos /= .5) < 1) return .5 * Math.pow(pos, 5); | |
return .5 * (Math.pow(pos - 2, 5) + 2) | |
}, | |
easeInSine: function(pos) { | |
return -Math.cos(pos * (Math.PI / 2)) + 1 | |
}, | |
easeOutSine: function(pos) { | |
return Math.sin(pos * (Math.PI / 2)) | |
}, | |
easeInOutSine: function(pos) { | |
return -.5 * (Math.cos(Math.PI * pos) - 1) | |
}, | |
easeInExpo: function(pos) { | |
return 0 === pos ? 0 : Math.pow(2, 10 * (pos - 1)) | |
}, | |
easeOutExpo: function(pos) { | |
return 1 === pos ? 1 : -Math.pow(2, -10 * pos) + 1 | |
}, | |
easeInOutExpo: function(pos) { | |
if (0 === pos) return 0; | |
if (1 === pos) return 1; | |
if ((pos /= .5) < 1) return .5 * Math.pow(2, 10 * (pos - 1)); | |
return .5 * (-Math.pow(2, -10 * --pos) + 2) | |
}, | |
easeInCirc: function(pos) { | |
return -(Math.sqrt(1 - pos * pos) - 1) | |
}, | |
easeOutCirc: function(pos) { | |
return Math.sqrt(1 - Math.pow(pos - 1, 2)) | |
}, | |
easeInOutCirc: function(pos) { | |
if ((pos /= .5) < 1) return -.5 * (Math.sqrt(1 - pos * pos) - 1); | |
return .5 * (Math.sqrt(1 - (pos -= 2) * pos) + 1) | |
}, | |
easeOutBounce: function(pos) { | |
return 1 / 2.75 > pos ? 7.5625 * pos * pos : 2 / 2.75 > pos ? 7.5625 * (pos -= 1.5 / 2.75) * pos + .75 : 2.5 / 2.75 > pos ? 7.5625 * (pos -= 2.25 / 2.75) * pos + .9375 : 7.5625 * (pos -= 2.625 / 2.75) * pos + .984375 | |
}, | |
easeInBack: function(pos) { | |
var s = 1.70158; | |
return pos * pos * ((s + 1) * pos - s) | |
}, | |
easeOutBack: function(pos) { | |
var s = 1.70158; | |
return (pos -= 1) * pos * ((s + 1) * pos + s) + 1 | |
}, | |
easeInOutBack: function(pos) { | |
var s = 1.70158; | |
if ((pos /= .5) < 1) return .5 * pos * pos * (((s *= 1.525) + 1) * pos - s); | |
return .5 * ((pos -= 2) * pos * (((s *= 1.525) + 1) * pos + s) + 2) | |
}, | |
elastic: function(pos) { | |
return -1 * Math.pow(4, -8 * pos) * Math.sin(2 * (6 * pos - 1) * Math.PI / 2) + 1 | |
}, | |
swingFromTo: function(pos) { | |
var s = 1.70158; | |
return (pos /= .5) < 1 ? .5 * pos * pos * (((s *= 1.525) + 1) * pos - s) : .5 * ((pos -= 2) * pos * (((s *= 1.525) + 1) * pos + s) + 2) | |
}, | |
swingFrom: function(pos) { | |
var s = 1.70158; | |
return pos * pos * ((s + 1) * pos - s) | |
}, | |
swingTo: function(pos) { | |
var s = 1.70158; | |
return (pos -= 1) * pos * ((s + 1) * pos + s) + 1 | |
}, | |
bounce: function(pos) { | |
return 1 / 2.75 > pos ? 7.5625 * pos * pos : 2 / 2.75 > pos ? 7.5625 * (pos -= 1.5 / 2.75) * pos + .75 : 2.5 / 2.75 > pos ? 7.5625 * (pos -= 2.25 / 2.75) * pos + .9375 : 7.5625 * (pos -= 2.625 / 2.75) * pos + .984375 | |
}, | |
bouncePast: function(pos) { | |
return 1 / 2.75 > pos ? 7.5625 * pos * pos : 2 / 2.75 > pos ? 2 - (7.5625 * (pos -= 1.5 / 2.75) * pos + .75) : 2.5 / 2.75 > pos ? 2 - (7.5625 * (pos -= 2.25 / 2.75) * pos + .9375) : 2 - (7.5625 * (pos -= 2.625 / 2.75) * pos + .984375) | |
}, | |
easeFromTo: function(pos) { | |
if ((pos /= .5) < 1) return .5 * Math.pow(pos, 4); | |
return -.5 * ((pos -= 2) * Math.pow(pos, 3) - 2) | |
}, | |
easeFrom: function(pos) { | |
return Math.pow(pos, 4) | |
}, | |
easeTo: function(pos) { | |
return Math.pow(pos, .25) | |
} | |
}) | |
}(), | |
function() { | |
function cubicBezierAtTime(t, p1x, p1y, p2x, p2y, duration) { | |
var ax = 0, | |
bx = 0, | |
cx = 0, | |
ay = 0, | |
by = 0, | |
cy = 0; | |
function sampleCurveX(t) { | |
return ((ax * t + bx) * t + cx) * t | |
} | |
function sampleCurveY(t) { | |
return ((ay * t + by) * t + cy) * t | |
} | |
function sampleCurveDerivativeX(t) { | |
return (3 * ax * t + 2 * bx) * t + cx | |
} | |
function solveEpsilon(duration) { | |
return 1 / (200 * duration) | |
} | |
function solve(x, epsilon) { | |
return sampleCurveY(solveCurveX(x, epsilon)) | |
} | |
function fabs(n) { | |
return n >= 0 ? n : 0 - n | |
} | |
function solveCurveX(x, epsilon) { | |
var t0, t1, t2, x2, d2, i; | |
for (t2 = x, i = 0; 8 > i; i++) { | |
if (x2 = sampleCurveX(t2) - x, fabs(x2) < epsilon) return t2; | |
if (d2 = sampleCurveDerivativeX(t2), fabs(d2) < 1e-6) break; | |
t2 -= x2 / d2 | |
} | |
if (t0 = 0, t1 = 1, t2 = x, t0 > t2) return t0; | |
if (t2 > t1) return t1; | |
for (; t1 > t0;) { | |
if (x2 = sampleCurveX(t2), fabs(x2 - x) < epsilon) return t2; | |
x > x2 ? t0 = t2 : t1 = t2, t2 = .5 * (t1 - t0) + t0 | |
} | |
return t2 | |
} | |
return cx = 3 * p1x, bx = 3 * (p2x - p1x) - cx, ax = 1 - cx - bx, cy = 3 * p1y, by = 3 * (p2y - p1y) - cy, ay = 1 - cy - by, solve(t, solveEpsilon(duration)) | |
} | |
function getCubicBezierTransition(x1, y1, x2, y2) { | |
return function(pos) { | |
return cubicBezierAtTime(pos, x1, y1, x2, y2, 1) | |
} | |
} | |
Tweenable.setBezierFunction = function(name, x1, y1, x2, y2) { | |
var cubicBezierTransition = getCubicBezierTransition(x1, y1, x2, y2); | |
return cubicBezierTransition.x1 = x1, cubicBezierTransition.y1 = y1, cubicBezierTransition.x2 = x2, cubicBezierTransition.y2 = y2, Tweenable.prototype.formula[name] = cubicBezierTransition | |
}, Tweenable.unsetBezierFunction = function(name) { | |
delete Tweenable.prototype.formula[name] | |
} | |
}(), | |
function() { | |
function getInterpolatedValues(from, current, targetState, position, easing) { | |
return Tweenable.tweenProps(position, current, from, targetState, 1, 0, easing) | |
} | |
var mockTweenable = new Tweenable; | |
mockTweenable._filterArgs = [], Tweenable.interpolate = function(from, targetState, position, easing) { | |
var current = Tweenable.shallowCopy({}, from), | |
easingObject = Tweenable.composeEasingObject(from, easing || "linear"); | |
mockTweenable.set({}); | |
var filterArgs = mockTweenable._filterArgs; | |
filterArgs.length = 0, filterArgs[0] = current, filterArgs[1] = from, filterArgs[2] = targetState, filterArgs[3] = easingObject, Tweenable.applyFilter(mockTweenable, "tweenCreated"), Tweenable.applyFilter(mockTweenable, "beforeTween"); | |
var interpolatedValues = getInterpolatedValues(from, current, targetState, position, easingObject); | |
return Tweenable.applyFilter(mockTweenable, "afterTween"), interpolatedValues | |
} | |
}(); | |
! function(Tweenable) { | |
var R_NUMBER_COMPONENT = /(\d|\-|\.)/, | |
R_FORMAT_CHUNKS = /([^\-0-9\.]+)/g, | |
R_UNFORMATTED_VALUES = /[0-9.\-]+/g, | |
R_RGB = new RegExp("rgb\\(" + R_UNFORMATTED_VALUES.source + /,\s*/.source + R_UNFORMATTED_VALUES.source + /,\s*/.source + R_UNFORMATTED_VALUES.source + "\\)", "g"), | |
R_RGB_PREFIX = /^.*\(/, | |
R_HEX = /#([0-9]|[a-f]){3,6}/gi, | |
VALUE_PLACEHOLDER = "VAL", | |
getFormatChunksFrom_accumulator = []; | |
function getFormatChunksFrom(rawValues, prefix) { | |
getFormatChunksFrom_accumulator.length = 0; | |
var i, rawValuesLength = rawValues.length; | |
for (i = 0; rawValuesLength > i; i++) getFormatChunksFrom_accumulator.push("_" + prefix + "_" + i); | |
return getFormatChunksFrom_accumulator | |
} | |
function getFormatStringFrom(formattedString) { | |
var chunks = formattedString.match(R_FORMAT_CHUNKS); | |
return chunks ? (1 === chunks.length || formattedString[0].match(R_NUMBER_COMPONENT)) && chunks.unshift("") : chunks = ["", ""], chunks.join(VALUE_PLACEHOLDER) | |
} | |
function sanitizeObjectForHexProps(stateObject) { | |
Tweenable.each(stateObject, function(prop) { | |
var currentProp = stateObject[prop]; | |
"string" == typeof currentProp && currentProp.match(R_HEX) && (stateObject[prop] = sanitizeHexChunksToRGB(currentProp)) | |
}) | |
} | |
function sanitizeHexChunksToRGB(str) { | |
return filterStringChunks(R_HEX, str, convertHexToRGB) | |
} | |
function convertHexToRGB(hexString) { | |
var rgbArr = hexToRGBArray(hexString); | |
return "rgb(" + rgbArr[0] + "," + rgbArr[1] + "," + rgbArr[2] + ")" | |
} | |
var hexToRGBArray_returnArray = []; | |
function hexToRGBArray(hex) { | |
return hex = hex.replace(/#/, ""), 3 === hex.length && (hex = hex.split(""), hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]), hexToRGBArray_returnArray[0] = hexToDec(hex.substr(0, 2)), hexToRGBArray_returnArray[1] = hexToDec(hex.substr(2, 2)), hexToRGBArray_returnArray[2] = hexToDec(hex.substr(4, 2)), hexToRGBArray_returnArray | |
} | |
function hexToDec(hex) { | |
return parseInt(hex, 16) | |
} | |
function filterStringChunks(pattern, unfilteredString, filter) { | |
var pattenMatches = unfilteredString.match(pattern), | |
filteredString = unfilteredString.replace(pattern, VALUE_PLACEHOLDER); | |
if (pattenMatches) | |
for (var currentChunk, pattenMatchesLength = pattenMatches.length, i = 0; pattenMatchesLength > i; i++) currentChunk = pattenMatches.shift(), filteredString = filteredString.replace(VALUE_PLACEHOLDER, filter(currentChunk)); | |
return filteredString | |
} | |
function sanitizeRGBChunks(formattedString) { | |
return filterStringChunks(R_RGB, formattedString, sanitizeRGBChunk) | |
} | |
function sanitizeRGBChunk(rgbChunk) { | |
for (var numbers = rgbChunk.match(R_UNFORMATTED_VALUES), numbersLength = numbers.length, sanitizedString = rgbChunk.match(R_RGB_PREFIX)[0], i = 0; numbersLength > i; i++) sanitizedString += parseInt(numbers[i], 10) + ","; | |
return sanitizedString = sanitizedString.slice(0, -1) + ")" | |
} | |
function getFormatManifests(stateObject) { | |
var manifestAccumulator = {}; | |
return Tweenable.each(stateObject, function(prop) { | |
var currentProp = stateObject[prop]; | |
if ("string" == typeof currentProp) { | |
var rawValues = getValuesFrom(currentProp); | |
manifestAccumulator[prop] = { | |
formatString: getFormatStringFrom(currentProp), | |
chunkNames: getFormatChunksFrom(rawValues, prop) | |
} | |
} | |
}), manifestAccumulator | |
} | |
function expandFormattedProperties(stateObject, formatManifests) { | |
Tweenable.each(formatManifests, function(prop) { | |
for (var currentProp = stateObject[prop], rawValues = getValuesFrom(currentProp), rawValuesLength = rawValues.length, i = 0; rawValuesLength > i; i++) stateObject[formatManifests[prop].chunkNames[i]] = +rawValues[i]; | |
delete stateObject[prop] | |
}) | |
} | |
function collapseFormattedProperties(stateObject, formatManifests) { | |
Tweenable.each(formatManifests, function(prop) { | |
var currentProp = stateObject[prop], | |
formatChunks = extractPropertyChunks(stateObject, formatManifests[prop].chunkNames), | |
valuesList = getValuesList(formatChunks, formatManifests[prop].chunkNames); | |
currentProp = getFormattedValues(formatManifests[prop].formatString, valuesList), stateObject[prop] = sanitizeRGBChunks(currentProp) | |
}) | |
} | |
function extractPropertyChunks(stateObject, chunkNames) { | |
for (var currentChunkName, extractedValues = {}, chunkNamesLength = chunkNames.length, i = 0; chunkNamesLength > i; i++) currentChunkName = chunkNames[i], extractedValues[currentChunkName] = stateObject[currentChunkName], delete stateObject[currentChunkName]; | |
return extractedValues | |
} | |
var getValuesList_accumulator = []; | |
function getValuesList(stateObject, chunkNames) { | |
getValuesList_accumulator.length = 0; | |
for (var chunkNamesLength = chunkNames.length, i = 0; chunkNamesLength > i; i++) getValuesList_accumulator.push(stateObject[chunkNames[i]]); | |
return getValuesList_accumulator | |
} | |
function getFormattedValues(formatString, rawValues) { | |
for (var formattedValueString = formatString, rawValuesLength = rawValues.length, i = 0; rawValuesLength > i; i++) formattedValueString = formattedValueString.replace(VALUE_PLACEHOLDER, +rawValues[i].toFixed(4)); | |
return formattedValueString | |
} | |
function getValuesFrom(formattedString) { | |
return formattedString.match(R_UNFORMATTED_VALUES) | |
} | |
function expandEasingObject(easingObject, tokenData) { | |
Tweenable.each(tokenData, function(prop) { | |
for (var currentProp = tokenData[prop], chunkNames = currentProp.chunkNames, chunkLength = chunkNames.length, easingChunks = easingObject[prop].split(" "), lastEasingChunk = easingChunks[easingChunks.length - 1], i = 0; chunkLength > i; i++) easingObject[chunkNames[i]] = easingChunks[i] || lastEasingChunk; | |
delete easingObject[prop] | |
}) | |
} | |
function collapseEasingObject(easingObject, tokenData) { | |
Tweenable.each(tokenData, function(prop) { | |
for (var currentProp = tokenData[prop], chunkNames = currentProp.chunkNames, chunkLength = chunkNames.length, composedEasingString = "", i = 0; chunkLength > i; i++) composedEasingString += " " + easingObject[chunkNames[i]], delete easingObject[chunkNames[i]]; | |
easingObject[prop] = composedEasingString.substr(1) | |
}) | |
} | |
Tweenable.prototype.filter.token = { | |
tweenCreated: function(currentState, fromState, toState, easingObject) { | |
sanitizeObjectForHexProps(currentState), sanitizeObjectForHexProps(fromState), sanitizeObjectForHexProps(toState), this._tokenData = getFormatManifests(currentState) | |
}, | |
beforeTween: function(currentState, fromState, toState, easingObject) { | |
expandEasingObject(easingObject, this._tokenData), expandFormattedProperties(currentState, this._tokenData), expandFormattedProperties(fromState, this._tokenData), expandFormattedProperties(toState, this._tokenData) | |
}, | |
afterTween: function(currentState, fromState, toState, easingObject) { | |
collapseFormattedProperties(currentState, this._tokenData), collapseFormattedProperties(fromState, this._tokenData), collapseFormattedProperties(toState, this._tokenData), collapseEasingObject(easingObject, this._tokenData) | |
} | |
} | |
}(Tweenable) | |
}(window), window.Tweenable | |
}), | |
function() { | |
"use strict"; | |
angular.module("angular-carousel").filter("carouselSlice", function() { | |
return function(collection, start, size) { | |
if (angular.isArray(collection)) return collection.slice(start, start + size); | |
if (angular.isObject(collection)) return collection | |
} | |
}) | |
}(), | |
function(f) { | |
var g; | |
"undefined" != typeof window ? g = window : "undefined" != typeof self && (g = self), g.ALGOLIA_MIGRATION_LAYER = f() | |
}(function() { | |
return function e(t, n, r) { | |
function s(o, u) { | |
if (!n[o]) { | |
if (!t[o]) { | |
var a = "function" == typeof require && require; | |
if (!u && a) return a(o, !0); | |
if (i) return i(o, !0); | |
var f = new Error("Cannot find module '" + o + "'"); | |
throw f.code = "MODULE_NOT_FOUND", f | |
} | |
var l = n[o] = { | |
exports: {} | |
}; | |
t[o][0].call(l.exports, function(e) { | |
var n = t[o][1][e]; | |
return s(n ? n : e) | |
}, l, l.exports, e, t, n, r) | |
} | |
return n[o].exports | |
} | |
for (var i = "function" == typeof require && require, o = 0; o < r.length; o++) s(r[o]); | |
return s | |
}({ | |
1: [function(require, module, exports) { | |
module.exports = function(src, opts, cb) { | |
var head = document.head || document.getElementsByTagName("head")[0], | |
script = document.createElement("script"); | |
"function" == typeof opts && (cb = opts, opts = {}), opts = opts || {}, cb = cb || function() {}, script.type = opts.type || "text/javascript", script.charset = opts.charset || "utf8", script.async = "async" in opts ? !!opts.async : !0, script.src = src, opts.attrs && setAttributes(script, opts.attrs), opts.text && (script.text = "" + opts.text); | |
var onend = "onload" in script ? stdOnEnd : ieOnEnd; | |
onend(script, cb), script.onload || stdOnEnd(script, cb), head.appendChild(script) | |
}; | |
function setAttributes(script, attrs) { | |
for (var attr in attrs) script.setAttribute(attr, attrs[attr]) | |
} | |
function stdOnEnd(script, cb) { | |
script.onload = function() { | |
this.onerror = this.onload = null, cb(null, script) | |
}, script.onerror = function() { | |
this.onerror = this.onload = null, cb(new Error("Failed to load " + this.src), script) | |
} | |
} | |
function ieOnEnd(script, cb) { | |
script.onreadystatechange = function() { | |
if ("complete" != this.readyState && "loaded" != this.readyState) return; | |
this.onreadystatechange = null, cb(null, script) | |
} | |
} | |
}, {}], | |
2: [function(require, module, exports) { | |
"use strict"; | |
module.exports = isUsingLatest; | |
function isUsingLatest(buildName) { | |
for (var toFind = new RegExp("cdn\\.jsdelivr\\.net/algoliasearch/latest/" + buildName.replace(".", "\\.") + "(?:\\.min)?\\.js$"), scripts = document.getElementsByTagName("script"), found = !1, currentScript = 0, nbScripts = scripts.length; nbScripts > currentScript; currentScript++) | |
if (scripts[currentScript].src && toFind.test(scripts[currentScript].src)) { | |
found = !0; | |
break | |
} | |
return found | |
} | |
}, {}], | |
3: [function(require, module, exports) { | |
"use strict"; | |
module.exports = loadV2; | |
function loadV2(buildName) { | |
var loadScript = require(1), | |
v2ScriptUrl = "//cdn.jsdelivr.net/algoliasearch/2/" + buildName + ".min.js", | |
message = "-- AlgoliaSearch `latest` warning --\nWarning, you are using the `latest` version string from jsDelivr to load the AlgoliaSearch library.\nUsing `latest` is no more recommended, you should load //cdn.jsdelivr.net/algoliasearch/2/algoliasearch.min.js\n\nAlso, we updated the AlgoliaSearch JavaScript client to V3. If you want to upgrade,\nplease read our migration guide at https://github.com/algolia/algoliasearch-client-js/wiki/Migration-guide-from-2.x.x-to-3.x.x\n-- /AlgoliaSearch `latest` warning --"; | |
window.console && (window.console.warn ? window.console.warn(message) : window.console.log && window.console.log(message)); | |
try { | |
document.write("<script>window.ALGOLIA_SUPPORTS_DOCWRITE = true<\/script>"), window.ALGOLIA_SUPPORTS_DOCWRITE === !0 ? (document.write('<script src="' + v2ScriptUrl + '"><\/script>'), scriptLoaded("document.write")()) : loadScript(v2ScriptUrl, scriptLoaded("DOMElement")) | |
} catch (e) { | |
loadScript(v2ScriptUrl, scriptLoaded("DOMElement")) | |
} | |
} | |
function scriptLoaded(method) { | |
return function() { | |
var message = "AlgoliaSearch: loaded V2 script using " + method; | |
window.console && window.console.log && window.console.log(message) | |
} | |
} | |
}, { | |
1: 1 | |
}], | |
4: [function(require, module, exports) { | |
"use strict"; | |
module.exports = oldGlobals; | |
function oldGlobals() { | |
var message = "-- AlgoliaSearch V2 => V3 error --\nYou are trying to use a new version of the AlgoliaSearch JavaScript client with an old notation.\nPlease read our migration guide at https://github.com/algolia/algoliasearch-client-js/wiki/Migration-guide-from-2.x.x-to-3.x.x\n-- /AlgoliaSearch V2 => V3 error --"; | |
window.AlgoliaSearch = function() { | |
throw new Error(message) | |
}, window.AlgoliaSearchHelper = function() { | |
throw new Error(message) | |
}, window.AlgoliaExplainResults = function() { | |
throw new Error(message) | |
} | |
} | |
}, {}], | |
5: [function(require, module, exports) { | |
"use strict"; | |
migrationLayer("algoliasearch.angular"); | |
function migrationLayer(buildName) { | |
var isUsingLatest = require(2), | |
loadV2 = require(3), | |
oldGlobals = require(4); | |
isUsingLatest(buildName) ? loadV2(buildName) : oldGlobals() | |
} | |
}, { | |
2: 2, | |
3: 3, | |
4: 4 | |
}] | |
}, {}, [5])(5) | |
}), | |
function e(t, n, r) { | |
function s(o, u) { | |
if (!n[o]) { | |
if (!t[o]) { | |
var a = "function" == typeof require && require; | |
if (!u && a) return a(o, !0); | |
if (i) return i(o, !0); | |
var f = new Error("Cannot find module '" + o + "'"); | |
throw f.code = "MODULE_NOT_FOUND", f | |
} | |
var l = n[o] = { | |
exports: {} | |
}; | |
t[o][0].call(l.exports, function(e) { | |
var n = t[o][1][e]; | |
return s(n ? n : e) | |
}, l, l.exports, e, t, n, r) | |
} | |
return n[o].exports | |
} | |
for (var i = "function" == typeof require && require, o = 0; o < r.length; o++) s(r[o]); | |
return s | |
}({ | |
1: [function(require, module, exports) { | |
function EventEmitter() { | |
this._events = this._events || {}, this._maxListeners = this._maxListeners || void 0 | |
} | |
module.exports = EventEmitter, EventEmitter.EventEmitter = EventEmitter, EventEmitter.prototype._events = void 0, EventEmitter.prototype._maxListeners = void 0, EventEmitter.defaultMaxListeners = 10, EventEmitter.prototype.setMaxListeners = function(n) { | |
if (!isNumber(n) || 0 > n || isNaN(n)) throw TypeError("n must be a positive number"); | |
return this._maxListeners = n, this | |
}, EventEmitter.prototype.emit = function(type) { | |
var er, handler, len, args, i, listeners; | |
if (this._events || (this._events = {}), "error" === type && (!this._events.error || isObject(this._events.error) && !this._events.error.length)) { | |
if (er = arguments[1], er instanceof Error) throw er; | |
throw TypeError('Uncaught, unspecified "error" event.') | |
} | |
if (handler = this._events[type], isUndefined(handler)) return !1; | |
if (isFunction(handler)) switch (arguments.length) { | |
case 1: | |
handler.call(this); | |
break; | |
case 2: | |
handler.call(this, arguments[1]); | |
break; | |
case 3: | |
handler.call(this, arguments[1], arguments[2]); | |
break; | |
default: | |
for (len = arguments.length, args = new Array(len - 1), i = 1; len > i; i++) args[i - 1] = arguments[i]; | |
handler.apply(this, args) | |
} else if (isObject(handler)) { | |
for (len = arguments.length, args = new Array(len - 1), i = 1; len > i; i++) args[i - 1] = arguments[i]; | |
for (listeners = handler.slice(), len = listeners.length, i = 0; len > i; i++) listeners[i].apply(this, args) | |
} | |
return !0 | |
}, EventEmitter.prototype.addListener = function(type, listener) { | |
var m; | |
if (!isFunction(listener)) throw TypeError("listener must be a function"); | |
if (this._events || (this._events = {}), this._events.newListener && this.emit("newListener", type, isFunction(listener.listener) ? listener.listener : listener), this._events[type] ? isObject(this._events[type]) ? this._events[type].push(listener) : this._events[type] = [this._events[type], listener] : this._events[type] = listener, isObject(this._events[type]) && !this._events[type].warned) { | |
var m; | |
m = isUndefined(this._maxListeners) ? EventEmitter.defaultMaxListeners : this._maxListeners, m && m > 0 && this._events[type].length > m && (this._events[type].warned = !0, console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.", this._events[type].length), "function" == typeof console.trace && console.trace()) | |
} | |
return this | |
}, EventEmitter.prototype.on = EventEmitter.prototype.addListener, EventEmitter.prototype.once = function(type, listener) { | |
if (!isFunction(listener)) throw TypeError("listener must be a function"); | |
var fired = !1; | |
function g() { | |
this.removeListener(type, g), fired || (fired = !0, listener.apply(this, arguments)) | |
} | |
return g.listener = listener, this.on(type, g), this | |
}, EventEmitter.prototype.removeListener = function(type, listener) { | |
var list, position, length, i; | |
if (!isFunction(listener)) throw TypeError("listener must be a function"); | |
if (!this._events || !this._events[type]) return this; | |
if (list = this._events[type], length = list.length, position = -1, list === listener || isFunction(list.listener) && list.listener === listener) delete this._events[type], this._events.removeListener && this.emit("removeListener", type, listener); | |
else if (isObject(list)) { | |
for (i = length; i-- > 0;) | |
if (list[i] === listener || list[i].listener && list[i].listener === listener) { | |
position = i; | |
break | |
} | |
if (0 > position) return this; | |
1 === list.length ? (list.length = 0, delete this._events[type]) : list.splice(position, 1), this._events.removeListener && this.emit("removeListener", type, listener) | |
} | |
return this | |
}, EventEmitter.prototype.removeAllListeners = function(type) { | |
var key, listeners; | |
if (!this._events) return this; | |
if (!this._events.removeListener) return 0 === arguments.length ? this._events = {} : this._events[type] && delete this._events[type], this; | |
if (0 === arguments.length) { | |
for (key in this._events) { | |
if ("removeListener" === key) continue; | |
this.removeAllListeners(key) | |
} | |
return this.removeAllListeners("removeListener"), this._events = {}, this | |
} | |
if (listeners = this._events[type], isFunction(listeners)) this.removeListener(type, listeners); | |
else | |
for (; listeners.length;) this.removeListener(type, listeners[listeners.length - 1]); | |
return delete this._events[type], this | |
}, EventEmitter.prototype.listeners = function(type) { | |
var ret; | |
return ret = this._events && this._events[type] ? isFunction(this._events[type]) ? [this._events[type]] : this._events[type].slice() : [] | |
}, EventEmitter.listenerCount = function(emitter, type) { | |
var ret; | |
return ret = emitter._events && emitter._events[type] ? isFunction(emitter._events[type]) ? 1 : emitter._events[type].length : 0 | |
}; | |
function isFunction(arg) { | |
return "function" == typeof arg | |
} | |
function isNumber(arg) { | |
return "number" == typeof arg | |
} | |
function isObject(arg) { | |
return "object" == typeof arg && null !== arg | |
} | |
function isUndefined(arg) { | |
return void 0 === arg | |
} | |
}, {}], | |
2: [function(require, module, exports) { | |
var currentQueue, process = module.exports = {}, | |
queue = [], | |
draining = !1, | |
queueIndex = -1; | |
function cleanUpNextTick() { | |
draining = !1, currentQueue.length ? queue = currentQueue.concat(queue) : queueIndex = -1, queue.length && drainQueue() | |
} | |
function drainQueue() { | |
if (draining) return; | |
var timeout = setTimeout(cleanUpNextTick); | |
draining = !0; | |
for (var len = queue.length; len;) { | |
for (currentQueue = queue, queue = []; ++queueIndex < len;) currentQueue && currentQueue[queueIndex].run(); | |
queueIndex = -1, len = queue.length | |
} | |
currentQueue = null, draining = !1, clearTimeout(timeout) | |
} | |
process.nextTick = function(fun) { | |
var args = new Array(arguments.length - 1); | |
if (arguments.length > 1) | |
for (var i = 1; i < arguments.length; i++) args[i - 1] = arguments[i]; | |
queue.push(new Item(fun, args)), 1 !== queue.length || draining || setTimeout(drainQueue, 0) | |
}; | |
function Item(fun, array) { | |
this.fun = fun, this.array = array | |
} | |
Item.prototype.run = function() { | |
this.fun.apply(null, this.array) | |
}, process.title = "browser", process.browser = !0, process.env = {}, process.argv = [], process.version = "", process.versions = {}; | |
function noop() {} | |
process.on = noop, process.addListener = noop, process.once = noop, process.off = noop, process.removeListener = noop, process.removeAllListeners = noop, process.emit = noop, process.binding = function(name) { | |
throw new Error("process.binding is not supported") | |
}, process.cwd = function() { | |
return "/" | |
}, process.chdir = function(dir) { | |
throw new Error("process.chdir is not supported") | |
}, process.umask = function() { | |
return 0 | |
} | |
}, {}], | |
3: [function(require, module, exports) { | |
"use strict"; | |
function hasOwnProperty(obj, prop) { | |
return Object.prototype.hasOwnProperty.call(obj, prop) | |
} | |
module.exports = function(qs, sep, eq, options) { | |
sep = sep || "&", eq = eq || "="; | |
var obj = {}; | |
if ("string" != typeof qs || 0 === qs.length) return obj; | |
var regexp = /\+/g; | |
qs = qs.split(sep); | |
var maxKeys = 1e3; | |
options && "number" == typeof options.maxKeys && (maxKeys = options.maxKeys); | |
var len = qs.length; | |
maxKeys > 0 && len > maxKeys && (len = maxKeys); | |
for (var i = 0; len > i; ++i) { | |
var kstr, vstr, k, v, x = qs[i].replace(regexp, "%20"), | |
idx = x.indexOf(eq); | |
idx >= 0 ? (kstr = x.substr(0, idx), vstr = x.substr(idx + 1)) : (kstr = x, vstr = ""), k = decodeURIComponent(kstr), v = decodeURIComponent(vstr), hasOwnProperty(obj, k) ? isArray(obj[k]) ? obj[k].push(v) : obj[k] = [obj[k], v] : obj[k] = v | |
} | |
return obj | |
}; | |
var isArray = Array.isArray || function(xs) { | |
return "[object Array]" === Object.prototype.toString.call(xs) | |
} | |
}, {}], | |
4: [function(require, module, exports) { | |
"use strict"; | |
var stringifyPrimitive = function(v) { | |
switch (typeof v) { | |
case "string": | |
return v; | |
case "boolean": | |
return v ? "true" : "false"; | |
case "number": | |
return isFinite(v) ? v : ""; | |
default: | |
return "" | |
} | |
}; | |
module.exports = function(obj, sep, eq, name) { | |
if (sep = sep || "&", eq = eq || "=", null === obj && (obj = void 0), "object" == typeof obj) return map(objectKeys(obj), function(k) { | |
var ks = encodeURIComponent(stringifyPrimitive(k)) + eq; | |
return isArray(obj[k]) ? map(obj[k], function(v) { | |
return ks + encodeURIComponent(stringifyPrimitive(v)) | |
}).join(sep) : ks + encodeURIComponent(stringifyPrimitive(obj[k])) | |
}).join(sep); | |
if (!name) return ""; | |
return encodeURIComponent(stringifyPrimitive(name)) + eq + encodeURIComponent(stringifyPrimitive(obj)) | |
}; | |
var isArray = Array.isArray || function(xs) { | |
return "[object Array]" === Object.prototype.toString.call(xs) | |
}; | |
function map(xs, f) { | |
if (xs.map) return xs.map(f); | |
for (var res = [], i = 0; i < xs.length; i++) res.push(f(xs[i], i)); | |
return res | |
} | |
var objectKeys = Object.keys || function(obj) { | |
var res = []; | |
for (var key in obj) Object.prototype.hasOwnProperty.call(obj, key) && res.push(key); | |
return res | |
} | |
}, {}], | |
5: [function(require, module, exports) { | |
"use strict"; | |
exports.decode = exports.parse = require(3), exports.encode = exports.stringify = require(4) | |
}, { | |
3: 3, | |
4: 4 | |
}], | |
6: [function(require, module, exports) { | |
exports = module.exports = require(7), exports.log = log, exports.formatArgs = formatArgs, exports.save = save, exports.load = load, exports.useColors = useColors, exports.storage = "undefined" != typeof chrome && "undefined" != typeof chrome.storage ? chrome.storage.local : localstorage(), exports.colors = ["lightseagreen", "forestgreen", "goldenrod", "dodgerblue", "darkorchid", "crimson"]; | |
function useColors() { | |
return "WebkitAppearance" in document.documentElement.style || window.console && (console.firebug || console.exception && console.table) || navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 | |
} | |
exports.formatters.j = function(v) { | |
return JSON.stringify(v) | |
}; | |
function formatArgs() { | |
var args = arguments, | |
useColors = this.useColors; | |
if (args[0] = (useColors ? "%c" : "") + this.namespace + (useColors ? " %c" : " ") + args[0] + (useColors ? "%c " : " ") + "+" + exports.humanize(this.diff), !useColors) return args; | |
var c = "color: " + this.color; | |
args = [args[0], c, "color: inherit"].concat(Array.prototype.slice.call(args, 1)); | |
var index = 0, | |
lastC = 0; | |
return args[0].replace(/%[a-z%]/g, function(match) { | |
if ("%%" === match) return; | |
index++, "%c" === match && (lastC = index) | |
}), args.splice(lastC, 0, c), args | |
} | |
function log() { | |
return "object" == typeof console && console.log && Function.prototype.apply.call(console.log, console, arguments) | |
} | |
function save(namespaces) { | |
try { | |
null == namespaces ? exports.storage.removeItem("debug") : exports.storage.debug = namespaces | |
} catch (e) {} | |
} | |
function load() { | |
var r; | |
try { | |
r = exports.storage.debug | |
} catch (e) {} | |
return r | |
} | |
exports.enable(load()); | |
function localstorage() { | |
try { | |
return window.localStorage | |
} catch (e) {} | |
} | |
}, { | |
7: 7 | |
}], | |
7: [function(require, module, exports) { | |
exports = module.exports = debug, exports.coerce = coerce, exports.disable = disable, exports.enable = enable, exports.enabled = enabled, exports.humanize = require(8), exports.names = [], exports.skips = [], exports.formatters = {}; | |
var prevTime, prevColor = 0; | |
function selectColor() { | |
return exports.colors[prevColor++ % exports.colors.length] | |
} | |
function debug(namespace) { | |
function disabled() {} | |
disabled.enabled = !1; | |
function enabled() { | |
var self = enabled, | |
curr = +new Date, | |
ms = curr - (prevTime || curr); | |
self.diff = ms, self.prev = prevTime, self.curr = curr, prevTime = curr, null == self.useColors && (self.useColors = exports.useColors()), null == self.color && self.useColors && (self.color = selectColor()); | |
var args = Array.prototype.slice.call(arguments); | |
args[0] = exports.coerce(args[0]), "string" != typeof args[0] && (args = ["%o"].concat(args)); | |
var index = 0; | |
args[0] = args[0].replace(/%([a-z%])/g, function(match, format) { | |
if ("%%" === match) return match; | |
index++; | |
var formatter = exports.formatters[format]; | |
if ("function" == typeof formatter) { | |
var val = args[index]; | |
match = formatter.call(self, val), args.splice(index, 1), index-- | |
} | |
return match | |
}), "function" == typeof exports.formatArgs && (args = exports.formatArgs.apply(self, args)); | |
var logFn = enabled.log || exports.log || console.log.bind(console); | |
logFn.apply(self, args) | |
} | |
enabled.enabled = !0; | |
var fn = exports.enabled(namespace) ? enabled : disabled; | |
return fn.namespace = namespace, fn | |
} | |
function enable(namespaces) { | |
exports.save(namespaces); | |
for (var split = (namespaces || "").split(/[\s,]+/), len = split.length, i = 0; len > i; i++) { | |
if (!split[i]) continue; | |
namespaces = split[i].replace(/\*/g, ".*?"), "-" === namespaces[0] ? exports.skips.push(new RegExp("^" + namespaces.substr(1) + "$")) : exports.names.push(new RegExp("^" + namespaces + "$")) | |
} | |
} | |
function disable() { | |
exports.enable("") | |
} | |
function enabled(name) { | |
var i, len; | |
for (i = 0, len = exports.skips.length; len > i; i++) | |
if (exports.skips[i].test(name)) return !1; | |
for (i = 0, len = exports.names.length; len > i; i++) | |
if (exports.names[i].test(name)) return !0; | |
return !1 | |
} | |
function coerce(val) { | |
if (val instanceof Error) return val.stack || val.message; | |
return val | |
} | |
}, { | |
8: 8 | |
}], | |
8: [function(require, module, exports) { | |
var s = 1e3, | |
m = 60 * s, | |
h = 60 * m, | |
d = 24 * h, | |
y = 365.25 * d; | |
module.exports = function(val, options) { | |
if (options = options || {}, "string" == typeof val) return parse(val); | |
return options["long"] ? _long(val) : _short(val) | |
}; | |
function parse(str) { | |
if (str = "" + str, str.length > 1e4) return; | |
var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str); | |
if (!match) return; | |
var n = parseFloat(match[1]), | |
type = (match[2] || "ms").toLowerCase(); | |
switch (type) { | |
case "years": | |
case "year": | |
case "yrs": | |
case "yr": | |
case "y": | |
return n * y; | |
case "days": | |
case "day": | |
case "d": | |
return n * d; | |
case "hours": | |
case "hour": | |
case "hrs": | |
case "hr": | |
case "h": | |
return n * h; | |
case "minutes": | |
case "minute": | |
case "mins": | |
case "min": | |
case "m": | |
return n * m; | |
case "seconds": | |
case "second": | |
case "secs": | |
case "sec": | |
case "s": | |
return n * s; | |
case "milliseconds": | |
case "millisecond": | |
case "msecs": | |
case "msec": | |
case "ms": | |
return n | |
} | |
} | |
function _short(ms) { | |
if (ms >= d) return Math.round(ms / d) + "d"; | |
if (ms >= h) return Math.round(ms / h) + "h"; | |
if (ms >= m) return Math.round(ms / m) + "m"; | |
if (ms >= s) return Math.round(ms / s) + "s"; | |
return ms + "ms" | |
} | |
function _long(ms) { | |
return plural(ms, d, "day") || plural(ms, h, "hour") || plural(ms, m, "minute") || plural(ms, s, "second") || ms + " ms" | |
} | |
function plural(ms, n, name) { | |
if (n > ms) return; | |
if (1.5 * n > ms) return Math.floor(ms / n) + " " + name; | |
return Math.ceil(ms / n) + " " + name + "s" | |
} | |
}, {}], | |
9: [function(require, module, exports) { | |
(function(process, global) { | |
(function() { | |
"use strict"; | |
function lib$es6$promise$utils$$objectOrFunction(x) { | |
return "function" == typeof x || "object" == typeof x && null !== x | |
} | |
function lib$es6$promise$utils$$isFunction(x) { | |
return "function" == typeof x | |
} | |
function lib$es6$promise$utils$$isMaybeThenable(x) { | |
return "object" == typeof x && null !== x | |
} | |
var lib$es6$promise$utils$$_isArray; | |
lib$es6$promise$utils$$_isArray = Array.isArray ? Array.isArray : function(x) { | |
return "[object Array]" === Object.prototype.toString.call(x) | |
}; | |
var lib$es6$promise$asap$$vertxNext, lib$es6$promise$asap$$customSchedulerFn, lib$es6$promise$utils$$isArray = lib$es6$promise$utils$$_isArray, | |
lib$es6$promise$asap$$len = 0, | |
lib$es6$promise$asap$$asap = ({}.toString, function(callback, arg) { | |
lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len] = callback, lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len + 1] = arg, lib$es6$promise$asap$$len += 2, 2 === lib$es6$promise$asap$$len && (lib$es6$promise$asap$$customSchedulerFn ? lib$es6$promise$asap$$customSchedulerFn(lib$es6$promise$asap$$flush) : lib$es6$promise$asap$$scheduleFlush()) | |
}); | |
function lib$es6$promise$asap$$setScheduler(scheduleFn) { | |
lib$es6$promise$asap$$customSchedulerFn = scheduleFn | |
} | |
function lib$es6$promise$asap$$setAsap(asapFn) { | |
lib$es6$promise$asap$$asap = asapFn | |
} | |
var lib$es6$promise$asap$$browserWindow = "undefined" != typeof window ? window : void 0, | |
lib$es6$promise$asap$$browserGlobal = lib$es6$promise$asap$$browserWindow || {}, | |
lib$es6$promise$asap$$BrowserMutationObserver = lib$es6$promise$asap$$browserGlobal.MutationObserver || lib$es6$promise$asap$$browserGlobal.WebKitMutationObserver, | |
lib$es6$promise$asap$$isNode = "undefined" != typeof process && "[object process]" === {}.toString.call(process), | |
lib$es6$promise$asap$$isWorker = "undefined" != typeof Uint8ClampedArray && "undefined" != typeof importScripts && "undefined" != typeof MessageChannel; | |
function lib$es6$promise$asap$$useNextTick() { | |
return function() { | |
process.nextTick(lib$es6$promise$asap$$flush) | |
} | |
} | |
function lib$es6$promise$asap$$useVertxTimer() { | |
return function() { | |
lib$es6$promise$asap$$vertxNext(lib$es6$promise$asap$$flush) | |
} | |
} | |
function lib$es6$promise$asap$$useMutationObserver() { | |
var iterations = 0, | |
observer = new lib$es6$promise$asap$$BrowserMutationObserver(lib$es6$promise$asap$$flush), | |
node = document.createTextNode(""); | |
return observer.observe(node, { | |
characterData: !0 | |
}), | |
function() { | |
node.data = iterations = ++iterations % 2 | |
} | |
} | |
function lib$es6$promise$asap$$useMessageChannel() { | |
var channel = new MessageChannel; | |
return channel.port1.onmessage = lib$es6$promise$asap$$flush, | |
function() { | |
channel.port2.postMessage(0) | |
} | |
} | |
function lib$es6$promise$asap$$useSetTimeout() { | |
return function() { | |
setTimeout(lib$es6$promise$asap$$flush, 1) | |
} | |
} | |
var lib$es6$promise$asap$$queue = new Array(1e3); | |
function lib$es6$promise$asap$$flush() { | |
for (var i = 0; lib$es6$promise$asap$$len > i; i += 2) { | |
var callback = lib$es6$promise$asap$$queue[i], | |
arg = lib$es6$promise$asap$$queue[i + 1]; | |
callback(arg), lib$es6$promise$asap$$queue[i] = void 0, lib$es6$promise$asap$$queue[i + 1] = void 0 | |
} | |
lib$es6$promise$asap$$len = 0 | |
} | |
function lib$es6$promise$asap$$attemptVertx() { | |
try { | |
var r = require, | |
vertx = r("vertx"); | |
return lib$es6$promise$asap$$vertxNext = vertx.runOnLoop || vertx.runOnContext, lib$es6$promise$asap$$useVertxTimer() | |
} catch (e) { | |
return lib$es6$promise$asap$$useSetTimeout() | |
} | |
} | |
var lib$es6$promise$asap$$scheduleFlush; | |
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$isNode ? lib$es6$promise$asap$$useNextTick() : lib$es6$promise$asap$$BrowserMutationObserver ? lib$es6$promise$asap$$useMutationObserver() : lib$es6$promise$asap$$isWorker ? lib$es6$promise$asap$$useMessageChannel() : void 0 === lib$es6$promise$asap$$browserWindow && "function" == typeof require ? lib$es6$promise$asap$$attemptVertx() : lib$es6$promise$asap$$useSetTimeout(); | |
function lib$es6$promise$$internal$$noop() {} | |
var lib$es6$promise$$internal$$PENDING = void 0, | |
lib$es6$promise$$internal$$FULFILLED = 1, | |
lib$es6$promise$$internal$$REJECTED = 2, | |
lib$es6$promise$$internal$$GET_THEN_ERROR = new lib$es6$promise$$internal$$ErrorObject; | |
function lib$es6$promise$$internal$$selfFulfillment() { | |
return new TypeError("You cannot resolve a promise with itself") | |
} | |
function lib$es6$promise$$internal$$cannotReturnOwn() { | |
return new TypeError("A promises callback cannot return that same promise.") | |
} | |
function lib$es6$promise$$internal$$getThen(promise) { | |
try { | |
return promise.then | |
} catch (error) { | |
return lib$es6$promise$$internal$$GET_THEN_ERROR.error = error, lib$es6$promise$$internal$$GET_THEN_ERROR | |
} | |
} | |
function lib$es6$promise$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) { | |
try { | |
then.call(value, fulfillmentHandler, rejectionHandler) | |
} catch (e) { | |
return e | |
} | |
} | |
function lib$es6$promise$$internal$$handleForeignThenable(promise, thenable, then) { | |
lib$es6$promise$asap$$asap(function(promise) { | |
var sealed = !1, | |
error = lib$es6$promise$$internal$$tryThen(then, thenable, function(value) { | |
if (sealed) return; | |
sealed = !0, thenable !== value ? lib$es6$promise$$internal$$resolve(promise, value) : lib$es6$promise$$internal$$fulfill(promise, value) | |
}, function(reason) { | |
if (sealed) return; | |
sealed = !0, lib$es6$promise$$internal$$reject(promise, reason) | |
}, "Settle: " + (promise._label || " unknown promise")); | |
!sealed && error && (sealed = !0, lib$es6$promise$$internal$$reject(promise, error)) | |
}, promise) | |
} | |
function lib$es6$promise$$internal$$handleOwnThenable(promise, thenable) { | |
thenable._state === lib$es6$promise$$internal$$FULFILLED ? lib$es6$promise$$internal$$fulfill(promise, thenable._result) : thenable._state === lib$es6$promise$$internal$$REJECTED ? lib$es6$promise$$internal$$reject(promise, thenable._result) : lib$es6$promise$$internal$$subscribe(thenable, void 0, function(value) { | |
lib$es6$promise$$internal$$resolve(promise, value) | |
}, function(reason) { | |
lib$es6$promise$$internal$$reject(promise, reason) | |
}) | |
} | |
function lib$es6$promise$$internal$$handleMaybeThenable(promise, maybeThenable) { | |
if (maybeThenable.constructor === promise.constructor) lib$es6$promise$$internal$$handleOwnThenable(promise, maybeThenable); | |
else { | |
var then = lib$es6$promise$$internal$$getThen(maybeThenable); | |
then === lib$es6$promise$$internal$$GET_THEN_ERROR ? lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$GET_THEN_ERROR.error) : void 0 === then ? lib$es6$promise$$internal$$fulfill(promise, maybeThenable) : lib$es6$promise$utils$$isFunction(then) ? lib$es6$promise$$internal$$handleForeignThenable(promise, maybeThenable, then) : lib$es6$promise$$internal$$fulfill(promise, maybeThenable) | |
} | |
} | |
function lib$es6$promise$$internal$$resolve(promise, value) { | |
promise === value ? lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$selfFulfillment()) : lib$es6$promise$utils$$objectOrFunction(value) ? lib$es6$promise$$internal$$handleMaybeThenable(promise, value) : lib$es6$promise$$internal$$fulfill(promise, value) | |
} | |
function lib$es6$promise$$internal$$publishRejection(promise) { | |
promise._onerror && promise._onerror(promise._result), lib$es6$promise$$internal$$publish(promise) | |
} | |
function lib$es6$promise$$internal$$fulfill(promise, value) { | |
if (promise._state !== lib$es6$promise$$internal$$PENDING) return; | |
promise._result = value, promise._state = lib$es6$promise$$internal$$FULFILLED, 0 !== promise._subscribers.length && lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, promise) | |
} | |
function lib$es6$promise$$internal$$reject(promise, reason) { | |
if (promise._state !== lib$es6$promise$$internal$$PENDING) return; | |
promise._state = lib$es6$promise$$internal$$REJECTED, promise._result = reason, lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publishRejection, promise) | |
} | |
function lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection) { | |
var subscribers = parent._subscribers, | |
length = subscribers.length; | |
parent._onerror = null, subscribers[length] = child, subscribers[length + lib$es6$promise$$internal$$FULFILLED] = onFulfillment, subscribers[length + lib$es6$promise$$internal$$REJECTED] = onRejection, 0 === length && parent._state && lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, parent) | |
} | |
function lib$es6$promise$$internal$$publish(promise) { | |
var subscribers = promise._subscribers, | |
settled = promise._state; | |
if (0 === subscribers.length) return; | |
for (var child, callback, detail = promise._result, i = 0; i < subscribers.length; i += 3) child = subscribers[i], callback = subscribers[i + settled], child ? lib$es6$promise$$internal$$invokeCallback(settled, child, callback, detail) : callback(detail); | |
promise._subscribers.length = 0 | |
} | |
function lib$es6$promise$$internal$$ErrorObject() { | |
this.error = null | |
} | |
var lib$es6$promise$$internal$$TRY_CATCH_ERROR = new lib$es6$promise$$internal$$ErrorObject; | |
function lib$es6$promise$$internal$$tryCatch(callback, detail) { | |
try { | |
return callback(detail) | |
} catch (e) { | |
return lib$es6$promise$$internal$$TRY_CATCH_ERROR.error = e, lib$es6$promise$$internal$$TRY_CATCH_ERROR | |
} | |
} | |
function lib$es6$promise$$internal$$invokeCallback(settled, promise, callback, detail) { | |
var value, error, succeeded, failed, hasCallback = lib$es6$promise$utils$$isFunction(callback); | |
if (hasCallback) { | |
if (value = lib$es6$promise$$internal$$tryCatch(callback, detail), value === lib$es6$promise$$internal$$TRY_CATCH_ERROR ? (failed = !0, error = value.error, value = null) : succeeded = !0, promise === value) return void lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$cannotReturnOwn()) | |
} else value = detail, succeeded = !0; | |
promise._state !== lib$es6$promise$$internal$$PENDING || (hasCallback && succeeded ? lib$es6$promise$$internal$$resolve(promise, value) : failed ? lib$es6$promise$$internal$$reject(promise, error) : settled === lib$es6$promise$$internal$$FULFILLED ? lib$es6$promise$$internal$$fulfill(promise, value) : settled === lib$es6$promise$$internal$$REJECTED && lib$es6$promise$$internal$$reject(promise, value)) | |
} | |
function lib$es6$promise$$internal$$initializePromise(promise, resolver) { | |
try { | |
resolver(function(value) { | |
lib$es6$promise$$internal$$resolve(promise, value) | |
}, function(reason) { | |
lib$es6$promise$$internal$$reject(promise, reason) | |
}) | |
} catch (e) { | |
lib$es6$promise$$internal$$reject(promise, e) | |
} | |
} | |
function lib$es6$promise$enumerator$$Enumerator(Constructor, input) { | |
var enumerator = this; | |
enumerator._instanceConstructor = Constructor, enumerator.promise = new Constructor(lib$es6$promise$$internal$$noop), enumerator._validateInput(input) ? (enumerator._input = input, enumerator.length = input.length, enumerator._remaining = input.length, enumerator._init(), 0 === enumerator.length ? lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result) : (enumerator.length = enumerator.length || 0, enumerator._enumerate(), 0 === enumerator._remaining && lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result))) : lib$es6$promise$$internal$$reject(enumerator.promise, enumerator._validationError()) | |
} | |
lib$es6$promise$enumerator$$Enumerator.prototype._validateInput = function(input) { | |
return lib$es6$promise$utils$$isArray(input) | |
}, lib$es6$promise$enumerator$$Enumerator.prototype._validationError = function() { | |
return new Error("Array Methods must be provided an Array") | |
}, lib$es6$promise$enumerator$$Enumerator.prototype._init = function() { | |
this._result = new Array(this.length) | |
}; | |
var lib$es6$promise$enumerator$$default = lib$es6$promise$enumerator$$Enumerator; | |
lib$es6$promise$enumerator$$Enumerator.prototype._enumerate = function() { | |
for (var enumerator = this, length = enumerator.length, promise = enumerator.promise, input = enumerator._input, i = 0; promise._state === lib$es6$promise$$internal$$PENDING && length > i; i++) enumerator._eachEntry(input[i], i) | |
}, lib$es6$promise$enumerator$$Enumerator.prototype._eachEntry = function(entry, i) { | |
var enumerator = this, | |
c = enumerator._instanceConstructor; | |
lib$es6$promise$utils$$isMaybeThenable(entry) ? entry.constructor === c && entry._state !== lib$es6$promise$$internal$$PENDING ? (entry._onerror = null, enumerator._settledAt(entry._state, i, entry._result)) : enumerator._willSettleAt(c.resolve(entry), i) : (enumerator._remaining--, enumerator._result[i] = entry) | |
}, lib$es6$promise$enumerator$$Enumerator.prototype._settledAt = function(state, i, value) { | |
var enumerator = this, | |
promise = enumerator.promise; | |
promise._state === lib$es6$promise$$internal$$PENDING && (enumerator._remaining--, state === lib$es6$promise$$internal$$REJECTED ? lib$es6$promise$$internal$$reject(promise, value) : enumerator._result[i] = value), 0 === enumerator._remaining && lib$es6$promise$$internal$$fulfill(promise, enumerator._result) | |
}, lib$es6$promise$enumerator$$Enumerator.prototype._willSettleAt = function(promise, i) { | |
var enumerator = this; | |
lib$es6$promise$$internal$$subscribe(promise, void 0, function(value) { | |
enumerator._settledAt(lib$es6$promise$$internal$$FULFILLED, i, value) | |
}, function(reason) { | |
enumerator._settledAt(lib$es6$promise$$internal$$REJECTED, i, reason) | |
}) | |
}; | |
function lib$es6$promise$promise$all$$all(entries) { | |
return new lib$es6$promise$enumerator$$default(this, entries).promise | |
} | |
var lib$es6$promise$promise$all$$default = lib$es6$promise$promise$all$$all; | |
function lib$es6$promise$promise$race$$race(entries) { | |
var Constructor = this, | |
promise = new Constructor(lib$es6$promise$$internal$$noop); | |
if (!lib$es6$promise$utils$$isArray(entries)) return lib$es6$promise$$internal$$reject(promise, new TypeError("You must pass an array to race.")), promise; | |
var length = entries.length; | |
function onFulfillment(value) { | |
lib$es6$promise$$internal$$resolve(promise, value) | |
} | |
function onRejection(reason) { | |
lib$es6$promise$$internal$$reject(promise, reason) | |
} | |
for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && length > i; i++) lib$es6$promise$$internal$$subscribe(Constructor.resolve(entries[i]), void 0, onFulfillment, onRejection); | |
return promise | |
} | |
var lib$es6$promise$promise$race$$default = lib$es6$promise$promise$race$$race; | |
function lib$es6$promise$promise$resolve$$resolve(object) { | |
var Constructor = this; | |
if (object && "object" == typeof object && object.constructor === Constructor) return object; | |
var promise = new Constructor(lib$es6$promise$$internal$$noop); | |
return lib$es6$promise$$internal$$resolve(promise, object), promise | |
} | |
var lib$es6$promise$promise$resolve$$default = lib$es6$promise$promise$resolve$$resolve; | |
function lib$es6$promise$promise$reject$$reject(reason) { | |
var Constructor = this, | |
promise = new Constructor(lib$es6$promise$$internal$$noop); | |
return lib$es6$promise$$internal$$reject(promise, reason), promise | |
} | |
var lib$es6$promise$promise$reject$$default = lib$es6$promise$promise$reject$$reject, | |
lib$es6$promise$promise$$counter = 0; | |
function lib$es6$promise$promise$$needsResolver() { | |
throw new TypeError("You must pass a resolver function as the first argument to the promise constructor") | |
} | |
function lib$es6$promise$promise$$needsNew() { | |
throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.") | |
} | |
var lib$es6$promise$promise$$default = lib$es6$promise$promise$$Promise; | |
function lib$es6$promise$promise$$Promise(resolver) { | |
this._id = lib$es6$promise$promise$$counter++, this._state = void 0, this._result = void 0, this._subscribers = [], lib$es6$promise$$internal$$noop !== resolver && (lib$es6$promise$utils$$isFunction(resolver) || lib$es6$promise$promise$$needsResolver(), this instanceof lib$es6$promise$promise$$Promise || lib$es6$promise$promise$$needsNew(), lib$es6$promise$$internal$$initializePromise(this, resolver)) | |
} | |
lib$es6$promise$promise$$Promise.all = lib$es6$promise$promise$all$$default, lib$es6$promise$promise$$Promise.race = lib$es6$promise$promise$race$$default, lib$es6$promise$promise$$Promise.resolve = lib$es6$promise$promise$resolve$$default, lib$es6$promise$promise$$Promise.reject = lib$es6$promise$promise$reject$$default, lib$es6$promise$promise$$Promise._setScheduler = lib$es6$promise$asap$$setScheduler, lib$es6$promise$promise$$Promise._setAsap = lib$es6$promise$asap$$setAsap, lib$es6$promise$promise$$Promise._asap = lib$es6$promise$asap$$asap, lib$es6$promise$promise$$Promise.prototype = { | |
constructor: lib$es6$promise$promise$$Promise, | |
then: function(onFulfillment, onRejection) { | |
var parent = this, | |
state = parent._state; | |
if (state === lib$es6$promise$$internal$$FULFILLED && !onFulfillment || state === lib$es6$promise$$internal$$REJECTED && !onRejection) return this; | |
var child = new this.constructor(lib$es6$promise$$internal$$noop), | |
result = parent._result; | |
if (state) { | |
var callback = arguments[state - 1]; | |
lib$es6$promise$asap$$asap(function() { | |
lib$es6$promise$$internal$$invokeCallback(state, child, callback, result) | |
}) | |
} else lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection); | |
return child | |
}, | |
"catch": function(onRejection) { | |
return this.then(null, onRejection) | |
} | |
}; | |
function lib$es6$promise$polyfill$$polyfill() { | |
var local; | |
if ("undefined" != typeof global) local = global; | |
else if ("undefined" != typeof self) local = self; | |
else try { | |
local = Function("return this")() | |
} catch (e) { | |
throw new Error("polyfill failed because global object is unavailable in this environment") | |
} | |
var P = local.Promise; | |
if (P && "[object Promise]" === Object.prototype.toString.call(P.resolve()) && !P.cast) return; | |
local.Promise = lib$es6$promise$promise$$default | |
} | |
var lib$es6$promise$polyfill$$default = lib$es6$promise$polyfill$$polyfill, | |
lib$es6$promise$umd$$ES6Promise = { | |
Promise: lib$es6$promise$promise$$default, | |
polyfill: lib$es6$promise$polyfill$$default | |
}; | |
"function" == typeof define && define.amd ? define(function() { | |
return lib$es6$promise$umd$$ES6Promise | |
}) : "undefined" != typeof module && module.exports ? module.exports = lib$es6$promise$umd$$ES6Promise : "undefined" != typeof this && (this.ES6Promise = lib$es6$promise$umd$$ES6Promise), lib$es6$promise$polyfill$$default() | |
}).call(this) | |
}).call(this, require(2), "undefined" != typeof global ? global : "undefined" != typeof self ? self : "undefined" != typeof window ? window : {}) | |
}, { | |
2: 2 | |
}], | |
10: [function(require, module, exports) { | |
"function" == typeof Object.create ? module.exports = function(ctor, superCtor) { | |
ctor.super_ = superCtor, ctor.prototype = Object.create(superCtor.prototype, { | |
constructor: { | |
value: ctor, | |
enumerable: !1, | |
writable: !0, | |
configurable: !0 | |
} | |
}) | |
} : module.exports = function(ctor, superCtor) { | |
ctor.super_ = superCtor; | |
var TempCtor = function() {}; | |
TempCtor.prototype = superCtor.prototype, ctor.prototype = new TempCtor, ctor.prototype.constructor = ctor | |
} | |
}, {}], | |
11: [function(require, module, exports) { | |
var arrayEach = require(14), | |
baseEach = require(18), | |
createForEach = require(30), | |
forEach = createForEach(arrayEach, baseEach); | |
module.exports = forEach | |
}, { | |
14: 14, | |
18: 18, | |
30: 30 | |
}], | |
12: [function(require, module, exports) { | |
var FUNC_ERROR_TEXT = "Expected a function", | |
nativeMax = Math.max; | |
function restParam(func, start) { | |
if ("function" != typeof func) throw new TypeError(FUNC_ERROR_TEXT); | |
return start = nativeMax(void 0 === start ? func.length - 1 : +start || 0, 0), | |
function() { | |
for (var args = arguments, index = -1, length = nativeMax(args.length - start, 0), rest = Array(length); ++index < length;) rest[index] = args[start + index]; | |
switch (start) { | |
case 0: | |
return func.call(this, rest); | |
case 1: | |
return func.call(this, args[0], rest); | |
case 2: | |
return func.call(this, args[0], args[1], rest) | |
} | |
var otherArgs = Array(start + 1); | |
for (index = -1; ++index < start;) otherArgs[index] = args[index]; | |
return otherArgs[start] = rest, func.apply(this, otherArgs) | |
} | |
} | |
module.exports = restParam | |
}, {}], | |
13: [function(require, module, exports) { | |
function arrayCopy(source, array) { | |
var index = -1, | |
length = source.length; | |
for (array || (array = Array(length)); ++index < length;) array[index] = source[index]; | |
return array | |
} | |
module.exports = arrayCopy | |
}, {}], | |
14: [function(require, module, exports) { | |
function arrayEach(array, iteratee) { | |
for (var index = -1, length = array.length; ++index < length && iteratee(array[index], index, array) !== !1;); | |
return array | |
} | |
module.exports = arrayEach | |
}, {}], | |
15: [function(require, module, exports) { | |
var baseCopy = require(17), | |
keys = require(53); | |
function baseAssign(object, source) { | |
return null == source ? object : baseCopy(source, keys(source), object) | |
} | |
module.exports = baseAssign | |
}, { | |
17: 17, | |
53: 53 | |
}], | |
16: [function(require, module, exports) { | |
var arrayCopy = require(13), | |
arrayEach = require(14), | |
baseAssign = require(15), | |
baseForOwn = require(21), | |
initCloneArray = require(33), | |
initCloneByTag = require(34), | |
initCloneObject = require(35), | |
isArray = require(46), | |
isObject = require(49), | |
argsTag = "[object Arguments]", | |
arrayTag = "[object Array]", | |
boolTag = "[object Boolean]", | |
dateTag = "[object Date]", | |
errorTag = "[object Error]", | |
funcTag = "[object Function]", | |
mapTag = "[object Map]", | |
numberTag = "[object Number]", | |
objectTag = "[object Object]", | |
regexpTag = "[object RegExp]", | |
setTag = "[object Set]", | |
stringTag = "[object String]", | |
weakMapTag = "[object WeakMap]", | |
arrayBufferTag = "[object ArrayBuffer]", | |
float32Tag = "[object Float32Array]", | |
float64Tag = "[object Float64Array]", | |
int8Tag = "[object Int8Array]", | |
int16Tag = "[object Int16Array]", | |
int32Tag = "[object Int32Array]", | |
uint8Tag = "[object Uint8Array]", | |
uint8ClampedTag = "[object Uint8ClampedArray]", | |
uint16Tag = "[object Uint16Array]", | |
uint32Tag = "[object Uint32Array]", | |
cloneableTags = {}; | |
cloneableTags[argsTag] = cloneableTags[arrayTag] = cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = cloneableTags[dateTag] = cloneableTags[float32Tag] = cloneableTags[float64Tag] = cloneableTags[int8Tag] = cloneableTags[int16Tag] = cloneableTags[int32Tag] = cloneableTags[numberTag] = cloneableTags[objectTag] = cloneableTags[regexpTag] = cloneableTags[stringTag] = cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = !0, cloneableTags[errorTag] = cloneableTags[funcTag] = cloneableTags[mapTag] = cloneableTags[setTag] = cloneableTags[weakMapTag] = !1; | |
var objectProto = Object.prototype, | |
objToString = objectProto.toString; | |
function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { | |
var result; | |
if (customizer && (result = object ? customizer(value, key, object) : customizer(value)), void 0 !== result) return result; | |
if (!isObject(value)) return value; | |
var isArr = isArray(value); | |
if (isArr) { | |
if (result = initCloneArray(value), !isDeep) return arrayCopy(value, result) | |
} else { | |
var tag = objToString.call(value), | |
isFunc = tag == funcTag; | |
if (tag != objectTag && tag != argsTag && (!isFunc || object)) return cloneableTags[tag] ? initCloneByTag(value, tag, isDeep) : object ? value : {}; | |
if (result = initCloneObject(isFunc ? {} : value), !isDeep) return baseAssign(result, value) | |
} | |
stackA || (stackA = []), stackB || (stackB = []); | |
for (var length = stackA.length; length--;) | |
if (stackA[length] == value) return stackB[length]; | |
return stackA.push(value), stackB.push(result), (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { | |
result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB) | |
}), result | |
} | |
module.exports = baseClone | |
}, { | |
13: 13, | |
14: 14, | |
15: 15, | |
21: 21, | |
33: 33, | |
34: 34, | |
35: 35, | |
46: 46, | |
49: 49 | |
}], | |
17: [function(require, module, exports) { | |
function baseCopy(source, props, object) { | |
object || (object = {}); | |
for (var index = -1, length = props.length; ++index < length;) { | |
var key = props[index]; | |
object[key] = source[key] | |
} | |
return object | |
} | |
module.exports = baseCopy | |
}, {}], | |
18: [function(require, module, exports) { | |
var baseForOwn = require(21), | |
createBaseEach = require(28), | |
baseEach = createBaseEach(baseForOwn); | |
module.exports = baseEach | |
}, { | |
21: 21, | |
28: 28 | |
}], | |
19: [function(require, module, exports) { | |
var createBaseFor = require(29), | |
baseFor = createBaseFor(); | |
module.exports = baseFor | |
}, { | |
29: 29 | |
}], | |
20: [function(require, module, exports) { | |
var baseFor = require(19), | |
keysIn = require(54); | |
function baseForIn(object, iteratee) { | |
return baseFor(object, iteratee, keysIn) | |
} | |
module.exports = baseForIn | |
}, { | |
19: 19, | |
54: 54 | |
}], | |
21: [function(require, module, exports) { | |
var baseFor = require(19), | |
keys = require(53); | |
function baseForOwn(object, iteratee) { | |
return baseFor(object, iteratee, keys) | |
} | |
module.exports = baseForOwn | |
}, { | |
19: 19, | |
53: 53 | |
}], | |
22: [function(require, module, exports) { | |
var arrayEach = require(14), | |
baseMergeDeep = require(23), | |
isArray = require(46), | |
isArrayLike = require(36), | |
isObject = require(49), | |
isObjectLike = require(40), | |
isTypedArray = require(51), | |
keys = require(53); | |
function baseMerge(object, source, customizer, stackA, stackB) { | |
if (!isObject(object)) return object; | |
var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)), | |
props = isSrcArr ? void 0 : keys(source); | |
return arrayEach(props || source, function(srcValue, key) { | |
if (props && (key = srcValue, srcValue = source[key]), isObjectLike(srcValue)) stackA || (stackA = []), stackB || (stackB = []), baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); | |
else { | |
var value = object[key], | |
result = customizer ? customizer(value, srcValue, key, object, source) : void 0, | |
isCommon = void 0 === result; | |
isCommon && (result = srcValue), void 0 === result && (!isSrcArr || key in object) || !isCommon && (result === result ? result === value : value !== value) || (object[key] = result) | |
} | |
}), object | |
} | |
module.exports = baseMerge | |
}, { | |
14: 14, | |
23: 23, | |
36: 36, | |
40: 40, | |
46: 46, | |
49: 49, | |
51: 51, | |
53: 53 | |
}], | |
23: [function(require, module, exports) { | |
var arrayCopy = require(13), | |
isArguments = require(45), | |
isArray = require(46), | |
isArrayLike = require(36), | |
isPlainObject = require(50), | |
isTypedArray = require(51), | |
toPlainObject = require(52); | |
function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) { | |
for (var length = stackA.length, srcValue = source[key]; length--;) | |
if (stackA[length] == srcValue) return void(object[key] = stackB[length]); | |
var value = object[key], | |
result = customizer ? customizer(value, srcValue, key, object, source) : void 0, | |
isCommon = void 0 === result; | |
isCommon && (result = srcValue, isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue)) ? result = isArray(value) ? value : isArrayLike(value) ? arrayCopy(value) : [] : isPlainObject(srcValue) || isArguments(srcValue) ? result = isArguments(value) ? toPlainObject(value) : isPlainObject(value) ? value : {} : isCommon = !1), stackA.push(srcValue), stackB.push(result), isCommon ? object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB) : (result === result ? result !== value : value === value) && (object[key] = result) | |
} | |
module.exports = baseMergeDeep | |
}, { | |
13: 13, | |
36: 36, | |
45: 45, | |
46: 46, | |
50: 50, | |
51: 51, | |
52: 52 | |
}], | |
24: [function(require, module, exports) { | |
function baseProperty(key) { | |
return function(object) { | |
return null == object ? void 0 : object[key] | |
} | |
} | |
module.exports = baseProperty | |
}, {}], | |
25: [function(require, module, exports) { | |
var identity = require(56); | |
function bindCallback(func, thisArg, argCount) { | |
if ("function" != typeof func) return identity; | |
if (void 0 === thisArg) return func; | |
switch (argCount) { | |
case 1: | |
return function(value) { | |
return func.call(thisArg, value) | |
}; | |
case 3: | |
return function(value, index, collection) { | |
return func.call(thisArg, value, index, collection) | |
}; | |
case 4: | |
return function(accumulator, value, index, collection) { | |
return func.call(thisArg, accumulator, value, index, collection) | |
}; | |
case 5: | |
return function(value, other, key, object, source) { | |
return func.call(thisArg, value, other, key, object, source) | |
} | |
} | |
return function() { | |
return func.apply(thisArg, arguments) | |
} | |
} | |
module.exports = bindCallback | |
}, { | |
56: 56 | |
}], | |
26: [function(require, module, exports) { | |
(function(global) { | |
var ArrayBuffer = global.ArrayBuffer, | |
Uint8Array = global.Uint8Array; | |
function bufferClone(buffer) { | |
var result = new ArrayBuffer(buffer.byteLength), | |
view = new Uint8Array(result); | |
return view.set(new Uint8Array(buffer)), result | |
} | |
module.exports = bufferClone | |
}).call(this, "undefined" != typeof global ? global : "undefined" != typeof self ? self : "undefined" != typeof window ? window : {}) | |
}, {}], | |
27: [function(require, module, exports) { | |
var bindCallback = require(25), | |
isIterateeCall = require(38), | |
restParam = require(12); | |
function createAssigner(assigner) { | |
return restParam(function(object, sources) { | |
var index = -1, | |
length = null == object ? 0 : sources.length, | |
customizer = length > 2 ? sources[length - 2] : void 0, | |
guard = length > 2 ? sources[2] : void 0, | |
thisArg = length > 1 ? sources[length - 1] : void 0; | |
for ("function" == typeof customizer ? (customizer = bindCallback(customizer, thisArg, 5), length -= 2) : (customizer = "function" == typeof thisArg ? thisArg : void 0, length -= customizer ? 1 : 0), guard && isIterateeCall(sources[0], sources[1], guard) && (customizer = 3 > length ? void 0 : customizer, length = 1); ++index < length;) { | |
var source = sources[index]; | |
source && assigner(object, source, customizer) | |
} | |
return object | |
}) | |
} | |
module.exports = createAssigner | |
}, { | |
12: 12, | |
25: 25, | |
38: 38 | |
}], | |
28: [function(require, module, exports) { | |
var getLength = require(31), | |
isLength = require(39), | |
toObject = require(42); | |
function createBaseEach(eachFunc, fromRight) { | |
return function(collection, iteratee) { | |
var length = collection ? getLength(collection) : 0; | |
if (!isLength(length)) return eachFunc(collection, iteratee); | |
for (var index = fromRight ? length : -1, iterable = toObject(collection); | |
(fromRight ? index-- : ++index < length) && iteratee(iterable[index], index, iterable) !== !1;); | |
return collection | |
} | |
} | |
module.exports = createBaseEach | |
}, { | |
31: 31, | |
39: 39, | |
42: 42 | |
}], | |
29: [function(require, module, exports) { | |
var toObject = require(42); | |
function createBaseFor(fromRight) { | |
return function(object, iteratee, keysFunc) { | |
for (var iterable = toObject(object), props = keysFunc(object), length = props.length, index = fromRight ? length : -1; fromRight ? index-- : ++index < length;) { | |
var key = props[index]; | |
if (iteratee(iterable[key], key, iterable) === !1) break | |
} | |
return object | |
} | |
} | |
module.exports = createBaseFor | |
}, { | |
42: 42 | |
}], | |
30: [function(require, module, exports) { | |
var bindCallback = require(25), | |
isArray = require(46); | |
function createForEach(arrayFunc, eachFunc) { | |
return function(collection, iteratee, thisArg) { | |
return "function" == typeof iteratee && void 0 === thisArg && isArray(collection) ? arrayFunc(collection, iteratee) : eachFunc(collection, bindCallback(iteratee, thisArg, 3)) | |
} | |
} | |
module.exports = createForEach | |
}, { | |
25: 25, | |
46: 46 | |
}], | |
31: [function(require, module, exports) { | |
var baseProperty = require(24), | |
getLength = baseProperty("length"); | |
module.exports = getLength | |
}, { | |
24: 24 | |
}], | |
32: [function(require, module, exports) { | |
var isNative = require(48); | |
function getNative(object, key) { | |
var value = null == object ? void 0 : object[key]; | |
return isNative(value) ? value : void 0 | |
} | |
module.exports = getNative | |
}, { | |
48: 48 | |
}], | |
33: [function(require, module, exports) { | |
var objectProto = Object.prototype, | |
hasOwnProperty = objectProto.hasOwnProperty; | |
function initCloneArray(array) { | |
var length = array.length, | |
result = new array.constructor(length); | |
return length && "string" == typeof array[0] && hasOwnProperty.call(array, "index") && (result.index = array.index, result.input = array.input), result | |
} | |
module.exports = initCloneArray | |
}, {}], | |
34: [function(require, module, exports) { | |
var bufferClone = require(26), | |
boolTag = "[object Boolean]", | |
dateTag = "[object Date]", | |
numberTag = "[object Number]", | |
regexpTag = "[object RegExp]", | |
stringTag = "[object String]", | |
arrayBufferTag = "[object ArrayBuffer]", | |
float32Tag = "[object Float32Array]", | |
float64Tag = "[object Float64Array]", | |
int8Tag = "[object Int8Array]", | |
int16Tag = "[object Int16Array]", | |
int32Tag = "[object Int32Array]", | |
uint8Tag = "[object Uint8Array]", | |
uint8ClampedTag = "[object Uint8ClampedArray]", | |
uint16Tag = "[object Uint16Array]", | |
uint32Tag = "[object Uint32Array]", | |
reFlags = /\w*$/; | |
function initCloneByTag(object, tag, isDeep) { | |
var Ctor = object.constructor; | |
switch (tag) { | |
case arrayBufferTag: | |
return bufferClone(object); | |
case boolTag: | |
case dateTag: | |
return new Ctor(+object); | |
case float32Tag: | |
case float64Tag: | |
case int8Tag: | |
case int16Tag: | |
case int32Tag: | |
case uint8Tag: | |
case uint8ClampedTag: | |
case uint16Tag: | |
case uint32Tag: | |
var buffer = object.buffer; | |
return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); | |
case numberTag: | |
case stringTag: | |
return new Ctor(object); | |
case regexpTag: | |
var result = new Ctor(object.source, reFlags.exec(object)); | |
result.lastIndex = object.lastIndex | |
} | |
return result | |
} | |
module.exports = initCloneByTag | |
}, { | |
26: 26 | |
}], | |
35: [function(require, module, exports) { | |
function initCloneObject(object) { | |
var Ctor = object.constructor; | |
return "function" == typeof Ctor && Ctor instanceof Ctor || (Ctor = Object), new Ctor | |
} | |
module.exports = initCloneObject | |
}, {}], | |
36: [function(require, module, exports) { | |
var getLength = require(31), | |
isLength = require(39); | |
function isArrayLike(value) { | |
return null != value && isLength(getLength(value)) | |
} | |
module.exports = isArrayLike | |
}, { | |
31: 31, | |
39: 39 | |
}], | |
37: [function(require, module, exports) { | |
var reIsUint = /^\d+$/, | |
MAX_SAFE_INTEGER = 9007199254740991; | |
function isIndex(value, length) { | |
return value = "number" == typeof value || reIsUint.test(value) ? +value : -1, length = null == length ? MAX_SAFE_INTEGER : length, value > -1 && value % 1 == 0 && length > value | |
} | |
module.exports = isIndex | |
}, {}], | |
38: [function(require, module, exports) { | |
var isArrayLike = require(36), | |
isIndex = require(37), | |
isObject = require(49); | |
function isIterateeCall(value, index, object) { | |
if (!isObject(object)) return !1; | |
var type = typeof index; | |
if ("number" == type ? isArrayLike(object) && isIndex(index, object.length) : "string" == type && index in object) { | |
var other = object[index]; | |
return value === value ? value === other : other !== other | |
} | |
return !1 | |
} | |
module.exports = isIterateeCall | |
}, { | |
36: 36, | |
37: 37, | |
49: 49 | |
}], | |
39: [function(require, module, exports) { | |
var MAX_SAFE_INTEGER = 9007199254740991; | |
function isLength(value) { | |
return "number" == typeof value && value > -1 && value % 1 == 0 && MAX_SAFE_INTEGER >= value | |
} | |
module.exports = isLength | |
}, {}], | |
40: [function(require, module, exports) { | |
function isObjectLike(value) { | |
return !!value && "object" == typeof value | |
} | |
module.exports = isObjectLike | |
}, {}], | |
41: [function(require, module, exports) { | |
var isArguments = require(45), | |
isArray = require(46), | |
isIndex = require(37), | |
isLength = require(39), | |
keysIn = require(54), | |
objectProto = Object.prototype, | |
hasOwnProperty = objectProto.hasOwnProperty; | |
function shimKeys(object) { | |
for (var props = keysIn(object), propsLength = props.length, length = propsLength && object.length, allowIndexes = !!length && isLength(length) && (isArray(object) || isArguments(object)), index = -1, result = []; ++index < propsLength;) { | |
var key = props[index]; | |
(allowIndexes && isIndex(key, length) || hasOwnProperty.call(object, key)) && result.push(key) | |
} | |
return result | |
} | |
module.exports = shimKeys | |
}, { | |
37: 37, | |
39: 39, | |
45: 45, | |
46: 46, | |
54: 54 | |
}], | |
42: [function(require, module, exports) { | |
var isObject = require(49); | |
function toObject(value) { | |
return isObject(value) ? value : Object(value) | |
} | |
module.exports = toObject | |
}, { | |
49: 49 | |
}], | |
43: [function(require, module, exports) { | |
var baseClone = require(16), | |
bindCallback = require(25), | |
isIterateeCall = require(38); | |
function clone(value, isDeep, customizer, thisArg) { | |
return isDeep && "boolean" != typeof isDeep && isIterateeCall(value, isDeep, customizer) ? isDeep = !1 : "function" == typeof isDeep && (thisArg = customizer, customizer = isDeep, isDeep = !1), "function" == typeof customizer ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 3)) : baseClone(value, isDeep) | |
} | |
module.exports = clone | |
}, { | |
16: 16, | |
25: 25, | |
38: 38 | |
}], | |
44: [function(require, module, exports) { | |
var baseClone = require(16), | |
bindCallback = require(25); | |
function cloneDeep(value, customizer, thisArg) { | |
return "function" == typeof customizer ? baseClone(value, !0, bindCallback(customizer, thisArg, 3)) : baseClone(value, !0) | |
} | |
module.exports = cloneDeep | |
}, { | |
16: 16, | |
25: 25 | |
}], | |
45: [function(require, module, exports) { | |
var isArrayLike = require(36), | |
isObjectLike = require(40), | |
objectProto = Object.prototype, | |
hasOwnProperty = objectProto.hasOwnProperty, | |
propertyIsEnumerable = objectProto.propertyIsEnumerable; | |
function isArguments(value) { | |
return isObjectLike(value) && isArrayLike(value) && hasOwnProperty.call(value, "callee") && !propertyIsEnumerable.call(value, "callee") | |
} | |
module.exports = isArguments | |
}, { | |
36: 36, | |
40: 40 | |
}], | |
46: [function(require, module, exports) { | |
var getNative = require(32), | |
isLength = require(39), | |
isObjectLike = require(40), | |
arrayTag = "[object Array]", | |
objectProto = Object.prototype, | |
objToString = objectProto.toString, | |
nativeIsArray = getNative(Array, "isArray"), | |
isArray = nativeIsArray || function(value) { | |
return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag | |
}; | |
module.exports = isArray | |
}, { | |
32: 32, | |
39: 39, | |
40: 40 | |
}], | |
47: [function(require, module, exports) { | |
var isObject = require(49), | |
funcTag = "[object Function]", | |
objectProto = Object.prototype, | |
objToString = objectProto.toString; | |
function isFunction(value) { | |
return isObject(value) && objToString.call(value) == funcTag | |
} | |
module.exports = isFunction | |
}, { | |
49: 49 | |
}], | |
48: [function(require, module, exports) { | |
var isFunction = require(47), | |
isObjectLike = require(40), | |
reIsHostCtor = /^\[object .+?Constructor\]$/, | |
objectProto = Object.prototype, | |
fnToString = Function.prototype.toString, | |
hasOwnProperty = objectProto.hasOwnProperty, | |
reIsNative = RegExp("^" + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"); | |
function isNative(value) { | |
if (null == value) return !1; | |
if (isFunction(value)) return reIsNative.test(fnToString.call(value)); | |
return isObjectLike(value) && reIsHostCtor.test(value) | |
} | |
module.exports = isNative | |
}, { | |
40: 40, | |
47: 47 | |
}], | |
49: [function(require, module, exports) { | |
function isObject(value) { | |
var type = typeof value; | |
return !!value && ("object" == type || "function" == type) | |
} | |
module.exports = isObject | |
}, {}], | |
50: [function(require, module, exports) { | |
var baseForIn = require(20), | |
isArguments = require(45), | |
isObjectLike = require(40), | |
objectTag = "[object Object]", | |
objectProto = Object.prototype, | |
hasOwnProperty = objectProto.hasOwnProperty, | |
objToString = objectProto.toString; | |
function isPlainObject(value) { | |
var Ctor; | |
if (!isObjectLike(value) || objToString.call(value) != objectTag || isArguments(value) || !hasOwnProperty.call(value, "constructor") && (Ctor = value.constructor, "function" == typeof Ctor && !(Ctor instanceof Ctor))) return !1; | |
var result; | |
return baseForIn(value, function(subValue, key) { | |
result = key | |
}), void 0 === result || hasOwnProperty.call(value, result) | |
} | |
module.exports = isPlainObject | |
}, { | |
20: 20, | |
40: 40, | |
45: 45 | |
}], | |
51: [function(require, module, exports) { | |
var isLength = require(39), | |
isObjectLike = require(40), | |
argsTag = "[object Arguments]", | |
arrayTag = "[object Array]", | |
boolTag = "[object Boolean]", | |
dateTag = "[object Date]", | |
errorTag = "[object Error]", | |
funcTag = "[object Function]", | |
mapTag = "[object Map]", | |
numberTag = "[object Number]", | |
objectTag = "[object Object]", | |
regexpTag = "[object RegExp]", | |
setTag = "[object Set]", | |
stringTag = "[object String]", | |
weakMapTag = "[object WeakMap]", | |
arrayBufferTag = "[object ArrayBuffer]", | |
float32Tag = "[object Float32Array]", | |
float64Tag = "[object Float64Array]", | |
int8Tag = "[object Int8Array]", | |
int16Tag = "[object Int16Array]", | |
int32Tag = "[object Int32Array]", | |
uint8Tag = "[object Uint8Array]", | |
uint8ClampedTag = "[object Uint8ClampedArray]", | |
uint16Tag = "[object Uint16Array]", | |
uint32Tag = "[object Uint32Array]", | |
typedArrayTags = {}; | |
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = !0, typedArrayTags[argsTag] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = typedArrayTags[dateTag] = typedArrayTags[errorTag] = typedArrayTags[funcTag] = typedArrayTags[mapTag] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[regexpTag] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = !1; | |
var objectProto = Object.prototype, | |
objToString = objectProto.toString; | |
function isTypedArray(value) { | |
return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)] | |
} | |
module.exports = isTypedArray | |
}, { | |
39: 39, | |
40: 40 | |
}], | |
52: [function(require, module, exports) { | |
var baseCopy = require(17), | |
keysIn = require(54); | |
function toPlainObject(value) { | |
return baseCopy(value, keysIn(value)) | |
} | |
module.exports = toPlainObject | |
}, { | |
17: 17, | |
54: 54 | |
}], | |
53: [function(require, module, exports) { | |
var getNative = require(32), | |
isArrayLike = require(36), | |
isObject = require(49), | |
shimKeys = require(41), | |
nativeKeys = getNative(Object, "keys"), | |
keys = nativeKeys ? function(object) { | |
var Ctor = null == object ? void 0 : object.constructor; | |
if ("function" == typeof Ctor && Ctor.prototype === object || "function" != typeof object && isArrayLike(object)) return shimKeys(object); | |
return isObject(object) ? nativeKeys(object) : [] | |
} : shimKeys; | |
module.exports = keys | |
}, { | |
32: 32, | |
36: 36, | |
41: 41, | |
49: 49 | |
}], | |
54: [function(require, module, exports) { | |
var isArguments = require(45), | |
isArray = require(46), | |
isIndex = require(37), | |
isLength = require(39), | |
isObject = require(49), | |
objectProto = Object.prototype, | |
hasOwnProperty = objectProto.hasOwnProperty; | |
function keysIn(object) { | |
if (null == object) return []; | |
isObject(object) || (object = Object(object)); | |
var length = object.length; | |
length = length && isLength(length) && (isArray(object) || isArguments(object)) && length || 0; | |
for (var Ctor = object.constructor, index = -1, isProto = "function" == typeof Ctor && Ctor.prototype === object, result = Array(length), skipIndexes = length > 0; ++index < length;) result[index] = index + ""; | |
for (var key in object) skipIndexes && isIndex(key, length) || "constructor" == key && (isProto || !hasOwnProperty.call(object, key)) || result.push(key); | |
return result | |
} | |
module.exports = keysIn | |
}, { | |
37: 37, | |
39: 39, | |
45: 45, | |
46: 46, | |
49: 49 | |
}], | |
55: [function(require, module, exports) { | |
var baseMerge = require(22), | |
createAssigner = require(27), | |
merge = createAssigner(baseMerge); | |
module.exports = merge | |
}, { | |
22: 22, | |
27: 27 | |
}], | |
56: [function(require, module, exports) { | |
function identity(value) { | |
return value | |
} | |
module.exports = identity | |
}, {}], | |
57: [function(require, module, exports) { | |
"use strict"; | |
module.exports = AlgoliaSearch; | |
var process = process || void 0; | |
process && process.env, 1; | |
var errors = require(64); | |
function AlgoliaSearch(applicationID, apiKey, opts) { | |
var debug = require(6)("algoliasearch"), | |
clone = require(43), | |
isArray = require(46), | |
usage = "Usage: algoliasearch(applicationID, apiKey, opts)"; | |
if (!applicationID) throw new errors.AlgoliaSearchError("Please provide an application ID. " + usage); | |
if (!apiKey) throw new errors.AlgoliaSearchError("Please provide an API key. " + usage); | |
this.applicationID = applicationID, this.apiKey = apiKey; | |
var defaultHosts = [this.applicationID + "-1.algolianet.com", this.applicationID + "-2.algolianet.com", this.applicationID + "-3.algolianet.com"]; | |
this.hosts = { | |
read: [], | |
write: [] | |
}, this.hostIndex = { | |
read: 0, | |
write: 0 | |
}, opts = opts || {}; | |
var protocol = opts.protocol || "https:", | |
timeout = void 0 === opts.timeout ? 2e3 : opts.timeout; | |
if (/:$/.test(protocol) || (protocol += ":"), "http:" !== opts.protocol && "https:" !== opts.protocol) throw new errors.AlgoliaSearchError("protocol must be `http:` or `https:` (was `" + opts.protocol + "`)"); | |
opts.hosts ? isArray(opts.hosts) ? (this.hosts.read = clone(opts.hosts), this.hosts.write = clone(opts.hosts)) : (this.hosts.read = clone(opts.hosts.read), this.hosts.write = clone(opts.hosts.write)) : (this.hosts.read = [this.applicationID + "-dsn.algolia.net"].concat(defaultHosts), this.hosts.write = [this.applicationID + ".algolia.net"].concat(defaultHosts)), this.hosts.read = map(this.hosts.read, prepareHost(protocol)), this.hosts.write = map(this.hosts.write, prepareHost(protocol)), this.requestTimeout = timeout, this.extraHeaders = [], this.cache = {}, this._ua = opts._ua, this._useCache = void 0 === opts._useCache ? !0 : opts._useCache, this._setTimeout = opts._setTimeout, debug("init done, %j", this) | |
} | |
AlgoliaSearch.prototype = { | |
deleteIndex: function(indexName, callback) { | |
return this._jsonRequest({ | |
method: "DELETE", | |
url: "/1/indexes/" + encodeURIComponent(indexName), | |
hostType: "write", | |
callback: callback | |
}) | |
}, | |
moveIndex: function(srcIndexName, dstIndexName, callback) { | |
var postObj = { | |
operation: "move", | |
destination: dstIndexName | |
}; | |
return this._jsonRequest({ | |
method: "POST", | |
url: "/1/indexes/" + encodeURIComponent(srcIndexName) + "/operation", | |
body: postObj, | |
hostType: "write", | |
callback: callback | |
}) | |
}, | |
copyIndex: function(srcIndexName, dstIndexName, callback) { | |
var postObj = { | |
operation: "copy", | |
destination: dstIndexName | |
}; | |
return this._jsonRequest({ | |
method: "POST", | |
url: "/1/indexes/" + encodeURIComponent(srcIndexName) + "/operation", | |
body: postObj, | |
hostType: "write", | |
callback: callback | |
}) | |
}, | |
getLogs: function(offset, length, callback) { | |
return 0 === arguments.length || "function" == typeof offset ? (callback = offset, offset = 0, length = 10) : (1 === arguments.length || "function" == typeof length) && (callback = length, | |
length = 10), this._jsonRequest({ | |
method: "GET", | |
url: "/1/logs?offset=" + offset + "&length=" + length, | |
hostType: "read", | |
callback: callback | |
}) | |
}, | |
listIndexes: function(page, callback) { | |
var params = ""; | |
return void 0 === page || "function" == typeof page ? callback = page : params = "?page=" + page, this._jsonRequest({ | |
method: "GET", | |
url: "/1/indexes" + params, | |
hostType: "read", | |
callback: callback | |
}) | |
}, | |
initIndex: function(indexName) { | |
return new this.Index(this, indexName) | |
}, | |
listUserKeys: function(callback) { | |
return this._jsonRequest({ | |
method: "GET", | |
url: "/1/keys", | |
hostType: "read", | |
callback: callback | |
}) | |
}, | |
getUserKeyACL: function(key, callback) { | |
return this._jsonRequest({ | |
method: "GET", | |
url: "/1/keys/" + key, | |
hostType: "read", | |
callback: callback | |
}) | |
}, | |
deleteUserKey: function(key, callback) { | |
return this._jsonRequest({ | |
method: "DELETE", | |
url: "/1/keys/" + key, | |
hostType: "write", | |
callback: callback | |
}) | |
}, | |
addUserKey: function(acls, params, callback) { | |
var isArray = require(46), | |
usage = "Usage: client.addUserKey(arrayOfAcls[, params, callback])"; | |
if (!isArray(acls)) throw new Error(usage); | |
(1 === arguments.length || "function" == typeof params) && (callback = params, params = null); | |
var postObj = { | |
acl: acls | |
}; | |
return params && (postObj.validity = params.validity, postObj.maxQueriesPerIPPerHour = params.maxQueriesPerIPPerHour, postObj.maxHitsPerQuery = params.maxHitsPerQuery, postObj.indexes = params.indexes, postObj.description = params.description, params.queryParameters && (postObj.queryParameters = this._getSearchParams(params.queryParameters, "")), postObj.referers = params.referers), this._jsonRequest({ | |
method: "POST", | |
url: "/1/keys", | |
body: postObj, | |
hostType: "write", | |
callback: callback | |
}) | |
}, | |
addUserKeyWithValidity: deprecate(function(acls, params, callback) { | |
return this.addUserKey(acls, params, callback) | |
}, deprecatedMessage("client.addUserKeyWithValidity()", "client.addUserKey()")), | |
updateUserKey: function(key, acls, params, callback) { | |
var isArray = require(46), | |
usage = "Usage: client.updateUserKey(key, arrayOfAcls[, params, callback])"; | |
if (!isArray(acls)) throw new Error(usage); | |
(2 === arguments.length || "function" == typeof params) && (callback = params, params = null); | |
var putObj = { | |
acl: acls | |
}; | |
return params && (putObj.validity = params.validity, putObj.maxQueriesPerIPPerHour = params.maxQueriesPerIPPerHour, putObj.maxHitsPerQuery = params.maxHitsPerQuery, putObj.indexes = params.indexes, putObj.description = params.description, params.queryParameters && (putObj.queryParameters = this._getSearchParams(params.queryParameters, "")), putObj.referers = params.referers), this._jsonRequest({ | |
method: "PUT", | |
url: "/1/keys/" + key, | |
body: putObj, | |
hostType: "write", | |
callback: callback | |
}) | |
}, | |
setSecurityTags: function(tags) { | |
if ("[object Array]" === Object.prototype.toString.call(tags)) { | |
for (var strTags = [], i = 0; i < tags.length; ++i) | |
if ("[object Array]" === Object.prototype.toString.call(tags[i])) { | |
for (var oredTags = [], j = 0; j < tags[i].length; ++j) oredTags.push(tags[i][j]); | |
strTags.push("(" + oredTags.join(",") + ")") | |
} else strTags.push(tags[i]); | |
tags = strTags.join(",") | |
} | |
this.securityTags = tags | |
}, | |
setUserToken: function(userToken) { | |
this.userToken = userToken | |
}, | |
startQueriesBatch: deprecate(function() { | |
this._batch = [] | |
}, deprecatedMessage("client.startQueriesBatch()", "client.search()")), | |
addQueryInBatch: deprecate(function(indexName, query, args) { | |
this._batch.push({ | |
indexName: indexName, | |
query: query, | |
params: args | |
}) | |
}, deprecatedMessage("client.addQueryInBatch()", "client.search()")), | |
clearCache: function() { | |
this.cache = {} | |
}, | |
sendQueriesBatch: deprecate(function(callback) { | |
return this.search(this._batch, callback) | |
}, deprecatedMessage("client.sendQueriesBatch()", "client.search()")), | |
setRequestTimeout: function(milliseconds) { | |
milliseconds && (this.requestTimeout = parseInt(milliseconds, 10)) | |
}, | |
search: function(queries, callback) { | |
var isArray = require(46), | |
usage = "Usage: client.search(arrayOfQueries[, callback])"; | |
if (!isArray(queries)) throw new Error(usage); | |
var client = this, | |
postObj = { | |
requests: map(queries, function(query) { | |
var params = ""; | |
return void 0 !== query.query && (params += "query=" + encodeURIComponent(query.query)), { | |
indexName: query.indexName, | |
params: client._getSearchParams(query.params, params) | |
} | |
}) | |
}; | |
return this._jsonRequest({ | |
cache: this.cache, | |
method: "POST", | |
url: "/1/indexes/*/queries", | |
body: postObj, | |
hostType: "read", | |
callback: callback | |
}) | |
}, | |
batch: function(operations, callback) { | |
var isArray = require(46), | |
usage = "Usage: client.batch(operations[, callback])"; | |
if (!isArray(operations)) throw new Error(usage); | |
return this._jsonRequest({ | |
method: "POST", | |
url: "/1/indexes/*/batch", | |
body: { | |
requests: operations | |
}, | |
hostType: "write", | |
callback: callback | |
}) | |
}, | |
destroy: notImplemented, | |
enableRateLimitForward: notImplemented, | |
disableRateLimitForward: notImplemented, | |
useSecuredAPIKey: notImplemented, | |
disableSecuredAPIKey: notImplemented, | |
generateSecuredApiKey: notImplemented, | |
Index: function(algoliasearch, indexName) { | |
this.indexName = indexName, this.as = algoliasearch, this.typeAheadArgs = null, this.typeAheadValueOption = null, this.cache = {} | |
}, | |
setExtraHeader: function(name, value) { | |
this.extraHeaders.push({ | |
name: name.toLowerCase(), | |
value: value | |
}) | |
}, | |
addAlgoliaAgent: function(algoliaAgent) { | |
this._ua += ";" + algoliaAgent | |
}, | |
_sendQueriesBatch: function(params, callback) { | |
function prepareParams() { | |
for (var reqParams = "", i = 0; i < params.requests.length; ++i) { | |
var q = "/1/indexes/" + encodeURIComponent(params.requests[i].indexName) + "?" + params.requests[i].params; | |
reqParams += i + "=" + encodeURIComponent(q) + "&" | |
} | |
return reqParams | |
} | |
return this._jsonRequest({ | |
cache: this.cache, | |
method: "POST", | |
url: "/1/indexes/*/queries", | |
body: params, | |
hostType: "read", | |
fallback: { | |
method: "GET", | |
url: "/1/indexes/*", | |
body: { | |
params: prepareParams() | |
} | |
}, | |
callback: callback | |
}) | |
}, | |
_jsonRequest: function(opts) { | |
var body, requestDebug = require(6)("algoliasearch:" + opts.url), | |
cache = opts.cache, | |
client = this, | |
tries = 0, | |
usingFallback = !1; | |
void 0 !== opts.body && (body = safeJSONStringify(opts.body)), requestDebug("request start"); | |
function doRequest(requester, reqOpts) { | |
var cacheID; | |
if (client._useCache && (cacheID = opts.url), client._useCache && body && (cacheID += "_body_" + reqOpts.body), client._useCache && cache && void 0 !== cache[cacheID]) return requestDebug("serving response from cache"), client._promise.resolve(JSON.parse(cache[cacheID])); | |
if (tries >= client.hosts[opts.hostType].length || client.useFallback && !usingFallback) { | |
if (!opts.fallback || !client._request.fallback || usingFallback) return requestDebug("could not get any response"), client._promise.reject(new errors.AlgoliaSearchError("Cannot connect to the AlgoliaSearch API. Send an email to support@algolia.com to report and resolve the issue. Application id was: " + client.applicationID)); | |
return requestDebug("switching to fallback"), tries = 0, reqOpts.method = opts.fallback.method, reqOpts.url = opts.fallback.url, reqOpts.jsonBody = opts.fallback.body, reqOpts.jsonBody && (reqOpts.body = safeJSONStringify(reqOpts.jsonBody)), reqOpts.timeout = client.requestTimeout * (tries + 1), client.hostIndex[opts.hostType] = 0, usingFallback = !0, doRequest(client._request.fallback, reqOpts) | |
} | |
var url = client.hosts[opts.hostType][client.hostIndex[opts.hostType]] + reqOpts.url, | |
options = { | |
body: body, | |
jsonBody: opts.body, | |
method: reqOpts.method, | |
headers: client._computeRequestHeaders(), | |
timeout: reqOpts.timeout, | |
debug: requestDebug | |
}; | |
return requestDebug("method: %s, url: %s, headers: %j, timeout: %d", options.method, url, options.headers, options.timeout), requester === client._request.fallback && requestDebug("using fallback"), requester.call(client, url, options).then(success, tryFallback); | |
function success(httpResponse) { | |
var status = httpResponse && httpResponse.body && httpResponse.body.message && httpResponse.body.status || httpResponse.statusCode || httpResponse && httpResponse.body && 200; | |
requestDebug("received response: statusCode: %s, computed statusCode: %d, headers: %j", httpResponse.statusCode, status, httpResponse.headers), process && process.env.DEBUG && -1 !== process.env.DEBUG.indexOf("debugBody") && requestDebug("body: %j", httpResponse.body); | |
var ok = 200 === status || 201 === status, | |
retry = !ok && 4 !== Math.floor(status / 100) && 1 !== Math.floor(status / 100); | |
if (client._useCache && ok && cache && (cache[cacheID] = httpResponse.responseText), ok) return httpResponse.body; | |
if (retry) return tries += 1, retryRequest(); | |
var unrecoverableError = new errors.AlgoliaSearchError(httpResponse.body && httpResponse.body.message); | |
return client._promise.reject(unrecoverableError) | |
} | |
function tryFallback(err) { | |
if (requestDebug("error: %s, stack: %s", err.message, err.stack), err instanceof errors.AlgoliaSearchError || (err = new errors.Unknown(err && err.message, err)), tries += 1, err instanceof errors.Unknown || err instanceof errors.UnparsableJSON || tries >= client.hosts[opts.hostType].length && (usingFallback || !opts.fallback || !client._request.fallback)) return client._promise.reject(err); | |
if (client.hostIndex[opts.hostType] = ++client.hostIndex[opts.hostType] % client.hosts[opts.hostType].length, err instanceof errors.RequestTimeout) return retryRequest(); | |
return client._request.fallback && !client.useFallback && (client.useFallback = !0), doRequest(requester, reqOpts) | |
} | |
function retryRequest() { | |
return client.hostIndex[opts.hostType] = ++client.hostIndex[opts.hostType] % client.hosts[opts.hostType].length, reqOpts.timeout = client.requestTimeout * (tries + 1), doRequest(requester, reqOpts) | |
} | |
} | |
var useFallback = client.useFallback && opts.fallback, | |
requestOptions = useFallback ? opts.fallback : opts, | |
promise = doRequest(useFallback ? client._request.fallback : client._request, { | |
url: requestOptions.url, | |
method: requestOptions.method, | |
body: body, | |
jsonBody: opts.body, | |
timeout: client.requestTimeout * (tries + 1) | |
}); | |
if (!opts.callback) return promise; | |
promise.then(function(content) { | |
exitPromise(function() { | |
opts.callback(null, content) | |
}, client._setTimeout || setTimeout) | |
}, function(err) { | |
exitPromise(function() { | |
opts.callback(err) | |
}, client._setTimeout || setTimeout) | |
}) | |
}, | |
_getSearchParams: function(args, params) { | |
if (this._isUndefined(args) || null === args) return params; | |
for (var key in args) null !== key && void 0 !== args[key] && args.hasOwnProperty(key) && (params += "" === params ? "" : "&", params += key + "=" + encodeURIComponent("[object Array]" === Object.prototype.toString.call(args[key]) ? safeJSONStringify(args[key]) : args[key])); | |
return params | |
}, | |
_isUndefined: function(obj) { | |
return void 0 === obj | |
}, | |
_computeRequestHeaders: function() { | |
var forEach = require(11), | |
requestHeaders = { | |
"x-algolia-api-key": this.apiKey, | |
"x-algolia-application-id": this.applicationID, | |
"x-algolia-agent": this._ua | |
}; | |
return this.userToken && (requestHeaders["x-algolia-usertoken"] = this.userToken), this.securityTags && (requestHeaders["x-algolia-tagfilters"] = this.securityTags), this.extraHeaders && forEach(this.extraHeaders, function(header) { | |
requestHeaders[header.name] = header.value | |
}), requestHeaders | |
} | |
}, AlgoliaSearch.prototype.Index.prototype = { | |
clearCache: function() { | |
this.cache = {} | |
}, | |
addObject: function(content, objectID, callback) { | |
var indexObj = this; | |
return (1 === arguments.length || "function" == typeof objectID) && (callback = objectID, objectID = void 0), this.as._jsonRequest({ | |
method: void 0 !== objectID ? "PUT" : "POST", | |
url: "/1/indexes/" + encodeURIComponent(indexObj.indexName) + (void 0 !== objectID ? "/" + encodeURIComponent(objectID) : ""), | |
body: content, | |
hostType: "write", | |
callback: callback | |
}) | |
}, | |
addObjects: function(objects, callback) { | |
var isArray = require(46), | |
usage = "Usage: index.addObjects(arrayOfObjects[, callback])"; | |
if (!isArray(objects)) throw new Error(usage); | |
for (var indexObj = this, postObj = { | |
requests: [] | |
}, i = 0; i < objects.length; ++i) { | |
var request = { | |
action: "addObject", | |
body: objects[i] | |
}; | |
postObj.requests.push(request) | |
} | |
return this.as._jsonRequest({ | |
method: "POST", | |
url: "/1/indexes/" + encodeURIComponent(indexObj.indexName) + "/batch", | |
body: postObj, | |
hostType: "write", | |
callback: callback | |
}) | |
}, | |
getObject: function(objectID, attrs, callback) { | |
var indexObj = this; | |
(1 === arguments.length || "function" == typeof attrs) && (callback = attrs, attrs = void 0); | |
var params = ""; | |
if (void 0 !== attrs) { | |
params = "?attributes="; | |
for (var i = 0; i < attrs.length; ++i) 0 !== i && (params += ","), params += attrs[i] | |
} | |
return this.as._jsonRequest({ | |
method: "GET", | |
url: "/1/indexes/" + encodeURIComponent(indexObj.indexName) + "/" + encodeURIComponent(objectID) + params, | |
hostType: "read", | |
callback: callback | |
}) | |
}, | |
getObjects: function(objectIDs, attributesToRetrieve, callback) { | |
var isArray = require(46), | |
usage = "Usage: index.getObjects(arrayOfObjectIDs[, callback])"; | |
if (!isArray(objectIDs)) throw new Error(usage); | |
var indexObj = this; | |
(1 === arguments.length || "function" == typeof attributesToRetrieve) && (callback = attributesToRetrieve, attributesToRetrieve = void 0); | |
var body = { | |
requests: map(objectIDs, function(objectID) { | |
var request = { | |
indexName: indexObj.indexName, | |
objectID: objectID | |
}; | |
return attributesToRetrieve && (request.attributesToRetrieve = attributesToRetrieve.join(",")), request | |
}) | |
}; | |
return this.as._jsonRequest({ | |
method: "POST", | |
url: "/1/indexes/*/objects", | |
hostType: "read", | |
body: body, | |
callback: callback | |
}) | |
}, | |
partialUpdateObject: function(partialObject, callback) { | |
var indexObj = this; | |
return this.as._jsonRequest({ | |
method: "POST", | |
url: "/1/indexes/" + encodeURIComponent(indexObj.indexName) + "/" + encodeURIComponent(partialObject.objectID) + "/partial", | |
body: partialObject, | |
hostType: "write", | |
callback: callback | |
}) | |
}, | |
partialUpdateObjects: function(objects, callback) { | |
var isArray = require(46), | |
usage = "Usage: index.partialUpdateObjects(arrayOfObjects[, callback])"; | |
if (!isArray(objects)) throw new Error(usage); | |
for (var indexObj = this, postObj = { | |
requests: [] | |
}, i = 0; i < objects.length; ++i) { | |
var request = { | |
action: "partialUpdateObject", | |
objectID: objects[i].objectID, | |
body: objects[i] | |
}; | |
postObj.requests.push(request) | |
} | |
return this.as._jsonRequest({ | |
method: "POST", | |
url: "/1/indexes/" + encodeURIComponent(indexObj.indexName) + "/batch", | |
body: postObj, | |
hostType: "write", | |
callback: callback | |
}) | |
}, | |
saveObject: function(object, callback) { | |
var indexObj = this; | |
return this.as._jsonRequest({ | |
method: "PUT", | |
url: "/1/indexes/" + encodeURIComponent(indexObj.indexName) + "/" + encodeURIComponent(object.objectID), | |
body: object, | |
hostType: "write", | |
callback: callback | |
}) | |
}, | |
saveObjects: function(objects, callback) { | |
var isArray = require(46), | |
usage = "Usage: index.saveObjects(arrayOfObjects[, callback])"; | |
if (!isArray(objects)) throw new Error(usage); | |
for (var indexObj = this, postObj = { | |
requests: [] | |
}, i = 0; i < objects.length; ++i) { | |
var request = { | |
action: "updateObject", | |
objectID: objects[i].objectID, | |
body: objects[i] | |
}; | |
postObj.requests.push(request) | |
} | |
return this.as._jsonRequest({ | |
method: "POST", | |
url: "/1/indexes/" + encodeURIComponent(indexObj.indexName) + "/batch", | |
body: postObj, | |
hostType: "write", | |
callback: callback | |
}) | |
}, | |
deleteObject: function(objectID, callback) { | |
if ("function" == typeof objectID || "string" != typeof objectID && "number" != typeof objectID) { | |
var err = new errors.AlgoliaSearchError("Cannot delete an object without an objectID"); | |
if (callback = objectID, "function" == typeof callback) return callback(err); | |
return this.as._promise.reject(err) | |
} | |
var indexObj = this; | |
return this.as._jsonRequest({ | |
method: "DELETE", | |
url: "/1/indexes/" + encodeURIComponent(indexObj.indexName) + "/" + encodeURIComponent(objectID), | |
hostType: "write", | |
callback: callback | |
}) | |
}, | |
deleteObjects: function(objectIDs, callback) { | |
var isArray = require(46), | |
usage = "Usage: index.deleteObjects(arrayOfObjectIDs[, callback])"; | |
if (!isArray(objectIDs)) throw new Error(usage); | |
var indexObj = this, | |
postObj = { | |
requests: map(objectIDs, function(objectID) { | |
return { | |
action: "deleteObject", | |
objectID: objectID, | |
body: { | |
objectID: objectID | |
} | |
} | |
}) | |
}; | |
return this.as._jsonRequest({ | |
method: "POST", | |
url: "/1/indexes/" + encodeURIComponent(indexObj.indexName) + "/batch", | |
body: postObj, | |
hostType: "write", | |
callback: callback | |
}) | |
}, | |
deleteByQuery: function(query, params, callback) { | |
var clone = require(43), | |
indexObj = this, | |
client = indexObj.as; | |
1 === arguments.length || "function" == typeof params ? (callback = params, params = {}) : params = clone(params), params.attributesToRetrieve = "objectID", params.hitsPerPage = 1e3, params.distinct = !1, this.clearCache(); | |
var promise = this.search(query, params).then(stopOrDelete); | |
function stopOrDelete(searchContent) { | |
if (0 === searchContent.nbHits) return searchContent; | |
var objectIDs = map(searchContent.hits, function(object) { | |
return object.objectID | |
}); | |
return indexObj.deleteObjects(objectIDs).then(waitTask).then(doDeleteByQuery) | |
} | |
function waitTask(deleteObjectsContent) { | |
return indexObj.waitTask(deleteObjectsContent.taskID) | |
} | |
function doDeleteByQuery() { | |
return indexObj.deleteByQuery(query, params) | |
} | |
if (!callback) return promise; | |
promise.then(success, failure); | |
function success() { | |
exitPromise(function() { | |
callback(null) | |
}, client._setTimeout || setTimeout) | |
} | |
function failure(err) { | |
exitPromise(function() { | |
callback(err) | |
}, client._setTimeout || setTimeout) | |
} | |
}, | |
search: buildSearchMethod("query"), | |
similarSearch: buildSearchMethod("similarQuery"), | |
browse: function(query, queryParameters, callback) { | |
var page, hitsPerPage, merge = require(55), | |
indexObj = this; | |
0 === arguments.length || 1 === arguments.length && "function" == typeof arguments[0] ? (page = 0, callback = arguments[0], query = void 0) : "number" == typeof arguments[0] ? (page = arguments[0], "number" == typeof arguments[1] ? hitsPerPage = arguments[1] : "function" == typeof arguments[1] && (callback = arguments[1], hitsPerPage = void 0), query = void 0, queryParameters = void 0) : "object" == typeof arguments[0] ? ("function" == typeof arguments[1] && (callback = arguments[1]), queryParameters = arguments[0], query = void 0) : "string" == typeof arguments[0] && "function" == typeof arguments[1] && (callback = arguments[1], queryParameters = void 0), queryParameters = merge({}, queryParameters || {}, { | |
page: page, | |
hitsPerPage: hitsPerPage, | |
query: query | |
}); | |
var params = this.as._getSearchParams(queryParameters, ""); | |
return this.as._jsonRequest({ | |
method: "GET", | |
url: "/1/indexes/" + encodeURIComponent(indexObj.indexName) + "/browse?" + params, | |
hostType: "read", | |
callback: callback | |
}) | |
}, | |
browseFrom: function(cursor, callback) { | |
return t |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment