praxis 0.16.1 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (399) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +0 -1
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +2 -1
  5. data/CHANGELOG.md +41 -0
  6. data/CONTRIBUTING.md +3 -0
  7. data/lib/api_browser/Gruntfile.js +20 -4
  8. data/lib/api_browser/app/bower_components/angular-mocks/.bower.json +6 -6
  9. data/lib/api_browser/app/bower_components/angular-mocks/README.md +11 -5
  10. data/lib/api_browser/app/bower_components/angular-mocks/angular-mocks.js +475 -216
  11. data/lib/api_browser/app/bower_components/angular-mocks/bower.json +2 -2
  12. data/lib/api_browser/app/bower_components/angular-mocks/ngAnimateMock.js +2 -0
  13. data/lib/api_browser/app/bower_components/angular-mocks/ngMock.js +2 -0
  14. data/lib/api_browser/app/bower_components/angular-mocks/ngMockE2E.js +2 -0
  15. data/lib/api_browser/app/bower_components/angular-mocks/package.json +1 -1
  16. data/lib/api_browser/app/bower_components/angular-sanitize/.bower.json +8 -8
  17. data/lib/api_browser/app/bower_components/angular-sanitize/README.md +19 -5
  18. data/lib/api_browser/app/bower_components/angular-sanitize/angular-sanitize.js +186 -127
  19. data/lib/api_browser/app/bower_components/angular-sanitize/angular-sanitize.min.js +12 -10
  20. data/lib/api_browser/app/bower_components/angular-sanitize/angular-sanitize.min.js.map +3 -3
  21. data/lib/api_browser/app/bower_components/angular-sanitize/bower.json +3 -2
  22. data/lib/api_browser/app/bower_components/angular-sanitize/index.js +2 -0
  23. data/lib/api_browser/app/bower_components/angular-sanitize/package.json +26 -0
  24. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/.bower.json +15 -8
  25. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/bower.json +11 -3
  26. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap-csp.css +6 -0
  27. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap-tpls.js +1177 -453
  28. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap-tpls.min.js +4 -4
  29. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap.js +1066 -404
  30. data/lib/api_browser/app/bower_components/angular-ui-bootstrap-bower/ui-bootstrap.min.js +3 -3
  31. data/lib/api_browser/app/bower_components/angular-ui-router/.bower.json +5 -6
  32. data/lib/api_browser/app/bower_components/angular-ui-router/CHANGELOG.md +208 -3
  33. data/lib/api_browser/app/bower_components/angular-ui-router/CONTRIBUTING.md +65 -0
  34. data/lib/api_browser/app/bower_components/angular-ui-router/LICENSE +1 -1
  35. data/lib/api_browser/app/bower_components/angular-ui-router/README.md +36 -71
  36. data/lib/api_browser/app/bower_components/angular-ui-router/api/angular-ui-router.d.ts +126 -0
  37. data/lib/api_browser/app/bower_components/angular-ui-router/bower.json +1 -1
  38. data/lib/api_browser/app/bower_components/angular-ui-router/release/angular-ui-router.js +1902 -755
  39. data/lib/api_browser/app/bower_components/angular-ui-router/release/angular-ui-router.min.js +2 -2
  40. data/lib/api_browser/app/bower_components/angular-ui-router/src/common.js +69 -23
  41. data/lib/api_browser/app/bower_components/angular-ui-router/src/resolve.js +15 -5
  42. data/lib/api_browser/app/bower_components/angular-ui-router/src/state.js +556 -295
  43. data/lib/api_browser/app/bower_components/angular-ui-router/src/stateDirectives.js +101 -42
  44. data/lib/api_browser/app/bower_components/angular-ui-router/src/stateFilters.js +6 -2
  45. data/lib/api_browser/app/bower_components/angular-ui-router/src/templateFactory.js +2 -2
  46. data/lib/api_browser/app/bower_components/angular-ui-router/src/urlMatcherFactory.js +822 -97
  47. data/lib/api_browser/app/bower_components/angular-ui-router/src/urlRouter.js +274 -120
  48. data/lib/api_browser/app/bower_components/angular-ui-router/src/viewDirective.js +33 -20
  49. data/lib/api_browser/app/bower_components/angular-ui-router/src/viewScroll.js +1 -1
  50. data/lib/api_browser/app/bower_components/angular/.bower.json +5 -5
  51. data/lib/api_browser/app/bower_components/angular/README.md +2 -5
  52. data/lib/api_browser/app/bower_components/angular/angular-csp.css +5 -8
  53. data/lib/api_browser/app/bower_components/angular/angular.js +12975 -6996
  54. data/lib/api_browser/app/bower_components/angular/angular.min.js +285 -213
  55. data/lib/api_browser/app/bower_components/angular/angular.min.js.gzip +0 -0
  56. data/lib/api_browser/app/bower_components/angular/angular.min.js.map +3 -3
  57. data/lib/api_browser/app/bower_components/angular/bower.json +1 -1
  58. data/lib/api_browser/app/bower_components/angular/index.js +2 -0
  59. data/lib/api_browser/app/bower_components/angular/package.json +2 -2
  60. data/lib/api_browser/app/bower_components/bootstrap-sass/.bower.json +31 -16
  61. data/lib/api_browser/app/bower_components/bootstrap-sass/CHANGELOG.md +108 -0
  62. data/lib/api_browser/app/bower_components/bootstrap-sass/CONTRIBUTING.md +55 -37
  63. data/lib/api_browser/app/bower_components/bootstrap-sass/README.md +147 -206
  64. data/lib/api_browser/app/bower_components/bootstrap-sass/bower.json +19 -8
  65. data/lib/api_browser/app/bower_components/bootstrap-sass/{dist/fonts → vendor/assets/fonts/bootstrap}/glyphicons-halflings-regular.eot +0 -0
  66. data/lib/api_browser/app/bower_components/bootstrap-sass/{dist/fonts → vendor/assets/fonts/bootstrap}/glyphicons-halflings-regular.svg +0 -0
  67. data/lib/api_browser/app/bower_components/bootstrap-sass/{dist/fonts → vendor/assets/fonts/bootstrap}/glyphicons-halflings-regular.ttf +0 -0
  68. data/lib/api_browser/app/bower_components/bootstrap-sass/{dist/fonts → vendor/assets/fonts/bootstrap}/glyphicons-halflings-regular.woff +0 -0
  69. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/javascripts/bootstrap.js +12 -0
  70. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/affix.js +1 -1
  71. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/alert.js +1 -1
  72. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/button.js +11 -5
  73. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/carousel.js +5 -5
  74. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/collapse.js +1 -1
  75. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/dropdown.js +5 -5
  76. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/modal.js +1 -1
  77. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/popover.js +1 -1
  78. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/scrollspy.js +2 -2
  79. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/tab.js +1 -1
  80. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/tooltip.js +1 -1
  81. data/lib/api_browser/app/bower_components/bootstrap-sass/{js → vendor/assets/javascripts/bootstrap}/transition.js +1 -1
  82. data/lib/api_browser/app/bower_components/bootstrap-sass/vendor/assets/stylesheets/bootstrap.scss +1 -0
  83. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_alerts.scss +0 -0
  84. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_badges.scss +6 -6
  85. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_breadcrumbs.scss +0 -0
  86. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_button-groups.scss +7 -33
  87. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_buttons.scss +2 -5
  88. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_carousel.scss +1 -0
  89. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_close.scss +0 -0
  90. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_code.scss +0 -0
  91. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_component-animations.scss +0 -0
  92. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_dropdowns.scss +3 -8
  93. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_forms.scss +11 -0
  94. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_glyphicons.scss +5 -5
  95. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_grid.scss +12 -26
  96. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_input-groups.scss +1 -1
  97. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_jumbotron.scss +8 -2
  98. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_labels.scss +6 -0
  99. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_list-group.scss +0 -0
  100. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_media.scss +0 -0
  101. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_mixins.scss +38 -51
  102. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_modals.scss +2 -5
  103. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_navbar.scss +41 -53
  104. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_navs.scss +0 -20
  105. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_normalize.scss +0 -0
  106. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_pager.scss +0 -0
  107. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_pagination.scss +0 -0
  108. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_panels.scss +11 -1
  109. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_popovers.scss +0 -0
  110. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_print.scss +0 -0
  111. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_progress-bars.scss +0 -12
  112. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_responsive-utilities.scss +0 -0
  113. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_scaffolding.scss +0 -0
  114. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_tables.scss +5 -18
  115. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_theme.scss +2 -2
  116. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_thumbnails.scss +9 -3
  117. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_tooltip.scss +0 -0
  118. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_type.scss +54 -52
  119. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_utilities.scss +0 -0
  120. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_variables.scss +20 -11
  121. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/_wells.scss +0 -0
  122. data/lib/api_browser/app/bower_components/bootstrap-sass/{lib → vendor/assets/stylesheets/bootstrap}/bootstrap.scss +0 -0
  123. data/lib/api_browser/app/bower_components/lodash/.bower.json +9 -13
  124. data/lib/api_browser/app/bower_components/lodash/LICENSE.txt +3 -3
  125. data/lib/api_browser/app/bower_components/lodash/bower.json +4 -7
  126. data/lib/api_browser/app/bower_components/lodash/lodash.js +12235 -0
  127. data/lib/api_browser/app/bower_components/lodash/lodash.min.js +98 -0
  128. data/lib/api_browser/app/index.html +0 -1
  129. data/lib/api_browser/app/js/app.js +2 -5
  130. data/lib/api_browser/app/js/controllers/action.js +21 -37
  131. data/lib/api_browser/app/js/controllers/controller.js +23 -1
  132. data/lib/api_browser/app/js/controllers/menu.js +46 -14
  133. data/lib/api_browser/app/js/controllers/type.js +2 -9
  134. data/lib/api_browser/app/js/directives/attribute_description.js +15 -5
  135. data/lib/api_browser/app/js/directives/attribute_table.js +6 -6
  136. data/lib/api_browser/app/js/directives/fixed_if_fits.js +20 -0
  137. data/lib/api_browser/app/js/directives/no_container.js +6 -6
  138. data/lib/api_browser/app/js/directives/type_placeholder.js +21 -0
  139. data/lib/api_browser/app/js/factories/Configuration.js +13 -0
  140. data/lib/api_browser/app/js/factories/Documentation.js +0 -3
  141. data/lib/api_browser/app/js/factories/normalize_attributes.js +19 -0
  142. data/lib/api_browser/app/js/factories/template_for.js +113 -0
  143. data/lib/api_browser/app/sass/modules/_body.scss +26 -4
  144. data/lib/api_browser/app/sass/modules/_sidebar.scss +68 -1
  145. data/lib/api_browser/app/sass/praxis.scss +1 -5
  146. data/lib/api_browser/app/sass/variables/_bootstrap-variables.scss +13 -4
  147. data/lib/api_browser/app/views/action.html +13 -17
  148. data/lib/api_browser/app/views/controller.html +32 -4
  149. data/lib/api_browser/app/views/directives/attribute_description.html +1 -1
  150. data/lib/api_browser/app/views/directives/attribute_description/{_default.html → default.html} +0 -0
  151. data/lib/api_browser/app/views/directives/attribute_description/example.html +13 -0
  152. data/lib/api_browser/app/views/directives/attribute_description/headers.html +8 -0
  153. data/lib/api_browser/app/views/directives/attribute_description/member_options.html +4 -0
  154. data/lib/api_browser/app/views/directives/attribute_description/values.html +14 -0
  155. data/lib/api_browser/app/views/directives/attribute_table.html +2 -2
  156. data/lib/api_browser/app/views/home.html +1 -3
  157. data/lib/api_browser/app/views/layout.html +3 -36
  158. data/lib/api_browser/app/views/menu.html +45 -0
  159. data/lib/api_browser/app/views/navbar.html +1 -1
  160. data/lib/api_browser/app/views/type.html +2 -2
  161. data/lib/api_browser/app/views/type/{_details.html → details.html} +6 -6
  162. data/lib/api_browser/app/views/types/embedded/default.html +10 -0
  163. data/lib/api_browser/app/views/types/embedded/links.html +11 -0
  164. data/lib/api_browser/app/views/types/embedded/struct.html +2 -0
  165. data/lib/api_browser/app/views/types/label/link.html +1 -0
  166. data/lib/api_browser/app/views/types/label/primitive.html +1 -0
  167. data/lib/api_browser/app/views/types/label/primitive_collection.html +1 -0
  168. data/lib/api_browser/app/views/types/label/type.html +1 -0
  169. data/lib/api_browser/app/views/types/label/type_collection.html +1 -0
  170. data/lib/api_browser/app/views/{directives/request_body/_default.html → types/standalone/default.html} +1 -1
  171. data/lib/api_browser/app/views/types/standalone/struct.html +1 -0
  172. data/lib/api_browser/bower.json +9 -9
  173. data/lib/api_browser/package.json +1 -1
  174. data/lib/praxis.rb +10 -4
  175. data/lib/praxis/action_definition.rb +16 -4
  176. data/lib/praxis/action_definition/headers_dsl_compiler.rb +5 -2
  177. data/lib/praxis/api_definition.rb +3 -1
  178. data/lib/praxis/api_general_info.rb +49 -5
  179. data/lib/praxis/application.rb +12 -4
  180. data/lib/praxis/bootloader.rb +1 -0
  181. data/lib/praxis/bootloader_stages/environment.rb +2 -0
  182. data/lib/praxis/bootloader_stages/routing.rb +1 -1
  183. data/lib/praxis/bootloader_stages/subgroup_loader.rb +1 -0
  184. data/lib/praxis/exceptions/validation.rb +7 -0
  185. data/lib/praxis/handlers/plain.rb +16 -0
  186. data/lib/praxis/handlers/xml.rb +4 -4
  187. data/lib/praxis/links.rb +13 -3
  188. data/lib/praxis/media_type_identifier.rb +3 -0
  189. data/lib/praxis/multipart/parser.rb +41 -48
  190. data/lib/praxis/multipart/part.rb +196 -3
  191. data/lib/praxis/request.rb +14 -11
  192. data/lib/praxis/request_stages/request_stage.rb +4 -0
  193. data/lib/praxis/request_stages/response.rb +10 -9
  194. data/lib/praxis/request_stages/validate.rb +1 -7
  195. data/lib/praxis/request_stages/validate_params_and_headers.rb +30 -5
  196. data/lib/praxis/request_stages/validate_payload.rb +14 -5
  197. data/lib/praxis/resource_definition.rb +117 -15
  198. data/lib/praxis/response.rb +6 -5
  199. data/lib/praxis/response_definition.rb +51 -5
  200. data/lib/praxis/responses/http.rb +5 -0
  201. data/lib/praxis/responses/multipart_ok.rb +51 -0
  202. data/lib/praxis/responses/validation_error.rb +7 -7
  203. data/lib/praxis/restful_doc_generator.rb +9 -4
  204. data/lib/praxis/route.rb +3 -2
  205. data/lib/praxis/router.rb +26 -16
  206. data/lib/praxis/router/rack.rb +51 -0
  207. data/lib/praxis/router/simple.rb +146 -0
  208. data/lib/praxis/routing_config.rb +2 -2
  209. data/lib/praxis/trait.rb +1 -1
  210. data/lib/praxis/types/fuzzy_hash.rb +49 -0
  211. data/lib/praxis/types/media_type_common.rb +1 -1
  212. data/lib/praxis/types/multipart.rb +47 -12
  213. data/lib/praxis/types/multipart_array.rb +320 -0
  214. data/lib/praxis/types/multipart_array/part_definition.rb +52 -0
  215. data/lib/praxis/validation_handler.rb +10 -0
  216. data/lib/praxis/version.rb +2 -2
  217. data/praxis.gemspec +3 -3
  218. data/spec/api_browser/directives/type_placeholder_spec.js +134 -0
  219. data/spec/api_browser/factories/normalize_attributes_spec.js +97 -0
  220. data/spec/api_browser/factories/template_for_spec.js +67 -0
  221. data/spec/functional_spec.rb +111 -45
  222. data/spec/praxis/action_definition_spec.rb +31 -7
  223. data/spec/praxis/api_definition_spec.rb +2 -2
  224. data/spec/praxis/api_general_info_spec.rb +25 -0
  225. data/spec/praxis/application_spec.rb +24 -11
  226. data/spec/praxis/handlers/xml_spec.rb +55 -33
  227. data/spec/praxis/links_spec.rb +18 -1
  228. data/spec/praxis/media_type_collection_spec.rb +1 -1
  229. data/spec/praxis/media_type_spec.rb +2 -2
  230. data/spec/praxis/multipart/parser_spec.rb +21 -13
  231. data/spec/praxis/plugins/praxis_mapper_plugin_spec.rb +1 -1
  232. data/spec/praxis/request_spec.rb +52 -24
  233. data/spec/praxis/{request_stages_action_spec.rb → request_stages/action_spec.rb} +1 -1
  234. data/spec/praxis/{request_stage_spec.rb → request_stages/request_stage_spec.rb} +0 -0
  235. data/spec/praxis/{request_stages_validate_spec.rb → request_stages/validate_spec.rb} +1 -1
  236. data/spec/praxis/resource_definition_spec.rb +30 -4
  237. data/spec/praxis/response_definition_spec.rb +60 -19
  238. data/spec/praxis/response_spec.rb +2 -2
  239. data/spec/praxis/responses/validation_error_spec.rb +33 -16
  240. data/spec/praxis/route_spec.rb +4 -2
  241. data/spec/praxis/router_spec.rb +28 -12
  242. data/spec/praxis/routing_config_spec.rb +11 -5
  243. data/spec/praxis/types/collection_spec.rb +1 -1
  244. data/spec/praxis/types/fuzzy_hash_spec.rb +20 -0
  245. data/spec/praxis/types/multipart_array/part_definition_spec.rb +5 -0
  246. data/spec/praxis/types/multipart_array_spec.rb +334 -0
  247. data/spec/praxis/types/multipart_spec.rb +14 -5
  248. data/spec/spec_app/app/controllers/instances.rb +20 -10
  249. data/spec/spec_app/app/controllers/volumes.rb +8 -4
  250. data/spec/spec_app/app/responses/bulk_response.rb +0 -6
  251. data/spec/spec_app/config/environment.rb +13 -0
  252. data/spec/spec_app/design/api.rb +7 -10
  253. data/spec/spec_app/design/media_types/instance.rb +3 -1
  254. data/spec/spec_app/design/resources/instances.rb +50 -41
  255. data/spec/spec_app/design/resources/volume_snapshots.rb +39 -0
  256. data/spec/spec_app/design/resources/volumes.rb +11 -6
  257. data/spec/spec_helper.rb +3 -1
  258. metadata +125 -218
  259. data/lib/api_browser/app/bower_components/angular-ui-router/src/compat.js +0 -146
  260. data/lib/api_browser/app/bower_components/bootstrap-sass/CNAME +0 -1
  261. data/lib/api_browser/app/bower_components/bootstrap-sass/DOCS-LICENSE +0 -319
  262. data/lib/api_browser/app/bower_components/bootstrap-sass/Gemfile +0 -5
  263. data/lib/api_browser/app/bower_components/bootstrap-sass/Gemfile.lock +0 -14
  264. data/lib/api_browser/app/bower_components/bootstrap-sass/Gruntfile.js +0 -244
  265. data/lib/api_browser/app/bower_components/bootstrap-sass/LICENSE +0 -176
  266. data/lib/api_browser/app/bower_components/bootstrap-sass/LICENSE-MIT +0 -21
  267. data/lib/api_browser/app/bower_components/bootstrap-sass/Rakefile +0 -44
  268. data/lib/api_browser/app/bower_components/bootstrap-sass/_config.yml +0 -25
  269. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/ads.html +0 -1
  270. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/footer.html +0 -34
  271. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/header.html +0 -42
  272. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-about.html +0 -12
  273. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-components.html +0 -137
  274. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-css.html +0 -99
  275. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-customize.html +0 -40
  276. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-getting-started.html +0 -44
  277. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-javascript.html +0 -88
  278. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/nav-main.html +0 -37
  279. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/old-bs-docs.html +0 -8
  280. data/lib/api_browser/app/bower_components/bootstrap-sass/_includes/social-buttons.html +0 -16
  281. data/lib/api_browser/app/bower_components/bootstrap-sass/_layouts/default.html +0 -79
  282. data/lib/api_browser/app/bower_components/bootstrap-sass/_layouts/home.html +0 -47
  283. data/lib/api_browser/app/bower_components/bootstrap-sass/about.html +0 -93
  284. data/lib/api_browser/app/bower_components/bootstrap-sass/browserstack.json +0 -37
  285. data/lib/api_browser/app/bower_components/bootstrap-sass/components.html +0 -3689
  286. data/lib/api_browser/app/bower_components/bootstrap-sass/composer.json +0 -28
  287. data/lib/api_browser/app/bower_components/bootstrap-sass/css.html +0 -2674
  288. data/lib/api_browser/app/bower_components/bootstrap-sass/customize.html +0 -1715
  289. data/lib/api_browser/app/bower_components/bootstrap-sass/dist/css/bootstrap-theme.css +0 -427
  290. data/lib/api_browser/app/bower_components/bootstrap-sass/dist/css/bootstrap-theme.min.css +0 -1
  291. data/lib/api_browser/app/bower_components/bootstrap-sass/dist/css/bootstrap.css +0 -6350
  292. data/lib/api_browser/app/bower_components/bootstrap-sass/dist/css/bootstrap.min.css +0 -1
  293. data/lib/api_browser/app/bower_components/bootstrap-sass/dist/js/bootstrap.js +0 -2002
  294. data/lib/api_browser/app/bower_components/bootstrap-sass/dist/js/bootstrap.min.js +0 -9
  295. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/css/docs.css +0 -1195
  296. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/css/pygments-manni.css +0 -66
  297. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/ico/apple-touch-icon-144-precomposed.png +0 -0
  298. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/ico/favicon.png +0 -0
  299. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/application.js +0 -103
  300. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/customizer.js +0 -332
  301. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/filesaver.js +0 -169
  302. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/holder.js +0 -404
  303. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/ie8-responsive-file-warning.js +0 -12
  304. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/jszip.js +0 -1467
  305. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/less.js +0 -9
  306. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/raw-files.js +0 -3
  307. data/lib/api_browser/app/bower_components/bootstrap-sass/docs-assets/js/uglify.js +0 -14
  308. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/carousel/carousel.css +0 -148
  309. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/carousel/index.html +0 -206
  310. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/grid/grid.css +0 -28
  311. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/grid/index.html +0 -148
  312. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/jumbotron-narrow/index.html +0 -82
  313. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/jumbotron-narrow/jumbotron-narrow.css +0 -79
  314. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/jumbotron/index.html +0 -99
  315. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/jumbotron/jumbotron.css +0 -5
  316. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/justified-nav/index.html +0 -83
  317. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/justified-nav/justified-nav.css +0 -88
  318. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar-fixed-top/index.html +0 -91
  319. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar-fixed-top/navbar-fixed-top.css +0 -4
  320. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar-static-top/index.html +0 -92
  321. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar-static-top/navbar-static-top.css +0 -7
  322. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar/index.html +0 -88
  323. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/navbar/navbar.css +0 -8
  324. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/non-responsive/index.html +0 -101
  325. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/non-responsive/non-responsive.css +0 -116
  326. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/offcanvas/index.html +0 -130
  327. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/offcanvas/offcanvas.css +0 -50
  328. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/offcanvas/offcanvas.js +0 -5
  329. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/carousel.jpg +0 -0
  330. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/grid.jpg +0 -0
  331. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/jumbotron-narrow.jpg +0 -0
  332. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/jumbotron.jpg +0 -0
  333. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/justified-nav.jpg +0 -0
  334. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/navbar-fixed.jpg +0 -0
  335. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/navbar-static.jpg +0 -0
  336. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/navbar.jpg +0 -0
  337. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/non-responsive.jpg +0 -0
  338. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/offcanvas.jpg +0 -0
  339. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/sign-in.jpg +0 -0
  340. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/starter-template.jpg +0 -0
  341. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/sticky-footer-navbar.jpg +0 -0
  342. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/sticky-footer.jpg +0 -0
  343. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/screenshots/theme.jpg +0 -0
  344. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/signin/index.html +0 -50
  345. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/signin/signin.css +0 -40
  346. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/starter-template/index.html +0 -68
  347. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/starter-template/starter-template.css +0 -7
  348. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/sticky-footer-navbar/index.html +0 -91
  349. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/sticky-footer-navbar/sticky-footer-navbar.css +0 -45
  350. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/sticky-footer/index.html +0 -55
  351. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/sticky-footer/sticky-footer.css +0 -38
  352. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/theme/index.html +0 -384
  353. data/lib/api_browser/app/bower_components/bootstrap-sass/examples/theme/theme.css +0 -14
  354. data/lib/api_browser/app/bower_components/bootstrap-sass/fonts/glyphicons-halflings-regular.eot +0 -0
  355. data/lib/api_browser/app/bower_components/bootstrap-sass/fonts/glyphicons-halflings-regular.svg +0 -229
  356. data/lib/api_browser/app/bower_components/bootstrap-sass/fonts/glyphicons-halflings-regular.ttf +0 -0
  357. data/lib/api_browser/app/bower_components/bootstrap-sass/fonts/glyphicons-halflings-regular.woff +0 -0
  358. data/lib/api_browser/app/bower_components/bootstrap-sass/getting-started.html +0 -1021
  359. data/lib/api_browser/app/bower_components/bootstrap-sass/index.html +0 -16
  360. data/lib/api_browser/app/bower_components/bootstrap-sass/javascript.html +0 -1983
  361. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/index.html +0 -52
  362. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/affix.js +0 -25
  363. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/alert.js +0 -62
  364. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/button.js +0 -116
  365. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/carousel.js +0 -87
  366. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/collapse.js +0 -164
  367. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/dropdown.js +0 -219
  368. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/modal.js +0 -196
  369. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/phantom.js +0 -69
  370. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/popover.js +0 -133
  371. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/scrollspy.js +0 -37
  372. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/tab.js +0 -86
  373. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/tooltip.js +0 -437
  374. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/unit/transition.js +0 -13
  375. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/vendor/jquery.js +0 -6
  376. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/vendor/qunit.css +0 -232
  377. data/lib/api_browser/app/bower_components/bootstrap-sass/js/tests/vendor/qunit.js +0 -1510
  378. data/lib/api_browser/app/bower_components/bootstrap-sass/package.json +0 -40
  379. data/lib/api_browser/app/bower_components/lodash/dist/lodash.compat.js +0 -7157
  380. data/lib/api_browser/app/bower_components/lodash/dist/lodash.compat.min.js +0 -61
  381. data/lib/api_browser/app/bower_components/lodash/dist/lodash.js +0 -6785
  382. data/lib/api_browser/app/bower_components/lodash/dist/lodash.min.js +0 -56
  383. data/lib/api_browser/app/bower_components/lodash/dist/lodash.underscore.js +0 -4979
  384. data/lib/api_browser/app/bower_components/lodash/dist/lodash.underscore.min.js +0 -39
  385. data/lib/api_browser/app/js/directives/attribute_table_row.js +0 -17
  386. data/lib/api_browser/app/js/directives/request_body.js +0 -25
  387. data/lib/api_browser/app/js/directives/request_headers.js +0 -17
  388. data/lib/api_browser/app/js/directives/request_parameters.js +0 -17
  389. data/lib/api_browser/app/js/directives/type_label.js +0 -52
  390. data/lib/api_browser/app/js/factories/PayloadTemplates.js +0 -10
  391. data/lib/api_browser/app/js/factories/TemplateProvider.js +0 -45
  392. data/lib/api_browser/app/js/factories/TypeTemplates.js +0 -11
  393. data/lib/api_browser/app/views/directives/attribute_description/_example.html +0 -13
  394. data/lib/api_browser/app/views/directives/attribute_description/_headers.html +0 -8
  395. data/lib/api_browser/app/views/directives/attribute_table_row/_default.html +0 -10
  396. data/lib/api_browser/app/views/directives/attribute_table_row/_links.html +0 -11
  397. data/lib/api_browser/app/views/directives/attribute_table_row/_struct.html +0 -2
  398. data/lib/api_browser/app/views/directives/request_body/_struct.html +0 -1
  399. data/lib/api_browser/app/views/resource/_actions.html +0 -27
@@ -2,9 +2,9 @@
2
2
  * angular-ui-bootstrap
3
3
  * http://angular-ui.github.io/bootstrap/
4
4
 
5
- * Version: 0.11.0 - 2014-05-01
5
+ * Version: 0.13.0 - 2015-05-02
6
6
  * License: MIT
7
7
  */
8
- angular.module("ui.bootstrap",["ui.bootstrap.tpls","ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.bindHtml","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.dateparser","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dropdown","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.typeahead"]),angular.module("ui.bootstrap.tpls",["template/accordion/accordion-group.html","template/accordion/accordion.html","template/alert/alert.html","template/carousel/carousel.html","template/carousel/slide.html","template/datepicker/datepicker.html","template/datepicker/day.html","template/datepicker/month.html","template/datepicker/popup.html","template/datepicker/year.html","template/modal/backdrop.html","template/modal/window.html","template/pagination/pager.html","template/pagination/pagination.html","template/tooltip/tooltip-html-unsafe-popup.html","template/tooltip/tooltip-popup.html","template/popover/popover.html","template/progressbar/bar.html","template/progressbar/progress.html","template/progressbar/progressbar.html","template/rating/rating.html","template/tabs/tab.html","template/tabs/tabset.html","template/timepicker/timepicker.html","template/typeahead/typeahead-match.html","template/typeahead/typeahead-popup.html"]),angular.module("ui.bootstrap.transition",[]).factory("$transition",["$q","$timeout","$rootScope",function(a,b,c){function d(a){for(var b in a)if(void 0!==f.style[b])return a[b]}var e=function(d,f,g){g=g||{};var h=a.defer(),i=e[g.animation?"animationEndEventName":"transitionEndEventName"],j=function(){c.$apply(function(){d.unbind(i,j),h.resolve(d)})};return i&&d.bind(i,j),b(function(){angular.isString(f)?d.addClass(f):angular.isFunction(f)?f(d):angular.isObject(f)&&d.css(f),i||h.resolve(d)}),h.promise.cancel=function(){i&&d.unbind(i,j),h.reject("Transition cancelled")},h.promise},f=document.createElement("trans"),g={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",transition:"transitionend"},h={WebkitTransition:"webkitAnimationEnd",MozTransition:"animationend",OTransition:"oAnimationEnd",transition:"animationend"};return e.transitionEndEventName=d(g),e.animationEndEventName=d(h),e}]),angular.module("ui.bootstrap.collapse",["ui.bootstrap.transition"]).directive("collapse",["$transition",function(a){return{link:function(b,c,d){function e(b){function d(){j===e&&(j=void 0)}var e=a(c,b);return j&&j.cancel(),j=e,e.then(d,d),e}function f(){k?(k=!1,g()):(c.removeClass("collapse").addClass("collapsing"),e({height:c[0].scrollHeight+"px"}).then(g))}function g(){c.removeClass("collapsing"),c.addClass("collapse in"),c.css({height:"auto"})}function h(){if(k)k=!1,i(),c.css({height:0});else{c.css({height:c[0].scrollHeight+"px"});{c[0].offsetWidth}c.removeClass("collapse in").addClass("collapsing"),e({height:0}).then(i)}}function i(){c.removeClass("collapsing"),c.addClass("collapse")}var j,k=!0;b.$watch(d.collapse,function(a){a?h():f()})}}}]),angular.module("ui.bootstrap.accordion",["ui.bootstrap.collapse"]).constant("accordionConfig",{closeOthers:!0}).controller("AccordionController",["$scope","$attrs","accordionConfig",function(a,b,c){this.groups=[],this.closeOthers=function(d){var e=angular.isDefined(b.closeOthers)?a.$eval(b.closeOthers):c.closeOthers;e&&angular.forEach(this.groups,function(a){a!==d&&(a.isOpen=!1)})},this.addGroup=function(a){var b=this;this.groups.push(a),a.$on("$destroy",function(){b.removeGroup(a)})},this.removeGroup=function(a){var b=this.groups.indexOf(a);-1!==b&&this.groups.splice(b,1)}}]).directive("accordion",function(){return{restrict:"EA",controller:"AccordionController",transclude:!0,replace:!1,templateUrl:"template/accordion/accordion.html"}}).directive("accordionGroup",function(){return{require:"^accordion",restrict:"EA",transclude:!0,replace:!0,templateUrl:"template/accordion/accordion-group.html",scope:{heading:"@",isOpen:"=?",isDisabled:"=?"},controller:function(){this.setHeading=function(a){this.heading=a}},link:function(a,b,c,d){d.addGroup(a),a.$watch("isOpen",function(b){b&&d.closeOthers(a)}),a.toggleOpen=function(){a.isDisabled||(a.isOpen=!a.isOpen)}}}}).directive("accordionHeading",function(){return{restrict:"EA",transclude:!0,template:"",replace:!0,require:"^accordionGroup",link:function(a,b,c,d,e){d.setHeading(e(a,function(){}))}}}).directive("accordionTransclude",function(){return{require:"^accordionGroup",link:function(a,b,c,d){a.$watch(function(){return d[c.accordionTransclude]},function(a){a&&(b.html(""),b.append(a))})}}}),angular.module("ui.bootstrap.alert",[]).controller("AlertController",["$scope","$attrs",function(a,b){a.closeable="close"in b}]).directive("alert",function(){return{restrict:"EA",controller:"AlertController",templateUrl:"template/alert/alert.html",transclude:!0,replace:!0,scope:{type:"@",close:"&"}}}),angular.module("ui.bootstrap.bindHtml",[]).directive("bindHtmlUnsafe",function(){return function(a,b,c){b.addClass("ng-binding").data("$binding",c.bindHtmlUnsafe),a.$watch(c.bindHtmlUnsafe,function(a){b.html(a||"")})}}),angular.module("ui.bootstrap.buttons",[]).constant("buttonConfig",{activeClass:"active",toggleEvent:"click"}).controller("ButtonsController",["buttonConfig",function(a){this.activeClass=a.activeClass||"active",this.toggleEvent=a.toggleEvent||"click"}]).directive("btnRadio",function(){return{require:["btnRadio","ngModel"],controller:"ButtonsController",link:function(a,b,c,d){var e=d[0],f=d[1];f.$render=function(){b.toggleClass(e.activeClass,angular.equals(f.$modelValue,a.$eval(c.btnRadio)))},b.bind(e.toggleEvent,function(){var d=b.hasClass(e.activeClass);(!d||angular.isDefined(c.uncheckable))&&a.$apply(function(){f.$setViewValue(d?null:a.$eval(c.btnRadio)),f.$render()})})}}}).directive("btnCheckbox",function(){return{require:["btnCheckbox","ngModel"],controller:"ButtonsController",link:function(a,b,c,d){function e(){return g(c.btnCheckboxTrue,!0)}function f(){return g(c.btnCheckboxFalse,!1)}function g(b,c){var d=a.$eval(b);return angular.isDefined(d)?d:c}var h=d[0],i=d[1];i.$render=function(){b.toggleClass(h.activeClass,angular.equals(i.$modelValue,e()))},b.bind(h.toggleEvent,function(){a.$apply(function(){i.$setViewValue(b.hasClass(h.activeClass)?f():e()),i.$render()})})}}}),angular.module("ui.bootstrap.carousel",["ui.bootstrap.transition"]).controller("CarouselController",["$scope","$timeout","$transition",function(a,b,c){function d(){e();var c=+a.interval;!isNaN(c)&&c>=0&&(g=b(f,c))}function e(){g&&(b.cancel(g),g=null)}function f(){h?(a.next(),d()):a.pause()}var g,h,i=this,j=i.slides=a.slides=[],k=-1;i.currentSlide=null;var l=!1;i.select=a.select=function(e,f){function g(){if(!l){if(i.currentSlide&&angular.isString(f)&&!a.noTransition&&e.$element){e.$element.addClass(f);{e.$element[0].offsetWidth}angular.forEach(j,function(a){angular.extend(a,{direction:"",entering:!1,leaving:!1,active:!1})}),angular.extend(e,{direction:f,active:!0,entering:!0}),angular.extend(i.currentSlide||{},{direction:f,leaving:!0}),a.$currentTransition=c(e.$element,{}),function(b,c){a.$currentTransition.then(function(){h(b,c)},function(){h(b,c)})}(e,i.currentSlide)}else h(e,i.currentSlide);i.currentSlide=e,k=m,d()}}function h(b,c){angular.extend(b,{direction:"",active:!0,leaving:!1,entering:!1}),angular.extend(c||{},{direction:"",active:!1,leaving:!1,entering:!1}),a.$currentTransition=null}var m=j.indexOf(e);void 0===f&&(f=m>k?"next":"prev"),e&&e!==i.currentSlide&&(a.$currentTransition?(a.$currentTransition.cancel(),b(g)):g())},a.$on("$destroy",function(){l=!0}),i.indexOfSlide=function(a){return j.indexOf(a)},a.next=function(){var b=(k+1)%j.length;return a.$currentTransition?void 0:i.select(j[b],"next")},a.prev=function(){var b=0>k-1?j.length-1:k-1;return a.$currentTransition?void 0:i.select(j[b],"prev")},a.isActive=function(a){return i.currentSlide===a},a.$watch("interval",d),a.$on("$destroy",e),a.play=function(){h||(h=!0,d())},a.pause=function(){a.noPause||(h=!1,e())},i.addSlide=function(b,c){b.$element=c,j.push(b),1===j.length||b.active?(i.select(j[j.length-1]),1==j.length&&a.play()):b.active=!1},i.removeSlide=function(a){var b=j.indexOf(a);j.splice(b,1),j.length>0&&a.active?i.select(b>=j.length?j[b-1]:j[b]):k>b&&k--}}]).directive("carousel",[function(){return{restrict:"EA",transclude:!0,replace:!0,controller:"CarouselController",require:"carousel",templateUrl:"template/carousel/carousel.html",scope:{interval:"=",noTransition:"=",noPause:"="}}}]).directive("slide",function(){return{require:"^carousel",restrict:"EA",transclude:!0,replace:!0,templateUrl:"template/carousel/slide.html",scope:{active:"=?"},link:function(a,b,c,d){d.addSlide(a,b),a.$on("$destroy",function(){d.removeSlide(a)}),a.$watch("active",function(b){b&&d.select(a)})}}}),angular.module("ui.bootstrap.dateparser",[]).service("dateParser",["$locale","orderByFilter",function(a,b){function c(a,b,c){return 1===b&&c>28?29===c&&(a%4===0&&a%100!==0||a%400===0):3===b||5===b||8===b||10===b?31>c:!0}this.parsers={};var d={yyyy:{regex:"\\d{4}",apply:function(a){this.year=+a}},yy:{regex:"\\d{2}",apply:function(a){this.year=+a+2e3}},y:{regex:"\\d{1,4}",apply:function(a){this.year=+a}},MMMM:{regex:a.DATETIME_FORMATS.MONTH.join("|"),apply:function(b){this.month=a.DATETIME_FORMATS.MONTH.indexOf(b)}},MMM:{regex:a.DATETIME_FORMATS.SHORTMONTH.join("|"),apply:function(b){this.month=a.DATETIME_FORMATS.SHORTMONTH.indexOf(b)}},MM:{regex:"0[1-9]|1[0-2]",apply:function(a){this.month=a-1}},M:{regex:"[1-9]|1[0-2]",apply:function(a){this.month=a-1}},dd:{regex:"[0-2][0-9]{1}|3[0-1]{1}",apply:function(a){this.date=+a}},d:{regex:"[1-2]?[0-9]{1}|3[0-1]{1}",apply:function(a){this.date=+a}},EEEE:{regex:a.DATETIME_FORMATS.DAY.join("|")},EEE:{regex:a.DATETIME_FORMATS.SHORTDAY.join("|")}};this.createParser=function(a){var c=[],e=a.split("");return angular.forEach(d,function(b,d){var f=a.indexOf(d);if(f>-1){a=a.split(""),e[f]="("+b.regex+")",a[f]="$";for(var g=f+1,h=f+d.length;h>g;g++)e[g]="",a[g]="$";a=a.join(""),c.push({index:f,apply:b.apply})}}),{regex:new RegExp("^"+e.join("")+"$"),map:b(c,"index")}},this.parse=function(b,d){if(!angular.isString(b))return b;d=a.DATETIME_FORMATS[d]||d,this.parsers[d]||(this.parsers[d]=this.createParser(d));var e=this.parsers[d],f=e.regex,g=e.map,h=b.match(f);if(h&&h.length){for(var i,j={year:1900,month:0,date:1,hours:0},k=1,l=h.length;l>k;k++){var m=g[k-1];m.apply&&m.apply.call(j,h[k])}return c(j.year,j.month,j.date)&&(i=new Date(j.year,j.month,j.date,j.hours)),i}}}]),angular.module("ui.bootstrap.position",[]).factory("$position",["$document","$window",function(a,b){function c(a,c){return a.currentStyle?a.currentStyle[c]:b.getComputedStyle?b.getComputedStyle(a)[c]:a.style[c]}function d(a){return"static"===(c(a,"position")||"static")}var e=function(b){for(var c=a[0],e=b.offsetParent||c;e&&e!==c&&d(e);)e=e.offsetParent;return e||c};return{position:function(b){var c=this.offset(b),d={top:0,left:0},f=e(b[0]);f!=a[0]&&(d=this.offset(angular.element(f)),d.top+=f.clientTop-f.scrollTop,d.left+=f.clientLeft-f.scrollLeft);var g=b[0].getBoundingClientRect();return{width:g.width||b.prop("offsetWidth"),height:g.height||b.prop("offsetHeight"),top:c.top-d.top,left:c.left-d.left}},offset:function(c){var d=c[0].getBoundingClientRect();return{width:d.width||c.prop("offsetWidth"),height:d.height||c.prop("offsetHeight"),top:d.top+(b.pageYOffset||a[0].documentElement.scrollTop),left:d.left+(b.pageXOffset||a[0].documentElement.scrollLeft)}},positionElements:function(a,b,c,d){var e,f,g,h,i=c.split("-"),j=i[0],k=i[1]||"center";e=d?this.offset(a):this.position(a),f=b.prop("offsetWidth"),g=b.prop("offsetHeight");var l={center:function(){return e.left+e.width/2-f/2},left:function(){return e.left},right:function(){return e.left+e.width}},m={center:function(){return e.top+e.height/2-g/2},top:function(){return e.top},bottom:function(){return e.top+e.height}};switch(j){case"right":h={top:m[k](),left:l[j]()};break;case"left":h={top:m[k](),left:e.left-f};break;case"bottom":h={top:m[j](),left:l[k]()};break;default:h={top:e.top-g,left:l[k]()}}return h}}}]),angular.module("ui.bootstrap.datepicker",["ui.bootstrap.dateparser","ui.bootstrap.position"]).constant("datepickerConfig",{formatDay:"dd",formatMonth:"MMMM",formatYear:"yyyy",formatDayHeader:"EEE",formatDayTitle:"MMMM yyyy",formatMonthTitle:"yyyy",datepickerMode:"day",minMode:"day",maxMode:"year",showWeeks:!0,startingDay:0,yearRange:20,minDate:null,maxDate:null}).controller("DatepickerController",["$scope","$attrs","$parse","$interpolate","$timeout","$log","dateFilter","datepickerConfig",function(a,b,c,d,e,f,g,h){var i=this,j={$setViewValue:angular.noop};this.modes=["day","month","year"],angular.forEach(["formatDay","formatMonth","formatYear","formatDayHeader","formatDayTitle","formatMonthTitle","minMode","maxMode","showWeeks","startingDay","yearRange"],function(c,e){i[c]=angular.isDefined(b[c])?8>e?d(b[c])(a.$parent):a.$parent.$eval(b[c]):h[c]}),angular.forEach(["minDate","maxDate"],function(d){b[d]?a.$parent.$watch(c(b[d]),function(a){i[d]=a?new Date(a):null,i.refreshView()}):i[d]=h[d]?new Date(h[d]):null}),a.datepickerMode=a.datepickerMode||h.datepickerMode,a.uniqueId="datepicker-"+a.$id+"-"+Math.floor(1e4*Math.random()),this.activeDate=angular.isDefined(b.initDate)?a.$parent.$eval(b.initDate):new Date,a.isActive=function(b){return 0===i.compare(b.date,i.activeDate)?(a.activeDateId=b.uid,!0):!1},this.init=function(a){j=a,j.$render=function(){i.render()}},this.render=function(){if(j.$modelValue){var a=new Date(j.$modelValue),b=!isNaN(a);b?this.activeDate=a:f.error('Datepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.'),j.$setValidity("date",b)}this.refreshView()},this.refreshView=function(){if(this.element){this._refreshView();var a=j.$modelValue?new Date(j.$modelValue):null;j.$setValidity("date-disabled",!a||this.element&&!this.isDisabled(a))}},this.createDateObject=function(a,b){var c=j.$modelValue?new Date(j.$modelValue):null;return{date:a,label:g(a,b),selected:c&&0===this.compare(a,c),disabled:this.isDisabled(a),current:0===this.compare(a,new Date)}},this.isDisabled=function(c){return this.minDate&&this.compare(c,this.minDate)<0||this.maxDate&&this.compare(c,this.maxDate)>0||b.dateDisabled&&a.dateDisabled({date:c,mode:a.datepickerMode})},this.split=function(a,b){for(var c=[];a.length>0;)c.push(a.splice(0,b));return c},a.select=function(b){if(a.datepickerMode===i.minMode){var c=j.$modelValue?new Date(j.$modelValue):new Date(0,0,0,0,0,0,0);c.setFullYear(b.getFullYear(),b.getMonth(),b.getDate()),j.$setViewValue(c),j.$render()}else i.activeDate=b,a.datepickerMode=i.modes[i.modes.indexOf(a.datepickerMode)-1]},a.move=function(a){var b=i.activeDate.getFullYear()+a*(i.step.years||0),c=i.activeDate.getMonth()+a*(i.step.months||0);i.activeDate.setFullYear(b,c,1),i.refreshView()},a.toggleMode=function(b){b=b||1,a.datepickerMode===i.maxMode&&1===b||a.datepickerMode===i.minMode&&-1===b||(a.datepickerMode=i.modes[i.modes.indexOf(a.datepickerMode)+b])},a.keys={13:"enter",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down"};var k=function(){e(function(){i.element[0].focus()},0,!1)};a.$on("datepicker.focus",k),a.keydown=function(b){var c=a.keys[b.which];if(c&&!b.shiftKey&&!b.altKey)if(b.preventDefault(),b.stopPropagation(),"enter"===c||"space"===c){if(i.isDisabled(i.activeDate))return;a.select(i.activeDate),k()}else!b.ctrlKey||"up"!==c&&"down"!==c?(i.handleKeyDown(c,b),i.refreshView()):(a.toggleMode("up"===c?1:-1),k())}}]).directive("datepicker",function(){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/datepicker.html",scope:{datepickerMode:"=?",dateDisabled:"&"},require:["datepicker","?^ngModel"],controller:"DatepickerController",link:function(a,b,c,d){var e=d[0],f=d[1];f&&e.init(f)}}}).directive("daypicker",["dateFilter",function(a){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/day.html",require:"^datepicker",link:function(b,c,d,e){function f(a,b){return 1!==b||a%4!==0||a%100===0&&a%400!==0?i[b]:29}function g(a,b){var c=new Array(b),d=new Date(a),e=0;for(d.setHours(12);b>e;)c[e++]=new Date(d),d.setDate(d.getDate()+1);return c}function h(a){var b=new Date(a);b.setDate(b.getDate()+4-(b.getDay()||7));var c=b.getTime();return b.setMonth(0),b.setDate(1),Math.floor(Math.round((c-b)/864e5)/7)+1}b.showWeeks=e.showWeeks,e.step={months:1},e.element=c;var i=[31,28,31,30,31,30,31,31,30,31,30,31];e._refreshView=function(){var c=e.activeDate.getFullYear(),d=e.activeDate.getMonth(),f=new Date(c,d,1),i=e.startingDay-f.getDay(),j=i>0?7-i:-i,k=new Date(f);j>0&&k.setDate(-j+1);for(var l=g(k,42),m=0;42>m;m++)l[m]=angular.extend(e.createDateObject(l[m],e.formatDay),{secondary:l[m].getMonth()!==d,uid:b.uniqueId+"-"+m});b.labels=new Array(7);for(var n=0;7>n;n++)b.labels[n]={abbr:a(l[n].date,e.formatDayHeader),full:a(l[n].date,"EEEE")};if(b.title=a(e.activeDate,e.formatDayTitle),b.rows=e.split(l,7),b.showWeeks){b.weekNumbers=[];for(var o=h(b.rows[0][0].date),p=b.rows.length;b.weekNumbers.push(o++)<p;);}},e.compare=function(a,b){return new Date(a.getFullYear(),a.getMonth(),a.getDate())-new Date(b.getFullYear(),b.getMonth(),b.getDate())},e.handleKeyDown=function(a){var b=e.activeDate.getDate();if("left"===a)b-=1;else if("up"===a)b-=7;else if("right"===a)b+=1;else if("down"===a)b+=7;else if("pageup"===a||"pagedown"===a){var c=e.activeDate.getMonth()+("pageup"===a?-1:1);e.activeDate.setMonth(c,1),b=Math.min(f(e.activeDate.getFullYear(),e.activeDate.getMonth()),b)}else"home"===a?b=1:"end"===a&&(b=f(e.activeDate.getFullYear(),e.activeDate.getMonth()));e.activeDate.setDate(b)},e.refreshView()}}}]).directive("monthpicker",["dateFilter",function(a){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/month.html",require:"^datepicker",link:function(b,c,d,e){e.step={years:1},e.element=c,e._refreshView=function(){for(var c=new Array(12),d=e.activeDate.getFullYear(),f=0;12>f;f++)c[f]=angular.extend(e.createDateObject(new Date(d,f,1),e.formatMonth),{uid:b.uniqueId+"-"+f});b.title=a(e.activeDate,e.formatMonthTitle),b.rows=e.split(c,3)},e.compare=function(a,b){return new Date(a.getFullYear(),a.getMonth())-new Date(b.getFullYear(),b.getMonth())},e.handleKeyDown=function(a){var b=e.activeDate.getMonth();if("left"===a)b-=1;else if("up"===a)b-=3;else if("right"===a)b+=1;else if("down"===a)b+=3;else if("pageup"===a||"pagedown"===a){var c=e.activeDate.getFullYear()+("pageup"===a?-1:1);e.activeDate.setFullYear(c)}else"home"===a?b=0:"end"===a&&(b=11);e.activeDate.setMonth(b)},e.refreshView()}}}]).directive("yearpicker",["dateFilter",function(){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/year.html",require:"^datepicker",link:function(a,b,c,d){function e(a){return parseInt((a-1)/f,10)*f+1}var f=d.yearRange;d.step={years:f},d.element=b,d._refreshView=function(){for(var b=new Array(f),c=0,g=e(d.activeDate.getFullYear());f>c;c++)b[c]=angular.extend(d.createDateObject(new Date(g+c,0,1),d.formatYear),{uid:a.uniqueId+"-"+c});a.title=[b[0].label,b[f-1].label].join(" - "),a.rows=d.split(b,5)},d.compare=function(a,b){return a.getFullYear()-b.getFullYear()},d.handleKeyDown=function(a){var b=d.activeDate.getFullYear();"left"===a?b-=1:"up"===a?b-=5:"right"===a?b+=1:"down"===a?b+=5:"pageup"===a||"pagedown"===a?b+=("pageup"===a?-1:1)*d.step.years:"home"===a?b=e(d.activeDate.getFullYear()):"end"===a&&(b=e(d.activeDate.getFullYear())+f-1),d.activeDate.setFullYear(b)},d.refreshView()}}}]).constant("datepickerPopupConfig",{datepickerPopup:"yyyy-MM-dd",currentText:"Today",clearText:"Clear",closeText:"Done",closeOnDateSelection:!0,appendToBody:!1,showButtonBar:!0}).directive("datepickerPopup",["$compile","$parse","$document","$position","dateFilter","dateParser","datepickerPopupConfig",function(a,b,c,d,e,f,g){return{restrict:"EA",require:"ngModel",scope:{isOpen:"=?",currentText:"@",clearText:"@",closeText:"@",dateDisabled:"&"},link:function(h,i,j,k){function l(a){return a.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()})}function m(a){if(a){if(angular.isDate(a)&&!isNaN(a))return k.$setValidity("date",!0),a;if(angular.isString(a)){var b=f.parse(a,n)||new Date(a);return isNaN(b)?void k.$setValidity("date",!1):(k.$setValidity("date",!0),b)}return void k.$setValidity("date",!1)}return k.$setValidity("date",!0),null}var n,o=angular.isDefined(j.closeOnDateSelection)?h.$parent.$eval(j.closeOnDateSelection):g.closeOnDateSelection,p=angular.isDefined(j.datepickerAppendToBody)?h.$parent.$eval(j.datepickerAppendToBody):g.appendToBody;h.showButtonBar=angular.isDefined(j.showButtonBar)?h.$parent.$eval(j.showButtonBar):g.showButtonBar,h.getText=function(a){return h[a+"Text"]||g[a+"Text"]},j.$observe("datepickerPopup",function(a){n=a||g.datepickerPopup,k.$render()});var q=angular.element("<div datepicker-popup-wrap><div datepicker></div></div>");q.attr({"ng-model":"date","ng-change":"dateSelection()"});var r=angular.element(q.children()[0]);j.datepickerOptions&&angular.forEach(h.$parent.$eval(j.datepickerOptions),function(a,b){r.attr(l(b),a)}),angular.forEach(["minDate","maxDate"],function(a){j[a]&&(h.$parent.$watch(b(j[a]),function(b){h[a]=b}),r.attr(l(a),a))}),j.dateDisabled&&r.attr("date-disabled","dateDisabled({ date: date, mode: mode })"),k.$parsers.unshift(m),h.dateSelection=function(a){angular.isDefined(a)&&(h.date=a),k.$setViewValue(h.date),k.$render(),o&&(h.isOpen=!1,i[0].focus())},i.bind("input change keyup",function(){h.$apply(function(){h.date=k.$modelValue})}),k.$render=function(){var a=k.$viewValue?e(k.$viewValue,n):"";i.val(a),h.date=m(k.$modelValue)};var s=function(a){h.isOpen&&a.target!==i[0]&&h.$apply(function(){h.isOpen=!1})},t=function(a){h.keydown(a)};i.bind("keydown",t),h.keydown=function(a){27===a.which?(a.preventDefault(),a.stopPropagation(),h.close()):40!==a.which||h.isOpen||(h.isOpen=!0)},h.$watch("isOpen",function(a){a?(h.$broadcast("datepicker.focus"),h.position=p?d.offset(i):d.position(i),h.position.top=h.position.top+i.prop("offsetHeight"),c.bind("click",s)):c.unbind("click",s)}),h.select=function(a){if("today"===a){var b=new Date;angular.isDate(k.$modelValue)?(a=new Date(k.$modelValue),a.setFullYear(b.getFullYear(),b.getMonth(),b.getDate())):a=new Date(b.setHours(0,0,0,0))}h.dateSelection(a)},h.close=function(){h.isOpen=!1,i[0].focus()};var u=a(q)(h);p?c.find("body").append(u):i.after(u),h.$on("$destroy",function(){u.remove(),i.unbind("keydown",t),c.unbind("click",s)})}}}]).directive("datepickerPopupWrap",function(){return{restrict:"EA",replace:!0,transclude:!0,templateUrl:"template/datepicker/popup.html",link:function(a,b){b.bind("click",function(a){a.preventDefault(),a.stopPropagation()})}}}),angular.module("ui.bootstrap.dropdown",[]).constant("dropdownConfig",{openClass:"open"}).service("dropdownService",["$document",function(a){var b=null;this.open=function(e){b||(a.bind("click",c),a.bind("keydown",d)),b&&b!==e&&(b.isOpen=!1),b=e},this.close=function(e){b===e&&(b=null,a.unbind("click",c),a.unbind("keydown",d))};var c=function(a){a&&a.isDefaultPrevented()||b.$apply(function(){b.isOpen=!1})},d=function(a){27===a.which&&(b.focusToggleElement(),c())}}]).controller("DropdownController",["$scope","$attrs","$parse","dropdownConfig","dropdownService","$animate",function(a,b,c,d,e,f){var g,h=this,i=a.$new(),j=d.openClass,k=angular.noop,l=b.onToggle?c(b.onToggle):angular.noop;this.init=function(d){h.$element=d,b.isOpen&&(g=c(b.isOpen),k=g.assign,a.$watch(g,function(a){i.isOpen=!!a}))},this.toggle=function(a){return i.isOpen=arguments.length?!!a:!i.isOpen},this.isOpen=function(){return i.isOpen},i.focusToggleElement=function(){h.toggleElement&&h.toggleElement[0].focus()},i.$watch("isOpen",function(b,c){f[b?"addClass":"removeClass"](h.$element,j),b?(i.focusToggleElement(),e.open(i)):e.close(i),k(a,b),angular.isDefined(b)&&b!==c&&l(a,{open:!!b})}),a.$on("$locationChangeSuccess",function(){i.isOpen=!1}),a.$on("$destroy",function(){i.$destroy()})}]).directive("dropdown",function(){return{restrict:"CA",controller:"DropdownController",link:function(a,b,c,d){d.init(b)}}}).directive("dropdownToggle",function(){return{restrict:"CA",require:"?^dropdown",link:function(a,b,c,d){if(d){d.toggleElement=b;var e=function(e){e.preventDefault(),b.hasClass("disabled")||c.disabled||a.$apply(function(){d.toggle()})};b.bind("click",e),b.attr({"aria-haspopup":!0,"aria-expanded":!1}),a.$watch(d.isOpen,function(a){b.attr("aria-expanded",!!a)}),a.$on("$destroy",function(){b.unbind("click",e)})}}}}),angular.module("ui.bootstrap.modal",["ui.bootstrap.transition"]).factory("$$stackedMap",function(){return{createNew:function(){var a=[];return{add:function(b,c){a.push({key:b,value:c})},get:function(b){for(var c=0;c<a.length;c++)if(b==a[c].key)return a[c]},keys:function(){for(var b=[],c=0;c<a.length;c++)b.push(a[c].key);return b},top:function(){return a[a.length-1]},remove:function(b){for(var c=-1,d=0;d<a.length;d++)if(b==a[d].key){c=d;break}return a.splice(c,1)[0]},removeTop:function(){return a.splice(a.length-1,1)[0]},length:function(){return a.length}}}}}).directive("modalBackdrop",["$timeout",function(a){return{restrict:"EA",replace:!0,templateUrl:"template/modal/backdrop.html",link:function(b){b.animate=!1,a(function(){b.animate=!0})}}}]).directive("modalWindow",["$modalStack","$timeout",function(a,b){return{restrict:"EA",scope:{index:"@",animate:"="},replace:!0,transclude:!0,templateUrl:function(a,b){return b.templateUrl||"template/modal/window.html"},link:function(c,d,e){d.addClass(e.windowClass||""),c.size=e.size,b(function(){c.animate=!0,d[0].focus()}),c.close=function(b){var c=a.getTop();c&&c.value.backdrop&&"static"!=c.value.backdrop&&b.target===b.currentTarget&&(b.preventDefault(),b.stopPropagation(),a.dismiss(c.key,"backdrop click"))}}}}]).factory("$modalStack",["$transition","$timeout","$document","$compile","$rootScope","$$stackedMap",function(a,b,c,d,e,f){function g(){for(var a=-1,b=n.keys(),c=0;c<b.length;c++)n.get(b[c]).value.backdrop&&(a=c);return a}function h(a){var b=c.find("body").eq(0),d=n.get(a).value;n.remove(a),j(d.modalDomEl,d.modalScope,300,function(){d.modalScope.$destroy(),b.toggleClass(m,n.length()>0),i()})}function i(){if(k&&-1==g()){var a=l;j(k,l,150,function(){a.$destroy(),a=null}),k=void 0,l=void 0}}function j(c,d,e,f){function g(){g.done||(g.done=!0,c.remove(),f&&f())}d.animate=!1;var h=a.transitionEndEventName;if(h){var i=b(g,e);c.bind(h,function(){b.cancel(i),g(),d.$apply()})}else b(g,0)}var k,l,m="modal-open",n=f.createNew(),o={};return e.$watch(g,function(a){l&&(l.index=a)}),c.bind("keydown",function(a){var b;27===a.which&&(b=n.top(),b&&b.value.keyboard&&(a.preventDefault(),e.$apply(function(){o.dismiss(b.key,"escape key press")})))}),o.open=function(a,b){n.add(a,{deferred:b.deferred,modalScope:b.scope,backdrop:b.backdrop,keyboard:b.keyboard});var f=c.find("body").eq(0),h=g();h>=0&&!k&&(l=e.$new(!0),l.index=h,k=d("<div modal-backdrop></div>")(l),f.append(k));var i=angular.element("<div modal-window></div>");i.attr({"template-url":b.windowTemplateUrl,"window-class":b.windowClass,size:b.size,index:n.length()-1,animate:"animate"}).html(b.content);var j=d(i)(b.scope);n.top().value.modalDomEl=j,f.append(j),f.addClass(m)},o.close=function(a,b){var c=n.get(a).value;c&&(c.deferred.resolve(b),h(a))},o.dismiss=function(a,b){var c=n.get(a).value;c&&(c.deferred.reject(b),h(a))},o.dismissAll=function(a){for(var b=this.getTop();b;)this.dismiss(b.key,a),b=this.getTop()},o.getTop=function(){return n.top()},o}]).provider("$modal",function(){var a={options:{backdrop:!0,keyboard:!0},$get:["$injector","$rootScope","$q","$http","$templateCache","$controller","$modalStack",function(b,c,d,e,f,g,h){function i(a){return a.template?d.when(a.template):e.get(a.templateUrl,{cache:f}).then(function(a){return a.data})}function j(a){var c=[];return angular.forEach(a,function(a){(angular.isFunction(a)||angular.isArray(a))&&c.push(d.when(b.invoke(a)))}),c}var k={};return k.open=function(b){var e=d.defer(),f=d.defer(),k={result:e.promise,opened:f.promise,close:function(a){h.close(k,a)},dismiss:function(a){h.dismiss(k,a)}};if(b=angular.extend({},a.options,b),b.resolve=b.resolve||{},!b.template&&!b.templateUrl)throw new Error("One of template or templateUrl options is required.");var l=d.all([i(b)].concat(j(b.resolve)));return l.then(function(a){var d=(b.scope||c).$new();d.$close=k.close,d.$dismiss=k.dismiss;var f,i={},j=1;b.controller&&(i.$scope=d,i.$modalInstance=k,angular.forEach(b.resolve,function(b,c){i[c]=a[j++]}),f=g(b.controller,i)),h.open(k,{scope:d,deferred:e,content:a[0],backdrop:b.backdrop,keyboard:b.keyboard,windowClass:b.windowClass,windowTemplateUrl:b.windowTemplateUrl,size:b.size})},function(a){e.reject(a)}),l.then(function(){f.resolve(!0)},function(){f.reject(!1)}),k},k}]};return a}),angular.module("ui.bootstrap.pagination",[]).controller("PaginationController",["$scope","$attrs","$parse",function(a,b,c){var d=this,e={$setViewValue:angular.noop},f=b.numPages?c(b.numPages).assign:angular.noop;this.init=function(f,g){e=f,this.config=g,e.$render=function(){d.render()},b.itemsPerPage?a.$parent.$watch(c(b.itemsPerPage),function(b){d.itemsPerPage=parseInt(b,10),a.totalPages=d.calculateTotalPages()}):this.itemsPerPage=g.itemsPerPage},this.calculateTotalPages=function(){var b=this.itemsPerPage<1?1:Math.ceil(a.totalItems/this.itemsPerPage);return Math.max(b||0,1)},this.render=function(){a.page=parseInt(e.$viewValue,10)||1},a.selectPage=function(b){a.page!==b&&b>0&&b<=a.totalPages&&(e.$setViewValue(b),e.$render())},a.getText=function(b){return a[b+"Text"]||d.config[b+"Text"]},a.noPrevious=function(){return 1===a.page},a.noNext=function(){return a.page===a.totalPages},a.$watch("totalItems",function(){a.totalPages=d.calculateTotalPages()}),a.$watch("totalPages",function(b){f(a.$parent,b),a.page>b?a.selectPage(b):e.$render()})}]).constant("paginationConfig",{itemsPerPage:10,boundaryLinks:!1,directionLinks:!0,firstText:"First",previousText:"Previous",nextText:"Next",lastText:"Last",rotate:!0}).directive("pagination",["$parse","paginationConfig",function(a,b){return{restrict:"EA",scope:{totalItems:"=",firstText:"@",previousText:"@",nextText:"@",lastText:"@"},require:["pagination","?ngModel"],controller:"PaginationController",templateUrl:"template/pagination/pagination.html",replace:!0,link:function(c,d,e,f){function g(a,b,c){return{number:a,text:b,active:c}}function h(a,b){var c=[],d=1,e=b,f=angular.isDefined(k)&&b>k;f&&(l?(d=Math.max(a-Math.floor(k/2),1),e=d+k-1,e>b&&(e=b,d=e-k+1)):(d=(Math.ceil(a/k)-1)*k+1,e=Math.min(d+k-1,b)));for(var h=d;e>=h;h++){var i=g(h,h,h===a);c.push(i)}if(f&&!l){if(d>1){var j=g(d-1,"...",!1);c.unshift(j)}if(b>e){var m=g(e+1,"...",!1);c.push(m)}}return c}var i=f[0],j=f[1];if(j){var k=angular.isDefined(e.maxSize)?c.$parent.$eval(e.maxSize):b.maxSize,l=angular.isDefined(e.rotate)?c.$parent.$eval(e.rotate):b.rotate;c.boundaryLinks=angular.isDefined(e.boundaryLinks)?c.$parent.$eval(e.boundaryLinks):b.boundaryLinks,c.directionLinks=angular.isDefined(e.directionLinks)?c.$parent.$eval(e.directionLinks):b.directionLinks,i.init(j,b),e.maxSize&&c.$parent.$watch(a(e.maxSize),function(a){k=parseInt(a,10),i.render()});var m=i.render;i.render=function(){m(),c.page>0&&c.page<=c.totalPages&&(c.pages=h(c.page,c.totalPages))}}}}}]).constant("pagerConfig",{itemsPerPage:10,previousText:"« Previous",nextText:"Next »",align:!0}).directive("pager",["pagerConfig",function(a){return{restrict:"EA",scope:{totalItems:"=",previousText:"@",nextText:"@"},require:["pager","?ngModel"],controller:"PaginationController",templateUrl:"template/pagination/pager.html",replace:!0,link:function(b,c,d,e){var f=e[0],g=e[1];g&&(b.align=angular.isDefined(d.align)?b.$parent.$eval(d.align):a.align,f.init(g,a))}}}]),angular.module("ui.bootstrap.tooltip",["ui.bootstrap.position","ui.bootstrap.bindHtml"]).provider("$tooltip",function(){function a(a){var b=/[A-Z]/g,c="-";
9
- return a.replace(b,function(a,b){return(b?c:"")+a.toLowerCase()})}var b={placement:"top",animation:!0,popupDelay:0},c={mouseenter:"mouseleave",click:"click",focus:"blur"},d={};this.options=function(a){angular.extend(d,a)},this.setTriggers=function(a){angular.extend(c,a)},this.$get=["$window","$compile","$timeout","$parse","$document","$position","$interpolate",function(e,f,g,h,i,j,k){return function(e,l,m){function n(a){var b=a||o.trigger||m,d=c[b]||b;return{show:b,hide:d}}var o=angular.extend({},b,d),p=a(e),q=k.startSymbol(),r=k.endSymbol(),s="<div "+p+'-popup title="'+q+"tt_title"+r+'" content="'+q+"tt_content"+r+'" placement="'+q+"tt_placement"+r+'" animation="tt_animation" is-open="tt_isOpen"></div>';return{restrict:"EA",scope:!0,compile:function(){var a=f(s);return function(b,c,d){function f(){b.tt_isOpen?m():k()}function k(){(!y||b.$eval(d[l+"Enable"]))&&(b.tt_popupDelay?v||(v=g(p,b.tt_popupDelay,!1),v.then(function(a){a()})):p()())}function m(){b.$apply(function(){q()})}function p(){return v=null,u&&(g.cancel(u),u=null),b.tt_content?(r(),t.css({top:0,left:0,display:"block"}),w?i.find("body").append(t):c.after(t),z(),b.tt_isOpen=!0,b.$digest(),z):angular.noop}function q(){b.tt_isOpen=!1,g.cancel(v),v=null,b.tt_animation?u||(u=g(s,500)):s()}function r(){t&&s(),t=a(b,function(){}),b.$digest()}function s(){u=null,t&&(t.remove(),t=null)}var t,u,v,w=angular.isDefined(o.appendToBody)?o.appendToBody:!1,x=n(void 0),y=angular.isDefined(d[l+"Enable"]),z=function(){var a=j.positionElements(c,t,b.tt_placement,w);a.top+="px",a.left+="px",t.css(a)};b.tt_isOpen=!1,d.$observe(e,function(a){b.tt_content=a,!a&&b.tt_isOpen&&q()}),d.$observe(l+"Title",function(a){b.tt_title=a}),d.$observe(l+"Placement",function(a){b.tt_placement=angular.isDefined(a)?a:o.placement}),d.$observe(l+"PopupDelay",function(a){var c=parseInt(a,10);b.tt_popupDelay=isNaN(c)?o.popupDelay:c});var A=function(){c.unbind(x.show,k),c.unbind(x.hide,m)};d.$observe(l+"Trigger",function(a){A(),x=n(a),x.show===x.hide?c.bind(x.show,f):(c.bind(x.show,k),c.bind(x.hide,m))});var B=b.$eval(d[l+"Animation"]);b.tt_animation=angular.isDefined(B)?!!B:o.animation,d.$observe(l+"AppendToBody",function(a){w=angular.isDefined(a)?h(a)(b):w}),w&&b.$on("$locationChangeSuccess",function(){b.tt_isOpen&&q()}),b.$on("$destroy",function(){g.cancel(u),g.cancel(v),A(),s()})}}}}}]}).directive("tooltipPopup",function(){return{restrict:"EA",replace:!0,scope:{content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-popup.html"}}).directive("tooltip",["$tooltip",function(a){return a("tooltip","tooltip","mouseenter")}]).directive("tooltipHtmlUnsafePopup",function(){return{restrict:"EA",replace:!0,scope:{content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-html-unsafe-popup.html"}}).directive("tooltipHtmlUnsafe",["$tooltip",function(a){return a("tooltipHtmlUnsafe","tooltip","mouseenter")}]),angular.module("ui.bootstrap.popover",["ui.bootstrap.tooltip"]).directive("popoverPopup",function(){return{restrict:"EA",replace:!0,scope:{title:"@",content:"@",placement:"@",animation:"&",isOpen:"&"},templateUrl:"template/popover/popover.html"}}).directive("popover",["$tooltip",function(a){return a("popover","popover","click")}]),angular.module("ui.bootstrap.progressbar",[]).constant("progressConfig",{animate:!0,max:100}).controller("ProgressController",["$scope","$attrs","progressConfig",function(a,b,c){var d=this,e=angular.isDefined(b.animate)?a.$parent.$eval(b.animate):c.animate;this.bars=[],a.max=angular.isDefined(b.max)?a.$parent.$eval(b.max):c.max,this.addBar=function(b,c){e||c.css({transition:"none"}),this.bars.push(b),b.$watch("value",function(c){b.percent=+(100*c/a.max).toFixed(2)}),b.$on("$destroy",function(){c=null,d.removeBar(b)})},this.removeBar=function(a){this.bars.splice(this.bars.indexOf(a),1)}}]).directive("progress",function(){return{restrict:"EA",replace:!0,transclude:!0,controller:"ProgressController",require:"progress",scope:{},templateUrl:"template/progressbar/progress.html"}}).directive("bar",function(){return{restrict:"EA",replace:!0,transclude:!0,require:"^progress",scope:{value:"=",type:"@"},templateUrl:"template/progressbar/bar.html",link:function(a,b,c,d){d.addBar(a,b)}}}).directive("progressbar",function(){return{restrict:"EA",replace:!0,transclude:!0,controller:"ProgressController",scope:{value:"=",type:"@"},templateUrl:"template/progressbar/progressbar.html",link:function(a,b,c,d){d.addBar(a,angular.element(b.children()[0]))}}}),angular.module("ui.bootstrap.rating",[]).constant("ratingConfig",{max:5,stateOn:null,stateOff:null}).controller("RatingController",["$scope","$attrs","ratingConfig",function(a,b,c){var d={$setViewValue:angular.noop};this.init=function(e){d=e,d.$render=this.render,this.stateOn=angular.isDefined(b.stateOn)?a.$parent.$eval(b.stateOn):c.stateOn,this.stateOff=angular.isDefined(b.stateOff)?a.$parent.$eval(b.stateOff):c.stateOff;var f=angular.isDefined(b.ratingStates)?a.$parent.$eval(b.ratingStates):new Array(angular.isDefined(b.max)?a.$parent.$eval(b.max):c.max);a.range=this.buildTemplateObjects(f)},this.buildTemplateObjects=function(a){for(var b=0,c=a.length;c>b;b++)a[b]=angular.extend({index:b},{stateOn:this.stateOn,stateOff:this.stateOff},a[b]);return a},a.rate=function(b){!a.readonly&&b>=0&&b<=a.range.length&&(d.$setViewValue(b),d.$render())},a.enter=function(b){a.readonly||(a.value=b),a.onHover({value:b})},a.reset=function(){a.value=d.$viewValue,a.onLeave()},a.onKeydown=function(b){/(37|38|39|40)/.test(b.which)&&(b.preventDefault(),b.stopPropagation(),a.rate(a.value+(38===b.which||39===b.which?1:-1)))},this.render=function(){a.value=d.$viewValue}}]).directive("rating",function(){return{restrict:"EA",require:["rating","ngModel"],scope:{readonly:"=?",onHover:"&",onLeave:"&"},controller:"RatingController",templateUrl:"template/rating/rating.html",replace:!0,link:function(a,b,c,d){var e=d[0],f=d[1];f&&e.init(f)}}}),angular.module("ui.bootstrap.tabs",[]).controller("TabsetController",["$scope",function(a){var b=this,c=b.tabs=a.tabs=[];b.select=function(a){angular.forEach(c,function(b){b.active&&b!==a&&(b.active=!1,b.onDeselect())}),a.active=!0,a.onSelect()},b.addTab=function(a){c.push(a),1===c.length?a.active=!0:a.active&&b.select(a)},b.removeTab=function(a){var d=c.indexOf(a);if(a.active&&c.length>1){var e=d==c.length-1?d-1:d+1;b.select(c[e])}c.splice(d,1)}}]).directive("tabset",function(){return{restrict:"EA",transclude:!0,replace:!0,scope:{type:"@"},controller:"TabsetController",templateUrl:"template/tabs/tabset.html",link:function(a,b,c){a.vertical=angular.isDefined(c.vertical)?a.$parent.$eval(c.vertical):!1,a.justified=angular.isDefined(c.justified)?a.$parent.$eval(c.justified):!1}}}).directive("tab",["$parse",function(a){return{require:"^tabset",restrict:"EA",replace:!0,templateUrl:"template/tabs/tab.html",transclude:!0,scope:{active:"=?",heading:"@",onSelect:"&select",onDeselect:"&deselect"},controller:function(){},compile:function(b,c,d){return function(b,c,e,f){b.$watch("active",function(a){a&&f.select(b)}),b.disabled=!1,e.disabled&&b.$parent.$watch(a(e.disabled),function(a){b.disabled=!!a}),b.select=function(){b.disabled||(b.active=!0)},f.addTab(b),b.$on("$destroy",function(){f.removeTab(b)}),b.$transcludeFn=d}}}}]).directive("tabHeadingTransclude",[function(){return{restrict:"A",require:"^tab",link:function(a,b){a.$watch("headingElement",function(a){a&&(b.html(""),b.append(a))})}}}]).directive("tabContentTransclude",function(){function a(a){return a.tagName&&(a.hasAttribute("tab-heading")||a.hasAttribute("data-tab-heading")||"tab-heading"===a.tagName.toLowerCase()||"data-tab-heading"===a.tagName.toLowerCase())}return{restrict:"A",require:"^tabset",link:function(b,c,d){var e=b.$eval(d.tabContentTransclude);e.$transcludeFn(e.$parent,function(b){angular.forEach(b,function(b){a(b)?e.headingElement=b:c.append(b)})})}}}),angular.module("ui.bootstrap.timepicker",[]).constant("timepickerConfig",{hourStep:1,minuteStep:1,showMeridian:!0,meridians:null,readonlyInput:!1,mousewheel:!0}).controller("TimepickerController",["$scope","$attrs","$parse","$log","$locale","timepickerConfig",function(a,b,c,d,e,f){function g(){var b=parseInt(a.hours,10),c=a.showMeridian?b>0&&13>b:b>=0&&24>b;return c?(a.showMeridian&&(12===b&&(b=0),a.meridian===p[1]&&(b+=12)),b):void 0}function h(){var b=parseInt(a.minutes,10);return b>=0&&60>b?b:void 0}function i(a){return angular.isDefined(a)&&a.toString().length<2?"0"+a:a}function j(a){k(),o.$setViewValue(new Date(n)),l(a)}function k(){o.$setValidity("time",!0),a.invalidHours=!1,a.invalidMinutes=!1}function l(b){var c=n.getHours(),d=n.getMinutes();a.showMeridian&&(c=0===c||12===c?12:c%12),a.hours="h"===b?c:i(c),a.minutes="m"===b?d:i(d),a.meridian=n.getHours()<12?p[0]:p[1]}function m(a){var b=new Date(n.getTime()+6e4*a);n.setHours(b.getHours(),b.getMinutes()),j()}var n=new Date,o={$setViewValue:angular.noop},p=angular.isDefined(b.meridians)?a.$parent.$eval(b.meridians):f.meridians||e.DATETIME_FORMATS.AMPMS;this.init=function(c,d){o=c,o.$render=this.render;var e=d.eq(0),g=d.eq(1),h=angular.isDefined(b.mousewheel)?a.$parent.$eval(b.mousewheel):f.mousewheel;h&&this.setupMousewheelEvents(e,g),a.readonlyInput=angular.isDefined(b.readonlyInput)?a.$parent.$eval(b.readonlyInput):f.readonlyInput,this.setupInputEvents(e,g)};var q=f.hourStep;b.hourStep&&a.$parent.$watch(c(b.hourStep),function(a){q=parseInt(a,10)});var r=f.minuteStep;b.minuteStep&&a.$parent.$watch(c(b.minuteStep),function(a){r=parseInt(a,10)}),a.showMeridian=f.showMeridian,b.showMeridian&&a.$parent.$watch(c(b.showMeridian),function(b){if(a.showMeridian=!!b,o.$error.time){var c=g(),d=h();angular.isDefined(c)&&angular.isDefined(d)&&(n.setHours(c),j())}else l()}),this.setupMousewheelEvents=function(b,c){var d=function(a){a.originalEvent&&(a=a.originalEvent);var b=a.wheelDelta?a.wheelDelta:-a.deltaY;return a.detail||b>0};b.bind("mousewheel wheel",function(b){a.$apply(d(b)?a.incrementHours():a.decrementHours()),b.preventDefault()}),c.bind("mousewheel wheel",function(b){a.$apply(d(b)?a.incrementMinutes():a.decrementMinutes()),b.preventDefault()})},this.setupInputEvents=function(b,c){if(a.readonlyInput)return a.updateHours=angular.noop,void(a.updateMinutes=angular.noop);var d=function(b,c){o.$setViewValue(null),o.$setValidity("time",!1),angular.isDefined(b)&&(a.invalidHours=b),angular.isDefined(c)&&(a.invalidMinutes=c)};a.updateHours=function(){var a=g();angular.isDefined(a)?(n.setHours(a),j("h")):d(!0)},b.bind("blur",function(){!a.invalidHours&&a.hours<10&&a.$apply(function(){a.hours=i(a.hours)})}),a.updateMinutes=function(){var a=h();angular.isDefined(a)?(n.setMinutes(a),j("m")):d(void 0,!0)},c.bind("blur",function(){!a.invalidMinutes&&a.minutes<10&&a.$apply(function(){a.minutes=i(a.minutes)})})},this.render=function(){var a=o.$modelValue?new Date(o.$modelValue):null;isNaN(a)?(o.$setValidity("time",!1),d.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.')):(a&&(n=a),k(),l())},a.incrementHours=function(){m(60*q)},a.decrementHours=function(){m(60*-q)},a.incrementMinutes=function(){m(r)},a.decrementMinutes=function(){m(-r)},a.toggleMeridian=function(){m(720*(n.getHours()<12?1:-1))}}]).directive("timepicker",function(){return{restrict:"EA",require:["timepicker","?^ngModel"],controller:"TimepickerController",replace:!0,scope:{},templateUrl:"template/timepicker/timepicker.html",link:function(a,b,c,d){var e=d[0],f=d[1];f&&e.init(f,b.find("input"))}}}),angular.module("ui.bootstrap.typeahead",["ui.bootstrap.position","ui.bootstrap.bindHtml"]).factory("typeaheadParser",["$parse",function(a){var b=/^\s*(.*?)(?:\s+as\s+(.*?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+(.*)$/;return{parse:function(c){var d=c.match(b);if(!d)throw new Error('Expected typeahead specification in form of "_modelValue_ (as _label_)? for _item_ in _collection_" but got "'+c+'".');return{itemName:d[3],source:a(d[4]),viewMapper:a(d[2]||d[1]),modelMapper:a(d[1])}}}}]).directive("typeahead",["$compile","$parse","$q","$timeout","$document","$position","typeaheadParser",function(a,b,c,d,e,f,g){var h=[9,13,27,38,40];return{require:"ngModel",link:function(i,j,k,l){var m,n=i.$eval(k.typeaheadMinLength)||1,o=i.$eval(k.typeaheadWaitMs)||0,p=i.$eval(k.typeaheadEditable)!==!1,q=b(k.typeaheadLoading).assign||angular.noop,r=b(k.typeaheadOnSelect),s=k.typeaheadInputFormatter?b(k.typeaheadInputFormatter):void 0,t=k.typeaheadAppendToBody?i.$eval(k.typeaheadAppendToBody):!1,u=b(k.ngModel).assign,v=g.parse(k.typeahead),w=i.$new();i.$on("$destroy",function(){w.$destroy()});var x="typeahead-"+w.$id+"-"+Math.floor(1e4*Math.random());j.attr({"aria-autocomplete":"list","aria-expanded":!1,"aria-owns":x});var y=angular.element("<div typeahead-popup></div>");y.attr({id:x,matches:"matches",active:"activeIdx",select:"select(activeIdx)",query:"query",position:"position"}),angular.isDefined(k.typeaheadTemplateUrl)&&y.attr("template-url",k.typeaheadTemplateUrl);var z=function(){w.matches=[],w.activeIdx=-1,j.attr("aria-expanded",!1)},A=function(a){return x+"-option-"+a};w.$watch("activeIdx",function(a){0>a?j.removeAttr("aria-activedescendant"):j.attr("aria-activedescendant",A(a))});var B=function(a){var b={$viewValue:a};q(i,!0),c.when(v.source(i,b)).then(function(c){var d=a===l.$viewValue;if(d&&m)if(c.length>0){w.activeIdx=0,w.matches.length=0;for(var e=0;e<c.length;e++)b[v.itemName]=c[e],w.matches.push({id:A(e),label:v.viewMapper(w,b),model:c[e]});w.query=a,w.position=t?f.offset(j):f.position(j),w.position.top=w.position.top+j.prop("offsetHeight"),j.attr("aria-expanded",!0)}else z();d&&q(i,!1)},function(){z(),q(i,!1)})};z(),w.query=void 0;var C;l.$parsers.unshift(function(a){return m=!0,a&&a.length>=n?o>0?(C&&d.cancel(C),C=d(function(){B(a)},o)):B(a):(q(i,!1),z()),p?a:a?void l.$setValidity("editable",!1):(l.$setValidity("editable",!0),a)}),l.$formatters.push(function(a){var b,c,d={};return s?(d.$model=a,s(i,d)):(d[v.itemName]=a,b=v.viewMapper(i,d),d[v.itemName]=void 0,c=v.viewMapper(i,d),b!==c?b:a)}),w.select=function(a){var b,c,e={};e[v.itemName]=c=w.matches[a].model,b=v.modelMapper(i,e),u(i,b),l.$setValidity("editable",!0),r(i,{$item:c,$model:b,$label:v.viewMapper(i,e)}),z(),d(function(){j[0].focus()},0,!1)},j.bind("keydown",function(a){0!==w.matches.length&&-1!==h.indexOf(a.which)&&(a.preventDefault(),40===a.which?(w.activeIdx=(w.activeIdx+1)%w.matches.length,w.$digest()):38===a.which?(w.activeIdx=(w.activeIdx?w.activeIdx:w.matches.length)-1,w.$digest()):13===a.which||9===a.which?w.$apply(function(){w.select(w.activeIdx)}):27===a.which&&(a.stopPropagation(),z(),w.$digest()))}),j.bind("blur",function(){m=!1});var D=function(a){j[0]!==a.target&&(z(),w.$digest())};e.bind("click",D),i.$on("$destroy",function(){e.unbind("click",D)});var E=a(y)(w);t?e.find("body").append(E):j.after(E)}}}]).directive("typeaheadPopup",function(){return{restrict:"EA",scope:{matches:"=",query:"=",active:"=",position:"=",select:"&"},replace:!0,templateUrl:"template/typeahead/typeahead-popup.html",link:function(a,b,c){a.templateUrl=c.templateUrl,a.isOpen=function(){return a.matches.length>0},a.isActive=function(b){return a.active==b},a.selectActive=function(b){a.active=b},a.selectMatch=function(b){a.select({activeIdx:b})}}}}).directive("typeaheadMatch",["$http","$templateCache","$compile","$parse",function(a,b,c,d){return{restrict:"EA",scope:{index:"=",match:"=",query:"="},link:function(e,f,g){var h=d(g.templateUrl)(e.$parent)||"template/typeahead/typeahead-match.html";a.get(h,{cache:b}).success(function(a){f.replaceWith(c(a.trim())(e))})}}}]).filter("typeaheadHighlight",function(){function a(a){return a.replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")}return function(b,c){return c?(""+b).replace(new RegExp(a(c),"gi"),"<strong>$&</strong>"):b}}),angular.module("template/accordion/accordion-group.html",[]).run(["$templateCache",function(a){a.put("template/accordion/accordion-group.html",'<div class="panel panel-default">\n <div class="panel-heading">\n <h4 class="panel-title">\n <a class="accordion-toggle" ng-click="toggleOpen()" accordion-transclude="heading"><span ng-class="{\'text-muted\': isDisabled}">{{heading}}</span></a>\n </h4>\n </div>\n <div class="panel-collapse" collapse="!isOpen">\n <div class="panel-body" ng-transclude></div>\n </div>\n</div>')}]),angular.module("template/accordion/accordion.html",[]).run(["$templateCache",function(a){a.put("template/accordion/accordion.html",'<div class="panel-group" ng-transclude></div>')}]),angular.module("template/alert/alert.html",[]).run(["$templateCache",function(a){a.put("template/alert/alert.html",'<div class="alert" ng-class="{\'alert-{{type || \'warning\'}}\': true, \'alert-dismissable\': closeable}" role="alert">\n <button ng-show="closeable" type="button" class="close" ng-click="close()">\n <span aria-hidden="true">&times;</span>\n <span class="sr-only">Close</span>\n </button>\n <div ng-transclude></div>\n</div>\n')}]),angular.module("template/carousel/carousel.html",[]).run(["$templateCache",function(a){a.put("template/carousel/carousel.html",'<div ng-mouseenter="pause()" ng-mouseleave="play()" class="carousel" ng-swipe-right="prev()" ng-swipe-left="next()">\n <ol class="carousel-indicators" ng-show="slides.length > 1">\n <li ng-repeat="slide in slides track by $index" ng-class="{active: isActive(slide)}" ng-click="select(slide)"></li>\n </ol>\n <div class="carousel-inner" ng-transclude></div>\n <a class="left carousel-control" ng-click="prev()" ng-show="slides.length > 1"><span class="glyphicon glyphicon-chevron-left"></span></a>\n <a class="right carousel-control" ng-click="next()" ng-show="slides.length > 1"><span class="glyphicon glyphicon-chevron-right"></span></a>\n</div>\n')}]),angular.module("template/carousel/slide.html",[]).run(["$templateCache",function(a){a.put("template/carousel/slide.html","<div ng-class=\"{\n 'active': leaving || (active && !entering),\n 'prev': (next || active) && direction=='prev',\n 'next': (next || active) && direction=='next',\n 'right': direction=='prev',\n 'left': direction=='next'\n }\" class=\"item text-center\" ng-transclude></div>\n")}]),angular.module("template/datepicker/datepicker.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/datepicker.html",'<div ng-switch="datepickerMode" role="application" ng-keydown="keydown($event)">\n <daypicker ng-switch-when="day" tabindex="0"></daypicker>\n <monthpicker ng-switch-when="month" tabindex="0"></monthpicker>\n <yearpicker ng-switch-when="year" tabindex="0"></yearpicker>\n</div>')}]),angular.module("template/datepicker/day.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/day.html",'<table role="grid" aria-labelledby="{{uniqueId}}-title" aria-activedescendant="{{activeDateId}}">\n <thead>\n <tr>\n <th><button type="button" class="btn btn-default btn-sm pull-left" ng-click="move(-1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-left"></i></button></th>\n <th colspan="{{5 + showWeeks}}"><button id="{{uniqueId}}-title" role="heading" aria-live="assertive" aria-atomic="true" type="button" class="btn btn-default btn-sm" ng-click="toggleMode()" tabindex="-1" style="width:100%;"><strong>{{title}}</strong></button></th>\n <th><button type="button" class="btn btn-default btn-sm pull-right" ng-click="move(1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-right"></i></button></th>\n </tr>\n <tr>\n <th ng-show="showWeeks" class="text-center"></th>\n <th ng-repeat="label in labels track by $index" class="text-center"><small aria-label="{{label.full}}">{{label.abbr}}</small></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="row in rows track by $index">\n <td ng-show="showWeeks" class="text-center h6"><em>{{ weekNumbers[$index] }}</em></td>\n <td ng-repeat="dt in row track by dt.date" class="text-center" role="gridcell" id="{{dt.uid}}" aria-disabled="{{!!dt.disabled}}">\n <button type="button" style="width:100%;" class="btn btn-default btn-sm" ng-class="{\'btn-info\': dt.selected, active: isActive(dt)}" ng-click="select(dt.date)" ng-disabled="dt.disabled" tabindex="-1"><span ng-class="{\'text-muted\': dt.secondary, \'text-info\': dt.current}">{{dt.label}}</span></button>\n </td>\n </tr>\n </tbody>\n</table>\n')}]),angular.module("template/datepicker/month.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/month.html",'<table role="grid" aria-labelledby="{{uniqueId}}-title" aria-activedescendant="{{activeDateId}}">\n <thead>\n <tr>\n <th><button type="button" class="btn btn-default btn-sm pull-left" ng-click="move(-1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-left"></i></button></th>\n <th><button id="{{uniqueId}}-title" role="heading" aria-live="assertive" aria-atomic="true" type="button" class="btn btn-default btn-sm" ng-click="toggleMode()" tabindex="-1" style="width:100%;"><strong>{{title}}</strong></button></th>\n <th><button type="button" class="btn btn-default btn-sm pull-right" ng-click="move(1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-right"></i></button></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="row in rows track by $index">\n <td ng-repeat="dt in row track by dt.date" class="text-center" role="gridcell" id="{{dt.uid}}" aria-disabled="{{!!dt.disabled}}">\n <button type="button" style="width:100%;" class="btn btn-default" ng-class="{\'btn-info\': dt.selected, active: isActive(dt)}" ng-click="select(dt.date)" ng-disabled="dt.disabled" tabindex="-1"><span ng-class="{\'text-info\': dt.current}">{{dt.label}}</span></button>\n </td>\n </tr>\n </tbody>\n</table>\n')}]),angular.module("template/datepicker/popup.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/popup.html",'<ul class="dropdown-menu" ng-style="{display: (isOpen && \'block\') || \'none\', top: position.top+\'px\', left: position.left+\'px\'}" ng-keydown="keydown($event)">\n <li ng-transclude></li>\n <li ng-if="showButtonBar" style="padding:10px 9px 2px">\n <span class="btn-group">\n <button type="button" class="btn btn-sm btn-info" ng-click="select(\'today\')">{{ getText(\'current\') }}</button>\n <button type="button" class="btn btn-sm btn-danger" ng-click="select(null)">{{ getText(\'clear\') }}</button>\n </span>\n <button type="button" class="btn btn-sm btn-success pull-right" ng-click="close()">{{ getText(\'close\') }}</button>\n </li>\n</ul>\n')}]),angular.module("template/datepicker/year.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/year.html",'<table role="grid" aria-labelledby="{{uniqueId}}-title" aria-activedescendant="{{activeDateId}}">\n <thead>\n <tr>\n <th><button type="button" class="btn btn-default btn-sm pull-left" ng-click="move(-1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-left"></i></button></th>\n <th colspan="3"><button id="{{uniqueId}}-title" role="heading" aria-live="assertive" aria-atomic="true" type="button" class="btn btn-default btn-sm" ng-click="toggleMode()" tabindex="-1" style="width:100%;"><strong>{{title}}</strong></button></th>\n <th><button type="button" class="btn btn-default btn-sm pull-right" ng-click="move(1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-right"></i></button></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="row in rows track by $index">\n <td ng-repeat="dt in row track by dt.date" class="text-center" role="gridcell" id="{{dt.uid}}" aria-disabled="{{!!dt.disabled}}">\n <button type="button" style="width:100%;" class="btn btn-default" ng-class="{\'btn-info\': dt.selected, active: isActive(dt)}" ng-click="select(dt.date)" ng-disabled="dt.disabled" tabindex="-1"><span ng-class="{\'text-info\': dt.current}">{{dt.label}}</span></button>\n </td>\n </tr>\n </tbody>\n</table>\n')}]),angular.module("template/modal/backdrop.html",[]).run(["$templateCache",function(a){a.put("template/modal/backdrop.html",'<div class="modal-backdrop fade"\n ng-class="{in: animate}"\n ng-style="{\'z-index\': 1040 + (index && 1 || 0) + index*10}"\n></div>\n')}]),angular.module("template/modal/window.html",[]).run(["$templateCache",function(a){a.put("template/modal/window.html",'<div tabindex="-1" role="dialog" class="modal fade" ng-class="{in: animate}" ng-style="{\'z-index\': 1050 + index*10, display: \'block\'}" ng-click="close($event)">\n <div class="modal-dialog" ng-class="{\'modal-sm\': size == \'sm\', \'modal-lg\': size == \'lg\'}"><div class="modal-content" ng-transclude></div></div>\n</div>')}]),angular.module("template/pagination/pager.html",[]).run(["$templateCache",function(a){a.put("template/pagination/pager.html",'<ul class="pager">\n <li ng-class="{disabled: noPrevious(), previous: align}"><a href ng-click="selectPage(page - 1)">{{getText(\'previous\')}}</a></li>\n <li ng-class="{disabled: noNext(), next: align}"><a href ng-click="selectPage(page + 1)">{{getText(\'next\')}}</a></li>\n</ul>')}]),angular.module("template/pagination/pagination.html",[]).run(["$templateCache",function(a){a.put("template/pagination/pagination.html",'<ul class="pagination">\n <li ng-if="boundaryLinks" ng-class="{disabled: noPrevious()}"><a href ng-click="selectPage(1)">{{getText(\'first\')}}</a></li>\n <li ng-if="directionLinks" ng-class="{disabled: noPrevious()}"><a href ng-click="selectPage(page - 1)">{{getText(\'previous\')}}</a></li>\n <li ng-repeat="page in pages track by $index" ng-class="{active: page.active}"><a href ng-click="selectPage(page.number)">{{page.text}}</a></li>\n <li ng-if="directionLinks" ng-class="{disabled: noNext()}"><a href ng-click="selectPage(page + 1)">{{getText(\'next\')}}</a></li>\n <li ng-if="boundaryLinks" ng-class="{disabled: noNext()}"><a href ng-click="selectPage(totalPages)">{{getText(\'last\')}}</a></li>\n</ul>')}]),angular.module("template/tooltip/tooltip-html-unsafe-popup.html",[]).run(["$templateCache",function(a){a.put("template/tooltip/tooltip-html-unsafe-popup.html",'<div class="tooltip {{placement}}" ng-class="{ in: isOpen(), fade: animation() }">\n <div class="tooltip-arrow"></div>\n <div class="tooltip-inner" bind-html-unsafe="content"></div>\n</div>\n')}]),angular.module("template/tooltip/tooltip-popup.html",[]).run(["$templateCache",function(a){a.put("template/tooltip/tooltip-popup.html",'<div class="tooltip {{placement}}" ng-class="{ in: isOpen(), fade: animation() }">\n <div class="tooltip-arrow"></div>\n <div class="tooltip-inner" ng-bind="content"></div>\n</div>\n')}]),angular.module("template/popover/popover.html",[]).run(["$templateCache",function(a){a.put("template/popover/popover.html",'<div class="popover {{placement}}" ng-class="{ in: isOpen(), fade: animation() }">\n <div class="arrow"></div>\n\n <div class="popover-inner">\n <h3 class="popover-title" ng-bind="title" ng-show="title"></h3>\n <div class="popover-content" ng-bind="content"></div>\n </div>\n</div>\n')}]),angular.module("template/progressbar/bar.html",[]).run(["$templateCache",function(a){a.put("template/progressbar/bar.html",'<div class="progress-bar" ng-class="type && \'progress-bar-\' + type" role="progressbar" aria-valuenow="{{value}}" aria-valuemin="0" aria-valuemax="{{max}}" ng-style="{width: percent + \'%\'}" aria-valuetext="{{percent | number:0}}%" ng-transclude></div>')}]),angular.module("template/progressbar/progress.html",[]).run(["$templateCache",function(a){a.put("template/progressbar/progress.html",'<div class="progress" ng-transclude></div>')}]),angular.module("template/progressbar/progressbar.html",[]).run(["$templateCache",function(a){a.put("template/progressbar/progressbar.html",'<div class="progress">\n <div class="progress-bar" ng-class="type && \'progress-bar-\' + type" role="progressbar" aria-valuenow="{{value}}" aria-valuemin="0" aria-valuemax="{{max}}" ng-style="{width: percent + \'%\'}" aria-valuetext="{{percent | number:0}}%" ng-transclude></div>\n</div>')}]),angular.module("template/rating/rating.html",[]).run(["$templateCache",function(a){a.put("template/rating/rating.html",'<span ng-mouseleave="reset()" ng-keydown="onKeydown($event)" tabindex="0" role="slider" aria-valuemin="0" aria-valuemax="{{range.length}}" aria-valuenow="{{value}}">\n <i ng-repeat="r in range track by $index" ng-mouseenter="enter($index + 1)" ng-click="rate($index + 1)" class="glyphicon" ng-class="$index < value && (r.stateOn || \'glyphicon-star\') || (r.stateOff || \'glyphicon-star-empty\')">\n <span class="sr-only">({{ $index < value ? \'*\' : \' \' }})</span>\n </i>\n</span>')}]),angular.module("template/tabs/tab.html",[]).run(["$templateCache",function(a){a.put("template/tabs/tab.html",'<li ng-class="{active: active, disabled: disabled}">\n <a ng-click="select()" tab-heading-transclude>{{heading}}</a>\n</li>\n')}]),angular.module("template/tabs/tabset-titles.html",[]).run(["$templateCache",function(a){a.put("template/tabs/tabset-titles.html","<ul class=\"nav {{type && 'nav-' + type}}\" ng-class=\"{'nav-stacked': vertical}\">\n</ul>\n")}]),angular.module("template/tabs/tabset.html",[]).run(["$templateCache",function(a){a.put("template/tabs/tabset.html",'\n<div>\n <ul class="nav nav-{{type || \'tabs\'}}" ng-class="{\'nav-stacked\': vertical, \'nav-justified\': justified}" ng-transclude></ul>\n <div class="tab-content">\n <div class="tab-pane" \n ng-repeat="tab in tabs" \n ng-class="{active: tab.active}"\n tab-content-transclude="tab">\n </div>\n </div>\n</div>\n')}]),angular.module("template/timepicker/timepicker.html",[]).run(["$templateCache",function(a){a.put("template/timepicker/timepicker.html",'<table>\n <tbody>\n <tr class="text-center">\n <td><a ng-click="incrementHours()" class="btn btn-link"><span class="glyphicon glyphicon-chevron-up"></span></a></td>\n <td>&nbsp;</td>\n <td><a ng-click="incrementMinutes()" class="btn btn-link"><span class="glyphicon glyphicon-chevron-up"></span></a></td>\n <td ng-show="showMeridian"></td>\n </tr>\n <tr>\n <td style="width:50px;" class="form-group" ng-class="{\'has-error\': invalidHours}">\n <input type="text" ng-model="hours" ng-change="updateHours()" class="form-control text-center" ng-mousewheel="incrementHours()" ng-readonly="readonlyInput" maxlength="2">\n </td>\n <td>:</td>\n <td style="width:50px;" class="form-group" ng-class="{\'has-error\': invalidMinutes}">\n <input type="text" ng-model="minutes" ng-change="updateMinutes()" class="form-control text-center" ng-readonly="readonlyInput" maxlength="2">\n </td>\n <td ng-show="showMeridian"><button type="button" class="btn btn-default text-center" ng-click="toggleMeridian()">{{meridian}}</button></td>\n </tr>\n <tr class="text-center">\n <td><a ng-click="decrementHours()" class="btn btn-link"><span class="glyphicon glyphicon-chevron-down"></span></a></td>\n <td>&nbsp;</td>\n <td><a ng-click="decrementMinutes()" class="btn btn-link"><span class="glyphicon glyphicon-chevron-down"></span></a></td>\n <td ng-show="showMeridian"></td>\n </tr>\n </tbody>\n</table>\n')}]),angular.module("template/typeahead/typeahead-match.html",[]).run(["$templateCache",function(a){a.put("template/typeahead/typeahead-match.html",'<a tabindex="-1" bind-html-unsafe="match.label | typeaheadHighlight:query"></a>')}]),angular.module("template/typeahead/typeahead-popup.html",[]).run(["$templateCache",function(a){a.put("template/typeahead/typeahead-popup.html",'<ul class="dropdown-menu" ng-if="isOpen()" ng-style="{top: position.top+\'px\', left: position.left+\'px\'}" style="display: block;" role="listbox" aria-hidden="{{!isOpen()}}">\n <li ng-repeat="match in matches track by $index" ng-class="{active: isActive($index) }" ng-mouseenter="selectActive($index)" ng-click="selectMatch($index)" role="option" id="{{match.id}}">\n <div typeahead-match index="$index" match="match" query="query" template-url="templateUrl"></div>\n </li>\n</ul>')
10
- }]);
8
+ angular.module("ui.bootstrap",["ui.bootstrap.tpls","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.bindHtml","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.dateparser","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dropdown","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.transition","ui.bootstrap.typeahead"]),angular.module("ui.bootstrap.tpls",["template/accordion/accordion-group.html","template/accordion/accordion.html","template/alert/alert.html","template/carousel/carousel.html","template/carousel/slide.html","template/datepicker/datepicker.html","template/datepicker/day.html","template/datepicker/month.html","template/datepicker/popup.html","template/datepicker/year.html","template/modal/backdrop.html","template/modal/window.html","template/pagination/pager.html","template/pagination/pagination.html","template/tooltip/tooltip-html-popup.html","template/tooltip/tooltip-html-unsafe-popup.html","template/tooltip/tooltip-popup.html","template/tooltip/tooltip-template-popup.html","template/popover/popover-template.html","template/popover/popover.html","template/progressbar/bar.html","template/progressbar/progress.html","template/progressbar/progressbar.html","template/rating/rating.html","template/tabs/tab.html","template/tabs/tabset.html","template/timepicker/timepicker.html","template/typeahead/typeahead-match.html","template/typeahead/typeahead-popup.html"]),angular.module("ui.bootstrap.collapse",[]).directive("collapse",["$animate",function(a){return{link:function(b,c,d){function e(){c.removeClass("collapse").addClass("collapsing"),a.addClass(c,"in",{to:{height:c[0].scrollHeight+"px"}}).then(f)}function f(){c.removeClass("collapsing"),c.css({height:"auto"})}function g(){c.css({height:c[0].scrollHeight+"px"}).removeClass("collapse").addClass("collapsing"),a.removeClass(c,"in",{to:{height:"0"}}).then(h)}function h(){c.css({height:"0"}),c.removeClass("collapsing"),c.addClass("collapse")}b.$watch(d.collapse,function(a){a?g():e()})}}}]),angular.module("ui.bootstrap.accordion",["ui.bootstrap.collapse"]).constant("accordionConfig",{closeOthers:!0}).controller("AccordionController",["$scope","$attrs","accordionConfig",function(a,b,c){this.groups=[],this.closeOthers=function(d){var e=angular.isDefined(b.closeOthers)?a.$eval(b.closeOthers):c.closeOthers;e&&angular.forEach(this.groups,function(a){a!==d&&(a.isOpen=!1)})},this.addGroup=function(a){var b=this;this.groups.push(a),a.$on("$destroy",function(){b.removeGroup(a)})},this.removeGroup=function(a){var b=this.groups.indexOf(a);-1!==b&&this.groups.splice(b,1)}}]).directive("accordion",function(){return{restrict:"EA",controller:"AccordionController",transclude:!0,replace:!1,templateUrl:"template/accordion/accordion.html"}}).directive("accordionGroup",function(){return{require:"^accordion",restrict:"EA",transclude:!0,replace:!0,templateUrl:"template/accordion/accordion-group.html",scope:{heading:"@",isOpen:"=?",isDisabled:"=?"},controller:function(){this.setHeading=function(a){this.heading=a}},link:function(a,b,c,d){d.addGroup(a),a.$watch("isOpen",function(b){b&&d.closeOthers(a)}),a.toggleOpen=function(){a.isDisabled||(a.isOpen=!a.isOpen)}}}}).directive("accordionHeading",function(){return{restrict:"EA",transclude:!0,template:"",replace:!0,require:"^accordionGroup",link:function(a,b,c,d,e){d.setHeading(e(a,angular.noop))}}}).directive("accordionTransclude",function(){return{require:"^accordionGroup",link:function(a,b,c,d){a.$watch(function(){return d[c.accordionTransclude]},function(a){a&&(b.html(""),b.append(a))})}}}),angular.module("ui.bootstrap.alert",[]).controller("AlertController",["$scope","$attrs",function(a,b){a.closeable="close"in b,this.close=a.close}]).directive("alert",function(){return{restrict:"EA",controller:"AlertController",templateUrl:"template/alert/alert.html",transclude:!0,replace:!0,scope:{type:"@",close:"&"}}}).directive("dismissOnTimeout",["$timeout",function(a){return{require:"alert",link:function(b,c,d,e){a(function(){e.close()},parseInt(d.dismissOnTimeout,10))}}}]),angular.module("ui.bootstrap.bindHtml",[]).directive("bindHtmlUnsafe",function(){return function(a,b,c){b.addClass("ng-binding").data("$binding",c.bindHtmlUnsafe),a.$watch(c.bindHtmlUnsafe,function(a){b.html(a||"")})}}),angular.module("ui.bootstrap.buttons",[]).constant("buttonConfig",{activeClass:"active",toggleEvent:"click"}).controller("ButtonsController",["buttonConfig",function(a){this.activeClass=a.activeClass||"active",this.toggleEvent=a.toggleEvent||"click"}]).directive("btnRadio",function(){return{require:["btnRadio","ngModel"],controller:"ButtonsController",link:function(a,b,c,d){var e=d[0],f=d[1];f.$render=function(){b.toggleClass(e.activeClass,angular.equals(f.$modelValue,a.$eval(c.btnRadio)))},b.bind(e.toggleEvent,function(){var d=b.hasClass(e.activeClass);(!d||angular.isDefined(c.uncheckable))&&a.$apply(function(){f.$setViewValue(d?null:a.$eval(c.btnRadio)),f.$render()})})}}}).directive("btnCheckbox",function(){return{require:["btnCheckbox","ngModel"],controller:"ButtonsController",link:function(a,b,c,d){function e(){return g(c.btnCheckboxTrue,!0)}function f(){return g(c.btnCheckboxFalse,!1)}function g(b,c){var d=a.$eval(b);return angular.isDefined(d)?d:c}var h=d[0],i=d[1];i.$render=function(){b.toggleClass(h.activeClass,angular.equals(i.$modelValue,e()))},b.bind(h.toggleEvent,function(){a.$apply(function(){i.$setViewValue(b.hasClass(h.activeClass)?f():e()),i.$render()})})}}}),angular.module("ui.bootstrap.carousel",[]).controller("CarouselController",["$scope","$interval","$animate",function(a,b,c){function d(a){if(angular.isUndefined(k[a].index))return k[a];{var b;k.length}for(b=0;b<k.length;++b)if(k[b].index==a)return k[b]}function e(){f();var c=+a.interval;!isNaN(c)&&c>0&&(h=b(g,c))}function f(){h&&(b.cancel(h),h=null)}function g(){var b=+a.interval;i&&!isNaN(b)&&b>0?a.next():a.pause()}var h,i,j=this,k=j.slides=a.slides=[],l=-1;j.currentSlide=null;var m=!1;j.select=a.select=function(b,d){function f(){m||(angular.extend(b,{direction:d,active:!0}),angular.extend(j.currentSlide||{},{direction:d,active:!1}),c.enabled()&&!a.noTransition&&b.$element&&(a.$currentTransition=!0,b.$element.one("$animate:close",function(){a.$currentTransition=null})),j.currentSlide=b,l=g,e())}var g=j.indexOfSlide(b);void 0===d&&(d=g>j.getCurrentIndex()?"next":"prev"),b&&b!==j.currentSlide&&f()},a.$on("$destroy",function(){m=!0}),j.getCurrentIndex=function(){return j.currentSlide&&angular.isDefined(j.currentSlide.index)?+j.currentSlide.index:l},j.indexOfSlide=function(a){return angular.isDefined(a.index)?+a.index:k.indexOf(a)},a.next=function(){var b=(j.getCurrentIndex()+1)%k.length;return a.$currentTransition?void 0:j.select(d(b),"next")},a.prev=function(){var b=j.getCurrentIndex()-1<0?k.length-1:j.getCurrentIndex()-1;return a.$currentTransition?void 0:j.select(d(b),"prev")},a.isActive=function(a){return j.currentSlide===a},a.$watch("interval",e),a.$on("$destroy",f),a.play=function(){i||(i=!0,e())},a.pause=function(){a.noPause||(i=!1,f())},j.addSlide=function(b,c){b.$element=c,k.push(b),1===k.length||b.active?(j.select(k[k.length-1]),1==k.length&&a.play()):b.active=!1},j.removeSlide=function(a){angular.isDefined(a.index)&&k.sort(function(a,b){return+a.index>+b.index});var b=k.indexOf(a);k.splice(b,1),k.length>0&&a.active?j.select(b>=k.length?k[b-1]:k[b]):l>b&&l--}}]).directive("carousel",[function(){return{restrict:"EA",transclude:!0,replace:!0,controller:"CarouselController",require:"carousel",templateUrl:"template/carousel/carousel.html",scope:{interval:"=",noTransition:"=",noPause:"="}}}]).directive("slide",function(){return{require:"^carousel",restrict:"EA",transclude:!0,replace:!0,templateUrl:"template/carousel/slide.html",scope:{active:"=?",index:"=?"},link:function(a,b,c,d){d.addSlide(a,b),a.$on("$destroy",function(){d.removeSlide(a)}),a.$watch("active",function(b){b&&d.select(a)})}}}).animation(".item",["$animate",function(a){return{beforeAddClass:function(b,c,d){if("active"==c&&b.parent()&&!b.parent().scope().noTransition){var e=!1,f=b.isolateScope().direction,g="next"==f?"left":"right";return b.addClass(f),a.addClass(b,g).then(function(){e||b.removeClass(g+" "+f),d()}),function(){e=!0}}d()},beforeRemoveClass:function(b,c,d){if("active"==c&&b.parent()&&!b.parent().scope().noTransition){var e=!1,f=b.isolateScope().direction,g="next"==f?"left":"right";return a.addClass(b,g).then(function(){e||b.removeClass(g),d()}),function(){e=!0}}d()}}}]),angular.module("ui.bootstrap.dateparser",[]).service("dateParser",["$locale","orderByFilter",function(a,b){function c(a){var c=[],d=a.split("");return angular.forEach(f,function(b,e){var f=a.indexOf(e);if(f>-1){a=a.split(""),d[f]="("+b.regex+")",a[f]="$";for(var g=f+1,h=f+e.length;h>g;g++)d[g]="",a[g]="$";a=a.join(""),c.push({index:f,apply:b.apply})}}),{regex:new RegExp("^"+d.join("")+"$"),map:b(c,"index")}}function d(a,b,c){return 1>c?!1:1===b&&c>28?29===c&&(a%4===0&&a%100!==0||a%400===0):3===b||5===b||8===b||10===b?31>c:!0}var e=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;this.parsers={};var f={yyyy:{regex:"\\d{4}",apply:function(a){this.year=+a}},yy:{regex:"\\d{2}",apply:function(a){this.year=+a+2e3}},y:{regex:"\\d{1,4}",apply:function(a){this.year=+a}},MMMM:{regex:a.DATETIME_FORMATS.MONTH.join("|"),apply:function(b){this.month=a.DATETIME_FORMATS.MONTH.indexOf(b)}},MMM:{regex:a.DATETIME_FORMATS.SHORTMONTH.join("|"),apply:function(b){this.month=a.DATETIME_FORMATS.SHORTMONTH.indexOf(b)}},MM:{regex:"0[1-9]|1[0-2]",apply:function(a){this.month=a-1}},M:{regex:"[1-9]|1[0-2]",apply:function(a){this.month=a-1}},dd:{regex:"[0-2][0-9]{1}|3[0-1]{1}",apply:function(a){this.date=+a}},d:{regex:"[1-2]?[0-9]{1}|3[0-1]{1}",apply:function(a){this.date=+a}},EEEE:{regex:a.DATETIME_FORMATS.DAY.join("|")},EEE:{regex:a.DATETIME_FORMATS.SHORTDAY.join("|")},HH:{regex:"(?:0|1)[0-9]|2[0-3]",apply:function(a){this.hours=+a}},H:{regex:"1?[0-9]|2[0-3]",apply:function(a){this.hours=+a}},mm:{regex:"[0-5][0-9]",apply:function(a){this.minutes=+a}},m:{regex:"[0-9]|[1-5][0-9]",apply:function(a){this.minutes=+a}},sss:{regex:"[0-9][0-9][0-9]",apply:function(a){this.milliseconds=+a}},ss:{regex:"[0-5][0-9]",apply:function(a){this.seconds=+a}},s:{regex:"[0-9]|[1-5][0-9]",apply:function(a){this.seconds=+a}}};this.parse=function(b,f,g){if(!angular.isString(b)||!f)return b;f=a.DATETIME_FORMATS[f]||f,f=f.replace(e,"\\$&"),this.parsers[f]||(this.parsers[f]=c(f));var h=this.parsers[f],i=h.regex,j=h.map,k=b.match(i);if(k&&k.length){var l,m;l=g?{year:g.getFullYear(),month:g.getMonth(),date:g.getDate(),hours:g.getHours(),minutes:g.getMinutes(),seconds:g.getSeconds(),milliseconds:g.getMilliseconds()}:{year:1900,month:0,date:1,hours:0,minutes:0,seconds:0,milliseconds:0};for(var n=1,o=k.length;o>n;n++){var p=j[n-1];p.apply&&p.apply.call(l,k[n])}return d(l.year,l.month,l.date)&&(m=new Date(l.year,l.month,l.date,l.hours,l.minutes,l.seconds,l.milliseconds||0)),m}}}]),angular.module("ui.bootstrap.position",[]).factory("$position",["$document","$window",function(a,b){function c(a,c){return a.currentStyle?a.currentStyle[c]:b.getComputedStyle?b.getComputedStyle(a)[c]:a.style[c]}function d(a){return"static"===(c(a,"position")||"static")}var e=function(b){for(var c=a[0],e=b.offsetParent||c;e&&e!==c&&d(e);)e=e.offsetParent;return e||c};return{position:function(b){var c=this.offset(b),d={top:0,left:0},f=e(b[0]);f!=a[0]&&(d=this.offset(angular.element(f)),d.top+=f.clientTop-f.scrollTop,d.left+=f.clientLeft-f.scrollLeft);var g=b[0].getBoundingClientRect();return{width:g.width||b.prop("offsetWidth"),height:g.height||b.prop("offsetHeight"),top:c.top-d.top,left:c.left-d.left}},offset:function(c){var d=c[0].getBoundingClientRect();return{width:d.width||c.prop("offsetWidth"),height:d.height||c.prop("offsetHeight"),top:d.top+(b.pageYOffset||a[0].documentElement.scrollTop),left:d.left+(b.pageXOffset||a[0].documentElement.scrollLeft)}},positionElements:function(a,b,c,d){var e,f,g,h,i=c.split("-"),j=i[0],k=i[1]||"center";e=d?this.offset(a):this.position(a),f=b.prop("offsetWidth"),g=b.prop("offsetHeight");var l={center:function(){return e.left+e.width/2-f/2},left:function(){return e.left},right:function(){return e.left+e.width}},m={center:function(){return e.top+e.height/2-g/2},top:function(){return e.top},bottom:function(){return e.top+e.height}};switch(j){case"right":h={top:m[k](),left:l[j]()};break;case"left":h={top:m[k](),left:e.left-f};break;case"bottom":h={top:m[j](),left:l[k]()};break;default:h={top:e.top-g,left:l[k]()}}return h}}}]),angular.module("ui.bootstrap.datepicker",["ui.bootstrap.dateparser","ui.bootstrap.position"]).constant("datepickerConfig",{formatDay:"dd",formatMonth:"MMMM",formatYear:"yyyy",formatDayHeader:"EEE",formatDayTitle:"MMMM yyyy",formatMonthTitle:"yyyy",datepickerMode:"day",minMode:"day",maxMode:"year",showWeeks:!0,startingDay:0,yearRange:20,minDate:null,maxDate:null,shortcutPropagation:!1}).controller("DatepickerController",["$scope","$attrs","$parse","$interpolate","$timeout","$log","dateFilter","datepickerConfig",function(a,b,c,d,e,f,g,h){var i=this,j={$setViewValue:angular.noop};this.modes=["day","month","year"],angular.forEach(["formatDay","formatMonth","formatYear","formatDayHeader","formatDayTitle","formatMonthTitle","minMode","maxMode","showWeeks","startingDay","yearRange","shortcutPropagation"],function(c,e){i[c]=angular.isDefined(b[c])?8>e?d(b[c])(a.$parent):a.$parent.$eval(b[c]):h[c]}),angular.forEach(["minDate","maxDate"],function(d){b[d]?a.$parent.$watch(c(b[d]),function(a){i[d]=a?new Date(a):null,i.refreshView()}):i[d]=h[d]?new Date(h[d]):null}),a.datepickerMode=a.datepickerMode||h.datepickerMode,a.maxMode=i.maxMode,a.uniqueId="datepicker-"+a.$id+"-"+Math.floor(1e4*Math.random()),angular.isDefined(b.initDate)?(this.activeDate=a.$parent.$eval(b.initDate)||new Date,a.$parent.$watch(b.initDate,function(a){a&&(j.$isEmpty(j.$modelValue)||j.$invalid)&&(i.activeDate=a,i.refreshView())})):this.activeDate=new Date,a.isActive=function(b){return 0===i.compare(b.date,i.activeDate)?(a.activeDateId=b.uid,!0):!1},this.init=function(a){j=a,j.$render=function(){i.render()}},this.render=function(){if(j.$viewValue){var a=new Date(j.$viewValue),b=!isNaN(a);b?this.activeDate=a:f.error('Datepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.'),j.$setValidity("date",b)}this.refreshView()},this.refreshView=function(){if(this.element){this._refreshView();var a=j.$viewValue?new Date(j.$viewValue):null;j.$setValidity("date-disabled",!a||this.element&&!this.isDisabled(a))}},this.createDateObject=function(a,b){var c=j.$viewValue?new Date(j.$viewValue):null;return{date:a,label:g(a,b),selected:c&&0===this.compare(a,c),disabled:this.isDisabled(a),current:0===this.compare(a,new Date),customClass:this.customClass(a)}},this.isDisabled=function(c){return this.minDate&&this.compare(c,this.minDate)<0||this.maxDate&&this.compare(c,this.maxDate)>0||b.dateDisabled&&a.dateDisabled({date:c,mode:a.datepickerMode})},this.customClass=function(b){return a.customClass({date:b,mode:a.datepickerMode})},this.split=function(a,b){for(var c=[];a.length>0;)c.push(a.splice(0,b));return c},a.select=function(b){if(a.datepickerMode===i.minMode){var c=j.$viewValue?new Date(j.$viewValue):new Date(0,0,0,0,0,0,0);c.setFullYear(b.getFullYear(),b.getMonth(),b.getDate()),j.$setViewValue(c),j.$render()}else i.activeDate=b,a.datepickerMode=i.modes[i.modes.indexOf(a.datepickerMode)-1]},a.move=function(a){var b=i.activeDate.getFullYear()+a*(i.step.years||0),c=i.activeDate.getMonth()+a*(i.step.months||0);i.activeDate.setFullYear(b,c,1),i.refreshView()},a.toggleMode=function(b){b=b||1,a.datepickerMode===i.maxMode&&1===b||a.datepickerMode===i.minMode&&-1===b||(a.datepickerMode=i.modes[i.modes.indexOf(a.datepickerMode)+b])},a.keys={13:"enter",32:"space",33:"pageup",34:"pagedown",35:"end",36:"home",37:"left",38:"up",39:"right",40:"down"};var k=function(){e(function(){i.element[0].focus()},0,!1)};a.$on("datepicker.focus",k),a.keydown=function(b){var c=a.keys[b.which];if(c&&!b.shiftKey&&!b.altKey)if(b.preventDefault(),i.shortcutPropagation||b.stopPropagation(),"enter"===c||"space"===c){if(i.isDisabled(i.activeDate))return;a.select(i.activeDate),k()}else!b.ctrlKey||"up"!==c&&"down"!==c?(i.handleKeyDown(c,b),i.refreshView()):(a.toggleMode("up"===c?1:-1),k())}}]).directive("datepicker",function(){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/datepicker.html",scope:{datepickerMode:"=?",dateDisabled:"&",customClass:"&",shortcutPropagation:"&?"},require:["datepicker","?^ngModel"],controller:"DatepickerController",link:function(a,b,c,d){var e=d[0],f=d[1];f&&e.init(f)}}}).directive("daypicker",["dateFilter",function(a){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/day.html",require:"^datepicker",link:function(b,c,d,e){function f(a,b){return 1!==b||a%4!==0||a%100===0&&a%400!==0?i[b]:29}function g(a,b){var c=new Array(b),d=new Date(a),e=0;for(d.setHours(12);b>e;)c[e++]=new Date(d),d.setDate(d.getDate()+1);return c}function h(a){var b=new Date(a);b.setDate(b.getDate()+4-(b.getDay()||7));var c=b.getTime();return b.setMonth(0),b.setDate(1),Math.floor(Math.round((c-b)/864e5)/7)+1}b.showWeeks=e.showWeeks,e.step={months:1},e.element=c;var i=[31,28,31,30,31,30,31,31,30,31,30,31];e._refreshView=function(){var c=e.activeDate.getFullYear(),d=e.activeDate.getMonth(),f=new Date(c,d,1),i=e.startingDay-f.getDay(),j=i>0?7-i:-i,k=new Date(f);j>0&&k.setDate(-j+1);for(var l=g(k,42),m=0;42>m;m++)l[m]=angular.extend(e.createDateObject(l[m],e.formatDay),{secondary:l[m].getMonth()!==d,uid:b.uniqueId+"-"+m});b.labels=new Array(7);for(var n=0;7>n;n++)b.labels[n]={abbr:a(l[n].date,e.formatDayHeader),full:a(l[n].date,"EEEE")};if(b.title=a(e.activeDate,e.formatDayTitle),b.rows=e.split(l,7),b.showWeeks){b.weekNumbers=[];for(var o=(11-e.startingDay)%7,p=b.rows.length,q=0;p>q;q++)b.weekNumbers.push(h(b.rows[q][o].date))}},e.compare=function(a,b){return new Date(a.getFullYear(),a.getMonth(),a.getDate())-new Date(b.getFullYear(),b.getMonth(),b.getDate())},e.handleKeyDown=function(a){var b=e.activeDate.getDate();if("left"===a)b-=1;else if("up"===a)b-=7;else if("right"===a)b+=1;else if("down"===a)b+=7;else if("pageup"===a||"pagedown"===a){var c=e.activeDate.getMonth()+("pageup"===a?-1:1);e.activeDate.setMonth(c,1),b=Math.min(f(e.activeDate.getFullYear(),e.activeDate.getMonth()),b)}else"home"===a?b=1:"end"===a&&(b=f(e.activeDate.getFullYear(),e.activeDate.getMonth()));e.activeDate.setDate(b)},e.refreshView()}}}]).directive("monthpicker",["dateFilter",function(a){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/month.html",require:"^datepicker",link:function(b,c,d,e){e.step={years:1},e.element=c,e._refreshView=function(){for(var c=new Array(12),d=e.activeDate.getFullYear(),f=0;12>f;f++)c[f]=angular.extend(e.createDateObject(new Date(d,f,1),e.formatMonth),{uid:b.uniqueId+"-"+f});b.title=a(e.activeDate,e.formatMonthTitle),b.rows=e.split(c,3)},e.compare=function(a,b){return new Date(a.getFullYear(),a.getMonth())-new Date(b.getFullYear(),b.getMonth())},e.handleKeyDown=function(a){var b=e.activeDate.getMonth();if("left"===a)b-=1;else if("up"===a)b-=3;else if("right"===a)b+=1;else if("down"===a)b+=3;else if("pageup"===a||"pagedown"===a){var c=e.activeDate.getFullYear()+("pageup"===a?-1:1);e.activeDate.setFullYear(c)}else"home"===a?b=0:"end"===a&&(b=11);e.activeDate.setMonth(b)},e.refreshView()}}}]).directive("yearpicker",["dateFilter",function(){return{restrict:"EA",replace:!0,templateUrl:"template/datepicker/year.html",require:"^datepicker",link:function(a,b,c,d){function e(a){return parseInt((a-1)/f,10)*f+1}var f=d.yearRange;d.step={years:f},d.element=b,d._refreshView=function(){for(var b=new Array(f),c=0,g=e(d.activeDate.getFullYear());f>c;c++)b[c]=angular.extend(d.createDateObject(new Date(g+c,0,1),d.formatYear),{uid:a.uniqueId+"-"+c});a.title=[b[0].label,b[f-1].label].join(" - "),a.rows=d.split(b,5)},d.compare=function(a,b){return a.getFullYear()-b.getFullYear()},d.handleKeyDown=function(a){var b=d.activeDate.getFullYear();"left"===a?b-=1:"up"===a?b-=5:"right"===a?b+=1:"down"===a?b+=5:"pageup"===a||"pagedown"===a?b+=("pageup"===a?-1:1)*d.step.years:"home"===a?b=e(d.activeDate.getFullYear()):"end"===a&&(b=e(d.activeDate.getFullYear())+f-1),d.activeDate.setFullYear(b)},d.refreshView()}}}]).constant("datepickerPopupConfig",{datepickerPopup:"yyyy-MM-dd",html5Types:{date:"yyyy-MM-dd","datetime-local":"yyyy-MM-ddTHH:mm:ss.sss",month:"yyyy-MM"},currentText:"Today",clearText:"Clear",closeText:"Done",closeOnDateSelection:!0,appendToBody:!1,showButtonBar:!0}).directive("datepickerPopup",["$compile","$parse","$document","$position","dateFilter","dateParser","datepickerPopupConfig",function(a,b,c,d,e,f,g){return{restrict:"EA",require:"ngModel",scope:{isOpen:"=?",currentText:"@",clearText:"@",closeText:"@",dateDisabled:"&",customClass:"&"},link:function(h,i,j,k){function l(a){return a.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()})}function m(a){if(angular.isNumber(a)&&(a=new Date(a)),a){if(angular.isDate(a)&&!isNaN(a))return a;if(angular.isString(a)){var b=f.parse(a,o,h.date)||new Date(a);return isNaN(b)?void 0:b}return void 0}return null}function n(a,b){var c=a||b;if(angular.isNumber(c)&&(c=new Date(c)),c){if(angular.isDate(c)&&!isNaN(c))return!0;if(angular.isString(c)){var d=f.parse(c,o)||new Date(c);return!isNaN(d)}return!1}return!0}var o,p=angular.isDefined(j.closeOnDateSelection)?h.$parent.$eval(j.closeOnDateSelection):g.closeOnDateSelection,q=angular.isDefined(j.datepickerAppendToBody)?h.$parent.$eval(j.datepickerAppendToBody):g.appendToBody;h.showButtonBar=angular.isDefined(j.showButtonBar)?h.$parent.$eval(j.showButtonBar):g.showButtonBar,h.getText=function(a){return h[a+"Text"]||g[a+"Text"]};var r=!1;if(g.html5Types[j.type]?(o=g.html5Types[j.type],r=!0):(o=j.datepickerPopup||g.datepickerPopup,j.$observe("datepickerPopup",function(a){var b=a||g.datepickerPopup;if(b!==o&&(o=b,k.$modelValue=null,!o))throw new Error("datepickerPopup must have a date format specified.")})),!o)throw new Error("datepickerPopup must have a date format specified.");if(r&&j.datepickerPopup)throw new Error("HTML5 date input types do not support custom formats.");var s=angular.element("<div datepicker-popup-wrap><div datepicker></div></div>");s.attr({"ng-model":"date","ng-change":"dateSelection()"});var t=angular.element(s.children()[0]);if(r&&"month"==j.type&&(t.attr("datepicker-mode",'"month"'),t.attr("min-mode","month")),j.datepickerOptions){var u=h.$parent.$eval(j.datepickerOptions);u.initDate&&(h.initDate=u.initDate,t.attr("init-date","initDate"),delete u.initDate),angular.forEach(u,function(a,b){t.attr(l(b),a)})}h.watchData={},angular.forEach(["minDate","maxDate","datepickerMode","initDate","shortcutPropagation"],function(a){if(j[a]){var c=b(j[a]);if(h.$parent.$watch(c,function(b){h.watchData[a]=b}),t.attr(l(a),"watchData."+a),"datepickerMode"===a){var d=c.assign;h.$watch("watchData."+a,function(a,b){a!==b&&d(h.$parent,a)})}}}),j.dateDisabled&&t.attr("date-disabled","dateDisabled({ date: date, mode: mode })"),j.showWeeks&&t.attr("show-weeks",j.showWeeks),j.customClass&&t.attr("custom-class","customClass({ date: date, mode: mode })"),r?k.$formatters.push(function(a){return h.date=a,a}):(k.$$parserName="date",k.$validators.date=n,k.$parsers.unshift(m),k.$formatters.push(function(a){return h.date=a,k.$isEmpty(a)?a:e(a,o)})),h.dateSelection=function(a){angular.isDefined(a)&&(h.date=a);var b=h.date?e(h.date,o):"";i.val(b),k.$setViewValue(b),p&&(h.isOpen=!1,i[0].focus())},k.$viewChangeListeners.push(function(){h.date=f.parse(k.$viewValue,o,h.date)||new Date(k.$viewValue)});var v=function(a){h.isOpen&&a.target!==i[0]&&h.$apply(function(){h.isOpen=!1})},w=function(a){h.keydown(a)};i.bind("keydown",w),h.keydown=function(a){27===a.which?(a.preventDefault(),h.isOpen&&a.stopPropagation(),h.close()):40!==a.which||h.isOpen||(h.isOpen=!0)},h.$watch("isOpen",function(a){a?(h.$broadcast("datepicker.focus"),h.position=q?d.offset(i):d.position(i),h.position.top=h.position.top+i.prop("offsetHeight"),c.bind("click",v)):c.unbind("click",v)}),h.select=function(a){if("today"===a){var b=new Date;angular.isDate(h.date)?(a=new Date(h.date),a.setFullYear(b.getFullYear(),b.getMonth(),b.getDate())):a=new Date(b.setHours(0,0,0,0))}h.dateSelection(a)},h.close=function(){h.isOpen=!1,i[0].focus()};var x=a(s)(h);s.remove(),q?c.find("body").append(x):i.after(x),h.$on("$destroy",function(){x.remove(),i.unbind("keydown",w),c.unbind("click",v)})}}}]).directive("datepickerPopupWrap",function(){return{restrict:"EA",replace:!0,transclude:!0,templateUrl:"template/datepicker/popup.html",link:function(a,b){b.bind("click",function(a){a.preventDefault(),a.stopPropagation()})}}}),angular.module("ui.bootstrap.dropdown",["ui.bootstrap.position"]).constant("dropdownConfig",{openClass:"open"}).service("dropdownService",["$document","$rootScope",function(a,b){var c=null;this.open=function(b){c||(a.bind("click",d),a.bind("keydown",e)),c&&c!==b&&(c.isOpen=!1),c=b},this.close=function(b){c===b&&(c=null,a.unbind("click",d),a.unbind("keydown",e))};var d=function(a){if(c&&(!a||"disabled"!==c.getAutoClose())){var d=c.getToggleElement();if(!(a&&d&&d[0].contains(a.target))){var e=c.getElement();a&&"outsideClick"===c.getAutoClose()&&e&&e[0].contains(a.target)||(c.isOpen=!1,b.$$phase||c.$apply())}}},e=function(a){27===a.which&&(c.focusToggleElement(),d())}}]).controller("DropdownController",["$scope","$attrs","$parse","dropdownConfig","dropdownService","$animate","$position","$document",function(a,b,c,d,e,f,g,h){var i,j=this,k=a.$new(),l=d.openClass,m=angular.noop,n=b.onToggle?c(b.onToggle):angular.noop,o=!1;this.init=function(d){j.$element=d,b.isOpen&&(i=c(b.isOpen),m=i.assign,a.$watch(i,function(a){k.isOpen=!!a})),o=angular.isDefined(b.dropdownAppendToBody),o&&j.dropdownMenu&&(h.find("body").append(j.dropdownMenu),d.on("$destroy",function(){j.dropdownMenu.remove()}))},this.toggle=function(a){return k.isOpen=arguments.length?!!a:!k.isOpen},this.isOpen=function(){return k.isOpen},k.getToggleElement=function(){return j.toggleElement},k.getAutoClose=function(){return b.autoClose||"always"},k.getElement=function(){return j.$element},k.focusToggleElement=function(){j.toggleElement&&j.toggleElement[0].focus()},k.$watch("isOpen",function(b,c){if(o&&j.dropdownMenu){var d=g.positionElements(j.$element,j.dropdownMenu,"bottom-left",!0);j.dropdownMenu.css({top:d.top+"px",left:d.left+"px",display:b?"block":"none"})}f[b?"addClass":"removeClass"](j.$element,l),b?(k.focusToggleElement(),e.open(k)):e.close(k),m(a,b),angular.isDefined(b)&&b!==c&&n(a,{open:!!b})}),a.$on("$locationChangeSuccess",function(){k.isOpen=!1}),a.$on("$destroy",function(){k.$destroy()})}]).directive("dropdown",function(){return{controller:"DropdownController",link:function(a,b,c,d){d.init(b)}}}).directive("dropdownMenu",function(){return{restrict:"AC",require:"?^dropdown",link:function(a,b,c,d){d&&(d.dropdownMenu=b)}}}).directive("dropdownToggle",function(){return{require:"?^dropdown",link:function(a,b,c,d){if(d){d.toggleElement=b;var e=function(e){e.preventDefault(),b.hasClass("disabled")||c.disabled||a.$apply(function(){d.toggle()})};b.bind("click",e),b.attr({"aria-haspopup":!0,"aria-expanded":!1}),a.$watch(d.isOpen,function(a){b.attr("aria-expanded",!!a)}),a.$on("$destroy",function(){b.unbind("click",e)})}}}}),angular.module("ui.bootstrap.modal",[]).factory("$$stackedMap",function(){return{createNew:function(){var a=[];return{add:function(b,c){a.push({key:b,value:c})},get:function(b){for(var c=0;c<a.length;c++)if(b==a[c].key)return a[c]},keys:function(){for(var b=[],c=0;c<a.length;c++)b.push(a[c].key);return b},top:function(){return a[a.length-1]},remove:function(b){for(var c=-1,d=0;d<a.length;d++)if(b==a[d].key){c=d;break}return a.splice(c,1)[0]},removeTop:function(){return a.splice(a.length-1,1)[0]},length:function(){return a.length}}}}}).directive("modalBackdrop",["$timeout",function(a){function b(b){b.animate=!1,a(function(){b.animate=!0})}return{restrict:"EA",replace:!0,templateUrl:"template/modal/backdrop.html",compile:function(a,c){return a.addClass(c.backdropClass),b}}}]).directive("modalWindow",["$modalStack","$q",function(a,b){return{restrict:"EA",scope:{index:"@",animate:"="},replace:!0,transclude:!0,templateUrl:function(a,b){return b.templateUrl||"template/modal/window.html"},link:function(c,d,e){d.addClass(e.windowClass||""),c.size=e.size,c.close=function(b){var c=a.getTop();c&&c.value.backdrop&&"static"!=c.value.backdrop&&b.target===b.currentTarget&&(b.preventDefault(),b.stopPropagation(),a.dismiss(c.key,"backdrop click"))},c.$isRendered=!0;var f=b.defer();e.$observe("modalRender",function(a){"true"==a&&f.resolve()}),f.promise.then(function(){c.animate=!0;var b=d[0].querySelectorAll("[autofocus]");b.length?b[0].focus():d[0].focus();var e=a.getTop();e&&a.modalRendered(e.key)})}}}]).directive("modalAnimationClass",[function(){return{compile:function(a,b){b.modalAnimation&&a.addClass(b.modalAnimationClass)}}}]).directive("modalTransclude",function(){return{link:function(a,b,c,d,e){e(a.$parent,function(a){b.empty(),b.append(a)})}}}).factory("$modalStack",["$animate","$timeout","$document","$compile","$rootScope","$$stackedMap",function(a,b,c,d,e,f){function g(){for(var a=-1,b=o.keys(),c=0;c<b.length;c++)o.get(b[c]).value.backdrop&&(a=c);return a}function h(a){var b=c.find("body").eq(0),d=o.get(a).value;o.remove(a),j(d.modalDomEl,d.modalScope,function(){b.toggleClass(n,o.length()>0),i()})}function i(){if(l&&-1==g()){var a=m;j(l,m,function(){a=null}),l=void 0,m=void 0}}function j(c,d,f){function g(){g.done||(g.done=!0,c.remove(),d.$destroy(),f&&f())}d.animate=!1,c.attr("modal-animation")&&a.enabled()?c.one("$animate:close",function(){e.$evalAsync(g)}):b(g)}function k(a,b,c){return!a.value.modalScope.$broadcast("modal.closing",b,c).defaultPrevented}var l,m,n="modal-open",o=f.createNew(),p={};return e.$watch(g,function(a){m&&(m.index=a)}),c.bind("keydown",function(a){var b;27===a.which&&(b=o.top(),b&&b.value.keyboard&&(a.preventDefault(),e.$apply(function(){p.dismiss(b.key,"escape key press")})))}),p.open=function(a,b){var f=c[0].activeElement;o.add(a,{deferred:b.deferred,renderDeferred:b.renderDeferred,modalScope:b.scope,backdrop:b.backdrop,keyboard:b.keyboard});var h=c.find("body").eq(0),i=g();if(i>=0&&!l){m=e.$new(!0),m.index=i;var j=angular.element('<div modal-backdrop="modal-backdrop"></div>');j.attr("backdrop-class",b.backdropClass),b.animation&&j.attr("modal-animation","true"),l=d(j)(m),h.append(l)}var k=angular.element('<div modal-window="modal-window"></div>');k.attr({"template-url":b.windowTemplateUrl,"window-class":b.windowClass,size:b.size,index:o.length()-1,animate:"animate"}).html(b.content),b.animation&&k.attr("modal-animation","true");var p=d(k)(b.scope);o.top().value.modalDomEl=p,o.top().value.modalOpener=f,h.append(p),h.addClass(n)},p.close=function(a,b){var c=o.get(a);return c&&k(c,b,!0)?(c.value.deferred.resolve(b),h(a),c.value.modalOpener.focus(),!0):!c},p.dismiss=function(a,b){var c=o.get(a);return c&&k(c,b,!1)?(c.value.deferred.reject(b),h(a),c.value.modalOpener.focus(),!0):!c},p.dismissAll=function(a){for(var b=this.getTop();b&&this.dismiss(b.key,a);)b=this.getTop()},p.getTop=function(){return o.top()},p.modalRendered=function(a){var b=o.get(a);b&&b.value.renderDeferred.resolve()},p}]).provider("$modal",function(){var a={options:{animation:!0,backdrop:!0,keyboard:!0},$get:["$injector","$rootScope","$q","$templateRequest","$controller","$modalStack",function(b,c,d,e,f,g){function h(a){return a.template?d.when(a.template):e(angular.isFunction(a.templateUrl)?a.templateUrl():a.templateUrl)}function i(a){var c=[];return angular.forEach(a,function(a){(angular.isFunction(a)||angular.isArray(a))&&c.push(d.when(b.invoke(a)))
9
+ }),c}var j={};return j.open=function(b){var e=d.defer(),j=d.defer(),k=d.defer(),l={result:e.promise,opened:j.promise,rendered:k.promise,close:function(a){return g.close(l,a)},dismiss:function(a){return g.dismiss(l,a)}};if(b=angular.extend({},a.options,b),b.resolve=b.resolve||{},!b.template&&!b.templateUrl)throw new Error("One of template or templateUrl options is required.");var m=d.all([h(b)].concat(i(b.resolve)));return m.then(function(a){var d=(b.scope||c).$new();d.$close=l.close,d.$dismiss=l.dismiss;var h,i={},j=1;b.controller&&(i.$scope=d,i.$modalInstance=l,angular.forEach(b.resolve,function(b,c){i[c]=a[j++]}),h=f(b.controller,i),b.controllerAs&&(d[b.controllerAs]=h)),g.open(l,{scope:d,deferred:e,renderDeferred:k,content:a[0],animation:b.animation,backdrop:b.backdrop,keyboard:b.keyboard,backdropClass:b.backdropClass,windowClass:b.windowClass,windowTemplateUrl:b.windowTemplateUrl,size:b.size})},function(a){e.reject(a)}),m.then(function(){j.resolve(!0)},function(a){j.reject(a)}),l},j}]};return a}),angular.module("ui.bootstrap.pagination",[]).controller("PaginationController",["$scope","$attrs","$parse",function(a,b,c){var d=this,e={$setViewValue:angular.noop},f=b.numPages?c(b.numPages).assign:angular.noop;this.init=function(g,h){e=g,this.config=h,e.$render=function(){d.render()},b.itemsPerPage?a.$parent.$watch(c(b.itemsPerPage),function(b){d.itemsPerPage=parseInt(b,10),a.totalPages=d.calculateTotalPages()}):this.itemsPerPage=h.itemsPerPage,a.$watch("totalItems",function(){a.totalPages=d.calculateTotalPages()}),a.$watch("totalPages",function(b){f(a.$parent,b),a.page>b?a.selectPage(b):e.$render()})},this.calculateTotalPages=function(){var b=this.itemsPerPage<1?1:Math.ceil(a.totalItems/this.itemsPerPage);return Math.max(b||0,1)},this.render=function(){a.page=parseInt(e.$viewValue,10)||1},a.selectPage=function(b,c){a.page!==b&&b>0&&b<=a.totalPages&&(c&&c.target&&c.target.blur(),e.$setViewValue(b),e.$render())},a.getText=function(b){return a[b+"Text"]||d.config[b+"Text"]},a.noPrevious=function(){return 1===a.page},a.noNext=function(){return a.page===a.totalPages}}]).constant("paginationConfig",{itemsPerPage:10,boundaryLinks:!1,directionLinks:!0,firstText:"First",previousText:"Previous",nextText:"Next",lastText:"Last",rotate:!0}).directive("pagination",["$parse","paginationConfig",function(a,b){return{restrict:"EA",scope:{totalItems:"=",firstText:"@",previousText:"@",nextText:"@",lastText:"@"},require:["pagination","?ngModel"],controller:"PaginationController",templateUrl:"template/pagination/pagination.html",replace:!0,link:function(c,d,e,f){function g(a,b,c){return{number:a,text:b,active:c}}function h(a,b){var c=[],d=1,e=b,f=angular.isDefined(k)&&b>k;f&&(l?(d=Math.max(a-Math.floor(k/2),1),e=d+k-1,e>b&&(e=b,d=e-k+1)):(d=(Math.ceil(a/k)-1)*k+1,e=Math.min(d+k-1,b)));for(var h=d;e>=h;h++){var i=g(h,h,h===a);c.push(i)}if(f&&!l){if(d>1){var j=g(d-1,"...",!1);c.unshift(j)}if(b>e){var m=g(e+1,"...",!1);c.push(m)}}return c}var i=f[0],j=f[1];if(j){var k=angular.isDefined(e.maxSize)?c.$parent.$eval(e.maxSize):b.maxSize,l=angular.isDefined(e.rotate)?c.$parent.$eval(e.rotate):b.rotate;c.boundaryLinks=angular.isDefined(e.boundaryLinks)?c.$parent.$eval(e.boundaryLinks):b.boundaryLinks,c.directionLinks=angular.isDefined(e.directionLinks)?c.$parent.$eval(e.directionLinks):b.directionLinks,i.init(j,b),e.maxSize&&c.$parent.$watch(a(e.maxSize),function(a){k=parseInt(a,10),i.render()});var m=i.render;i.render=function(){m(),c.page>0&&c.page<=c.totalPages&&(c.pages=h(c.page,c.totalPages))}}}}}]).constant("pagerConfig",{itemsPerPage:10,previousText:"« Previous",nextText:"Next »",align:!0}).directive("pager",["pagerConfig",function(a){return{restrict:"EA",scope:{totalItems:"=",previousText:"@",nextText:"@"},require:["pager","?ngModel"],controller:"PaginationController",templateUrl:"template/pagination/pager.html",replace:!0,link:function(b,c,d,e){var f=e[0],g=e[1];g&&(b.align=angular.isDefined(d.align)?b.$parent.$eval(d.align):a.align,f.init(g,a))}}}]),angular.module("ui.bootstrap.tooltip",["ui.bootstrap.position","ui.bootstrap.bindHtml"]).provider("$tooltip",function(){function a(a){var b=/[A-Z]/g,c="-";return a.replace(b,function(a,b){return(b?c:"")+a.toLowerCase()})}var b={placement:"top",animation:!0,popupDelay:0,useContentExp:!1},c={mouseenter:"mouseleave",click:"click",focus:"blur"},d={};this.options=function(a){angular.extend(d,a)},this.setTriggers=function(a){angular.extend(c,a)},this.$get=["$window","$compile","$timeout","$document","$position","$interpolate",function(e,f,g,h,i,j){return function(e,k,l,m){function n(a){var b=a||m.trigger||l,d=c[b]||b;return{show:b,hide:d}}m=angular.extend({},b,d,m);var o=a(e),p=j.startSymbol(),q=j.endSymbol(),r="<div "+o+'-popup title="'+p+"title"+q+'" '+(m.useContentExp?'content-exp="contentExp()" ':'content="'+p+"content"+q+'" ')+'placement="'+p+"placement"+q+'" popup-class="'+p+"popupClass"+q+'" animation="animation" is-open="isOpen"origin-scope="origScope" ></div>';return{restrict:"EA",compile:function(){var a=f(r);return function(b,c,d){function f(){E.isOpen?l():j()}function j(){(!D||b.$eval(d[k+"Enable"]))&&(s(),E.popupDelay?A||(A=g(o,E.popupDelay,!1),A.then(function(a){a()})):o()())}function l(){b.$apply(function(){p()})}function o(){return A=null,z&&(g.cancel(z),z=null),(m.useContentExp?E.contentExp():E.content)?(q(),x.css({top:0,left:0,display:"block"}),E.$digest(),F(),E.isOpen=!0,E.$apply(),F):angular.noop}function p(){E.isOpen=!1,g.cancel(A),A=null,E.animation?z||(z=g(r,500)):r()}function q(){x&&r(),y=E.$new(),x=a(y,function(a){B?h.find("body").append(a):c.after(a)}),y.$watch(function(){g(F,0,!1)}),m.useContentExp&&y.$watch("contentExp()",function(a){!a&&E.isOpen&&p()})}function r(){z=null,x&&(x.remove(),x=null),y&&(y.$destroy(),y=null)}function s(){t(),u(),v()}function t(){E.popupClass=d[k+"Class"]}function u(){var a=d[k+"Placement"];E.placement=angular.isDefined(a)?a:m.placement}function v(){var a=d[k+"PopupDelay"],b=parseInt(a,10);E.popupDelay=isNaN(b)?m.popupDelay:b}function w(){var a=d[k+"Trigger"];G(),C=n(a),C.show===C.hide?c.bind(C.show,f):(c.bind(C.show,j),c.bind(C.hide,l))}var x,y,z,A,B=angular.isDefined(m.appendToBody)?m.appendToBody:!1,C=n(void 0),D=angular.isDefined(d[k+"Enable"]),E=b.$new(!0),F=function(){if(x){var a=i.positionElements(c,x,E.placement,B);a.top+="px",a.left+="px",x.css(a)}};E.origScope=b,E.isOpen=!1,E.contentExp=function(){return b.$eval(d[e])},m.useContentExp||d.$observe(e,function(a){E.content=a,!a&&E.isOpen&&p()}),d.$observe("disabled",function(a){a&&E.isOpen&&p()}),d.$observe(k+"Title",function(a){E.title=a});var G=function(){c.unbind(C.show,j),c.unbind(C.hide,l)};w();var H=b.$eval(d[k+"Animation"]);E.animation=angular.isDefined(H)?!!H:m.animation;var I=b.$eval(d[k+"AppendToBody"]);B=angular.isDefined(I)?I:B,B&&b.$on("$locationChangeSuccess",function(){E.isOpen&&p()}),b.$on("$destroy",function(){g.cancel(z),g.cancel(A),G(),r(),E=null})}}}}}]}).directive("tooltipTemplateTransclude",["$animate","$sce","$compile","$templateRequest",function(a,b,c,d){return{link:function(e,f,g){var h,i,j,k=e.$eval(g.tooltipTemplateTranscludeScope),l=0,m=function(){i&&(i.remove(),i=null),h&&(h.$destroy(),h=null),j&&(a.leave(j).then(function(){i=null}),i=j,j=null)};e.$watch(b.parseAsResourceUrl(g.tooltipTemplateTransclude),function(b){var g=++l;b?(d(b,!0).then(function(d){if(g===l){var e=k.$new(),i=d,n=c(i)(e,function(b){m(),a.enter(b,f)});h=e,j=n,h.$emit("$includeContentLoaded",b)}},function(){g===l&&(m(),e.$emit("$includeContentError",b))}),e.$emit("$includeContentRequested",b)):m()}),e.$on("$destroy",m)}}}]).directive("tooltipClasses",function(){return{restrict:"A",link:function(a,b,c){a.placement&&b.addClass(a.placement),a.popupClass&&b.addClass(a.popupClass),a.animation()&&b.addClass(c.tooltipAnimationClass)}}}).directive("tooltipPopup",function(){return{restrict:"EA",replace:!0,scope:{content:"@",placement:"@",popupClass:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-popup.html"}}).directive("tooltip",["$tooltip",function(a){return a("tooltip","tooltip","mouseenter")}]).directive("tooltipTemplatePopup",function(){return{restrict:"EA",replace:!0,scope:{contentExp:"&",placement:"@",popupClass:"@",animation:"&",isOpen:"&",originScope:"&"},templateUrl:"template/tooltip/tooltip-template-popup.html"}}).directive("tooltipTemplate",["$tooltip",function(a){return a("tooltipTemplate","tooltip","mouseenter",{useContentExp:!0})}]).directive("tooltipHtmlPopup",function(){return{restrict:"EA",replace:!0,scope:{contentExp:"&",placement:"@",popupClass:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-html-popup.html"}}).directive("tooltipHtml",["$tooltip",function(a){return a("tooltipHtml","tooltip","mouseenter",{useContentExp:!0})}]).directive("tooltipHtmlUnsafePopup",function(){return{restrict:"EA",replace:!0,scope:{content:"@",placement:"@",popupClass:"@",animation:"&",isOpen:"&"},templateUrl:"template/tooltip/tooltip-html-unsafe-popup.html"}}).value("tooltipHtmlUnsafeSuppressDeprecated",!1).directive("tooltipHtmlUnsafe",["$tooltip","tooltipHtmlUnsafeSuppressDeprecated","$log",function(a,b,c){return b||c.warn("tooltip-html-unsafe is now deprecated. Use tooltip-html or tooltip-template instead."),a("tooltipHtmlUnsafe","tooltip","mouseenter")}]),angular.module("ui.bootstrap.popover",["ui.bootstrap.tooltip"]).directive("popoverTemplatePopup",function(){return{restrict:"EA",replace:!0,scope:{title:"@",contentExp:"&",placement:"@",popupClass:"@",animation:"&",isOpen:"&",originScope:"&"},templateUrl:"template/popover/popover-template.html"}}).directive("popoverTemplate",["$tooltip",function(a){return a("popoverTemplate","popover","click",{useContentExp:!0})}]).directive("popoverPopup",function(){return{restrict:"EA",replace:!0,scope:{title:"@",content:"@",placement:"@",popupClass:"@",animation:"&",isOpen:"&"},templateUrl:"template/popover/popover.html"}}).directive("popover",["$tooltip",function(a){return a("popover","popover","click")}]),angular.module("ui.bootstrap.progressbar",[]).constant("progressConfig",{animate:!0,max:100}).controller("ProgressController",["$scope","$attrs","progressConfig",function(a,b,c){var d=this,e=angular.isDefined(b.animate)?a.$parent.$eval(b.animate):c.animate;this.bars=[],a.max=angular.isDefined(a.max)?a.max:c.max,this.addBar=function(b,c){e||c.css({transition:"none"}),this.bars.push(b),b.$watch("value",function(c){b.percent=+(100*c/a.max).toFixed(2)}),b.$on("$destroy",function(){c=null,d.removeBar(b)})},this.removeBar=function(a){this.bars.splice(this.bars.indexOf(a),1)}}]).directive("progress",function(){return{restrict:"EA",replace:!0,transclude:!0,controller:"ProgressController",require:"progress",scope:{},templateUrl:"template/progressbar/progress.html"}}).directive("bar",function(){return{restrict:"EA",replace:!0,transclude:!0,require:"^progress",scope:{value:"=",max:"=?",type:"@"},templateUrl:"template/progressbar/bar.html",link:function(a,b,c,d){d.addBar(a,b)}}}).directive("progressbar",function(){return{restrict:"EA",replace:!0,transclude:!0,controller:"ProgressController",scope:{value:"=",max:"=?",type:"@"},templateUrl:"template/progressbar/progressbar.html",link:function(a,b,c,d){d.addBar(a,angular.element(b.children()[0]))}}}),angular.module("ui.bootstrap.rating",[]).constant("ratingConfig",{max:5,stateOn:null,stateOff:null}).controller("RatingController",["$scope","$attrs","ratingConfig",function(a,b,c){var d={$setViewValue:angular.noop};this.init=function(e){d=e,d.$render=this.render,d.$formatters.push(function(a){return angular.isNumber(a)&&a<<0!==a&&(a=Math.round(a)),a}),this.stateOn=angular.isDefined(b.stateOn)?a.$parent.$eval(b.stateOn):c.stateOn,this.stateOff=angular.isDefined(b.stateOff)?a.$parent.$eval(b.stateOff):c.stateOff;var f=angular.isDefined(b.ratingStates)?a.$parent.$eval(b.ratingStates):new Array(angular.isDefined(b.max)?a.$parent.$eval(b.max):c.max);a.range=this.buildTemplateObjects(f)},this.buildTemplateObjects=function(a){for(var b=0,c=a.length;c>b;b++)a[b]=angular.extend({index:b},{stateOn:this.stateOn,stateOff:this.stateOff},a[b]);return a},a.rate=function(b){!a.readonly&&b>=0&&b<=a.range.length&&(d.$setViewValue(b),d.$render())},a.enter=function(b){a.readonly||(a.value=b),a.onHover({value:b})},a.reset=function(){a.value=d.$viewValue,a.onLeave()},a.onKeydown=function(b){/(37|38|39|40)/.test(b.which)&&(b.preventDefault(),b.stopPropagation(),a.rate(a.value+(38===b.which||39===b.which?1:-1)))},this.render=function(){a.value=d.$viewValue}}]).directive("rating",function(){return{restrict:"EA",require:["rating","ngModel"],scope:{readonly:"=?",onHover:"&",onLeave:"&"},controller:"RatingController",templateUrl:"template/rating/rating.html",replace:!0,link:function(a,b,c,d){var e=d[0],f=d[1];e.init(f)}}}),angular.module("ui.bootstrap.tabs",[]).controller("TabsetController",["$scope",function(a){var b=this,c=b.tabs=a.tabs=[];b.select=function(a){angular.forEach(c,function(b){b.active&&b!==a&&(b.active=!1,b.onDeselect())}),a.active=!0,a.onSelect()},b.addTab=function(a){c.push(a),1===c.length&&a.active!==!1?a.active=!0:a.active?b.select(a):a.active=!1},b.removeTab=function(a){var e=c.indexOf(a);if(a.active&&c.length>1&&!d){var f=e==c.length-1?e-1:e+1;b.select(c[f])}c.splice(e,1)};var d;a.$on("$destroy",function(){d=!0})}]).directive("tabset",function(){return{restrict:"EA",transclude:!0,replace:!0,scope:{type:"@"},controller:"TabsetController",templateUrl:"template/tabs/tabset.html",link:function(a,b,c){a.vertical=angular.isDefined(c.vertical)?a.$parent.$eval(c.vertical):!1,a.justified=angular.isDefined(c.justified)?a.$parent.$eval(c.justified):!1}}}).directive("tab",["$parse","$log",function(a,b){return{require:"^tabset",restrict:"EA",replace:!0,templateUrl:"template/tabs/tab.html",transclude:!0,scope:{active:"=?",heading:"@",onSelect:"&select",onDeselect:"&deselect"},controller:function(){},compile:function(c,d,e){return function(c,d,f,g){c.$watch("active",function(a){a&&g.select(c)}),c.disabled=!1,f.disable&&c.$parent.$watch(a(f.disable),function(a){c.disabled=!!a}),f.disabled&&(b.warn('Use of "disabled" attribute has been deprecated, please use "disable"'),c.$parent.$watch(a(f.disabled),function(a){c.disabled=!!a})),c.select=function(){c.disabled||(c.active=!0)},g.addTab(c),c.$on("$destroy",function(){g.removeTab(c)}),c.$transcludeFn=e}}}}]).directive("tabHeadingTransclude",[function(){return{restrict:"A",require:"^tab",link:function(a,b){a.$watch("headingElement",function(a){a&&(b.html(""),b.append(a))})}}}]).directive("tabContentTransclude",function(){function a(a){return a.tagName&&(a.hasAttribute("tab-heading")||a.hasAttribute("data-tab-heading")||"tab-heading"===a.tagName.toLowerCase()||"data-tab-heading"===a.tagName.toLowerCase())}return{restrict:"A",require:"^tabset",link:function(b,c,d){var e=b.$eval(d.tabContentTransclude);e.$transcludeFn(e.$parent,function(b){angular.forEach(b,function(b){a(b)?e.headingElement=b:c.append(b)})})}}}),angular.module("ui.bootstrap.timepicker",[]).constant("timepickerConfig",{hourStep:1,minuteStep:1,showMeridian:!0,meridians:null,readonlyInput:!1,mousewheel:!0,arrowkeys:!0}).controller("TimepickerController",["$scope","$attrs","$parse","$log","$locale","timepickerConfig",function(a,b,c,d,e,f){function g(){var b=parseInt(a.hours,10),c=a.showMeridian?b>0&&13>b:b>=0&&24>b;return c?(a.showMeridian&&(12===b&&(b=0),a.meridian===p[1]&&(b+=12)),b):void 0}function h(){var b=parseInt(a.minutes,10);return b>=0&&60>b?b:void 0}function i(a){return angular.isDefined(a)&&a.toString().length<2?"0"+a:a.toString()}function j(a){k(),o.$setViewValue(new Date(n)),l(a)}function k(){o.$setValidity("time",!0),a.invalidHours=!1,a.invalidMinutes=!1}function l(b){var c=n.getHours(),d=n.getMinutes();a.showMeridian&&(c=0===c||12===c?12:c%12),a.hours="h"===b?c:i(c),"m"!==b&&(a.minutes=i(d)),a.meridian=n.getHours()<12?p[0]:p[1]}function m(a){var b=new Date(n.getTime()+6e4*a);n.setHours(b.getHours(),b.getMinutes()),j()}var n=new Date,o={$setViewValue:angular.noop},p=angular.isDefined(b.meridians)?a.$parent.$eval(b.meridians):f.meridians||e.DATETIME_FORMATS.AMPMS;this.init=function(c,d){o=c,o.$render=this.render,o.$formatters.unshift(function(a){return a?new Date(a):null});var e=d.eq(0),g=d.eq(1),h=angular.isDefined(b.mousewheel)?a.$parent.$eval(b.mousewheel):f.mousewheel;h&&this.setupMousewheelEvents(e,g);var i=angular.isDefined(b.arrowkeys)?a.$parent.$eval(b.arrowkeys):f.arrowkeys;i&&this.setupArrowkeyEvents(e,g),a.readonlyInput=angular.isDefined(b.readonlyInput)?a.$parent.$eval(b.readonlyInput):f.readonlyInput,this.setupInputEvents(e,g)};var q=f.hourStep;b.hourStep&&a.$parent.$watch(c(b.hourStep),function(a){q=parseInt(a,10)});var r=f.minuteStep;b.minuteStep&&a.$parent.$watch(c(b.minuteStep),function(a){r=parseInt(a,10)}),a.showMeridian=f.showMeridian,b.showMeridian&&a.$parent.$watch(c(b.showMeridian),function(b){if(a.showMeridian=!!b,o.$error.time){var c=g(),d=h();angular.isDefined(c)&&angular.isDefined(d)&&(n.setHours(c),j())}else l()}),this.setupMousewheelEvents=function(b,c){var d=function(a){a.originalEvent&&(a=a.originalEvent);var b=a.wheelDelta?a.wheelDelta:-a.deltaY;return a.detail||b>0};b.bind("mousewheel wheel",function(b){a.$apply(d(b)?a.incrementHours():a.decrementHours()),b.preventDefault()}),c.bind("mousewheel wheel",function(b){a.$apply(d(b)?a.incrementMinutes():a.decrementMinutes()),b.preventDefault()})},this.setupArrowkeyEvents=function(b,c){b.bind("keydown",function(b){38===b.which?(b.preventDefault(),a.incrementHours(),a.$apply()):40===b.which&&(b.preventDefault(),a.decrementHours(),a.$apply())}),c.bind("keydown",function(b){38===b.which?(b.preventDefault(),a.incrementMinutes(),a.$apply()):40===b.which&&(b.preventDefault(),a.decrementMinutes(),a.$apply())})},this.setupInputEvents=function(b,c){if(a.readonlyInput)return a.updateHours=angular.noop,void(a.updateMinutes=angular.noop);var d=function(b,c){o.$setViewValue(null),o.$setValidity("time",!1),angular.isDefined(b)&&(a.invalidHours=b),angular.isDefined(c)&&(a.invalidMinutes=c)};a.updateHours=function(){var a=g();angular.isDefined(a)?(n.setHours(a),j("h")):d(!0)},b.bind("blur",function(){!a.invalidHours&&a.hours<10&&a.$apply(function(){a.hours=i(a.hours)})}),a.updateMinutes=function(){var a=h();angular.isDefined(a)?(n.setMinutes(a),j("m")):d(void 0,!0)},c.bind("blur",function(){!a.invalidMinutes&&a.minutes<10&&a.$apply(function(){a.minutes=i(a.minutes)})})},this.render=function(){var a=o.$viewValue;isNaN(a)?(o.$setValidity("time",!1),d.error('Timepicker directive: "ng-model" value must be a Date object, a number of milliseconds since 01.01.1970 or a string representing an RFC2822 or ISO 8601 date.')):(a&&(n=a),k(),l())},a.incrementHours=function(){m(60*q)},a.decrementHours=function(){m(60*-q)},a.incrementMinutes=function(){m(r)},a.decrementMinutes=function(){m(-r)},a.toggleMeridian=function(){m(720*(n.getHours()<12?1:-1))}}]).directive("timepicker",function(){return{restrict:"EA",require:["timepicker","?^ngModel"],controller:"TimepickerController",replace:!0,scope:{},templateUrl:"template/timepicker/timepicker.html",link:function(a,b,c,d){var e=d[0],f=d[1];f&&e.init(f,b.find("input"))}}}),angular.module("ui.bootstrap.transition",[]).value("$transitionSuppressDeprecated",!1).factory("$transition",["$q","$timeout","$rootScope","$log","$transitionSuppressDeprecated",function(a,b,c,d,e){function f(a){for(var b in a)if(void 0!==h.style[b])return a[b]}e||d.warn("$transition is now deprecated. Use $animate from ngAnimate instead.");var g=function(d,e,f){f=f||{};var h=a.defer(),i=g[f.animation?"animationEndEventName":"transitionEndEventName"],j=function(){c.$apply(function(){d.unbind(i,j),h.resolve(d)})};return i&&d.bind(i,j),b(function(){angular.isString(e)?d.addClass(e):angular.isFunction(e)?e(d):angular.isObject(e)&&d.css(e),i||h.resolve(d)}),h.promise.cancel=function(){i&&d.unbind(i,j),h.reject("Transition cancelled")},h.promise},h=document.createElement("trans"),i={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",transition:"transitionend"},j={WebkitTransition:"webkitAnimationEnd",MozTransition:"animationend",OTransition:"oAnimationEnd",transition:"animationend"};return g.transitionEndEventName=f(i),g.animationEndEventName=f(j),g}]),angular.module("ui.bootstrap.typeahead",["ui.bootstrap.position","ui.bootstrap.bindHtml"]).factory("typeaheadParser",["$parse",function(a){var b=/^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+([\s\S]+?)$/;return{parse:function(c){var d=c.match(b);if(!d)throw new Error('Expected typeahead specification in form of "_modelValue_ (as _label_)? for _item_ in _collection_" but got "'+c+'".');return{itemName:d[3],source:a(d[4]),viewMapper:a(d[2]||d[1]),modelMapper:a(d[1])}}}}]).directive("typeahead",["$compile","$parse","$q","$timeout","$document","$position","typeaheadParser",function(a,b,c,d,e,f,g){var h=[9,13,27,38,40];return{require:"ngModel",link:function(i,j,k,l){var m,n=i.$eval(k.typeaheadMinLength)||1,o=i.$eval(k.typeaheadWaitMs)||0,p=i.$eval(k.typeaheadEditable)!==!1,q=b(k.typeaheadLoading).assign||angular.noop,r=b(k.typeaheadOnSelect),s=k.typeaheadInputFormatter?b(k.typeaheadInputFormatter):void 0,t=k.typeaheadAppendToBody?i.$eval(k.typeaheadAppendToBody):!1,u=i.$eval(k.typeaheadFocusFirst)!==!1,v=b(k.ngModel).assign,w=g.parse(k.typeahead),x=i.$new();i.$on("$destroy",function(){x.$destroy()});var y="typeahead-"+x.$id+"-"+Math.floor(1e4*Math.random());j.attr({"aria-autocomplete":"list","aria-expanded":!1,"aria-owns":y});var z=angular.element("<div typeahead-popup></div>");z.attr({id:y,matches:"matches",active:"activeIdx",select:"select(activeIdx)",query:"query",position:"position"}),angular.isDefined(k.typeaheadTemplateUrl)&&z.attr("template-url",k.typeaheadTemplateUrl);var A=function(){x.matches=[],x.activeIdx=-1,j.attr("aria-expanded",!1)},B=function(a){return y+"-option-"+a};x.$watch("activeIdx",function(a){0>a?j.removeAttr("aria-activedescendant"):j.attr("aria-activedescendant",B(a))});var C=function(a){var b={$viewValue:a};q(i,!0),c.when(w.source(i,b)).then(function(c){var d=a===l.$viewValue;if(d&&m)if(c&&c.length>0){x.activeIdx=u?0:-1,x.matches.length=0;for(var e=0;e<c.length;e++)b[w.itemName]=c[e],x.matches.push({id:B(e),label:w.viewMapper(x,b),model:c[e]});x.query=a,x.position=t?f.offset(j):f.position(j),x.position.top=x.position.top+j.prop("offsetHeight"),j.attr("aria-expanded",!0)}else A();d&&q(i,!1)},function(){A(),q(i,!1)})};A(),x.query=void 0;var D,E=function(a){D=d(function(){C(a)},o)},F=function(){D&&d.cancel(D)};l.$parsers.unshift(function(a){return m=!0,a&&a.length>=n?o>0?(F(),E(a)):C(a):(q(i,!1),F(),A()),p?a:a?void l.$setValidity("editable",!1):(l.$setValidity("editable",!0),a)}),l.$formatters.push(function(a){var b,c,d={};return p||l.$setValidity("editable",!0),s?(d.$model=a,s(i,d)):(d[w.itemName]=a,b=w.viewMapper(i,d),d[w.itemName]=void 0,c=w.viewMapper(i,d),b!==c?b:a)}),x.select=function(a){var b,c,e={};e[w.itemName]=c=x.matches[a].model,b=w.modelMapper(i,e),v(i,b),l.$setValidity("editable",!0),l.$setValidity("parse",!0),r(i,{$item:c,$model:b,$label:w.viewMapper(i,e)}),A(),d(function(){j[0].focus()},0,!1)},j.bind("keydown",function(a){0!==x.matches.length&&-1!==h.indexOf(a.which)&&(-1!=x.activeIdx||13!==a.which&&9!==a.which)&&(a.preventDefault(),40===a.which?(x.activeIdx=(x.activeIdx+1)%x.matches.length,x.$digest()):38===a.which?(x.activeIdx=(x.activeIdx>0?x.activeIdx:x.matches.length)-1,x.$digest()):13===a.which||9===a.which?x.$apply(function(){x.select(x.activeIdx)}):27===a.which&&(a.stopPropagation(),A(),x.$digest()))}),j.bind("blur",function(){m=!1});var G=function(a){j[0]!==a.target&&(A(),x.$digest())};e.bind("click",G),i.$on("$destroy",function(){e.unbind("click",G),t&&H.remove(),z.remove()});var H=a(z)(x);t?e.find("body").append(H):j.after(H)}}}]).directive("typeaheadPopup",function(){return{restrict:"EA",scope:{matches:"=",query:"=",active:"=",position:"=",select:"&"},replace:!0,templateUrl:"template/typeahead/typeahead-popup.html",link:function(a,b,c){a.templateUrl=c.templateUrl,a.isOpen=function(){return a.matches.length>0},a.isActive=function(b){return a.active==b},a.selectActive=function(b){a.active=b},a.selectMatch=function(b){a.select({activeIdx:b})}}}}).directive("typeaheadMatch",["$templateRequest","$compile","$parse",function(a,b,c){return{restrict:"EA",scope:{index:"=",match:"=",query:"="},link:function(d,e,f){var g=c(f.templateUrl)(d.$parent)||"template/typeahead/typeahead-match.html";a(g).then(function(a){b(a.trim())(d,function(a){e.replaceWith(a)})})}}}]).filter("typeaheadHighlight",function(){function a(a){return a.replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1")}return function(b,c){return c?(""+b).replace(new RegExp(a(c),"gi"),"<strong>$&</strong>"):b}}),angular.module("template/accordion/accordion-group.html",[]).run(["$templateCache",function(a){a.put("template/accordion/accordion-group.html",'<div class="panel panel-default">\n <div class="panel-heading">\n <h4 class="panel-title">\n <a href="javascript:void(0)" tabindex="0" class="accordion-toggle" ng-click="toggleOpen()" accordion-transclude="heading"><span ng-class="{\'text-muted\': isDisabled}">{{heading}}</span></a>\n </h4>\n </div>\n <div class="panel-collapse collapse" collapse="!isOpen">\n <div class="panel-body" ng-transclude></div>\n </div>\n</div>\n')}]),angular.module("template/accordion/accordion.html",[]).run(["$templateCache",function(a){a.put("template/accordion/accordion.html",'<div class="panel-group" ng-transclude></div>')}]),angular.module("template/alert/alert.html",[]).run(["$templateCache",function(a){a.put("template/alert/alert.html",'<div class="alert" ng-class="[\'alert-\' + (type || \'warning\'), closeable ? \'alert-dismissable\' : null]" role="alert">\n <button ng-show="closeable" type="button" class="close" ng-click="close()">\n <span aria-hidden="true">&times;</span>\n <span class="sr-only">Close</span>\n </button>\n <div ng-transclude></div>\n</div>\n')}]),angular.module("template/carousel/carousel.html",[]).run(["$templateCache",function(a){a.put("template/carousel/carousel.html",'<div ng-mouseenter="pause()" ng-mouseleave="play()" class="carousel" ng-swipe-right="prev()" ng-swipe-left="next()">\n <ol class="carousel-indicators" ng-show="slides.length > 1">\n <li ng-repeat="slide in slides | orderBy:\'index\' track by $index" ng-class="{active: isActive(slide)}" ng-click="select(slide)"></li>\n </ol>\n <div class="carousel-inner" ng-transclude></div>\n <a class="left carousel-control" ng-click="prev()" ng-show="slides.length > 1"><span class="glyphicon glyphicon-chevron-left"></span></a>\n <a class="right carousel-control" ng-click="next()" ng-show="slides.length > 1"><span class="glyphicon glyphicon-chevron-right"></span></a>\n</div>\n')}]),angular.module("template/carousel/slide.html",[]).run(["$templateCache",function(a){a.put("template/carousel/slide.html",'<div ng-class="{\n \'active\': active\n }" class="item text-center" ng-transclude></div>\n')}]),angular.module("template/datepicker/datepicker.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/datepicker.html",'<div ng-switch="datepickerMode" role="application" ng-keydown="keydown($event)">\n <daypicker ng-switch-when="day" tabindex="0"></daypicker>\n <monthpicker ng-switch-when="month" tabindex="0"></monthpicker>\n <yearpicker ng-switch-when="year" tabindex="0"></yearpicker>\n</div>')}]),angular.module("template/datepicker/day.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/day.html",'<table role="grid" aria-labelledby="{{uniqueId}}-title" aria-activedescendant="{{activeDateId}}">\n <thead>\n <tr>\n <th><button type="button" class="btn btn-default btn-sm pull-left" ng-click="move(-1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-left"></i></button></th>\n <th colspan="{{5 + showWeeks}}"><button id="{{uniqueId}}-title" role="heading" aria-live="assertive" aria-atomic="true" type="button" class="btn btn-default btn-sm" ng-click="toggleMode()" ng-disabled="datepickerMode === maxMode" tabindex="-1" style="width:100%;"><strong>{{title}}</strong></button></th>\n <th><button type="button" class="btn btn-default btn-sm pull-right" ng-click="move(1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-right"></i></button></th>\n </tr>\n <tr>\n <th ng-show="showWeeks" class="text-center"></th>\n <th ng-repeat="label in labels track by $index" class="text-center"><small aria-label="{{label.full}}">{{label.abbr}}</small></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="row in rows track by $index">\n <td ng-show="showWeeks" class="text-center h6"><em>{{ weekNumbers[$index] }}</em></td>\n <td ng-repeat="dt in row track by dt.date" class="text-center" role="gridcell" id="{{dt.uid}}" aria-disabled="{{!!dt.disabled}}" ng-class="dt.customClass">\n <button type="button" style="width:100%;" class="btn btn-default btn-sm" ng-class="{\'btn-info\': dt.selected, active: isActive(dt)}" ng-click="select(dt.date)" ng-disabled="dt.disabled" tabindex="-1"><span ng-class="{\'text-muted\': dt.secondary, \'text-info\': dt.current}">{{dt.label}}</span></button>\n </td>\n </tr>\n </tbody>\n</table>\n')}]),angular.module("template/datepicker/month.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/month.html",'<table role="grid" aria-labelledby="{{uniqueId}}-title" aria-activedescendant="{{activeDateId}}">\n <thead>\n <tr>\n <th><button type="button" class="btn btn-default btn-sm pull-left" ng-click="move(-1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-left"></i></button></th>\n <th><button id="{{uniqueId}}-title" role="heading" aria-live="assertive" aria-atomic="true" type="button" class="btn btn-default btn-sm" ng-click="toggleMode()" ng-disabled="datepickerMode === maxMode" tabindex="-1" style="width:100%;"><strong>{{title}}</strong></button></th>\n <th><button type="button" class="btn btn-default btn-sm pull-right" ng-click="move(1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-right"></i></button></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="row in rows track by $index">\n <td ng-repeat="dt in row track by dt.date" class="text-center" role="gridcell" id="{{dt.uid}}" aria-disabled="{{!!dt.disabled}}">\n <button type="button" style="width:100%;" class="btn btn-default" ng-class="{\'btn-info\': dt.selected, active: isActive(dt)}" ng-click="select(dt.date)" ng-disabled="dt.disabled" tabindex="-1"><span ng-class="{\'text-info\': dt.current}">{{dt.label}}</span></button>\n </td>\n </tr>\n </tbody>\n</table>\n')}]),angular.module("template/datepicker/popup.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/popup.html",'<ul class="dropdown-menu" ng-style="{display: (isOpen && \'block\') || \'none\', top: position.top+\'px\', left: position.left+\'px\'}" ng-keydown="keydown($event)">\n <li ng-transclude></li>\n <li ng-if="showButtonBar" style="padding:10px 9px 2px">\n <span class="btn-group pull-left">\n <button type="button" class="btn btn-sm btn-info" ng-click="select(\'today\')">{{ getText(\'current\') }}</button>\n <button type="button" class="btn btn-sm btn-danger" ng-click="select(null)">{{ getText(\'clear\') }}</button>\n </span>\n <button type="button" class="btn btn-sm btn-success pull-right" ng-click="close()">{{ getText(\'close\') }}</button>\n </li>\n</ul>\n')}]),angular.module("template/datepicker/year.html",[]).run(["$templateCache",function(a){a.put("template/datepicker/year.html",'<table role="grid" aria-labelledby="{{uniqueId}}-title" aria-activedescendant="{{activeDateId}}">\n <thead>\n <tr>\n <th><button type="button" class="btn btn-default btn-sm pull-left" ng-click="move(-1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-left"></i></button></th>\n <th colspan="3"><button id="{{uniqueId}}-title" role="heading" aria-live="assertive" aria-atomic="true" type="button" class="btn btn-default btn-sm" ng-click="toggleMode()" ng-disabled="datepickerMode === maxMode" tabindex="-1" style="width:100%;"><strong>{{title}}</strong></button></th>\n <th><button type="button" class="btn btn-default btn-sm pull-right" ng-click="move(1)" tabindex="-1"><i class="glyphicon glyphicon-chevron-right"></i></button></th>\n </tr>\n </thead>\n <tbody>\n <tr ng-repeat="row in rows track by $index">\n <td ng-repeat="dt in row track by dt.date" class="text-center" role="gridcell" id="{{dt.uid}}" aria-disabled="{{!!dt.disabled}}">\n <button type="button" style="width:100%;" class="btn btn-default" ng-class="{\'btn-info\': dt.selected, active: isActive(dt)}" ng-click="select(dt.date)" ng-disabled="dt.disabled" tabindex="-1"><span ng-class="{\'text-info\': dt.current}">{{dt.label}}</span></button>\n </td>\n </tr>\n </tbody>\n</table>\n')
10
+ }]),angular.module("template/modal/backdrop.html",[]).run(["$templateCache",function(a){a.put("template/modal/backdrop.html",'<div class="modal-backdrop"\n modal-animation-class="fade"\n ng-class="{in: animate}"\n ng-style="{\'z-index\': 1040 + (index && 1 || 0) + index*10}"\n></div>\n')}]),angular.module("template/modal/window.html",[]).run(["$templateCache",function(a){a.put("template/modal/window.html",'<div modal-render="{{$isRendered}}" tabindex="-1" role="dialog" class="modal"\n modal-animation-class="fade"\n ng-class="{in: animate}" ng-style="{\'z-index\': 1050 + index*10, display: \'block\'}" ng-click="close($event)">\n <div class="modal-dialog" ng-class="size ? \'modal-\' + size : \'\'"><div class="modal-content" modal-transclude></div></div>\n</div>\n')}]),angular.module("template/pagination/pager.html",[]).run(["$templateCache",function(a){a.put("template/pagination/pager.html",'<ul class="pager">\n <li ng-class="{disabled: noPrevious(), previous: align}"><a href ng-click="selectPage(page - 1, $event)">{{getText(\'previous\')}}</a></li>\n <li ng-class="{disabled: noNext(), next: align}"><a href ng-click="selectPage(page + 1, $event)">{{getText(\'next\')}}</a></li>\n</ul>')}]),angular.module("template/pagination/pagination.html",[]).run(["$templateCache",function(a){a.put("template/pagination/pagination.html",'<ul class="pagination">\n <li ng-if="boundaryLinks" ng-class="{disabled: noPrevious()}"><a href ng-click="selectPage(1, $event)">{{getText(\'first\')}}</a></li>\n <li ng-if="directionLinks" ng-class="{disabled: noPrevious()}"><a href ng-click="selectPage(page - 1, $event)">{{getText(\'previous\')}}</a></li>\n <li ng-repeat="page in pages track by $index" ng-class="{active: page.active}"><a href ng-click="selectPage(page.number, $event)">{{page.text}}</a></li>\n <li ng-if="directionLinks" ng-class="{disabled: noNext()}"><a href ng-click="selectPage(page + 1, $event)">{{getText(\'next\')}}</a></li>\n <li ng-if="boundaryLinks" ng-class="{disabled: noNext()}"><a href ng-click="selectPage(totalPages, $event)">{{getText(\'last\')}}</a></li>\n</ul>')}]),angular.module("template/tooltip/tooltip-html-popup.html",[]).run(["$templateCache",function(a){a.put("template/tooltip/tooltip-html-popup.html",'<div class="tooltip"\n tooltip-animation-class="fade"\n tooltip-classes\n ng-class="{ in: isOpen() }">\n <div class="tooltip-arrow"></div>\n <div class="tooltip-inner" ng-bind-html="contentExp()"></div>\n</div>\n')}]),angular.module("template/tooltip/tooltip-html-unsafe-popup.html",[]).run(["$templateCache",function(a){a.put("template/tooltip/tooltip-html-unsafe-popup.html",'<div class="tooltip"\n tooltip-animation-class="fade"\n tooltip-classes\n ng-class="{ in: isOpen() }">\n <div class="tooltip-arrow"></div>\n <div class="tooltip-inner" bind-html-unsafe="content"></div>\n</div>\n')}]),angular.module("template/tooltip/tooltip-popup.html",[]).run(["$templateCache",function(a){a.put("template/tooltip/tooltip-popup.html",'<div class="tooltip"\n tooltip-animation-class="fade"\n tooltip-classes\n ng-class="{ in: isOpen() }">\n <div class="tooltip-arrow"></div>\n <div class="tooltip-inner" ng-bind="content"></div>\n</div>\n')}]),angular.module("template/tooltip/tooltip-template-popup.html",[]).run(["$templateCache",function(a){a.put("template/tooltip/tooltip-template-popup.html",'<div class="tooltip"\n tooltip-animation-class="fade"\n tooltip-classes\n ng-class="{ in: isOpen() }">\n <div class="tooltip-arrow"></div>\n <div class="tooltip-inner"\n tooltip-template-transclude="contentExp()"\n tooltip-template-transclude-scope="originScope()"></div>\n</div>\n')}]),angular.module("template/popover/popover-template.html",[]).run(["$templateCache",function(a){a.put("template/popover/popover-template.html",'<div class="popover"\n tooltip-animation-class="fade"\n tooltip-classes\n ng-class="{ in: isOpen() }">\n <div class="arrow"></div>\n\n <div class="popover-inner">\n <h3 class="popover-title" ng-bind="title" ng-if="title"></h3>\n <div class="popover-content"\n tooltip-template-transclude="contentExp()"\n tooltip-template-transclude-scope="originScope()"></div>\n </div>\n</div>\n')}]),angular.module("template/popover/popover-window.html",[]).run(["$templateCache",function(a){a.put("template/popover/popover-window.html",'<div class="popover {{placement}}" ng-class="{ in: isOpen, fade: animation }">\n <div class="arrow"></div>\n\n <div class="popover-inner">\n <h3 class="popover-title" ng-bind="title" ng-show="title"></h3>\n <div class="popover-content" tooltip-template-transclude></div>\n </div>\n</div>\n')}]),angular.module("template/popover/popover.html",[]).run(["$templateCache",function(a){a.put("template/popover/popover.html",'<div class="popover"\n tooltip-animation-class="fade"\n tooltip-classes\n ng-class="{ in: isOpen() }">\n <div class="arrow"></div>\n\n <div class="popover-inner">\n <h3 class="popover-title" ng-bind="title" ng-if="title"></h3>\n <div class="popover-content" ng-bind="content"></div>\n </div>\n</div>\n')}]),angular.module("template/progressbar/bar.html",[]).run(["$templateCache",function(a){a.put("template/progressbar/bar.html",'<div class="progress-bar" ng-class="type && \'progress-bar-\' + type" role="progressbar" aria-valuenow="{{value}}" aria-valuemin="0" aria-valuemax="{{max}}" ng-style="{width: (percent < 100 ? percent : 100) + \'%\'}" aria-valuetext="{{percent | number:0}}%" ng-transclude></div>\n')}]),angular.module("template/progressbar/progress.html",[]).run(["$templateCache",function(a){a.put("template/progressbar/progress.html",'<div class="progress" ng-transclude></div>')}]),angular.module("template/progressbar/progressbar.html",[]).run(["$templateCache",function(a){a.put("template/progressbar/progressbar.html",'<div class="progress">\n <div class="progress-bar" ng-class="type && \'progress-bar-\' + type" role="progressbar" aria-valuenow="{{value}}" aria-valuemin="0" aria-valuemax="{{max}}" ng-style="{width: (percent < 100 ? percent : 100) + \'%\'}" aria-valuetext="{{percent | number:0}}%" ng-transclude></div>\n</div>\n')}]),angular.module("template/rating/rating.html",[]).run(["$templateCache",function(a){a.put("template/rating/rating.html",'<span ng-mouseleave="reset()" ng-keydown="onKeydown($event)" tabindex="0" role="slider" aria-valuemin="0" aria-valuemax="{{range.length}}" aria-valuenow="{{value}}">\n <i ng-repeat="r in range track by $index" ng-mouseenter="enter($index + 1)" ng-click="rate($index + 1)" class="glyphicon" ng-class="$index < value && (r.stateOn || \'glyphicon-star\') || (r.stateOff || \'glyphicon-star-empty\')">\n <span class="sr-only">({{ $index < value ? \'*\' : \' \' }})</span>\n </i>\n</span>')}]),angular.module("template/tabs/tab.html",[]).run(["$templateCache",function(a){a.put("template/tabs/tab.html",'<li ng-class="{active: active, disabled: disabled}">\n <a href ng-click="select()" tab-heading-transclude>{{heading}}</a>\n</li>\n')}]),angular.module("template/tabs/tabset.html",[]).run(["$templateCache",function(a){a.put("template/tabs/tabset.html",'<div>\n <ul class="nav nav-{{type || \'tabs\'}}" ng-class="{\'nav-stacked\': vertical, \'nav-justified\': justified}" ng-transclude></ul>\n <div class="tab-content">\n <div class="tab-pane" \n ng-repeat="tab in tabs" \n ng-class="{active: tab.active}"\n tab-content-transclude="tab">\n </div>\n </div>\n</div>\n')}]),angular.module("template/timepicker/timepicker.html",[]).run(["$templateCache",function(a){a.put("template/timepicker/timepicker.html",'<table>\n <tbody>\n <tr class="text-center">\n <td><a ng-click="incrementHours()" class="btn btn-link"><span class="glyphicon glyphicon-chevron-up"></span></a></td>\n <td>&nbsp;</td>\n <td><a ng-click="incrementMinutes()" class="btn btn-link"><span class="glyphicon glyphicon-chevron-up"></span></a></td>\n <td ng-show="showMeridian"></td>\n </tr>\n <tr>\n <td class="form-group" ng-class="{\'has-error\': invalidHours}">\n <input style="width:50px;" type="text" ng-model="hours" ng-change="updateHours()" class="form-control text-center" ng-readonly="readonlyInput" maxlength="2">\n </td>\n <td>:</td>\n <td class="form-group" ng-class="{\'has-error\': invalidMinutes}">\n <input style="width:50px;" type="text" ng-model="minutes" ng-change="updateMinutes()" class="form-control text-center" ng-readonly="readonlyInput" maxlength="2">\n </td>\n <td ng-show="showMeridian"><button type="button" class="btn btn-default text-center" ng-click="toggleMeridian()">{{meridian}}</button></td>\n </tr>\n <tr class="text-center">\n <td><a ng-click="decrementHours()" class="btn btn-link"><span class="glyphicon glyphicon-chevron-down"></span></a></td>\n <td>&nbsp;</td>\n <td><a ng-click="decrementMinutes()" class="btn btn-link"><span class="glyphicon glyphicon-chevron-down"></span></a></td>\n <td ng-show="showMeridian"></td>\n </tr>\n </tbody>\n</table>\n')}]),angular.module("template/typeahead/typeahead-match.html",[]).run(["$templateCache",function(a){a.put("template/typeahead/typeahead-match.html",'<a tabindex="-1" bind-html-unsafe="match.label | typeaheadHighlight:query"></a>')}]),angular.module("template/typeahead/typeahead-popup.html",[]).run(["$templateCache",function(a){a.put("template/typeahead/typeahead-popup.html",'<ul class="dropdown-menu" ng-show="isOpen()" ng-style="{top: position.top+\'px\', left: position.left+\'px\'}" style="display: block;" role="listbox" aria-hidden="{{!isOpen()}}">\n <li ng-repeat="match in matches track by $index" ng-class="{active: isActive($index) }" ng-mouseenter="selectActive($index)" ng-click="selectMatch($index)" role="option" id="{{match.id}}">\n <div typeahead-match index="$index" match="match" query="query" template-url="templateUrl"></div>\n </li>\n</ul>\n')}]),!angular.$$csp()&&angular.element(document).find("head").prepend('<style type="text/css">.ng-animate.item:not(.left):not(.right){-webkit-transition:0s ease-in-out left;transition:0s ease-in-out left}</style>');
@@ -2,154 +2,46 @@
2
2
  * angular-ui-bootstrap
3
3
  * http://angular-ui.github.io/bootstrap/
4
4
 
5
- * Version: 0.11.0 - 2014-05-01
5
+ * Version: 0.13.0 - 2015-05-02
6
6
  * License: MIT
7
7
  */
8
- angular.module("ui.bootstrap", ["ui.bootstrap.transition","ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.bindHtml","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.dateparser","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dropdown","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.typeahead"]);
9
- angular.module('ui.bootstrap.transition', [])
10
-
11
- /**
12
- * $transition service provides a consistent interface to trigger CSS 3 transitions and to be informed when they complete.
13
- * @param {DOMElement} element The DOMElement that will be animated.
14
- * @param {string|object|function} trigger The thing that will cause the transition to start:
15
- * - As a string, it represents the css class to be added to the element.
16
- * - As an object, it represents a hash of style attributes to be applied to the element.
17
- * - As a function, it represents a function to be called that will cause the transition to occur.
18
- * @return {Promise} A promise that is resolved when the transition finishes.
19
- */
20
- .factory('$transition', ['$q', '$timeout', '$rootScope', function($q, $timeout, $rootScope) {
21
-
22
- var $transition = function(element, trigger, options) {
23
- options = options || {};
24
- var deferred = $q.defer();
25
- var endEventName = $transition[options.animation ? 'animationEndEventName' : 'transitionEndEventName'];
26
-
27
- var transitionEndHandler = function(event) {
28
- $rootScope.$apply(function() {
29
- element.unbind(endEventName, transitionEndHandler);
30
- deferred.resolve(element);
31
- });
32
- };
8
+ angular.module("ui.bootstrap", ["ui.bootstrap.collapse","ui.bootstrap.accordion","ui.bootstrap.alert","ui.bootstrap.bindHtml","ui.bootstrap.buttons","ui.bootstrap.carousel","ui.bootstrap.dateparser","ui.bootstrap.position","ui.bootstrap.datepicker","ui.bootstrap.dropdown","ui.bootstrap.modal","ui.bootstrap.pagination","ui.bootstrap.tooltip","ui.bootstrap.popover","ui.bootstrap.progressbar","ui.bootstrap.rating","ui.bootstrap.tabs","ui.bootstrap.timepicker","ui.bootstrap.transition","ui.bootstrap.typeahead"]);
9
+ angular.module('ui.bootstrap.collapse', [])
33
10
 
34
- if (endEventName) {
35
- element.bind(endEventName, transitionEndHandler);
36
- }
37
-
38
- // Wrap in a timeout to allow the browser time to update the DOM before the transition is to occur
39
- $timeout(function() {
40
- if ( angular.isString(trigger) ) {
41
- element.addClass(trigger);
42
- } else if ( angular.isFunction(trigger) ) {
43
- trigger(element);
44
- } else if ( angular.isObject(trigger) ) {
45
- element.css(trigger);
46
- }
47
- //If browser does not support transitions, instantly resolve
48
- if ( !endEventName ) {
49
- deferred.resolve(element);
50
- }
51
- });
52
-
53
- // Add our custom cancel function to the promise that is returned
54
- // We can call this if we are about to run a new transition, which we know will prevent this transition from ending,
55
- // i.e. it will therefore never raise a transitionEnd event for that transition
56
- deferred.promise.cancel = function() {
57
- if ( endEventName ) {
58
- element.unbind(endEventName, transitionEndHandler);
59
- }
60
- deferred.reject('Transition cancelled');
61
- };
62
-
63
- return deferred.promise;
64
- };
65
-
66
- // Work out the name of the transitionEnd event
67
- var transElement = document.createElement('trans');
68
- var transitionEndEventNames = {
69
- 'WebkitTransition': 'webkitTransitionEnd',
70
- 'MozTransition': 'transitionend',
71
- 'OTransition': 'oTransitionEnd',
72
- 'transition': 'transitionend'
73
- };
74
- var animationEndEventNames = {
75
- 'WebkitTransition': 'webkitAnimationEnd',
76
- 'MozTransition': 'animationend',
77
- 'OTransition': 'oAnimationEnd',
78
- 'transition': 'animationend'
79
- };
80
- function findEndEventName(endEventNames) {
81
- for (var name in endEventNames){
82
- if (transElement.style[name] !== undefined) {
83
- return endEventNames[name];
84
- }
85
- }
86
- }
87
- $transition.transitionEndEventName = findEndEventName(transitionEndEventNames);
88
- $transition.animationEndEventName = findEndEventName(animationEndEventNames);
89
- return $transition;
90
- }]);
91
-
92
- angular.module('ui.bootstrap.collapse', ['ui.bootstrap.transition'])
93
-
94
- .directive('collapse', ['$transition', function ($transition) {
11
+ .directive('collapse', ['$animate', function ($animate) {
95
12
 
96
13
  return {
97
14
  link: function (scope, element, attrs) {
98
-
99
- var initialAnimSkip = true;
100
- var currentTransition;
101
-
102
- function doTransition(change) {
103
- var newTransition = $transition(element, change);
104
- if (currentTransition) {
105
- currentTransition.cancel();
106
- }
107
- currentTransition = newTransition;
108
- newTransition.then(newTransitionDone, newTransitionDone);
109
- return newTransition;
110
-
111
- function newTransitionDone() {
112
- // Make sure it's this transition, otherwise, leave it alone.
113
- if (currentTransition === newTransition) {
114
- currentTransition = undefined;
115
- }
116
- }
117
- }
118
-
119
15
  function expand() {
120
- if (initialAnimSkip) {
121
- initialAnimSkip = false;
122
- expandDone();
123
- } else {
124
- element.removeClass('collapse').addClass('collapsing');
125
- doTransition({ height: element[0].scrollHeight + 'px' }).then(expandDone);
126
- }
16
+ element.removeClass('collapse').addClass('collapsing');
17
+ $animate.addClass(element, 'in', {
18
+ to: { height: element[0].scrollHeight + 'px' }
19
+ }).then(expandDone);
127
20
  }
128
21
 
129
22
  function expandDone() {
130
23
  element.removeClass('collapsing');
131
- element.addClass('collapse in');
132
24
  element.css({height: 'auto'});
133
25
  }
134
26
 
135
27
  function collapse() {
136
- if (initialAnimSkip) {
137
- initialAnimSkip = false;
138
- collapseDone();
139
- element.css({height: 0});
140
- } else {
141
- // CSS transitions don't work with height: auto, so we have to manually change the height to a specific value
142
- element.css({ height: element[0].scrollHeight + 'px' });
143
- //trigger reflow so a browser realizes that height was updated from auto to a specific value
144
- var x = element[0].offsetWidth;
145
-
146
- element.removeClass('collapse in').addClass('collapsing');
147
-
148
- doTransition({ height: 0 }).then(collapseDone);
149
- }
28
+ element
29
+ // IMPORTANT: The height must be set before adding "collapsing" class.
30
+ // Otherwise, the browser attempts to animate from height 0 (in
31
+ // collapsing class) to the given height here.
32
+ .css({height: element[0].scrollHeight + 'px'})
33
+ // initially all panel collapse have the collapse class, this removal
34
+ // prevents the animation from jumping to collapsed state
35
+ .removeClass('collapse')
36
+ .addClass('collapsing');
37
+
38
+ $animate.removeClass(element, 'in', {
39
+ to: {height: '0'}
40
+ }).then(collapseDone);
150
41
  }
151
42
 
152
43
  function collapseDone() {
44
+ element.css({height: '0'}); // Required so that collapse works when animation is disabled
153
45
  element.removeClass('collapsing');
154
46
  element.addClass('collapse');
155
47
  }
@@ -271,7 +163,7 @@ angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
271
163
  // Pass the heading to the accordion-group controller
272
164
  // so that it can be transcluded into the right place in the template
273
165
  // [The second parameter to transclude causes the elements to be cloned so that they work in ng-repeat]
274
- accordionGroupCtrl.setHeading(transclude(scope, function() {}));
166
+ accordionGroupCtrl.setHeading(transclude(scope, angular.noop));
275
167
  }
276
168
  };
277
169
  })
@@ -294,12 +186,15 @@ angular.module('ui.bootstrap.accordion', ['ui.bootstrap.collapse'])
294
186
  });
295
187
  }
296
188
  };
297
- });
189
+ })
190
+
191
+ ;
298
192
 
299
193
  angular.module('ui.bootstrap.alert', [])
300
194
 
301
195
  .controller('AlertController', ['$scope', '$attrs', function ($scope, $attrs) {
302
196
  $scope.closeable = 'close' in $attrs;
197
+ this.close = $scope.close;
303
198
  }])
304
199
 
305
200
  .directive('alert', function () {
@@ -314,7 +209,18 @@ angular.module('ui.bootstrap.alert', [])
314
209
  close: '&'
315
210
  }
316
211
  };
317
- });
212
+ })
213
+
214
+ .directive('dismissOnTimeout', ['$timeout', function($timeout) {
215
+ return {
216
+ require: 'alert',
217
+ link: function(scope, element, attrs, alertCtrl) {
218
+ $timeout(function(){
219
+ alertCtrl.close();
220
+ }, parseInt(attrs.dismissOnTimeout, 10));
221
+ }
222
+ };
223
+ }]);
318
224
 
319
225
  angular.module('ui.bootstrap.bindHtml', [])
320
226
 
@@ -409,93 +315,87 @@ angular.module('ui.bootstrap.buttons', [])
409
315
  * AngularJS version of an image carousel.
410
316
  *
411
317
  */
412
- angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition'])
413
- .controller('CarouselController', ['$scope', '$timeout', '$transition', function ($scope, $timeout, $transition) {
318
+ angular.module('ui.bootstrap.carousel', [])
319
+ .controller('CarouselController', ['$scope', '$interval', '$animate', function ($scope, $interval, $animate) {
414
320
  var self = this,
415
321
  slides = self.slides = $scope.slides = [],
416
322
  currentIndex = -1,
417
- currentTimeout, isPlaying;
323
+ currentInterval, isPlaying;
418
324
  self.currentSlide = null;
419
325
 
420
326
  var destroyed = false;
421
327
  /* direction: "prev" or "next" */
422
328
  self.select = $scope.select = function(nextSlide, direction) {
423
- var nextIndex = slides.indexOf(nextSlide);
329
+ var nextIndex = self.indexOfSlide(nextSlide);
424
330
  //Decide direction if it's not given
425
331
  if (direction === undefined) {
426
- direction = nextIndex > currentIndex ? 'next' : 'prev';
332
+ direction = nextIndex > self.getCurrentIndex() ? 'next' : 'prev';
427
333
  }
428
334
  if (nextSlide && nextSlide !== self.currentSlide) {
429
- if ($scope.$currentTransition) {
430
- $scope.$currentTransition.cancel();
431
- //Timeout so ng-class in template has time to fix classes for finished slide
432
- $timeout(goNext);
433
- } else {
434
- goNext();
435
- }
335
+ goNext();
436
336
  }
437
337
  function goNext() {
438
338
  // Scope has been destroyed, stop here.
439
339
  if (destroyed) { return; }
440
- //If we have a slide to transition from and we have a transition type and we're allowed, go
441
- if (self.currentSlide && angular.isString(direction) && !$scope.noTransition && nextSlide.$element) {
442
- //We shouldn't do class manip in here, but it's the same weird thing bootstrap does. need to fix sometime
443
- nextSlide.$element.addClass(direction);
444
- var reflow = nextSlide.$element[0].offsetWidth; //force reflow
445
-
446
- //Set all other slides to stop doing their stuff for the new transition
447
- angular.forEach(slides, function(slide) {
448
- angular.extend(slide, {direction: '', entering: false, leaving: false, active: false});
340
+
341
+ angular.extend(nextSlide, {direction: direction, active: true});
342
+ angular.extend(self.currentSlide || {}, {direction: direction, active: false});
343
+ if ($animate.enabled() && !$scope.noTransition && nextSlide.$element) {
344
+ $scope.$currentTransition = true;
345
+ nextSlide.$element.one('$animate:close', function closeFn() {
346
+ $scope.$currentTransition = null;
449
347
  });
450
- angular.extend(nextSlide, {direction: direction, active: true, entering: true});
451
- angular.extend(self.currentSlide||{}, {direction: direction, leaving: true});
452
-
453
- $scope.$currentTransition = $transition(nextSlide.$element, {});
454
- //We have to create new pointers inside a closure since next & current will change
455
- (function(next,current) {
456
- $scope.$currentTransition.then(
457
- function(){ transitionDone(next, current); },
458
- function(){ transitionDone(next, current); }
459
- );
460
- }(nextSlide, self.currentSlide));
461
- } else {
462
- transitionDone(nextSlide, self.currentSlide);
463
348
  }
349
+
464
350
  self.currentSlide = nextSlide;
465
351
  currentIndex = nextIndex;
466
352
  //every time you change slides, reset the timer
467
353
  restartTimer();
468
354
  }
469
- function transitionDone(next, current) {
470
- angular.extend(next, {direction: '', active: true, leaving: false, entering: false});
471
- angular.extend(current||{}, {direction: '', active: false, leaving: false, entering: false});
472
- $scope.$currentTransition = null;
473
- }
474
355
  };
475
356
  $scope.$on('$destroy', function () {
476
357
  destroyed = true;
477
358
  });
478
359
 
360
+ function getSlideByIndex(index) {
361
+ if (angular.isUndefined(slides[index].index)) {
362
+ return slides[index];
363
+ }
364
+ var i, len = slides.length;
365
+ for (i = 0; i < slides.length; ++i) {
366
+ if (slides[i].index == index) {
367
+ return slides[i];
368
+ }
369
+ }
370
+ }
371
+
372
+ self.getCurrentIndex = function() {
373
+ if (self.currentSlide && angular.isDefined(self.currentSlide.index)) {
374
+ return +self.currentSlide.index;
375
+ }
376
+ return currentIndex;
377
+ };
378
+
479
379
  /* Allow outside people to call indexOf on slides array */
480
380
  self.indexOfSlide = function(slide) {
481
- return slides.indexOf(slide);
381
+ return angular.isDefined(slide.index) ? +slide.index : slides.indexOf(slide);
482
382
  };
483
383
 
484
384
  $scope.next = function() {
485
- var newIndex = (currentIndex + 1) % slides.length;
385
+ var newIndex = (self.getCurrentIndex() + 1) % slides.length;
486
386
 
487
387
  //Prevent this user-triggered transition from occurring if there is already one in progress
488
388
  if (!$scope.$currentTransition) {
489
- return self.select(slides[newIndex], 'next');
389
+ return self.select(getSlideByIndex(newIndex), 'next');
490
390
  }
491
391
  };
492
392
 
493
393
  $scope.prev = function() {
494
- var newIndex = currentIndex - 1 < 0 ? slides.length - 1 : currentIndex - 1;
394
+ var newIndex = self.getCurrentIndex() - 1 < 0 ? slides.length - 1 : self.getCurrentIndex() - 1;
495
395
 
496
396
  //Prevent this user-triggered transition from occurring if there is already one in progress
497
397
  if (!$scope.$currentTransition) {
498
- return self.select(slides[newIndex], 'prev');
398
+ return self.select(getSlideByIndex(newIndex), 'prev');
499
399
  }
500
400
  };
501
401
 
@@ -509,22 +409,22 @@ angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition'])
509
409
  function restartTimer() {
510
410
  resetTimer();
511
411
  var interval = +$scope.interval;
512
- if (!isNaN(interval) && interval>=0) {
513
- currentTimeout = $timeout(timerFn, interval);
412
+ if (!isNaN(interval) && interval > 0) {
413
+ currentInterval = $interval(timerFn, interval);
514
414
  }
515
415
  }
516
416
 
517
417
  function resetTimer() {
518
- if (currentTimeout) {
519
- $timeout.cancel(currentTimeout);
520
- currentTimeout = null;
418
+ if (currentInterval) {
419
+ $interval.cancel(currentInterval);
420
+ currentInterval = null;
521
421
  }
522
422
  }
523
423
 
524
424
  function timerFn() {
525
- if (isPlaying) {
425
+ var interval = +$scope.interval;
426
+ if (isPlaying && !isNaN(interval) && interval > 0) {
526
427
  $scope.next();
527
- restartTimer();
528
428
  } else {
529
429
  $scope.pause();
530
430
  }
@@ -558,6 +458,11 @@ angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition'])
558
458
  };
559
459
 
560
460
  self.removeSlide = function(slide) {
461
+ if (angular.isDefined(slide.index)) {
462
+ slides.sort(function(a, b) {
463
+ return +a.index > +b.index;
464
+ });
465
+ }
561
466
  //get the index of the slide inside the carousel
562
467
  var index = slides.indexOf(slide);
563
468
  slides.splice(index, 1);
@@ -637,13 +542,14 @@ angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition'])
637
542
  * Creates a slide inside a {@link ui.bootstrap.carousel.directive:carousel carousel}. Must be placed as a child of a carousel element.
638
543
  *
639
544
  * @param {boolean=} active Model binding, whether or not this slide is currently active.
545
+ * @param {number=} index The index of the slide. The slides will be sorted by this parameter.
640
546
  *
641
547
  * @example
642
548
  <example module="ui.bootstrap">
643
549
  <file name="index.html">
644
550
  <div ng-controller="CarouselDemoCtrl">
645
551
  <carousel>
646
- <slide ng-repeat="slide in slides" active="slide.active">
552
+ <slide ng-repeat="slide in slides" active="slide.active" index="$index">
647
553
  <img ng-src="{{slide.image}}" style="margin:auto;">
648
554
  <div class="carousel-caption">
649
555
  <h4>Slide {{$index}}</h4>
@@ -677,7 +583,8 @@ function CarouselDemoCtrl($scope) {
677
583
  replace: true,
678
584
  templateUrl: 'template/carousel/slide.html',
679
585
  scope: {
680
- active: '=?'
586
+ active: '=?',
587
+ index: '=?'
681
588
  },
682
589
  link: function (scope, element, attrs, carouselCtrl) {
683
590
  carouselCtrl.addSlide(scope, element);
@@ -693,11 +600,64 @@ function CarouselDemoCtrl($scope) {
693
600
  });
694
601
  }
695
602
  };
696
- });
603
+ })
604
+
605
+ .animation('.item', [
606
+ '$animate',
607
+ function ($animate) {
608
+ return {
609
+ beforeAddClass: function (element, className, done) {
610
+ // Due to transclusion, noTransition property is on parent's scope
611
+ if (className == 'active' && element.parent() &&
612
+ !element.parent().scope().noTransition) {
613
+ var stopped = false;
614
+ var direction = element.isolateScope().direction;
615
+ var directionClass = direction == 'next' ? 'left' : 'right';
616
+ element.addClass(direction);
617
+ $animate.addClass(element, directionClass).then(function () {
618
+ if (!stopped) {
619
+ element.removeClass(directionClass + ' ' + direction);
620
+ }
621
+ done();
622
+ });
623
+
624
+ return function () {
625
+ stopped = true;
626
+ };
627
+ }
628
+ done();
629
+ },
630
+ beforeRemoveClass: function (element, className, done) {
631
+ // Due to transclusion, noTransition property is on parent's scope
632
+ if (className == 'active' && element.parent() &&
633
+ !element.parent().scope().noTransition) {
634
+ var stopped = false;
635
+ var direction = element.isolateScope().direction;
636
+ var directionClass = direction == 'next' ? 'left' : 'right';
637
+ $animate.addClass(element, directionClass).then(function () {
638
+ if (!stopped) {
639
+ element.removeClass(directionClass);
640
+ }
641
+ done();
642
+ });
643
+ return function () {
644
+ stopped = true;
645
+ };
646
+ }
647
+ done();
648
+ }
649
+ };
650
+
651
+ }])
652
+
653
+
654
+ ;
697
655
 
698
656
  angular.module('ui.bootstrap.dateparser', [])
699
657
 
700
658
  .service('dateParser', ['$locale', 'orderByFilter', function($locale, orderByFilter) {
659
+ // Pulled from https://github.com/mbostock/d3/blob/master/src/format/requote.js
660
+ var SPECIAL_CHARACTERS_REGEXP = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
701
661
 
702
662
  this.parsers = {};
703
663
 
@@ -743,10 +703,38 @@ angular.module('ui.bootstrap.dateparser', [])
743
703
  },
744
704
  'EEE': {
745
705
  regex: $locale.DATETIME_FORMATS.SHORTDAY.join('|')
706
+ },
707
+ 'HH': {
708
+ regex: '(?:0|1)[0-9]|2[0-3]',
709
+ apply: function(value) { this.hours = +value; }
710
+ },
711
+ 'H': {
712
+ regex: '1?[0-9]|2[0-3]',
713
+ apply: function(value) { this.hours = +value; }
714
+ },
715
+ 'mm': {
716
+ regex: '[0-5][0-9]',
717
+ apply: function(value) { this.minutes = +value; }
718
+ },
719
+ 'm': {
720
+ regex: '[0-9]|[1-5][0-9]',
721
+ apply: function(value) { this.minutes = +value; }
722
+ },
723
+ 'sss': {
724
+ regex: '[0-9][0-9][0-9]',
725
+ apply: function(value) { this.milliseconds = +value; }
726
+ },
727
+ 'ss': {
728
+ regex: '[0-5][0-9]',
729
+ apply: function(value) { this.seconds = +value; }
730
+ },
731
+ 's': {
732
+ regex: '[0-9]|[1-5][0-9]',
733
+ apply: function(value) { this.seconds = +value; }
746
734
  }
747
735
  };
748
736
 
749
- this.createParser = function(format) {
737
+ function createParser(format) {
750
738
  var map = [], regex = format.split('');
751
739
 
752
740
  angular.forEach(formatCodeToRegex, function(data, code) {
@@ -771,17 +759,18 @@ angular.module('ui.bootstrap.dateparser', [])
771
759
  regex: new RegExp('^' + regex.join('') + '$'),
772
760
  map: orderByFilter(map, 'index')
773
761
  };
774
- };
762
+ }
775
763
 
776
- this.parse = function(input, format) {
777
- if ( !angular.isString(input) ) {
764
+ this.parse = function(input, format, baseDate) {
765
+ if ( !angular.isString(input) || !format ) {
778
766
  return input;
779
767
  }
780
768
 
781
769
  format = $locale.DATETIME_FORMATS[format] || format;
770
+ format = format.replace(SPECIAL_CHARACTERS_REGEXP, '\\$&');
782
771
 
783
772
  if ( !this.parsers[format] ) {
784
- this.parsers[format] = this.createParser(format);
773
+ this.parsers[format] = createParser(format);
785
774
  }
786
775
 
787
776
  var parser = this.parsers[format],
@@ -790,7 +779,20 @@ angular.module('ui.bootstrap.dateparser', [])
790
779
  results = input.match(regex);
791
780
 
792
781
  if ( results && results.length ) {
793
- var fields = { year: 1900, month: 0, date: 1, hours: 0 }, dt;
782
+ var fields, dt;
783
+ if (baseDate) {
784
+ fields = {
785
+ year: baseDate.getFullYear(),
786
+ month: baseDate.getMonth(),
787
+ date: baseDate.getDate(),
788
+ hours: baseDate.getHours(),
789
+ minutes: baseDate.getMinutes(),
790
+ seconds: baseDate.getSeconds(),
791
+ milliseconds: baseDate.getMilliseconds()
792
+ };
793
+ } else {
794
+ fields = { year: 1900, month: 0, date: 1, hours: 0, minutes: 0, seconds: 0, milliseconds: 0 };
795
+ }
794
796
 
795
797
  for( var i = 1, n = results.length; i < n; i++ ) {
796
798
  var mapper = map[i-1];
@@ -800,7 +802,8 @@ angular.module('ui.bootstrap.dateparser', [])
800
802
  }
801
803
 
802
804
  if ( isValid(fields.year, fields.month, fields.date) ) {
803
- dt = new Date( fields.year, fields.month, fields.date, fields.hours);
805
+ dt = new Date(fields.year, fields.month, fields.date, fields.hours, fields.minutes, fields.seconds,
806
+ fields.milliseconds || 0);
804
807
  }
805
808
 
806
809
  return dt;
@@ -810,6 +813,10 @@ angular.module('ui.bootstrap.dateparser', [])
810
813
  // Check if date is valid for specific month (and year for February).
811
814
  // Month: 0 = Jan, 1 = Feb, etc
812
815
  function isValid(year, month, date) {
816
+ if (date < 1) {
817
+ return false;
818
+ }
819
+
813
820
  if ( month === 1 && date > 28) {
814
821
  return date === 29 && ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0);
815
822
  }
@@ -991,7 +998,8 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
991
998
  startingDay: 0,
992
999
  yearRange: 20,
993
1000
  minDate: null,
994
- maxDate: null
1001
+ maxDate: null,
1002
+ shortcutPropagation: false
995
1003
  })
996
1004
 
997
1005
  .controller('DatepickerController', ['$scope', '$attrs', '$parse', '$interpolate', '$timeout', '$log', 'dateFilter', 'datepickerConfig', function($scope, $attrs, $parse, $interpolate, $timeout, $log, dateFilter, datepickerConfig) {
@@ -1003,11 +1011,11 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
1003
1011
 
1004
1012
  // Configuration attributes
1005
1013
  angular.forEach(['formatDay', 'formatMonth', 'formatYear', 'formatDayHeader', 'formatDayTitle', 'formatMonthTitle',
1006
- 'minMode', 'maxMode', 'showWeeks', 'startingDay', 'yearRange'], function( key, index ) {
1014
+ 'minMode', 'maxMode', 'showWeeks', 'startingDay', 'yearRange', 'shortcutPropagation'], function( key, index ) {
1007
1015
  self[key] = angular.isDefined($attrs[key]) ? (index < 8 ? $interpolate($attrs[key])($scope.$parent) : $scope.$parent.$eval($attrs[key])) : datepickerConfig[key];
1008
1016
  });
1009
1017
 
1010
- // Watchable attributes
1018
+ // Watchable date attributes
1011
1019
  angular.forEach(['minDate', 'maxDate'], function( key ) {
1012
1020
  if ( $attrs[key] ) {
1013
1021
  $scope.$parent.$watch($parse($attrs[key]), function(value) {
@@ -1020,8 +1028,20 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
1020
1028
  });
1021
1029
 
1022
1030
  $scope.datepickerMode = $scope.datepickerMode || datepickerConfig.datepickerMode;
1031
+ $scope.maxMode = self.maxMode;
1023
1032
  $scope.uniqueId = 'datepicker-' + $scope.$id + '-' + Math.floor(Math.random() * 10000);
1024
- this.activeDate = angular.isDefined($attrs.initDate) ? $scope.$parent.$eval($attrs.initDate) : new Date();
1033
+
1034
+ if(angular.isDefined($attrs.initDate)) {
1035
+ this.activeDate = $scope.$parent.$eval($attrs.initDate) || new Date();
1036
+ $scope.$parent.$watch($attrs.initDate, function(initDate){
1037
+ if(initDate && (ngModelCtrl.$isEmpty(ngModelCtrl.$modelValue) || ngModelCtrl.$invalid)){
1038
+ self.activeDate = initDate;
1039
+ self.refreshView();
1040
+ }
1041
+ });
1042
+ } else {
1043
+ this.activeDate = new Date();
1044
+ }
1025
1045
 
1026
1046
  $scope.isActive = function(dateObject) {
1027
1047
  if (self.compare(dateObject.date, self.activeDate) === 0) {
@@ -1040,8 +1060,8 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
1040
1060
  };
1041
1061
 
1042
1062
  this.render = function() {
1043
- if ( ngModelCtrl.$modelValue ) {
1044
- var date = new Date( ngModelCtrl.$modelValue ),
1063
+ if ( ngModelCtrl.$viewValue ) {
1064
+ var date = new Date( ngModelCtrl.$viewValue ),
1045
1065
  isValid = !isNaN(date);
1046
1066
 
1047
1067
  if ( isValid ) {
@@ -1058,19 +1078,20 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
1058
1078
  if ( this.element ) {
1059
1079
  this._refreshView();
1060
1080
 
1061
- var date = ngModelCtrl.$modelValue ? new Date(ngModelCtrl.$modelValue) : null;
1081
+ var date = ngModelCtrl.$viewValue ? new Date(ngModelCtrl.$viewValue) : null;
1062
1082
  ngModelCtrl.$setValidity('date-disabled', !date || (this.element && !this.isDisabled(date)));
1063
1083
  }
1064
1084
  };
1065
1085
 
1066
1086
  this.createDateObject = function(date, format) {
1067
- var model = ngModelCtrl.$modelValue ? new Date(ngModelCtrl.$modelValue) : null;
1087
+ var model = ngModelCtrl.$viewValue ? new Date(ngModelCtrl.$viewValue) : null;
1068
1088
  return {
1069
1089
  date: date,
1070
1090
  label: dateFilter(date, format),
1071
1091
  selected: model && this.compare(date, model) === 0,
1072
1092
  disabled: this.isDisabled(date),
1073
- current: this.compare(date, new Date()) === 0
1093
+ current: this.compare(date, new Date()) === 0,
1094
+ customClass: this.customClass(date)
1074
1095
  };
1075
1096
  };
1076
1097
 
@@ -1078,6 +1099,10 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
1078
1099
  return ((this.minDate && this.compare(date, this.minDate) < 0) || (this.maxDate && this.compare(date, this.maxDate) > 0) || ($attrs.dateDisabled && $scope.dateDisabled({date: date, mode: $scope.datepickerMode})));
1079
1100
  };
1080
1101
 
1102
+ this.customClass = function( date ) {
1103
+ return $scope.customClass({date: date, mode: $scope.datepickerMode});
1104
+ };
1105
+
1081
1106
  // Split array into smaller arrays
1082
1107
  this.split = function(arr, size) {
1083
1108
  var arrays = [];
@@ -1089,7 +1114,7 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
1089
1114
 
1090
1115
  $scope.select = function( date ) {
1091
1116
  if ( $scope.datepickerMode === self.minMode ) {
1092
- var dt = ngModelCtrl.$modelValue ? new Date( ngModelCtrl.$modelValue ) : new Date(0, 0, 0, 0, 0, 0, 0);
1117
+ var dt = ngModelCtrl.$viewValue ? new Date( ngModelCtrl.$viewValue ) : new Date(0, 0, 0, 0, 0, 0, 0);
1093
1118
  dt.setFullYear( date.getFullYear(), date.getMonth(), date.getDate() );
1094
1119
  ngModelCtrl.$setViewValue( dt );
1095
1120
  ngModelCtrl.$render();
@@ -1136,7 +1161,9 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
1136
1161
  }
1137
1162
 
1138
1163
  evt.preventDefault();
1139
- evt.stopPropagation();
1164
+ if(!self.shortcutPropagation){
1165
+ evt.stopPropagation();
1166
+ }
1140
1167
 
1141
1168
  if (key === 'enter' || key === 'space') {
1142
1169
  if ( self.isDisabled(self.activeDate)) {
@@ -1161,7 +1188,9 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
1161
1188
  templateUrl: 'template/datepicker/datepicker.html',
1162
1189
  scope: {
1163
1190
  datepickerMode: '=?',
1164
- dateDisabled: '&'
1191
+ dateDisabled: '&',
1192
+ customClass: '&',
1193
+ shortcutPropagation: '&?'
1165
1194
  },
1166
1195
  require: ['datepicker', '?^ngModel'],
1167
1196
  controller: 'DatepickerController',
@@ -1236,9 +1265,12 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
1236
1265
 
1237
1266
  if ( scope.showWeeks ) {
1238
1267
  scope.weekNumbers = [];
1239
- var weekNumber = getISO8601WeekNumber( scope.rows[0][0].date ),
1268
+ var thursdayIndex = (4 + 7 - ctrl.startingDay) % 7,
1240
1269
  numWeeks = scope.rows.length;
1241
- while( scope.weekNumbers.push(weekNumber++) < numWeeks ) {}
1270
+ for (var curWeek = 0; curWeek < numWeeks; curWeek++) {
1271
+ scope.weekNumbers.push(
1272
+ getISO8601WeekNumber( scope.rows[curWeek][thursdayIndex].date ));
1273
+ }
1242
1274
  }
1243
1275
  };
1244
1276
 
@@ -1399,6 +1431,11 @@ angular.module('ui.bootstrap.datepicker', ['ui.bootstrap.dateparser', 'ui.bootst
1399
1431
 
1400
1432
  .constant('datepickerPopupConfig', {
1401
1433
  datepickerPopup: 'yyyy-MM-dd',
1434
+ html5Types: {
1435
+ date: 'yyyy-MM-dd',
1436
+ 'datetime-local': 'yyyy-MM-ddTHH:mm:ss.sss',
1437
+ 'month': 'yyyy-MM'
1438
+ },
1402
1439
  currentText: 'Today',
1403
1440
  clearText: 'Clear',
1404
1441
  closeText: 'Done',
@@ -1417,7 +1454,8 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
1417
1454
  currentText: '@',
1418
1455
  clearText: '@',
1419
1456
  closeText: '@',
1420
- dateDisabled: '&'
1457
+ dateDisabled: '&',
1458
+ customClass: '&'
1421
1459
  },
1422
1460
  link: function(scope, element, attrs, ngModel) {
1423
1461
  var dateFormat,
@@ -1430,10 +1468,34 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
1430
1468
  return scope[key + 'Text'] || datepickerPopupConfig[key + 'Text'];
1431
1469
  };
1432
1470
 
1433
- attrs.$observe('datepickerPopup', function(value) {
1434
- dateFormat = value || datepickerPopupConfig.datepickerPopup;
1435
- ngModel.$render();
1436
- });
1471
+ var isHtml5DateInput = false;
1472
+ if (datepickerPopupConfig.html5Types[attrs.type]) {
1473
+ dateFormat = datepickerPopupConfig.html5Types[attrs.type];
1474
+ isHtml5DateInput = true;
1475
+ } else {
1476
+ dateFormat = attrs.datepickerPopup || datepickerPopupConfig.datepickerPopup;
1477
+ attrs.$observe('datepickerPopup', function(value, oldValue) {
1478
+ var newDateFormat = value || datepickerPopupConfig.datepickerPopup;
1479
+ // Invalidate the $modelValue to ensure that formatters re-run
1480
+ // FIXME: Refactor when PR is merged: https://github.com/angular/angular.js/pull/10764
1481
+ if (newDateFormat !== dateFormat) {
1482
+ dateFormat = newDateFormat;
1483
+ ngModel.$modelValue = null;
1484
+
1485
+ if (!dateFormat) {
1486
+ throw new Error('datepickerPopup must have a date format specified.');
1487
+ }
1488
+ }
1489
+ });
1490
+ }
1491
+
1492
+ if (!dateFormat) {
1493
+ throw new Error('datepickerPopup must have a date format specified.');
1494
+ }
1495
+
1496
+ if (isHtml5DateInput && attrs.datepickerPopup) {
1497
+ throw new Error('HTML5 date input types do not support custom formats.');
1498
+ }
1437
1499
 
1438
1500
  // popup element used to display calendar
1439
1501
  var popupEl = angular.element('<div datepicker-popup-wrap><div datepicker></div></div>');
@@ -1448,54 +1510,121 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
1448
1510
 
1449
1511
  // datepicker element
1450
1512
  var datepickerEl = angular.element(popupEl.children()[0]);
1513
+ if (isHtml5DateInput) {
1514
+ if (attrs.type == 'month') {
1515
+ datepickerEl.attr('datepicker-mode', '"month"');
1516
+ datepickerEl.attr('min-mode', 'month');
1517
+ }
1518
+ }
1519
+
1451
1520
  if ( attrs.datepickerOptions ) {
1452
- angular.forEach(scope.$parent.$eval(attrs.datepickerOptions), function( value, option ) {
1521
+ var options = scope.$parent.$eval(attrs.datepickerOptions);
1522
+ if(options.initDate) {
1523
+ scope.initDate = options.initDate;
1524
+ datepickerEl.attr( 'init-date', 'initDate' );
1525
+ delete options.initDate;
1526
+ }
1527
+ angular.forEach(options, function( value, option ) {
1453
1528
  datepickerEl.attr( cameltoDash(option), value );
1454
1529
  });
1455
1530
  }
1456
1531
 
1457
- angular.forEach(['minDate', 'maxDate'], function( key ) {
1532
+ scope.watchData = {};
1533
+ angular.forEach(['minDate', 'maxDate', 'datepickerMode', 'initDate', 'shortcutPropagation'], function( key ) {
1458
1534
  if ( attrs[key] ) {
1459
- scope.$parent.$watch($parse(attrs[key]), function(value){
1460
- scope[key] = value;
1535
+ var getAttribute = $parse(attrs[key]);
1536
+ scope.$parent.$watch(getAttribute, function(value){
1537
+ scope.watchData[key] = value;
1461
1538
  });
1462
- datepickerEl.attr(cameltoDash(key), key);
1539
+ datepickerEl.attr(cameltoDash(key), 'watchData.' + key);
1540
+
1541
+ // Propagate changes from datepicker to outside
1542
+ if ( key === 'datepickerMode' ) {
1543
+ var setAttribute = getAttribute.assign;
1544
+ scope.$watch('watchData.' + key, function(value, oldvalue) {
1545
+ if ( value !== oldvalue ) {
1546
+ setAttribute(scope.$parent, value);
1547
+ }
1548
+ });
1549
+ }
1463
1550
  }
1464
1551
  });
1465
1552
  if (attrs.dateDisabled) {
1466
1553
  datepickerEl.attr('date-disabled', 'dateDisabled({ date: date, mode: mode })');
1467
1554
  }
1468
1555
 
1556
+ if (attrs.showWeeks) {
1557
+ datepickerEl.attr('show-weeks', attrs.showWeeks);
1558
+ }
1559
+
1560
+ if (attrs.customClass){
1561
+ datepickerEl.attr('custom-class', 'customClass({ date: date, mode: mode })');
1562
+ }
1563
+
1469
1564
  function parseDate(viewValue) {
1565
+ if (angular.isNumber(viewValue)) {
1566
+ // presumably timestamp to date object
1567
+ viewValue = new Date(viewValue);
1568
+ }
1569
+
1470
1570
  if (!viewValue) {
1471
- ngModel.$setValidity('date', true);
1472
1571
  return null;
1473
1572
  } else if (angular.isDate(viewValue) && !isNaN(viewValue)) {
1474
- ngModel.$setValidity('date', true);
1475
1573
  return viewValue;
1476
1574
  } else if (angular.isString(viewValue)) {
1477
- var date = dateParser.parse(viewValue, dateFormat) || new Date(viewValue);
1575
+ var date = dateParser.parse(viewValue, dateFormat, scope.date) || new Date(viewValue);
1478
1576
  if (isNaN(date)) {
1479
- ngModel.$setValidity('date', false);
1480
1577
  return undefined;
1481
1578
  } else {
1482
- ngModel.$setValidity('date', true);
1483
1579
  return date;
1484
1580
  }
1485
1581
  } else {
1486
- ngModel.$setValidity('date', false);
1487
1582
  return undefined;
1488
1583
  }
1489
1584
  }
1490
- ngModel.$parsers.unshift(parseDate);
1585
+
1586
+ function validator(modelValue, viewValue) {
1587
+ var value = modelValue || viewValue;
1588
+ if (angular.isNumber(value)) {
1589
+ value = new Date(value);
1590
+ }
1591
+ if (!value) {
1592
+ return true;
1593
+ } else if (angular.isDate(value) && !isNaN(value)) {
1594
+ return true;
1595
+ } else if (angular.isString(value)) {
1596
+ var date = dateParser.parse(value, dateFormat) || new Date(value);
1597
+ return !isNaN(date);
1598
+ } else {
1599
+ return false;
1600
+ }
1601
+ }
1602
+
1603
+ if (!isHtml5DateInput) {
1604
+ // Internal API to maintain the correct ng-invalid-[key] class
1605
+ ngModel.$$parserName = 'date';
1606
+ ngModel.$validators.date = validator;
1607
+ ngModel.$parsers.unshift(parseDate);
1608
+ ngModel.$formatters.push(function (value) {
1609
+ scope.date = value;
1610
+ return ngModel.$isEmpty(value) ? value : dateFilter(value, dateFormat);
1611
+ });
1612
+ }
1613
+ else {
1614
+ ngModel.$formatters.push(function (value) {
1615
+ scope.date = value;
1616
+ return value;
1617
+ });
1618
+ }
1491
1619
 
1492
1620
  // Inner change
1493
1621
  scope.dateSelection = function(dt) {
1494
1622
  if (angular.isDefined(dt)) {
1495
1623
  scope.date = dt;
1496
1624
  }
1497
- ngModel.$setViewValue(scope.date);
1498
- ngModel.$render();
1625
+ var date = scope.date ? dateFilter(scope.date, dateFormat) : '';
1626
+ element.val(date);
1627
+ ngModel.$setViewValue(date);
1499
1628
 
1500
1629
  if ( closeOnDateSelection ) {
1501
1630
  scope.isOpen = false;
@@ -1503,19 +1632,11 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
1503
1632
  }
1504
1633
  };
1505
1634
 
1506
- element.bind('input change keyup', function() {
1507
- scope.$apply(function() {
1508
- scope.date = ngModel.$modelValue;
1509
- });
1635
+ // Detect changes in the view from the text box
1636
+ ngModel.$viewChangeListeners.push(function () {
1637
+ scope.date = dateParser.parse(ngModel.$viewValue, dateFormat, scope.date) || new Date(ngModel.$viewValue);
1510
1638
  });
1511
1639
 
1512
- // Outter change
1513
- ngModel.$render = function() {
1514
- var date = ngModel.$viewValue ? dateFilter(ngModel.$viewValue, dateFormat) : '';
1515
- element.val(date);
1516
- scope.date = parseDate( ngModel.$modelValue );
1517
- };
1518
-
1519
1640
  var documentClickBind = function(event) {
1520
1641
  if (scope.isOpen && event.target !== element[0]) {
1521
1642
  scope.$apply(function() {
@@ -1532,7 +1653,9 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
1532
1653
  scope.keydown = function(evt) {
1533
1654
  if (evt.which === 27) {
1534
1655
  evt.preventDefault();
1535
- evt.stopPropagation();
1656
+ if (scope.isOpen) {
1657
+ evt.stopPropagation();
1658
+ }
1536
1659
  scope.close();
1537
1660
  } else if (evt.which === 40 && !scope.isOpen) {
1538
1661
  scope.isOpen = true;
@@ -1554,8 +1677,8 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
1554
1677
  scope.select = function( date ) {
1555
1678
  if (date === 'today') {
1556
1679
  var today = new Date();
1557
- if (angular.isDate(ngModel.$modelValue)) {
1558
- date = new Date(ngModel.$modelValue);
1680
+ if (angular.isDate(scope.date)) {
1681
+ date = new Date(scope.date);
1559
1682
  date.setFullYear(today.getFullYear(), today.getMonth(), today.getDate());
1560
1683
  } else {
1561
1684
  date = new Date(today.setHours(0, 0, 0, 0));
@@ -1570,6 +1693,9 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
1570
1693
  };
1571
1694
 
1572
1695
  var $popup = $compile(popupEl)(scope);
1696
+ // Prevent jQuery cache memory leak (template is now redundant after linking)
1697
+ popupEl.remove();
1698
+
1573
1699
  if ( appendToBody ) {
1574
1700
  $document.find('body').append($popup);
1575
1701
  } else {
@@ -1600,13 +1726,13 @@ function ($compile, $parse, $document, $position, dateFilter, dateParser, datepi
1600
1726
  };
1601
1727
  });
1602
1728
 
1603
- angular.module('ui.bootstrap.dropdown', [])
1729
+ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position'])
1604
1730
 
1605
1731
  .constant('dropdownConfig', {
1606
1732
  openClass: 'open'
1607
1733
  })
1608
1734
 
1609
- .service('dropdownService', ['$document', function($document) {
1735
+ .service('dropdownService', ['$document', '$rootScope', function($document, $rootScope) {
1610
1736
  var openScope = null;
1611
1737
 
1612
1738
  this.open = function( dropdownScope ) {
@@ -1631,13 +1757,27 @@ angular.module('ui.bootstrap.dropdown', [])
1631
1757
  };
1632
1758
 
1633
1759
  var closeDropdown = function( evt ) {
1634
- if (evt && evt.isDefaultPrevented()) {
1760
+ // This method may still be called during the same mouse event that
1761
+ // unbound this event handler. So check openScope before proceeding.
1762
+ if (!openScope) { return; }
1763
+
1764
+ if( evt && openScope.getAutoClose() === 'disabled' ) { return ; }
1765
+
1766
+ var toggleElement = openScope.getToggleElement();
1767
+ if ( evt && toggleElement && toggleElement[0].contains(evt.target) ) {
1635
1768
  return;
1636
1769
  }
1637
1770
 
1638
- openScope.$apply(function() {
1639
- openScope.isOpen = false;
1640
- });
1771
+ var $element = openScope.getElement();
1772
+ if( evt && openScope.getAutoClose() === 'outsideClick' && $element && $element[0].contains(evt.target) ) {
1773
+ return;
1774
+ }
1775
+
1776
+ openScope.isOpen = false;
1777
+
1778
+ if (!$rootScope.$$phase) {
1779
+ openScope.$apply();
1780
+ }
1641
1781
  };
1642
1782
 
1643
1783
  var escapeKeyBind = function( evt ) {
@@ -1648,13 +1788,14 @@ angular.module('ui.bootstrap.dropdown', [])
1648
1788
  };
1649
1789
  }])
1650
1790
 
1651
- .controller('DropdownController', ['$scope', '$attrs', '$parse', 'dropdownConfig', 'dropdownService', '$animate', function($scope, $attrs, $parse, dropdownConfig, dropdownService, $animate) {
1791
+ .controller('DropdownController', ['$scope', '$attrs', '$parse', 'dropdownConfig', 'dropdownService', '$animate', '$position', '$document', function($scope, $attrs, $parse, dropdownConfig, dropdownService, $animate, $position, $document) {
1652
1792
  var self = this,
1653
1793
  scope = $scope.$new(), // create a child scope so we are not polluting original one
1654
1794
  openClass = dropdownConfig.openClass,
1655
1795
  getIsOpen,
1656
1796
  setIsOpen = angular.noop,
1657
- toggleInvoker = $attrs.onToggle ? $parse($attrs.onToggle) : angular.noop;
1797
+ toggleInvoker = $attrs.onToggle ? $parse($attrs.onToggle) : angular.noop,
1798
+ appendToBody = false;
1658
1799
 
1659
1800
  this.init = function( element ) {
1660
1801
  self.$element = element;
@@ -1667,6 +1808,15 @@ angular.module('ui.bootstrap.dropdown', [])
1667
1808
  scope.isOpen = !!value;
1668
1809
  });
1669
1810
  }
1811
+
1812
+ appendToBody = angular.isDefined($attrs.dropdownAppendToBody);
1813
+
1814
+ if ( appendToBody && self.dropdownMenu ) {
1815
+ $document.find('body').append( self.dropdownMenu );
1816
+ element.on('$destroy', function handleDestroyEvent() {
1817
+ self.dropdownMenu.remove();
1818
+ });
1819
+ }
1670
1820
  };
1671
1821
 
1672
1822
  this.toggle = function( open ) {
@@ -1678,6 +1828,18 @@ angular.module('ui.bootstrap.dropdown', [])
1678
1828
  return scope.isOpen;
1679
1829
  };
1680
1830
 
1831
+ scope.getToggleElement = function() {
1832
+ return self.toggleElement;
1833
+ };
1834
+
1835
+ scope.getAutoClose = function() {
1836
+ return $attrs.autoClose || 'always'; //or 'outsideClick' or 'disabled'
1837
+ };
1838
+
1839
+ scope.getElement = function() {
1840
+ return self.$element;
1841
+ };
1842
+
1681
1843
  scope.focusToggleElement = function() {
1682
1844
  if ( self.toggleElement ) {
1683
1845
  self.toggleElement[0].focus();
@@ -1685,6 +1847,15 @@ angular.module('ui.bootstrap.dropdown', [])
1685
1847
  };
1686
1848
 
1687
1849
  scope.$watch('isOpen', function( isOpen, wasOpen ) {
1850
+ if ( appendToBody && self.dropdownMenu ) {
1851
+ var pos = $position.positionElements(self.$element, self.dropdownMenu, 'bottom-left', true);
1852
+ self.dropdownMenu.css({
1853
+ top: pos.top + 'px',
1854
+ left: pos.left + 'px',
1855
+ display: isOpen ? 'block' : 'none'
1856
+ });
1857
+ }
1858
+
1688
1859
  $animate[isOpen ? 'addClass' : 'removeClass'](self.$element, openClass);
1689
1860
 
1690
1861
  if ( isOpen ) {
@@ -1711,7 +1882,6 @@ angular.module('ui.bootstrap.dropdown', [])
1711
1882
 
1712
1883
  .directive('dropdown', function() {
1713
1884
  return {
1714
- restrict: 'CA',
1715
1885
  controller: 'DropdownController',
1716
1886
  link: function(scope, element, attrs, dropdownCtrl) {
1717
1887
  dropdownCtrl.init( element );
@@ -1719,9 +1889,21 @@ angular.module('ui.bootstrap.dropdown', [])
1719
1889
  };
1720
1890
  })
1721
1891
 
1892
+ .directive('dropdownMenu', function() {
1893
+ return {
1894
+ restrict: 'AC',
1895
+ require: '?^dropdown',
1896
+ link: function(scope, element, attrs, dropdownCtrl) {
1897
+ if ( !dropdownCtrl ) {
1898
+ return;
1899
+ }
1900
+ dropdownCtrl.dropdownMenu = element;
1901
+ }
1902
+ };
1903
+ })
1904
+
1722
1905
  .directive('dropdownToggle', function() {
1723
1906
  return {
1724
- restrict: 'CA',
1725
1907
  require: '?^dropdown',
1726
1908
  link: function(scope, element, attrs, dropdownCtrl) {
1727
1909
  if ( !dropdownCtrl ) {
@@ -1755,7 +1937,7 @@ angular.module('ui.bootstrap.dropdown', [])
1755
1937
  };
1756
1938
  });
1757
1939
 
1758
- angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1940
+ angular.module('ui.bootstrap.modal', [])
1759
1941
 
1760
1942
  /**
1761
1943
  * A helper, internal data structure that acts as a map but also allows getting / removing
@@ -1819,19 +2001,23 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1819
2001
  restrict: 'EA',
1820
2002
  replace: true,
1821
2003
  templateUrl: 'template/modal/backdrop.html',
1822
- link: function (scope) {
1823
-
1824
- scope.animate = false;
1825
-
1826
- //trigger CSS transitions
1827
- $timeout(function () {
1828
- scope.animate = true;
1829
- });
2004
+ compile: function (tElement, tAttrs) {
2005
+ tElement.addClass(tAttrs.backdropClass);
2006
+ return linkFn;
1830
2007
  }
1831
2008
  };
2009
+
2010
+ function linkFn(scope, element, attrs) {
2011
+ scope.animate = false;
2012
+
2013
+ //trigger CSS transitions
2014
+ $timeout(function () {
2015
+ scope.animate = true;
2016
+ });
2017
+ }
1832
2018
  }])
1833
2019
 
1834
- .directive('modalWindow', ['$modalStack', '$timeout', function ($modalStack, $timeout) {
2020
+ .directive('modalWindow', ['$modalStack', '$q', function ($modalStack, $q) {
1835
2021
  return {
1836
2022
  restrict: 'EA',
1837
2023
  scope: {
@@ -1847,13 +2033,6 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1847
2033
  element.addClass(attrs.windowClass || '');
1848
2034
  scope.size = attrs.size;
1849
2035
 
1850
- $timeout(function () {
1851
- // trigger CSS transitions
1852
- scope.animate = true;
1853
- // focus a freshly-opened modal
1854
- element[0].focus();
1855
- });
1856
-
1857
2036
  scope.close = function (evt) {
1858
2037
  var modal = $modalStack.getTop();
1859
2038
  if (modal && modal.value.backdrop && modal.value.backdrop != 'static' && (evt.target === evt.currentTarget)) {
@@ -1862,12 +2041,75 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1862
2041
  $modalStack.dismiss(modal.key, 'backdrop click');
1863
2042
  }
1864
2043
  };
2044
+
2045
+ // This property is only added to the scope for the purpose of detecting when this directive is rendered.
2046
+ // We can detect that by using this property in the template associated with this directive and then use
2047
+ // {@link Attribute#$observe} on it. For more details please see {@link TableColumnResize}.
2048
+ scope.$isRendered = true;
2049
+
2050
+ // Deferred object that will be resolved when this modal is render.
2051
+ var modalRenderDeferObj = $q.defer();
2052
+ // Observe function will be called on next digest cycle after compilation, ensuring that the DOM is ready.
2053
+ // In order to use this way of finding whether DOM is ready, we need to observe a scope property used in modal's template.
2054
+ attrs.$observe('modalRender', function (value) {
2055
+ if (value == 'true') {
2056
+ modalRenderDeferObj.resolve();
2057
+ }
2058
+ });
2059
+
2060
+ modalRenderDeferObj.promise.then(function () {
2061
+ // trigger CSS transitions
2062
+ scope.animate = true;
2063
+
2064
+ var inputsWithAutofocus = element[0].querySelectorAll('[autofocus]');
2065
+ /**
2066
+ * Auto-focusing of a freshly-opened modal element causes any child elements
2067
+ * with the autofocus attribute to lose focus. This is an issue on touch
2068
+ * based devices which will show and then hide the onscreen keyboard.
2069
+ * Attempts to refocus the autofocus element via JavaScript will not reopen
2070
+ * the onscreen keyboard. Fixed by updated the focusing logic to only autofocus
2071
+ * the modal element if the modal does not contain an autofocus element.
2072
+ */
2073
+ if (inputsWithAutofocus.length) {
2074
+ inputsWithAutofocus[0].focus();
2075
+ } else {
2076
+ element[0].focus();
2077
+ }
2078
+
2079
+ // Notify {@link $modalStack} that modal is rendered.
2080
+ var modal = $modalStack.getTop();
2081
+ if (modal) {
2082
+ $modalStack.modalRendered(modal.key);
2083
+ }
2084
+ });
1865
2085
  }
1866
2086
  };
1867
2087
  }])
1868
2088
 
1869
- .factory('$modalStack', ['$transition', '$timeout', '$document', '$compile', '$rootScope', '$$stackedMap',
1870
- function ($transition, $timeout, $document, $compile, $rootScope, $$stackedMap) {
2089
+ .directive('modalAnimationClass', [
2090
+ function () {
2091
+ return {
2092
+ compile: function (tElement, tAttrs) {
2093
+ if (tAttrs.modalAnimation) {
2094
+ tElement.addClass(tAttrs.modalAnimationClass);
2095
+ }
2096
+ }
2097
+ };
2098
+ }])
2099
+
2100
+ .directive('modalTransclude', function () {
2101
+ return {
2102
+ link: function($scope, $element, $attrs, controller, $transclude) {
2103
+ $transclude($scope.$parent, function(clone) {
2104
+ $element.empty();
2105
+ $element.append(clone);
2106
+ });
2107
+ }
2108
+ };
2109
+ })
2110
+
2111
+ .factory('$modalStack', ['$animate', '$timeout', '$document', '$compile', '$rootScope', '$$stackedMap',
2112
+ function ($animate, $timeout, $document, $compile, $rootScope, $$stackedMap) {
1871
2113
 
1872
2114
  var OPENED_MODAL_CLASS = 'modal-open';
1873
2115
 
@@ -1901,8 +2143,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1901
2143
  openedWindows.remove(modalInstance);
1902
2144
 
1903
2145
  //remove window DOM element
1904
- removeAfterAnimate(modalWindow.modalDomEl, modalWindow.modalScope, 300, function() {
1905
- modalWindow.modalScope.$destroy();
2146
+ removeAfterAnimate(modalWindow.modalDomEl, modalWindow.modalScope, function() {
1906
2147
  body.toggleClass(OPENED_MODAL_CLASS, openedWindows.length() > 0);
1907
2148
  checkRemoveBackdrop();
1908
2149
  });
@@ -1912,8 +2153,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1912
2153
  //remove backdrop if no longer needed
1913
2154
  if (backdropDomEl && backdropIndex() == -1) {
1914
2155
  var backdropScopeRef = backdropScope;
1915
- removeAfterAnimate(backdropDomEl, backdropScope, 150, function () {
1916
- backdropScopeRef.$destroy();
2156
+ removeAfterAnimate(backdropDomEl, backdropScope, function () {
1917
2157
  backdropScopeRef = null;
1918
2158
  });
1919
2159
  backdropDomEl = undefined;
@@ -1921,23 +2161,18 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1921
2161
  }
1922
2162
  }
1923
2163
 
1924
- function removeAfterAnimate(domEl, scope, emulateTime, done) {
2164
+ function removeAfterAnimate(domEl, scope, done) {
1925
2165
  // Closing animation
1926
2166
  scope.animate = false;
1927
2167
 
1928
- var transitionEndEventName = $transition.transitionEndEventName;
1929
- if (transitionEndEventName) {
2168
+ if (domEl.attr('modal-animation') && $animate.enabled()) {
1930
2169
  // transition out
1931
- var timeout = $timeout(afterAnimating, emulateTime);
1932
-
1933
- domEl.bind(transitionEndEventName, function () {
1934
- $timeout.cancel(timeout);
1935
- afterAnimating();
1936
- scope.$apply();
2170
+ domEl.one('$animate:close', function closeFn() {
2171
+ $rootScope.$evalAsync(afterAnimating);
1937
2172
  });
1938
2173
  } else {
1939
2174
  // Ensure this call is async
1940
- $timeout(afterAnimating, 0);
2175
+ $timeout(afterAnimating);
1941
2176
  }
1942
2177
 
1943
2178
  function afterAnimating() {
@@ -1947,6 +2182,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1947
2182
  afterAnimating.done = true;
1948
2183
 
1949
2184
  domEl.remove();
2185
+ scope.$destroy();
1950
2186
  if (done) {
1951
2187
  done();
1952
2188
  }
@@ -1969,8 +2205,11 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1969
2205
 
1970
2206
  $modalStack.open = function (modalInstance, modal) {
1971
2207
 
2208
+ var modalOpener = $document[0].activeElement;
2209
+
1972
2210
  openedWindows.add(modalInstance, {
1973
2211
  deferred: modal.deferred,
2212
+ renderDeferred: modal.renderDeferred,
1974
2213
  modalScope: modal.scope,
1975
2214
  backdrop: modal.backdrop,
1976
2215
  keyboard: modal.keyboard
@@ -1982,11 +2221,16 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1982
2221
  if (currBackdropIndex >= 0 && !backdropDomEl) {
1983
2222
  backdropScope = $rootScope.$new(true);
1984
2223
  backdropScope.index = currBackdropIndex;
1985
- backdropDomEl = $compile('<div modal-backdrop></div>')(backdropScope);
2224
+ var angularBackgroundDomEl = angular.element('<div modal-backdrop="modal-backdrop"></div>');
2225
+ angularBackgroundDomEl.attr('backdrop-class', modal.backdropClass);
2226
+ if (modal.animation) {
2227
+ angularBackgroundDomEl.attr('modal-animation', 'true');
2228
+ }
2229
+ backdropDomEl = $compile(angularBackgroundDomEl)(backdropScope);
1986
2230
  body.append(backdropDomEl);
1987
2231
  }
1988
2232
 
1989
- var angularDomEl = angular.element('<div modal-window></div>');
2233
+ var angularDomEl = angular.element('<div modal-window="modal-window"></div>');
1990
2234
  angularDomEl.attr({
1991
2235
  'template-url': modal.windowTemplateUrl,
1992
2236
  'window-class': modal.windowClass,
@@ -1994,33 +2238,46 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
1994
2238
  'index': openedWindows.length() - 1,
1995
2239
  'animate': 'animate'
1996
2240
  }).html(modal.content);
2241
+ if (modal.animation) {
2242
+ angularDomEl.attr('modal-animation', 'true');
2243
+ }
1997
2244
 
1998
2245
  var modalDomEl = $compile(angularDomEl)(modal.scope);
1999
2246
  openedWindows.top().value.modalDomEl = modalDomEl;
2247
+ openedWindows.top().value.modalOpener = modalOpener;
2000
2248
  body.append(modalDomEl);
2001
2249
  body.addClass(OPENED_MODAL_CLASS);
2002
2250
  };
2003
2251
 
2252
+ function broadcastClosing(modalWindow, resultOrReason, closing) {
2253
+ return !modalWindow.value.modalScope.$broadcast('modal.closing', resultOrReason, closing).defaultPrevented;
2254
+ }
2255
+
2004
2256
  $modalStack.close = function (modalInstance, result) {
2005
- var modalWindow = openedWindows.get(modalInstance).value;
2006
- if (modalWindow) {
2007
- modalWindow.deferred.resolve(result);
2257
+ var modalWindow = openedWindows.get(modalInstance);
2258
+ if (modalWindow && broadcastClosing(modalWindow, result, true)) {
2259
+ modalWindow.value.deferred.resolve(result);
2008
2260
  removeModalWindow(modalInstance);
2261
+ modalWindow.value.modalOpener.focus();
2262
+ return true;
2009
2263
  }
2264
+ return !modalWindow;
2010
2265
  };
2011
2266
 
2012
2267
  $modalStack.dismiss = function (modalInstance, reason) {
2013
- var modalWindow = openedWindows.get(modalInstance).value;
2014
- if (modalWindow) {
2015
- modalWindow.deferred.reject(reason);
2268
+ var modalWindow = openedWindows.get(modalInstance);
2269
+ if (modalWindow && broadcastClosing(modalWindow, reason, false)) {
2270
+ modalWindow.value.deferred.reject(reason);
2016
2271
  removeModalWindow(modalInstance);
2272
+ modalWindow.value.modalOpener.focus();
2273
+ return true;
2017
2274
  }
2275
+ return !modalWindow;
2018
2276
  };
2019
2277
 
2020
2278
  $modalStack.dismissAll = function (reason) {
2021
2279
  var topModal = this.getTop();
2022
- while (topModal) {
2023
- this.dismiss(topModal.key, reason);
2280
+ while (topModal && this.dismiss(topModal.key, reason)) {
2024
2281
  topModal = this.getTop();
2025
2282
  }
2026
2283
  };
@@ -2029,6 +2286,13 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
2029
2286
  return openedWindows.top();
2030
2287
  };
2031
2288
 
2289
+ $modalStack.modalRendered = function (modalInstance) {
2290
+ var modalWindow = openedWindows.get(modalInstance);
2291
+ if (modalWindow) {
2292
+ modalWindow.value.renderDeferred.resolve();
2293
+ }
2294
+ };
2295
+
2032
2296
  return $modalStack;
2033
2297
  }])
2034
2298
 
@@ -2036,24 +2300,23 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
2036
2300
 
2037
2301
  var $modalProvider = {
2038
2302
  options: {
2039
- backdrop: true, //can be also false or 'static'
2303
+ animation: true,
2304
+ backdrop: true, //can also be false or 'static'
2040
2305
  keyboard: true
2041
2306
  },
2042
- $get: ['$injector', '$rootScope', '$q', '$http', '$templateCache', '$controller', '$modalStack',
2043
- function ($injector, $rootScope, $q, $http, $templateCache, $controller, $modalStack) {
2307
+ $get: ['$injector', '$rootScope', '$q', '$templateRequest', '$controller', '$modalStack',
2308
+ function ($injector, $rootScope, $q, $templateRequest, $controller, $modalStack) {
2044
2309
 
2045
2310
  var $modal = {};
2046
2311
 
2047
2312
  function getTemplatePromise(options) {
2048
2313
  return options.template ? $q.when(options.template) :
2049
- $http.get(options.templateUrl, {cache: $templateCache}).then(function (result) {
2050
- return result.data;
2051
- });
2314
+ $templateRequest(angular.isFunction(options.templateUrl) ? (options.templateUrl)() : options.templateUrl);
2052
2315
  }
2053
2316
 
2054
2317
  function getResolvePromises(resolves) {
2055
2318
  var promisesArr = [];
2056
- angular.forEach(resolves, function (value, key) {
2319
+ angular.forEach(resolves, function (value) {
2057
2320
  if (angular.isFunction(value) || angular.isArray(value)) {
2058
2321
  promisesArr.push($q.when($injector.invoke(value)));
2059
2322
  }
@@ -2065,16 +2328,18 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
2065
2328
 
2066
2329
  var modalResultDeferred = $q.defer();
2067
2330
  var modalOpenedDeferred = $q.defer();
2331
+ var modalRenderDeferred = $q.defer();
2068
2332
 
2069
2333
  //prepare an instance of a modal to be injected into controllers and returned to a caller
2070
2334
  var modalInstance = {
2071
2335
  result: modalResultDeferred.promise,
2072
2336
  opened: modalOpenedDeferred.promise,
2337
+ rendered: modalRenderDeferred.promise,
2073
2338
  close: function (result) {
2074
- $modalStack.close(modalInstance, result);
2339
+ return $modalStack.close(modalInstance, result);
2075
2340
  },
2076
2341
  dismiss: function (reason) {
2077
- $modalStack.dismiss(modalInstance, reason);
2342
+ return $modalStack.dismiss(modalInstance, reason);
2078
2343
  }
2079
2344
  };
2080
2345
 
@@ -2109,14 +2374,20 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
2109
2374
  });
2110
2375
 
2111
2376
  ctrlInstance = $controller(modalOptions.controller, ctrlLocals);
2377
+ if (modalOptions.controllerAs) {
2378
+ modalScope[modalOptions.controllerAs] = ctrlInstance;
2379
+ }
2112
2380
  }
2113
2381
 
2114
2382
  $modalStack.open(modalInstance, {
2115
2383
  scope: modalScope,
2116
2384
  deferred: modalResultDeferred,
2385
+ renderDeferred: modalRenderDeferred,
2117
2386
  content: tplAndVars[0],
2387
+ animation: modalOptions.animation,
2118
2388
  backdrop: modalOptions.backdrop,
2119
2389
  keyboard: modalOptions.keyboard,
2390
+ backdropClass: modalOptions.backdropClass,
2120
2391
  windowClass: modalOptions.windowClass,
2121
2392
  windowTemplateUrl: modalOptions.windowTemplateUrl,
2122
2393
  size: modalOptions.size
@@ -2128,8 +2399,8 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
2128
2399
 
2129
2400
  templateAndResolvePromise.then(function () {
2130
2401
  modalOpenedDeferred.resolve(true);
2131
- }, function () {
2132
- modalOpenedDeferred.reject(false);
2402
+ }, function (reason) {
2403
+ modalOpenedDeferred.reject(reason);
2133
2404
  });
2134
2405
 
2135
2406
  return modalInstance;
@@ -2165,6 +2436,20 @@ angular.module('ui.bootstrap.pagination', [])
2165
2436
  } else {
2166
2437
  this.itemsPerPage = config.itemsPerPage;
2167
2438
  }
2439
+
2440
+ $scope.$watch('totalItems', function() {
2441
+ $scope.totalPages = self.calculateTotalPages();
2442
+ });
2443
+
2444
+ $scope.$watch('totalPages', function(value) {
2445
+ setNumPages($scope.$parent, value); // Readonly variable
2446
+
2447
+ if ( $scope.page > value ) {
2448
+ $scope.selectPage(value);
2449
+ } else {
2450
+ ngModelCtrl.$render();
2451
+ }
2452
+ });
2168
2453
  };
2169
2454
 
2170
2455
  this.calculateTotalPages = function() {
@@ -2176,8 +2461,11 @@ angular.module('ui.bootstrap.pagination', [])
2176
2461
  $scope.page = parseInt(ngModelCtrl.$viewValue, 10) || 1;
2177
2462
  };
2178
2463
 
2179
- $scope.selectPage = function(page) {
2464
+ $scope.selectPage = function(page, evt) {
2180
2465
  if ( $scope.page !== page && page > 0 && page <= $scope.totalPages) {
2466
+ if (evt && evt.target) {
2467
+ evt.target.blur();
2468
+ }
2181
2469
  ngModelCtrl.$setViewValue(page);
2182
2470
  ngModelCtrl.$render();
2183
2471
  }
@@ -2192,20 +2480,6 @@ angular.module('ui.bootstrap.pagination', [])
2192
2480
  $scope.noNext = function() {
2193
2481
  return $scope.page === $scope.totalPages;
2194
2482
  };
2195
-
2196
- $scope.$watch('totalItems', function() {
2197
- $scope.totalPages = self.calculateTotalPages();
2198
- });
2199
-
2200
- $scope.$watch('totalPages', function(value) {
2201
- setNumPages($scope.$parent, value); // Readonly variable
2202
-
2203
- if ( $scope.page > value ) {
2204
- $scope.selectPage(value);
2205
- } else {
2206
- ngModelCtrl.$render();
2207
- }
2208
- });
2209
2483
  }])
2210
2484
 
2211
2485
  .constant('paginationConfig', {
@@ -2373,7 +2647,8 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
2373
2647
  var defaultOptions = {
2374
2648
  placement: 'top',
2375
2649
  animation: true,
2376
- popupDelay: 0
2650
+ popupDelay: 0,
2651
+ useContentExp: false
2377
2652
  };
2378
2653
 
2379
2654
  // Default hide triggers for each show trigger
@@ -2423,9 +2698,9 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
2423
2698
  * Returns the actual instance of the $tooltip service.
2424
2699
  * TODO support multiple triggers
2425
2700
  */
2426
- this.$get = [ '$window', '$compile', '$timeout', '$parse', '$document', '$position', '$interpolate', function ( $window, $compile, $timeout, $parse, $document, $position, $interpolate ) {
2427
- return function $tooltip ( type, prefix, defaultTriggerShow ) {
2428
- var options = angular.extend( {}, defaultOptions, globalOptions );
2701
+ this.$get = [ '$window', '$compile', '$timeout', '$document', '$position', '$interpolate', function ( $window, $compile, $timeout, $document, $position, $interpolate ) {
2702
+ return function $tooltip ( type, prefix, defaultTriggerShow, options ) {
2703
+ options = angular.extend( {}, defaultOptions, globalOptions, options );
2429
2704
 
2430
2705
  /**
2431
2706
  * Returns an object of show and hide triggers.
@@ -2456,31 +2731,37 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
2456
2731
  var endSym = $interpolate.endSymbol();
2457
2732
  var template =
2458
2733
  '<div '+ directiveName +'-popup '+
2459
- 'title="'+startSym+'tt_title'+endSym+'" '+
2460
- 'content="'+startSym+'tt_content'+endSym+'" '+
2461
- 'placement="'+startSym+'tt_placement'+endSym+'" '+
2462
- 'animation="tt_animation" '+
2463
- 'is-open="tt_isOpen"'+
2734
+ 'title="'+startSym+'title'+endSym+'" '+
2735
+ (options.useContentExp ?
2736
+ 'content-exp="contentExp()" ' :
2737
+ 'content="'+startSym+'content'+endSym+'" ') +
2738
+ 'placement="'+startSym+'placement'+endSym+'" '+
2739
+ 'popup-class="'+startSym+'popupClass'+endSym+'" '+
2740
+ 'animation="animation" '+
2741
+ 'is-open="isOpen"'+
2742
+ 'origin-scope="origScope" '+
2464
2743
  '>'+
2465
2744
  '</div>';
2466
2745
 
2467
2746
  return {
2468
2747
  restrict: 'EA',
2469
- scope: true,
2470
2748
  compile: function (tElem, tAttrs) {
2471
2749
  var tooltipLinker = $compile( template );
2472
2750
 
2473
- return function link ( scope, element, attrs ) {
2751
+ return function link ( scope, element, attrs, tooltipCtrl ) {
2474
2752
  var tooltip;
2753
+ var tooltipLinkedScope;
2475
2754
  var transitionTimeout;
2476
2755
  var popupTimeout;
2477
2756
  var appendToBody = angular.isDefined( options.appendToBody ) ? options.appendToBody : false;
2478
2757
  var triggers = getTriggers( undefined );
2479
2758
  var hasEnableExp = angular.isDefined(attrs[prefix+'Enable']);
2759
+ var ttScope = scope.$new(true);
2480
2760
 
2481
2761
  var positionTooltip = function () {
2762
+ if (!tooltip) { return; }
2482
2763
 
2483
- var ttPosition = $position.positionElements(element, tooltip, scope.tt_placement, appendToBody);
2764
+ var ttPosition = $position.positionElements(element, tooltip, ttScope.placement, appendToBody);
2484
2765
  ttPosition.top += 'px';
2485
2766
  ttPosition.left += 'px';
2486
2767
 
@@ -2488,12 +2769,15 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
2488
2769
  tooltip.css( ttPosition );
2489
2770
  };
2490
2771
 
2772
+ // Set up the correct scope to allow transclusion later
2773
+ ttScope.origScope = scope;
2774
+
2491
2775
  // By default, the tooltip is not open.
2492
2776
  // TODO add ability to start tooltip opened
2493
- scope.tt_isOpen = false;
2777
+ ttScope.isOpen = false;
2494
2778
 
2495
2779
  function toggleTooltipBind () {
2496
- if ( ! scope.tt_isOpen ) {
2780
+ if ( ! ttScope.isOpen ) {
2497
2781
  showTooltipBind();
2498
2782
  } else {
2499
2783
  hideTooltipBind();
@@ -2505,11 +2789,14 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
2505
2789
  if(hasEnableExp && !scope.$eval(attrs[prefix+'Enable'])) {
2506
2790
  return;
2507
2791
  }
2508
- if ( scope.tt_popupDelay ) {
2792
+
2793
+ prepareTooltip();
2794
+
2795
+ if ( ttScope.popupDelay ) {
2509
2796
  // Do nothing if the tooltip was already scheduled to pop-up.
2510
2797
  // This happens if show is triggered multiple times before any hide is triggered.
2511
2798
  if (!popupTimeout) {
2512
- popupTimeout = $timeout( show, scope.tt_popupDelay, false );
2799
+ popupTimeout = $timeout( show, ttScope.popupDelay, false );
2513
2800
  popupTimeout.then(function(reposition){reposition();});
2514
2801
  }
2515
2802
  } else {
@@ -2536,7 +2823,7 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
2536
2823
  }
2537
2824
 
2538
2825
  // Don't show empty tooltips.
2539
- if ( ! scope.tt_content ) {
2826
+ if ( !(options.useContentExp ? ttScope.contentExp() : ttScope.content) ) {
2540
2827
  return angular.noop;
2541
2828
  }
2542
2829
 
@@ -2544,20 +2831,13 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
2544
2831
 
2545
2832
  // Set the initial positioning.
2546
2833
  tooltip.css({ top: 0, left: 0, display: 'block' });
2547
-
2548
- // Now we add it to the DOM because need some info about it. But it's not
2549
- // visible yet anyway.
2550
- if ( appendToBody ) {
2551
- $document.find( 'body' ).append( tooltip );
2552
- } else {
2553
- element.after( tooltip );
2554
- }
2834
+ ttScope.$digest();
2555
2835
 
2556
2836
  positionTooltip();
2557
2837
 
2558
2838
  // And show the tooltip.
2559
- scope.tt_isOpen = true;
2560
- scope.$digest(); // digest required as $apply is not called
2839
+ ttScope.isOpen = true;
2840
+ ttScope.$apply(); // digest required as $apply is not called
2561
2841
 
2562
2842
  // Return positioning function as promise callback for correct
2563
2843
  // positioning after draw.
@@ -2567,16 +2847,16 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
2567
2847
  // Hide the tooltip popup element.
2568
2848
  function hide() {
2569
2849
  // First things first: we don't show it anymore.
2570
- scope.tt_isOpen = false;
2850
+ ttScope.isOpen = false;
2571
2851
 
2572
2852
  //if tooltip is going to be shown after delay, we must cancel this
2573
2853
  $timeout.cancel( popupTimeout );
2574
2854
  popupTimeout = null;
2575
2855
 
2576
- // And now we remove it from the DOM. However, if we have animation, we
2856
+ // And now we remove it from the DOM. However, if we have animation, we
2577
2857
  // need to wait for it to expire beforehand.
2578
2858
  // FIXME: this is a placeholder for a port of the transitions library.
2579
- if ( scope.tt_animation ) {
2859
+ if ( ttScope.animation ) {
2580
2860
  if (!transitionTimeout) {
2581
2861
  transitionTimeout = $timeout(removeTooltip, 500);
2582
2862
  }
@@ -2590,10 +2870,26 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
2590
2870
  if (tooltip) {
2591
2871
  removeTooltip();
2592
2872
  }
2593
- tooltip = tooltipLinker(scope, function () {});
2873
+ tooltipLinkedScope = ttScope.$new();
2874
+ tooltip = tooltipLinker(tooltipLinkedScope, function (tooltip) {
2875
+ if ( appendToBody ) {
2876
+ $document.find( 'body' ).append( tooltip );
2877
+ } else {
2878
+ element.after( tooltip );
2879
+ }
2880
+ });
2881
+
2882
+ tooltipLinkedScope.$watch(function () {
2883
+ $timeout(positionTooltip, 0, false);
2884
+ });
2594
2885
 
2595
- // Get contents rendered into the tooltip
2596
- scope.$digest();
2886
+ if (options.useContentExp) {
2887
+ tooltipLinkedScope.$watch('contentExp()', function (val) {
2888
+ if (!val && ttScope.isOpen ) {
2889
+ hide();
2890
+ }
2891
+ });
2892
+ }
2597
2893
  }
2598
2894
 
2599
2895
  function removeTooltip() {
@@ -2602,38 +2898,67 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
2602
2898
  tooltip.remove();
2603
2899
  tooltip = null;
2604
2900
  }
2901
+ if (tooltipLinkedScope) {
2902
+ tooltipLinkedScope.$destroy();
2903
+ tooltipLinkedScope = null;
2904
+ }
2905
+ }
2906
+
2907
+ function prepareTooltip() {
2908
+ prepPopupClass();
2909
+ prepPlacement();
2910
+ prepPopupDelay();
2605
2911
  }
2606
2912
 
2913
+ ttScope.contentExp = function () {
2914
+ return scope.$eval(attrs[type]);
2915
+ };
2916
+
2607
2917
  /**
2608
2918
  * Observe the relevant attributes.
2609
2919
  */
2610
- attrs.$observe( type, function ( val ) {
2611
- scope.tt_content = val;
2920
+ if (!options.useContentExp) {
2921
+ attrs.$observe( type, function ( val ) {
2922
+ ttScope.content = val;
2923
+
2924
+ if (!val && ttScope.isOpen ) {
2925
+ hide();
2926
+ }
2927
+ });
2928
+ }
2612
2929
 
2613
- if (!val && scope.tt_isOpen ) {
2930
+ attrs.$observe( 'disabled', function ( val ) {
2931
+ if (val && ttScope.isOpen ) {
2614
2932
  hide();
2615
2933
  }
2616
2934
  });
2617
2935
 
2618
2936
  attrs.$observe( prefix+'Title', function ( val ) {
2619
- scope.tt_title = val;
2937
+ ttScope.title = val;
2620
2938
  });
2621
2939
 
2622
- attrs.$observe( prefix+'Placement', function ( val ) {
2623
- scope.tt_placement = angular.isDefined( val ) ? val : options.placement;
2624
- });
2940
+ function prepPopupClass() {
2941
+ ttScope.popupClass = attrs[prefix + 'Class'];
2942
+ }
2943
+
2944
+ function prepPlacement() {
2945
+ var val = attrs[ prefix + 'Placement' ];
2946
+ ttScope.placement = angular.isDefined( val ) ? val : options.placement;
2947
+ }
2625
2948
 
2626
- attrs.$observe( prefix+'PopupDelay', function ( val ) {
2949
+ function prepPopupDelay() {
2950
+ var val = attrs[ prefix + 'PopupDelay' ];
2627
2951
  var delay = parseInt( val, 10 );
2628
- scope.tt_popupDelay = ! isNaN(delay) ? delay : options.popupDelay;
2629
- });
2952
+ ttScope.popupDelay = ! isNaN(delay) ? delay : options.popupDelay;
2953
+ }
2630
2954
 
2631
2955
  var unregisterTriggers = function () {
2632
2956
  element.unbind(triggers.show, showTooltipBind);
2633
2957
  element.unbind(triggers.hide, hideTooltipBind);
2634
2958
  };
2635
2959
 
2636
- attrs.$observe( prefix+'Trigger', function ( val ) {
2960
+ function prepTriggers() {
2961
+ var val = attrs[ prefix + 'Trigger' ];
2637
2962
  unregisterTriggers();
2638
2963
 
2639
2964
  triggers = getTriggers( val );
@@ -2644,21 +2969,21 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
2644
2969
  element.bind( triggers.show, showTooltipBind );
2645
2970
  element.bind( triggers.hide, hideTooltipBind );
2646
2971
  }
2647
- });
2972
+ }
2973
+ prepTriggers();
2648
2974
 
2649
2975
  var animation = scope.$eval(attrs[prefix + 'Animation']);
2650
- scope.tt_animation = angular.isDefined(animation) ? !!animation : options.animation;
2976
+ ttScope.animation = angular.isDefined(animation) ? !!animation : options.animation;
2651
2977
 
2652
- attrs.$observe( prefix+'AppendToBody', function ( val ) {
2653
- appendToBody = angular.isDefined( val ) ? $parse( val )( scope ) : appendToBody;
2654
- });
2978
+ var appendToBodyVal = scope.$eval(attrs[prefix + 'AppendToBody']);
2979
+ appendToBody = angular.isDefined(appendToBodyVal) ? appendToBodyVal : appendToBody;
2655
2980
 
2656
2981
  // if a tooltip is attached to <body> we need to remove it on
2657
2982
  // location change as its parent scope will probably not be destroyed
2658
2983
  // by the change.
2659
2984
  if ( appendToBody ) {
2660
2985
  scope.$on('$locationChangeSuccess', function closeTooltipOnLocationChangeSuccess () {
2661
- if ( scope.tt_isOpen ) {
2986
+ if ( ttScope.isOpen ) {
2662
2987
  hide();
2663
2988
  }
2664
2989
  });
@@ -2670,6 +2995,7 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
2670
2995
  $timeout.cancel( popupTimeout );
2671
2996
  unregisterTriggers();
2672
2997
  removeTooltip();
2998
+ ttScope = null;
2673
2999
  });
2674
3000
  };
2675
3001
  }
@@ -2678,11 +3004,101 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
2678
3004
  }];
2679
3005
  })
2680
3006
 
3007
+ // This is mostly ngInclude code but with a custom scope
3008
+ .directive( 'tooltipTemplateTransclude', [
3009
+ '$animate', '$sce', '$compile', '$templateRequest',
3010
+ function ($animate , $sce , $compile , $templateRequest) {
3011
+ return {
3012
+ link: function ( scope, elem, attrs ) {
3013
+ var origScope = scope.$eval(attrs.tooltipTemplateTranscludeScope);
3014
+
3015
+ var changeCounter = 0,
3016
+ currentScope,
3017
+ previousElement,
3018
+ currentElement;
3019
+
3020
+ var cleanupLastIncludeContent = function() {
3021
+ if (previousElement) {
3022
+ previousElement.remove();
3023
+ previousElement = null;
3024
+ }
3025
+ if (currentScope) {
3026
+ currentScope.$destroy();
3027
+ currentScope = null;
3028
+ }
3029
+ if (currentElement) {
3030
+ $animate.leave(currentElement).then(function() {
3031
+ previousElement = null;
3032
+ });
3033
+ previousElement = currentElement;
3034
+ currentElement = null;
3035
+ }
3036
+ };
3037
+
3038
+ scope.$watch($sce.parseAsResourceUrl(attrs.tooltipTemplateTransclude), function (src) {
3039
+ var thisChangeId = ++changeCounter;
3040
+
3041
+ if (src) {
3042
+ //set the 2nd param to true to ignore the template request error so that the inner
3043
+ //contents and scope can be cleaned up.
3044
+ $templateRequest(src, true).then(function(response) {
3045
+ if (thisChangeId !== changeCounter) { return; }
3046
+ var newScope = origScope.$new();
3047
+ var template = response;
3048
+
3049
+ var clone = $compile(template)(newScope, function(clone) {
3050
+ cleanupLastIncludeContent();
3051
+ $animate.enter(clone, elem);
3052
+ });
3053
+
3054
+ currentScope = newScope;
3055
+ currentElement = clone;
3056
+
3057
+ currentScope.$emit('$includeContentLoaded', src);
3058
+ }, function() {
3059
+ if (thisChangeId === changeCounter) {
3060
+ cleanupLastIncludeContent();
3061
+ scope.$emit('$includeContentError', src);
3062
+ }
3063
+ });
3064
+ scope.$emit('$includeContentRequested', src);
3065
+ } else {
3066
+ cleanupLastIncludeContent();
3067
+ }
3068
+ });
3069
+
3070
+ scope.$on('$destroy', cleanupLastIncludeContent);
3071
+ }
3072
+ };
3073
+ }])
3074
+
3075
+ /**
3076
+ * Note that it's intentional that these classes are *not* applied through $animate.
3077
+ * They must not be animated as they're expected to be present on the tooltip on
3078
+ * initialization.
3079
+ */
3080
+ .directive('tooltipClasses', function () {
3081
+ return {
3082
+ restrict: 'A',
3083
+ link: function (scope, element, attrs) {
3084
+ if (scope.placement) {
3085
+ element.addClass(scope.placement);
3086
+ }
3087
+ if (scope.popupClass) {
3088
+ element.addClass(scope.popupClass);
3089
+ }
3090
+ if (scope.animation()) {
3091
+ element.addClass(attrs.tooltipAnimationClass);
3092
+ }
3093
+ }
3094
+ };
3095
+ })
3096
+
2681
3097
  .directive( 'tooltipPopup', function () {
2682
3098
  return {
2683
3099
  restrict: 'EA',
2684
3100
  replace: true,
2685
- scope: { content: '@', placement: '@', animation: '&', isOpen: '&' },
3101
+ scope: { content: '@', placement: '@', popupClass: '@', animation: '&', isOpen: '&' },
2686
3102
  templateUrl: 'template/tooltip/tooltip-popup.html'
2687
3103
  };
2688
3104
  })
@@ -2691,16 +3107,56 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
2691
3107
  return $tooltip( 'tooltip', 'tooltip', 'mouseenter' );
2692
3108
  }])
2693
3109
 
3110
+ .directive( 'tooltipTemplatePopup', function () {
3111
+ return {
3112
+ restrict: 'EA',
3113
+ replace: true,
3114
+ scope: { contentExp: '&', placement: '@', popupClass: '@', animation: '&', isOpen: '&',
3115
+ originScope: '&' },
3116
+ templateUrl: 'template/tooltip/tooltip-template-popup.html'
3117
+ };
3118
+ })
3119
+
3120
+ .directive( 'tooltipTemplate', [ '$tooltip', function ( $tooltip ) {
3121
+ return $tooltip('tooltipTemplate', 'tooltip', 'mouseenter', {
3122
+ useContentExp: true
3123
+ });
3124
+ }])
3125
+
3126
+ .directive( 'tooltipHtmlPopup', function () {
3127
+ return {
3128
+ restrict: 'EA',
3129
+ replace: true,
3130
+ scope: { contentExp: '&', placement: '@', popupClass: '@', animation: '&', isOpen: '&' },
3131
+ templateUrl: 'template/tooltip/tooltip-html-popup.html'
3132
+ };
3133
+ })
3134
+
3135
+ .directive( 'tooltipHtml', [ '$tooltip', function ( $tooltip ) {
3136
+ return $tooltip('tooltipHtml', 'tooltip', 'mouseenter', {
3137
+ useContentExp: true
3138
+ });
3139
+ }])
3140
+
3141
+ /*
3142
+ Deprecated
3143
+ */
2694
3144
  .directive( 'tooltipHtmlUnsafePopup', function () {
2695
3145
  return {
2696
3146
  restrict: 'EA',
2697
3147
  replace: true,
2698
- scope: { content: '@', placement: '@', animation: '&', isOpen: '&' },
3148
+ scope: { content: '@', placement: '@', popupClass: '@', animation: '&', isOpen: '&' },
2699
3149
  templateUrl: 'template/tooltip/tooltip-html-unsafe-popup.html'
2700
3150
  };
2701
3151
  })
2702
3152
 
2703
- .directive( 'tooltipHtmlUnsafe', [ '$tooltip', function ( $tooltip ) {
3153
+ .value('tooltipHtmlUnsafeSuppressDeprecated', false)
3154
+ .directive( 'tooltipHtmlUnsafe', [
3155
+ '$tooltip', 'tooltipHtmlUnsafeSuppressDeprecated', '$log',
3156
+ function ( $tooltip , tooltipHtmlUnsafeSuppressDeprecated , $log) {
3157
+ if (!tooltipHtmlUnsafeSuppressDeprecated) {
3158
+ $log.warn('tooltip-html-unsafe is now deprecated. Use tooltip-html or tooltip-template instead.');
3159
+ }
2704
3160
  return $tooltip( 'tooltipHtmlUnsafe', 'tooltip', 'mouseenter' );
2705
3161
  }]);
2706
3162
 
@@ -2711,11 +3167,27 @@ angular.module( 'ui.bootstrap.tooltip', [ 'ui.bootstrap.position', 'ui.bootstrap
2711
3167
  */
2712
3168
  angular.module( 'ui.bootstrap.popover', [ 'ui.bootstrap.tooltip' ] )
2713
3169
 
3170
+ .directive( 'popoverTemplatePopup', function () {
3171
+ return {
3172
+ restrict: 'EA',
3173
+ replace: true,
3174
+ scope: { title: '@', contentExp: '&', placement: '@', popupClass: '@', animation: '&', isOpen: '&',
3175
+ originScope: '&' },
3176
+ templateUrl: 'template/popover/popover-template.html'
3177
+ };
3178
+ })
3179
+
3180
+ .directive( 'popoverTemplate', [ '$tooltip', function ( $tooltip ) {
3181
+ return $tooltip( 'popoverTemplate', 'popover', 'click', {
3182
+ useContentExp: true
3183
+ } );
3184
+ }])
3185
+
2714
3186
  .directive( 'popoverPopup', function () {
2715
3187
  return {
2716
3188
  restrict: 'EA',
2717
3189
  replace: true,
2718
- scope: { title: '@', content: '@', placement: '@', animation: '&', isOpen: '&' },
3190
+ scope: { title: '@', content: '@', placement: '@', popupClass: '@', animation: '&', isOpen: '&' },
2719
3191
  templateUrl: 'template/popover/popover.html'
2720
3192
  };
2721
3193
  })
@@ -2736,7 +3208,7 @@ angular.module('ui.bootstrap.progressbar', [])
2736
3208
  animate = angular.isDefined($attrs.animate) ? $scope.$parent.$eval($attrs.animate) : progressConfig.animate;
2737
3209
 
2738
3210
  this.bars = [];
2739
- $scope.max = angular.isDefined($attrs.max) ? $scope.$parent.$eval($attrs.max) : progressConfig.max;
3211
+ $scope.max = angular.isDefined($scope.max) ? $scope.max : progressConfig.max;
2740
3212
 
2741
3213
  this.addBar = function(bar, element) {
2742
3214
  if ( !animate ) {
@@ -2780,6 +3252,7 @@ angular.module('ui.bootstrap.progressbar', [])
2780
3252
  require: '^progress',
2781
3253
  scope: {
2782
3254
  value: '=',
3255
+ max: '=?',
2783
3256
  type: '@'
2784
3257
  },
2785
3258
  templateUrl: 'template/progressbar/bar.html',
@@ -2797,6 +3270,7 @@ angular.module('ui.bootstrap.progressbar', [])
2797
3270
  controller: 'ProgressController',
2798
3271
  scope: {
2799
3272
  value: '=',
3273
+ max: '=?',
2800
3274
  type: '@'
2801
3275
  },
2802
3276
  templateUrl: 'template/progressbar/progressbar.html',
@@ -2805,6 +3279,7 @@ angular.module('ui.bootstrap.progressbar', [])
2805
3279
  }
2806
3280
  };
2807
3281
  });
3282
+
2808
3283
  angular.module('ui.bootstrap.rating', [])
2809
3284
 
2810
3285
  .constant('ratingConfig', {
@@ -2820,6 +3295,13 @@ angular.module('ui.bootstrap.rating', [])
2820
3295
  ngModelCtrl = ngModelCtrl_;
2821
3296
  ngModelCtrl.$render = this.render;
2822
3297
 
3298
+ ngModelCtrl.$formatters.push(function(value) {
3299
+ if (angular.isNumber(value) && value << 0 !== value) {
3300
+ value = Math.round(value);
3301
+ }
3302
+ return value;
3303
+ });
3304
+
2823
3305
  this.stateOn = angular.isDefined($attrs.stateOn) ? $scope.$parent.$eval($attrs.stateOn) : ratingConfig.stateOn;
2824
3306
  this.stateOff = angular.isDefined($attrs.stateOff) ? $scope.$parent.$eval($attrs.stateOff) : ratingConfig.stateOff;
2825
3307
 
@@ -2881,10 +3363,7 @@ angular.module('ui.bootstrap.rating', [])
2881
3363
  replace: true,
2882
3364
  link: function(scope, element, attrs, ctrls) {
2883
3365
  var ratingCtrl = ctrls[0], ngModelCtrl = ctrls[1];
2884
-
2885
- if ( ngModelCtrl ) {
2886
- ratingCtrl.init( ngModelCtrl );
2887
- }
3366
+ ratingCtrl.init( ngModelCtrl );
2888
3367
  }
2889
3368
  };
2890
3369
  });
@@ -2918,23 +3397,31 @@ angular.module('ui.bootstrap.tabs', [])
2918
3397
  tabs.push(tab);
2919
3398
  // we can't run the select function on the first tab
2920
3399
  // since that would select it twice
2921
- if (tabs.length === 1) {
3400
+ if (tabs.length === 1 && tab.active !== false) {
2922
3401
  tab.active = true;
2923
3402
  } else if (tab.active) {
2924
3403
  ctrl.select(tab);
2925
3404
  }
3405
+ else {
3406
+ tab.active = false;
3407
+ }
2926
3408
  };
2927
3409
 
2928
3410
  ctrl.removeTab = function removeTab(tab) {
2929
3411
  var index = tabs.indexOf(tab);
2930
- //Select a new tab if the tab to be removed is selected
2931
- if (tab.active && tabs.length > 1) {
3412
+ //Select a new tab if the tab to be removed is selected and not destroyed
3413
+ if (tab.active && tabs.length > 1 && !destroyed) {
2932
3414
  //If this is the last tab, select the previous tab. else, the next tab.
2933
3415
  var newActiveIndex = index == tabs.length - 1 ? index - 1 : index + 1;
2934
3416
  ctrl.select(tabs[newActiveIndex]);
2935
3417
  }
2936
3418
  tabs.splice(index, 1);
2937
3419
  };
3420
+
3421
+ var destroyed;
3422
+ $scope.$on('$destroy', function() {
3423
+ destroyed = true;
3424
+ });
2938
3425
  }])
2939
3426
 
2940
3427
  /**
@@ -3064,7 +3551,7 @@ angular.module('ui.bootstrap.tabs', [])
3064
3551
  </file>
3065
3552
  </example>
3066
3553
  */
3067
- .directive('tab', ['$parse', function($parse) {
3554
+ .directive('tab', ['$parse', '$log', function($parse, $log) {
3068
3555
  return {
3069
3556
  require: '^tabset',
3070
3557
  restrict: 'EA',
@@ -3090,7 +3577,18 @@ angular.module('ui.bootstrap.tabs', [])
3090
3577
  });
3091
3578
 
3092
3579
  scope.disabled = false;
3580
+ if ( attrs.disable ) {
3581
+ scope.$parent.$watch($parse(attrs.disable), function(value) {
3582
+ scope.disabled = !! value;
3583
+ });
3584
+ }
3585
+
3586
+ // Deprecation support of "disabled" parameter
3587
+ // fix(tab): IE9 disabled attr renders grey text on enabled tab #2677
3588
+ // This code is duplicated from the lines above to make it easy to remove once
3589
+ // the feature has been completely deprecated
3093
3590
  if ( attrs.disabled ) {
3591
+ $log.warn('Use of "disabled" attribute has been deprecated, please use "disable"');
3094
3592
  scope.$parent.$watch($parse(attrs.disabled), function(value) {
3095
3593
  scope.disabled = !! value;
3096
3594
  });
@@ -3171,7 +3669,8 @@ angular.module('ui.bootstrap.timepicker', [])
3171
3669
  showMeridian: true,
3172
3670
  meridians: null,
3173
3671
  readonlyInput: false,
3174
- mousewheel: true
3672
+ mousewheel: true,
3673
+ arrowkeys: true
3175
3674
  })
3176
3675
 
3177
3676
  .controller('TimepickerController', ['$scope', '$attrs', '$parse', '$log', '$locale', 'timepickerConfig', function($scope, $attrs, $parse, $log, $locale, timepickerConfig) {
@@ -3183,6 +3682,10 @@ angular.module('ui.bootstrap.timepicker', [])
3183
3682
  ngModelCtrl = ngModelCtrl_;
3184
3683
  ngModelCtrl.$render = this.render;
3185
3684
 
3685
+ ngModelCtrl.$formatters.unshift(function (modelValue) {
3686
+ return modelValue ? new Date( modelValue ) : null;
3687
+ });
3688
+
3186
3689
  var hoursInputEl = inputs.eq(0),
3187
3690
  minutesInputEl = inputs.eq(1);
3188
3691
 
@@ -3191,6 +3694,11 @@ angular.module('ui.bootstrap.timepicker', [])
3191
3694
  this.setupMousewheelEvents( hoursInputEl, minutesInputEl );
3192
3695
  }
3193
3696
 
3697
+ var arrowkeys = angular.isDefined($attrs.arrowkeys) ? $scope.$parent.$eval($attrs.arrowkeys) : timepickerConfig.arrowkeys;
3698
+ if (arrowkeys) {
3699
+ this.setupArrowkeyEvents( hoursInputEl, minutesInputEl );
3700
+ }
3701
+
3194
3702
  $scope.readonlyInput = angular.isDefined($attrs.readonlyInput) ? $scope.$parent.$eval($attrs.readonlyInput) : timepickerConfig.readonlyInput;
3195
3703
  this.setupInputEvents( hoursInputEl, minutesInputEl );
3196
3704
  };
@@ -3253,7 +3761,7 @@ angular.module('ui.bootstrap.timepicker', [])
3253
3761
  }
3254
3762
 
3255
3763
  function pad( value ) {
3256
- return ( angular.isDefined(value) && value.toString().length < 2 ) ? '0' + value : value;
3764
+ return ( angular.isDefined(value) && value.toString().length < 2 ) ? '0' + value : value.toString();
3257
3765
  }
3258
3766
 
3259
3767
  // Respond on mousewheel spin
@@ -3279,6 +3787,35 @@ angular.module('ui.bootstrap.timepicker', [])
3279
3787
 
3280
3788
  };
3281
3789
 
3790
+ // Respond on up/down arrowkeys
3791
+ this.setupArrowkeyEvents = function( hoursInputEl, minutesInputEl ) {
3792
+ hoursInputEl.bind('keydown', function(e) {
3793
+ if ( e.which === 38 ) { // up
3794
+ e.preventDefault();
3795
+ $scope.incrementHours();
3796
+ $scope.$apply();
3797
+ }
3798
+ else if ( e.which === 40 ) { // down
3799
+ e.preventDefault();
3800
+ $scope.decrementHours();
3801
+ $scope.$apply();
3802
+ }
3803
+ });
3804
+
3805
+ minutesInputEl.bind('keydown', function(e) {
3806
+ if ( e.which === 38 ) { // up
3807
+ e.preventDefault();
3808
+ $scope.incrementMinutes();
3809
+ $scope.$apply();
3810
+ }
3811
+ else if ( e.which === 40 ) { // down
3812
+ e.preventDefault();
3813
+ $scope.decrementMinutes();
3814
+ $scope.$apply();
3815
+ }
3816
+ });
3817
+ };
3818
+
3282
3819
  this.setupInputEvents = function( hoursInputEl, minutesInputEl ) {
3283
3820
  if ( $scope.readonlyInput ) {
3284
3821
  $scope.updateHours = angular.noop;
@@ -3338,7 +3875,7 @@ angular.module('ui.bootstrap.timepicker', [])
3338
3875
  };
3339
3876
 
3340
3877
  this.render = function() {
3341
- var date = ngModelCtrl.$modelValue ? new Date( ngModelCtrl.$modelValue ) : null;
3878
+ var date = ngModelCtrl.$viewValue;
3342
3879
 
3343
3880
  if ( isNaN(date) ) {
3344
3881
  ngModelCtrl.$setValidity('time', false);
@@ -3373,7 +3910,9 @@ angular.module('ui.bootstrap.timepicker', [])
3373
3910
  }
3374
3911
 
3375
3912
  $scope.hours = keyboardChange === 'h' ? hours : pad(hours);
3376
- $scope.minutes = keyboardChange === 'm' ? minutes : pad(minutes);
3913
+ if (keyboardChange !== 'm') {
3914
+ $scope.minutes = pad(minutes);
3915
+ }
3377
3916
  $scope.meridian = selected.getHours() < 12 ? meridians[0] : meridians[1];
3378
3917
  }
3379
3918
 
@@ -3418,6 +3957,96 @@ angular.module('ui.bootstrap.timepicker', [])
3418
3957
  };
3419
3958
  });
3420
3959
 
3960
+ angular.module('ui.bootstrap.transition', [])
3961
+
3962
+ .value('$transitionSuppressDeprecated', false)
3963
+ /**
3964
+ * $transition service provides a consistent interface to trigger CSS 3 transitions and to be informed when they complete.
3965
+ * @param {DOMElement} element The DOMElement that will be animated.
3966
+ * @param {string|object|function} trigger The thing that will cause the transition to start:
3967
+ * - As a string, it represents the css class to be added to the element.
3968
+ * - As an object, it represents a hash of style attributes to be applied to the element.
3969
+ * - As a function, it represents a function to be called that will cause the transition to occur.
3970
+ * @return {Promise} A promise that is resolved when the transition finishes.
3971
+ */
3972
+ .factory('$transition', [
3973
+ '$q', '$timeout', '$rootScope', '$log', '$transitionSuppressDeprecated',
3974
+ function($q , $timeout , $rootScope , $log , $transitionSuppressDeprecated) {
3975
+
3976
+ if (!$transitionSuppressDeprecated) {
3977
+ $log.warn('$transition is now deprecated. Use $animate from ngAnimate instead.');
3978
+ }
3979
+
3980
+ var $transition = function(element, trigger, options) {
3981
+ options = options || {};
3982
+ var deferred = $q.defer();
3983
+ var endEventName = $transition[options.animation ? 'animationEndEventName' : 'transitionEndEventName'];
3984
+
3985
+ var transitionEndHandler = function(event) {
3986
+ $rootScope.$apply(function() {
3987
+ element.unbind(endEventName, transitionEndHandler);
3988
+ deferred.resolve(element);
3989
+ });
3990
+ };
3991
+
3992
+ if (endEventName) {
3993
+ element.bind(endEventName, transitionEndHandler);
3994
+ }
3995
+
3996
+ // Wrap in a timeout to allow the browser time to update the DOM before the transition is to occur
3997
+ $timeout(function() {
3998
+ if ( angular.isString(trigger) ) {
3999
+ element.addClass(trigger);
4000
+ } else if ( angular.isFunction(trigger) ) {
4001
+ trigger(element);
4002
+ } else if ( angular.isObject(trigger) ) {
4003
+ element.css(trigger);
4004
+ }
4005
+ //If browser does not support transitions, instantly resolve
4006
+ if ( !endEventName ) {
4007
+ deferred.resolve(element);
4008
+ }
4009
+ });
4010
+
4011
+ // Add our custom cancel function to the promise that is returned
4012
+ // We can call this if we are about to run a new transition, which we know will prevent this transition from ending,
4013
+ // i.e. it will therefore never raise a transitionEnd event for that transition
4014
+ deferred.promise.cancel = function() {
4015
+ if ( endEventName ) {
4016
+ element.unbind(endEventName, transitionEndHandler);
4017
+ }
4018
+ deferred.reject('Transition cancelled');
4019
+ };
4020
+
4021
+ return deferred.promise;
4022
+ };
4023
+
4024
+ // Work out the name of the transitionEnd event
4025
+ var transElement = document.createElement('trans');
4026
+ var transitionEndEventNames = {
4027
+ 'WebkitTransition': 'webkitTransitionEnd',
4028
+ 'MozTransition': 'transitionend',
4029
+ 'OTransition': 'oTransitionEnd',
4030
+ 'transition': 'transitionend'
4031
+ };
4032
+ var animationEndEventNames = {
4033
+ 'WebkitTransition': 'webkitAnimationEnd',
4034
+ 'MozTransition': 'animationend',
4035
+ 'OTransition': 'oAnimationEnd',
4036
+ 'transition': 'animationend'
4037
+ };
4038
+ function findEndEventName(endEventNames) {
4039
+ for (var name in endEventNames){
4040
+ if (transElement.style[name] !== undefined) {
4041
+ return endEventNames[name];
4042
+ }
4043
+ }
4044
+ }
4045
+ $transition.transitionEndEventName = findEndEventName(transitionEndEventNames);
4046
+ $transition.animationEndEventName = findEndEventName(animationEndEventNames);
4047
+ return $transition;
4048
+ }]);
4049
+
3421
4050
  angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap.bindHtml'])
3422
4051
 
3423
4052
  /**
@@ -3427,7 +4056,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3427
4056
  .factory('typeaheadParser', ['$parse', function ($parse) {
3428
4057
 
3429
4058
  // 00000111000000000000022200000000000000003333333333333330000000000044000
3430
- var TYPEAHEAD_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+(.*)$/;
4059
+ var TYPEAHEAD_REGEXP = /^\s*([\s\S]+?)(?:\s+as\s+([\s\S]+?))?\s+for\s+(?:([\$\w][\$\w\d]*))\s+in\s+([\s\S]+?)$/;
3431
4060
 
3432
4061
  return {
3433
4062
  parse:function (input) {
@@ -3463,7 +4092,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3463
4092
  //minimal no of characters that needs to be entered before typeahead kicks-in
3464
4093
  var minSearch = originalScope.$eval(attrs.typeaheadMinLength) || 1;
3465
4094
 
3466
- //minimal wait time after last character typed before typehead kicks-in
4095
+ //minimal wait time after last character typed before typeahead kicks-in
3467
4096
  var waitTime = originalScope.$eval(attrs.typeaheadWaitMs) || 0;
3468
4097
 
3469
4098
  //should it restrict model values to the ones selected from the popup only?
@@ -3479,6 +4108,8 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3479
4108
 
3480
4109
  var appendToBody = attrs.typeaheadAppendToBody ? originalScope.$eval(attrs.typeaheadAppendToBody) : false;
3481
4110
 
4111
+ var focusFirst = originalScope.$eval(attrs.typeaheadFocusFirst) !== false;
4112
+
3482
4113
  //INTERNAL VARIABLES
3483
4114
 
3484
4115
  //model setter executed upon match selection
@@ -3549,9 +4180,9 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3549
4180
  //but we are interested only in responses that correspond to the current view value
3550
4181
  var onCurrentRequest = (inputValue === modelCtrl.$viewValue);
3551
4182
  if (onCurrentRequest && hasFocus) {
3552
- if (matches.length > 0) {
4183
+ if (matches && matches.length > 0) {
3553
4184
 
3554
- scope.activeIdx = 0;
4185
+ scope.activeIdx = focusFirst ? 0 : -1;
3555
4186
  scope.matches.length = 0;
3556
4187
 
3557
4188
  //transform labels
@@ -3590,9 +4221,21 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3590
4221
  //we need to propagate user's query so we can higlight matches
3591
4222
  scope.query = undefined;
3592
4223
 
3593
- //Declare the timeout promise var outside the function scope so that stacked calls can be cancelled later
4224
+ //Declare the timeout promise var outside the function scope so that stacked calls can be cancelled later
3594
4225
  var timeoutPromise;
3595
4226
 
4227
+ var scheduleSearchWithTimeout = function(inputValue) {
4228
+ timeoutPromise = $timeout(function () {
4229
+ getMatchesAsync(inputValue);
4230
+ }, waitTime);
4231
+ };
4232
+
4233
+ var cancelPreviousTimeout = function() {
4234
+ if (timeoutPromise) {
4235
+ $timeout.cancel(timeoutPromise);
4236
+ }
4237
+ };
4238
+
3596
4239
  //plug into $parsers pipeline to open a typeahead on view changes initiated from DOM
3597
4240
  //$parsers kick-in on all the changes coming from the view as well as manually triggered by $setViewValue
3598
4241
  modelCtrl.$parsers.unshift(function (inputValue) {
@@ -3601,17 +4244,14 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3601
4244
 
3602
4245
  if (inputValue && inputValue.length >= minSearch) {
3603
4246
  if (waitTime > 0) {
3604
- if (timeoutPromise) {
3605
- $timeout.cancel(timeoutPromise);//cancel previous timeout
3606
- }
3607
- timeoutPromise = $timeout(function () {
3608
- getMatchesAsync(inputValue);
3609
- }, waitTime);
4247
+ cancelPreviousTimeout();
4248
+ scheduleSearchWithTimeout(inputValue);
3610
4249
  } else {
3611
4250
  getMatchesAsync(inputValue);
3612
4251
  }
3613
4252
  } else {
3614
4253
  isLoadingSetter(originalScope, false);
4254
+ cancelPreviousTimeout();
3615
4255
  resetMatches();
3616
4256
  }
3617
4257
 
@@ -3634,9 +4274,16 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3634
4274
  var candidateViewValue, emptyViewValue;
3635
4275
  var locals = {};
3636
4276
 
4277
+ // The validity may be set to false via $parsers (see above) if
4278
+ // the model is restricted to selected values. If the model
4279
+ // is set manually it is considered to be valid.
4280
+ if (!isEditable) {
4281
+ modelCtrl.$setValidity('editable', true);
4282
+ }
4283
+
3637
4284
  if (inputFormatter) {
3638
4285
 
3639
- locals['$model'] = modelValue;
4286
+ locals.$model = modelValue;
3640
4287
  return inputFormatter(originalScope, locals);
3641
4288
 
3642
4289
  } else {
@@ -3661,6 +4308,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3661
4308
  model = parserResult.modelMapper(originalScope, locals);
3662
4309
  $setModelValue(originalScope, model);
3663
4310
  modelCtrl.$setValidity('editable', true);
4311
+ modelCtrl.$setValidity('parse', true);
3664
4312
 
3665
4313
  onSelectCallback(originalScope, {
3666
4314
  $item: item,
@@ -3683,6 +4331,11 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3683
4331
  return;
3684
4332
  }
3685
4333
 
4334
+ // if there's nothing selected (i.e. focusFirst) and enter is hit, don't do anything
4335
+ if (scope.activeIdx == -1 && (evt.which === 13 || evt.which === 9)) {
4336
+ return;
4337
+ }
4338
+
3686
4339
  evt.preventDefault();
3687
4340
 
3688
4341
  if (evt.which === 40) {
@@ -3690,7 +4343,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3690
4343
  scope.$digest();
3691
4344
 
3692
4345
  } else if (evt.which === 38) {
3693
- scope.activeIdx = (scope.activeIdx ? scope.activeIdx : scope.matches.length) - 1;
4346
+ scope.activeIdx = (scope.activeIdx > 0 ? scope.activeIdx : scope.matches.length) - 1;
3694
4347
  scope.$digest();
3695
4348
 
3696
4349
  } else if (evt.which === 13 || evt.which === 9) {
@@ -3722,10 +4375,16 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3722
4375
 
3723
4376
  originalScope.$on('$destroy', function(){
3724
4377
  $document.unbind('click', dismissClickHandler);
4378
+ if (appendToBody) {
4379
+ $popup.remove();
4380
+ }
4381
+ // Prevent jQuery cache memory leak
4382
+ popUpEl.remove();
3725
4383
  });
3726
4384
 
3727
4385
  var $popup = $compile(popUpEl)(scope);
3728
- if ( appendToBody ) {
4386
+
4387
+ if (appendToBody) {
3729
4388
  $document.find('body').append($popup);
3730
4389
  } else {
3731
4390
  element.after($popup);
@@ -3770,7 +4429,7 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3770
4429
  };
3771
4430
  })
3772
4431
 
3773
- .directive('typeaheadMatch', ['$http', '$templateCache', '$compile', '$parse', function ($http, $templateCache, $compile, $parse) {
4432
+ .directive('typeaheadMatch', ['$templateRequest', '$compile', '$parse', function ($templateRequest, $compile, $parse) {
3774
4433
  return {
3775
4434
  restrict:'EA',
3776
4435
  scope:{
@@ -3780,8 +4439,10 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3780
4439
  },
3781
4440
  link:function (scope, element, attrs) {
3782
4441
  var tplUrl = $parse(attrs.templateUrl)(scope.$parent) || 'template/typeahead/typeahead-match.html';
3783
- $http.get(tplUrl, {cache: $templateCache}).success(function(tplContent){
3784
- element.replaceWith($compile(tplContent.trim())(scope));
4442
+ $templateRequest(tplUrl).then(function(tplContent) {
4443
+ $compile(tplContent.trim())(scope, function(clonedElement){
4444
+ element.replaceWith(clonedElement);
4445
+ });
3785
4446
  });
3786
4447
  }
3787
4448
  };
@@ -3797,3 +4458,4 @@ angular.module('ui.bootstrap.typeahead', ['ui.bootstrap.position', 'ui.bootstrap
3797
4458
  return query ? ('' + matchItem).replace(new RegExp(escapeRegexp(query), 'gi'), '<strong>$&</strong>') : matchItem;
3798
4459
  };
3799
4460
  });
4461
+ !angular.$$csp() && angular.element(document).find('head').prepend('<style type="text/css">.ng-animate.item:not(.left):not(.right){-webkit-transition:0s ease-in-out left;transition:0s ease-in-out left}</style>');