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
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * State-based routing for AngularJS
3
- * @version v0.2.10
3
+ * @version v0.2.15
4
4
  * @link http://angular-ui.github.com/
5
5
  * @license MIT License, http://www.opensource.org/licenses/MIT
6
6
  */
7
- "undefined"!=typeof module&&"undefined"!=typeof exports&&module.exports===exports&&(module.exports="ui.router"),function(a,b,c){"use strict";function d(a,b){return I(new(I(function(){},{prototype:a})),b)}function e(a){return H(arguments,function(b){b!==a&&H(b,function(b,c){a.hasOwnProperty(c)||(a[c]=b)})}),a}function f(a,b){var c=[];for(var d in a.path){if(a.path[d]!==b.path[d])break;c.push(a.path[d])}return c}function g(a,b){if(Array.prototype.indexOf)return a.indexOf(b,Number(arguments[2])||0);var c=a.length>>>0,d=Number(arguments[2])||0;for(d=0>d?Math.ceil(d):Math.floor(d),0>d&&(d+=c);c>d;d++)if(d in a&&a[d]===b)return d;return-1}function h(a,b,c,d){var e,h=f(c,d),i={},j=[];for(var k in h)if(h[k].params&&h[k].params.length){e=h[k].params;for(var l in e)g(j,e[l])>=0||(j.push(e[l]),i[e[l]]=a[e[l]])}return I({},i,b)}function i(a,b){var c={};return H(a,function(a){var d=b[a];c[a]=null!=d?String(d):null}),c}function j(a,b,c){if(!c){c=[];for(var d in a)c.push(d)}for(var e=0;e<c.length;e++){var f=c[e];if(a[f]!=b[f])return!1}return!0}function k(a,b){var c={};return H(a,function(a){c[a]=b[a]}),c}function l(a,b){var d=1,f=2,g={},h=[],i=g,j=I(a.when(g),{$$promises:g,$$values:g});this.study=function(g){function k(a,c){if(o[c]!==f){if(n.push(c),o[c]===d)throw n.splice(0,n.indexOf(c)),new Error("Cyclic dependency: "+n.join(" -> "));if(o[c]=d,E(a))m.push(c,[function(){return b.get(a)}],h);else{var e=b.annotate(a);H(e,function(a){a!==c&&g.hasOwnProperty(a)&&k(g[a],a)}),m.push(c,a,e)}n.pop(),o[c]=f}}function l(a){return F(a)&&a.then&&a.$$promises}if(!F(g))throw new Error("'invocables' must be an object");var m=[],n=[],o={};return H(g,k),g=n=o=null,function(d,f,g){function h(){--s||(t||e(r,f.$$values),p.$$values=r,p.$$promises=!0,o.resolve(r))}function k(a){p.$$failure=a,o.reject(a)}function n(c,e,f){function i(a){l.reject(a),k(a)}function j(){if(!C(p.$$failure))try{l.resolve(b.invoke(e,g,r)),l.promise.then(function(a){r[c]=a,h()},i)}catch(a){i(a)}}var l=a.defer(),m=0;H(f,function(a){q.hasOwnProperty(a)&&!d.hasOwnProperty(a)&&(m++,q[a].then(function(b){r[a]=b,--m||j()},i))}),m||j(),q[c]=l.promise}if(l(d)&&g===c&&(g=f,f=d,d=null),d){if(!F(d))throw new Error("'locals' must be an object")}else d=i;if(f){if(!l(f))throw new Error("'parent' must be a promise returned by $resolve.resolve()")}else f=j;var o=a.defer(),p=o.promise,q=p.$$promises={},r=I({},d),s=1+m.length/3,t=!1;if(C(f.$$failure))return k(f.$$failure),p;f.$$values?(t=e(r,f.$$values),h()):(I(q,f.$$promises),f.then(h,k));for(var u=0,v=m.length;v>u;u+=3)d.hasOwnProperty(m[u])?h():n(m[u],m[u+1],m[u+2]);return p}},this.resolve=function(a,b,c,d){return this.study(a)(b,c,d)}}function m(a,b,c){this.fromConfig=function(a,b,c){return C(a.template)?this.fromString(a.template,b):C(a.templateUrl)?this.fromUrl(a.templateUrl,b):C(a.templateProvider)?this.fromProvider(a.templateProvider,b,c):null},this.fromString=function(a,b){return D(a)?a(b):a},this.fromUrl=function(c,d){return D(c)&&(c=c(d)),null==c?null:a.get(c,{cache:b}).then(function(a){return a.data})},this.fromProvider=function(a,b,d){return c.invoke(a,null,d||{params:b})}}function n(a){function b(b){if(!/^\w+(-+\w+)*$/.test(b))throw new Error("Invalid parameter name '"+b+"' in pattern '"+a+"'");if(f[b])throw new Error("Duplicate parameter name '"+b+"' in pattern '"+a+"'");f[b]=!0,j.push(b)}function c(a){return a.replace(/[\\\[\]\^$*+?.()|{}]/g,"\\$&")}var d,e=/([:*])(\w+)|\{(\w+)(?:\:((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,f={},g="^",h=0,i=this.segments=[],j=this.params=[];this.source=a;for(var k,l,m;(d=e.exec(a))&&(k=d[2]||d[3],l=d[4]||("*"==d[1]?".*":"[^/]*"),m=a.substring(h,d.index),!(m.indexOf("?")>=0));)g+=c(m)+"("+l+")",b(k),i.push(m),h=e.lastIndex;m=a.substring(h);var n=m.indexOf("?");if(n>=0){var o=this.sourceSearch=m.substring(n);m=m.substring(0,n),this.sourcePath=a.substring(0,h+n),H(o.substring(1).split(/[&?]/),b)}else this.sourcePath=a,this.sourceSearch="";g+=c(m)+"$",i.push(m),this.regexp=new RegExp(g),this.prefix=i[0]}function o(){this.compile=function(a){return new n(a)},this.isMatcher=function(a){return F(a)&&D(a.exec)&&D(a.format)&&D(a.concat)},this.$get=function(){return this}}function p(a){function b(a){var b=/^\^((?:\\[^a-zA-Z0-9]|[^\\\[\]\^$*+?.()|{}]+)*)/.exec(a.source);return null!=b?b[1].replace(/\\(.)/g,"$1"):""}function c(a,b){return a.replace(/\$(\$|\d{1,2})/,function(a,c){return b["$"===c?0:Number(c)]})}function d(a,b,c){if(!c)return!1;var d=a.invoke(b,b,{$match:c});return C(d)?d:!0}var e=[],f=null;this.rule=function(a){if(!D(a))throw new Error("'rule' must be a function");return e.push(a),this},this.otherwise=function(a){if(E(a)){var b=a;a=function(){return b}}else if(!D(a))throw new Error("'rule' must be a function");return f=a,this},this.when=function(e,f){var g,h=E(f);if(E(e)&&(e=a.compile(e)),!h&&!D(f)&&!G(f))throw new Error("invalid 'handler' in when()");var i={matcher:function(b,c){return h&&(g=a.compile(c),c=["$match",function(a){return g.format(a)}]),I(function(a,e){return d(a,c,b.exec(e.path(),e.search()))},{prefix:E(b.prefix)?b.prefix:""})},regex:function(a,e){if(a.global||a.sticky)throw new Error("when() RegExp must not be global or sticky");return h&&(g=e,e=["$match",function(a){return c(g,a)}]),I(function(b,c){return d(b,e,a.exec(c.path()))},{prefix:b(a)})}},j={matcher:a.isMatcher(e),regex:e instanceof RegExp};for(var k in j)if(j[k])return this.rule(i[k](e,f));throw new Error("invalid 'what' in when()")},this.$get=["$location","$rootScope","$injector",function(a,b,c){function d(b){function d(b){var d=b(c,a);return d?(E(d)&&a.replace().url(d),!0):!1}if(!b||!b.defaultPrevented){var g,h=e.length;for(g=0;h>g;g++)if(d(e[g]))return;f&&d(f)}}return b.$on("$locationChangeSuccess",d),{sync:function(){d()}}}]}function q(a,e,f){function g(a){return 0===a.indexOf(".")||0===a.indexOf("^")}function l(a,b){var d=E(a),e=d?a:a.name,f=g(e);if(f){if(!b)throw new Error("No reference point given for path '"+e+"'");for(var h=e.split("."),i=0,j=h.length,k=b;j>i;i++)if(""!==h[i]||0!==i){if("^"!==h[i])break;if(!k.parent)throw new Error("Path '"+e+"' not valid for state '"+b.name+"'");k=k.parent}else k=b;h=h.slice(i).join("."),e=k.name+(k.name&&h?".":"")+h}var l=w[e];return!l||!d&&(d||l!==a&&l.self!==a)?c:l}function m(a,b){x[a]||(x[a]=[]),x[a].push(b)}function n(b){b=d(b,{self:b,resolve:b.resolve||{},toString:function(){return this.name}});var c=b.name;if(!E(c)||c.indexOf("@")>=0)throw new Error("State must have a valid name");if(w.hasOwnProperty(c))throw new Error("State '"+c+"'' is already defined");var e=-1!==c.indexOf(".")?c.substring(0,c.lastIndexOf(".")):E(b.parent)?b.parent:"";if(e&&!w[e])return m(e,b.self);for(var f in z)D(z[f])&&(b[f]=z[f](b,z.$delegates[f]));if(w[c]=b,!b[y]&&b.url&&a.when(b.url,["$match","$stateParams",function(a,c){v.$current.navigable==b&&j(a,c)||v.transitionTo(b,a,{location:!1})}]),x[c])for(var g=0;g<x[c].length;g++)n(x[c][g]);return b}function o(a){return a.indexOf("*")>-1}function p(a){var b=a.split("."),c=v.$current.name.split(".");if("**"===b[0]&&(c=c.slice(c.indexOf(b[1])),c.unshift("**")),"**"===b[b.length-1]&&(c.splice(c.indexOf(b[b.length-2])+1,Number.MAX_VALUE),c.push("**")),b.length!=c.length)return!1;for(var d=0,e=b.length;e>d;d++)"*"===b[d]&&(c[d]="*");return c.join("")===b.join("")}function q(a,b){return E(a)&&!C(b)?z[a]:D(b)&&E(a)?(z[a]&&!z.$delegates[a]&&(z.$delegates[a]=z[a]),z[a]=b,this):this}function r(a,b){return F(a)?b=a:b.name=a,n(b),this}function s(a,e,g,m,n,q,r,s,x){function z(){r.url()!==M&&(r.url(M),r.replace())}function A(a,c,d,f,h){var i=d?c:k(a.params,c),j={$stateParams:i};h.resolve=n.resolve(a.resolve,j,h.resolve,a);var l=[h.resolve.then(function(a){h.globals=a})];return f&&l.push(f),H(a.views,function(c,d){var e=c.resolve&&c.resolve!==a.resolve?c.resolve:{};e.$template=[function(){return g.load(d,{view:c,locals:j,params:i,notify:!1})||""}],l.push(n.resolve(e,j,h.resolve,a).then(function(f){if(D(c.controllerProvider)||G(c.controllerProvider)){var g=b.extend({},e,j);f.$$controller=m.invoke(c.controllerProvider,null,g)}else f.$$controller=c.controller;f.$$state=a,f.$$controllerAs=c.controllerAs,h[d]=f}))}),e.all(l).then(function(){return h})}var B=e.reject(new Error("transition superseded")),F=e.reject(new Error("transition prevented")),K=e.reject(new Error("transition aborted")),L=e.reject(new Error("transition failed")),M=r.url(),N=x.baseHref();return u.locals={resolve:null,globals:{$stateParams:{}}},v={params:{},current:u.self,$current:u,transition:null},v.reload=function(){v.transitionTo(v.current,q,{reload:!0,inherit:!1,notify:!1})},v.go=function(a,b,c){return this.transitionTo(a,b,I({inherit:!0,relative:v.$current},c))},v.transitionTo=function(b,c,f){c=c||{},f=I({location:!0,inherit:!1,relative:null,notify:!0,reload:!1,$retry:!1},f||{});var g,k=v.$current,n=v.params,o=k.path,p=l(b,f.relative);if(!C(p)){var s={to:b,toParams:c,options:f};if(g=a.$broadcast("$stateNotFound",s,k.self,n),g.defaultPrevented)return z(),K;if(g.retry){if(f.$retry)return z(),L;var w=v.transition=e.when(g.retry);return w.then(function(){return w!==v.transition?B:(s.options.$retry=!0,v.transitionTo(s.to,s.toParams,s.options))},function(){return K}),z(),w}if(b=s.to,c=s.toParams,f=s.options,p=l(b,f.relative),!C(p)){if(f.relative)throw new Error("Could not resolve '"+b+"' from state '"+f.relative+"'");throw new Error("No such state '"+b+"'")}}if(p[y])throw new Error("Cannot transition to abstract state '"+b+"'");f.inherit&&(c=h(q,c||{},v.$current,p)),b=p;var x,D,E=b.path,G=u.locals,H=[];for(x=0,D=E[x];D&&D===o[x]&&j(c,n,D.ownParams)&&!f.reload;x++,D=E[x])G=H[x]=D.locals;if(t(b,k,G,f))return b.self.reloadOnSearch!==!1&&z(),v.transition=null,e.when(v.current);if(c=i(b.params,c||{}),f.notify&&(g=a.$broadcast("$stateChangeStart",b.self,c,k.self,n),g.defaultPrevented))return z(),F;for(var N=e.when(G),O=x;O<E.length;O++,D=E[O])G=H[O]=d(G),N=A(D,c,D===b,N,G);var P=v.transition=N.then(function(){var d,e,g;if(v.transition!==P)return B;for(d=o.length-1;d>=x;d--)g=o[d],g.self.onExit&&m.invoke(g.self.onExit,g.self,g.locals.globals),g.locals=null;for(d=x;d<E.length;d++)e=E[d],e.locals=H[d],e.self.onEnter&&m.invoke(e.self.onEnter,e.self,e.locals.globals);if(v.transition!==P)return B;v.$current=b,v.current=b.self,v.params=c,J(v.params,q),v.transition=null;var h=b.navigable;return f.location&&h&&(r.url(h.url.format(h.locals.globals.$stateParams)),"replace"===f.location&&r.replace()),f.notify&&a.$broadcast("$stateChangeSuccess",b.self,c,k.self,n),M=r.url(),v.current},function(d){return v.transition!==P?B:(v.transition=null,a.$broadcast("$stateChangeError",b.self,c,k.self,n,d),z(),e.reject(d))});return P},v.is=function(a,d){var e=l(a);return C(e)?v.$current!==e?!1:C(d)&&null!==d?b.equals(q,d):!0:c},v.includes=function(a,d){if(E(a)&&o(a)){if(!p(a))return!1;a=v.$current.name}var e=l(a);if(!C(e))return c;if(!C(v.$current.includes[e.name]))return!1;var f=!0;return b.forEach(d,function(a,b){C(q[b])&&q[b]===a||(f=!1)}),f},v.href=function(a,b,c){c=I({lossy:!0,inherit:!1,absolute:!1,relative:v.$current},c||{});var d=l(a,c.relative);if(!C(d))return null;b=h(q,b||{},v.$current,d);var e=d&&c.lossy?d.navigable:d,g=e&&e.url?e.url.format(i(d.params,b||{})):null;return!f.html5Mode()&&g&&(g="#"+f.hashPrefix()+g),"/"!==N&&(f.html5Mode()?g=N.slice(0,-1)+g:c.absolute&&(g=N.slice(1)+g)),c.absolute&&g&&(g=r.protocol()+"://"+r.host()+(80==r.port()||443==r.port()?"":":"+r.port())+(!f.html5Mode()&&g?"/":"")+g),g},v.get=function(a,b){if(!C(a)){var c=[];return H(w,function(a){c.push(a.self)}),c}var d=l(a,b);return d&&d.self?d.self:null},v}function t(a,b,c,d){return a!==b||(c!==b.locals||d.reload)&&a.self.reloadOnSearch!==!1?void 0:!0}var u,v,w={},x={},y="abstract",z={parent:function(a){if(C(a.parent)&&a.parent)return l(a.parent);var b=/^(.+)\.[^.]+$/.exec(a.name);return b?l(b[1]):u},data:function(a){return a.parent&&a.parent.data&&(a.data=a.self.data=I({},a.parent.data,a.data)),a.data},url:function(a){var b=a.url;if(E(b))return"^"==b.charAt(0)?e.compile(b.substring(1)):(a.parent.navigable||u).url.concat(b);if(e.isMatcher(b)||null==b)return b;throw new Error("Invalid url '"+b+"' in state '"+a+"'")},navigable:function(a){return a.url?a:a.parent?a.parent.navigable:null},params:function(a){if(!a.params)return a.url?a.url.parameters():a.parent.params;if(!G(a.params))throw new Error("Invalid params in state '"+a+"'");if(a.url)throw new Error("Both params and url specicified in state '"+a+"'");return a.params},views:function(a){var b={};return H(C(a.views)?a.views:{"":a},function(c,d){d.indexOf("@")<0&&(d+="@"+a.parent.name),b[d]=c}),b},ownParams:function(a){if(!a.parent)return a.params;var b={};H(a.params,function(a){b[a]=!0}),H(a.parent.params,function(c){if(!b[c])throw new Error("Missing required parameter '"+c+"' in state '"+a.name+"'");b[c]=!1});var c=[];return H(b,function(a,b){a&&c.push(b)}),c},path:function(a){return a.parent?a.parent.path.concat(a):[]},includes:function(a){var b=a.parent?I({},a.parent.includes):{};return b[a.name]=!0,b},$delegates:{}};u=n({name:"",url:"^",views:null,"abstract":!0}),u.navigable=null,this.decorator=q,this.state=r,this.$get=s,s.$inject=["$rootScope","$q","$view","$injector","$resolve","$stateParams","$location","$urlRouter","$browser"]}function r(){function a(a,b){return{load:function(c,d){var e,f={template:null,controller:null,view:null,locals:null,notify:!0,async:!0,params:{}};return d=I(f,d),d.view&&(e=b.fromConfig(d.view,d.params,d.locals)),e&&d.notify&&a.$broadcast("$viewContentLoading",d),e}}}this.$get=a,a.$inject=["$rootScope","$templateFactory"]}function s(){var a=!1;this.useAnchorScroll=function(){a=!0},this.$get=["$anchorScroll","$timeout",function(b,c){return a?b:function(a){c(function(){a[0].scrollIntoView()},0,!1)}}]}function t(a,c,d){function e(){return c.has?function(a){return c.has(a)?c.get(a):null}:function(a){try{return c.get(a)}catch(b){return null}}}function f(a,b){var c=function(){return{enter:function(a,b,c){b.after(a),c()},leave:function(a,b){a.remove(),b()}}};if(i)return{enter:function(a,b,c){i.enter(a,null,b,c)},leave:function(a,b){i.leave(a,b)}};if(h){var d=h&&h(b,a);return{enter:function(a,b,c){d.enter(a,null,b),c()},leave:function(a,b){d.leave(a),b()}}}return c()}var g=e(),h=g("$animator"),i=g("$animate"),j={restrict:"ECA",terminal:!0,priority:400,transclude:"element",compile:function(c,e,g){return function(c,e,h){function i(){k&&(k.remove(),k=null),m&&(m.$destroy(),m=null),l&&(q.leave(l,function(){k=null}),k=l,l=null)}function j(f){var h=c.$new(),j=l&&l.data("$uiViewName"),k=j&&a.$current&&a.$current.locals[j];if(f||k!==n){var r=g(h,function(a){q.enter(a,e,function(){(b.isDefined(p)&&!p||c.$eval(p))&&d(a)}),i()});n=a.$current.locals[r.data("$uiViewName")],l=r,m=h,m.$emit("$viewContentLoaded"),m.$eval(o)}}var k,l,m,n,o=h.onload||"",p=h.autoscroll,q=f(h,c);c.$on("$stateChangeSuccess",function(){j(!1)}),c.$on("$viewContentLoading",function(){j(!1)}),j(!0)}}};return j}function u(a,b,c){return{restrict:"ECA",priority:-400,compile:function(d){var e=d.html();return function(d,f,g){var h=g.uiView||g.name||"",i=f.inheritedData("$uiView");h.indexOf("@")<0&&(h=h+"@"+(i?i.state.name:"")),f.data("$uiViewName",h);var j=c.$current,k=j&&j.locals[h];if(k){f.data("$uiView",{name:h,state:k.$$state}),f.html(k.$template?k.$template:e);var l=a(f.contents());if(k.$$controller){k.$scope=d;var m=b(k.$$controller,k);k.$$controllerAs&&(d[k.$$controllerAs]=m),f.data("$ngControllerController",m),f.children().data("$ngControllerController",m)}l(d)}}}}}function v(a){var b=a.replace(/\n/g," ").match(/^([^(]+?)\s*(\((.*)\))?$/);if(!b||4!==b.length)throw new Error("Invalid state ref '"+a+"'");return{state:b[1],paramExpr:b[3]||null}}function w(a){var b=a.parent().inheritedData("$uiView");return b&&b.state&&b.state.name?b.state:void 0}function x(a,c){var d=["location","inherit","reload"];return{restrict:"A",require:"?^uiSrefActive",link:function(e,f,g,h){var i=v(g.uiSref),j=null,k=w(f)||a.$current,l="FORM"===f[0].nodeName,m=l?"action":"href",n=!0,o={relative:k},p=e.$eval(g.uiSrefOpts)||{};b.forEach(d,function(a){a in p&&(o[a]=p[a])});var q=function(b){if(b&&(j=b),n){var c=a.href(i.state,j,o);return h&&h.$$setStateInfo(i.state,j),c?void(f[0][m]=c):(n=!1,!1)}};i.paramExpr&&(e.$watch(i.paramExpr,function(a){a!==j&&q(a)},!0),j=e.$eval(i.paramExpr)),q(),l||f.bind("click",function(b){var d=b.which||b.button;d>1||b.ctrlKey||b.metaKey||b.shiftKey||f.attr("target")||(c(function(){a.go(i.state,j,o)}),b.preventDefault())})}}}function y(a,b,c){return{restrict:"A",controller:["$scope","$element","$attrs",function(d,e,f){function g(){a.$current.self===i&&h()?e.addClass(l):e.removeClass(l)}function h(){return!k||j(k,b)}var i,k,l;l=c(f.uiSrefActive||"",!1)(d),this.$$setStateInfo=function(b,c){i=a.get(b,w(e)),k=c,g()},d.$on("$stateChangeSuccess",g)}]}}function z(a){return function(b){return a.is(b)}}function A(a){return function(b){return a.includes(b)}}function B(a,b){function e(a){this.locals=a.locals.globals,this.params=this.locals.$stateParams}function f(){this.locals=null,this.params=null}function g(c,g){if(null!=g.redirectTo){var h,j=g.redirectTo;if(E(j))h=j;else{if(!D(j))throw new Error("Invalid 'redirectTo' in when()");h=function(a,b){return j(a,b.path(),b.search())}}b.when(c,h)}else a.state(d(g,{parent:null,name:"route:"+encodeURIComponent(c),url:c,onEnter:e,onExit:f}));return i.push(g),this}function h(a,b,d){function e(a){return""!==a.name?a:c}var f={routes:i,params:d,current:c};return b.$on("$stateChangeStart",function(a,c,d,f){b.$broadcast("$routeChangeStart",e(c),e(f))}),b.$on("$stateChangeSuccess",function(a,c,d,g){f.current=e(c),b.$broadcast("$routeChangeSuccess",e(c),e(g)),J(d,f.params)}),b.$on("$stateChangeError",function(a,c,d,f,g,h){b.$broadcast("$routeChangeError",e(c),e(f),h)}),f}var i=[];e.$inject=["$$state"],this.when=g,this.$get=h,h.$inject=["$state","$rootScope","$routeParams"]}var C=b.isDefined,D=b.isFunction,E=b.isString,F=b.isObject,G=b.isArray,H=b.forEach,I=b.extend,J=b.copy;b.module("ui.router.util",["ng"]),b.module("ui.router.router",["ui.router.util"]),b.module("ui.router.state",["ui.router.router","ui.router.util"]),b.module("ui.router",["ui.router.state"]),b.module("ui.router.compat",["ui.router"]),l.$inject=["$q","$injector"],b.module("ui.router.util").service("$resolve",l),m.$inject=["$http","$templateCache","$injector"],b.module("ui.router.util").service("$templateFactory",m),n.prototype.concat=function(a){return new n(this.sourcePath+a+this.sourceSearch)},n.prototype.toString=function(){return this.source},n.prototype.exec=function(a,b){var c=this.regexp.exec(a);if(!c)return null;var d,e=this.params,f=e.length,g=this.segments.length-1,h={};if(g!==c.length-1)throw new Error("Unbalanced capture group in route '"+this.source+"'");for(d=0;g>d;d++)h[e[d]]=c[d+1];for(;f>d;d++)h[e[d]]=b[e[d]];return h},n.prototype.parameters=function(){return this.params},n.prototype.format=function(a){var b=this.segments,c=this.params;if(!a)return b.join("");var d,e,f,g=b.length-1,h=c.length,i=b[0];for(d=0;g>d;d++)f=a[c[d]],null!=f&&(i+=encodeURIComponent(f)),i+=b[d+1];for(;h>d;d++)f=a[c[d]],null!=f&&(i+=(e?"&":"?")+c[d]+"="+encodeURIComponent(f),e=!0);return i},b.module("ui.router.util").provider("$urlMatcherFactory",o),p.$inject=["$urlMatcherFactoryProvider"],b.module("ui.router.router").provider("$urlRouter",p),q.$inject=["$urlRouterProvider","$urlMatcherFactoryProvider","$locationProvider"],b.module("ui.router.state").value("$stateParams",{}).provider("$state",q),r.$inject=[],b.module("ui.router.state").provider("$view",r),b.module("ui.router.state").provider("$uiViewScroll",s),t.$inject=["$state","$injector","$uiViewScroll"],u.$inject=["$compile","$controller","$state"],b.module("ui.router.state").directive("uiView",t),b.module("ui.router.state").directive("uiView",u),x.$inject=["$state","$timeout"],y.$inject=["$state","$stateParams","$interpolate"],b.module("ui.router.state").directive("uiSref",x).directive("uiSrefActive",y),z.$inject=["$state"],A.$inject=["$state"],b.module("ui.router.state").filter("isState",z).filter("includedByState",A),B.$inject=["$stateProvider","$urlRouterProvider"],b.module("ui.router.compat").provider("$route",B).directive("ngView",t)}(window,window.angular);
7
+ "undefined"!=typeof module&&"undefined"!=typeof exports&&module.exports===exports&&(module.exports="ui.router"),function(a,b,c){"use strict";function d(a,b){return N(new(N(function(){},{prototype:a})),b)}function e(a){return M(arguments,function(b){b!==a&&M(b,function(b,c){a.hasOwnProperty(c)||(a[c]=b)})}),a}function f(a,b){var c=[];for(var d in a.path){if(a.path[d]!==b.path[d])break;c.push(a.path[d])}return c}function g(a){if(Object.keys)return Object.keys(a);var b=[];return M(a,function(a,c){b.push(c)}),b}function h(a,b){if(Array.prototype.indexOf)return a.indexOf(b,Number(arguments[2])||0);var c=a.length>>>0,d=Number(arguments[2])||0;for(d=0>d?Math.ceil(d):Math.floor(d),0>d&&(d+=c);c>d;d++)if(d in a&&a[d]===b)return d;return-1}function i(a,b,c,d){var e,i=f(c,d),j={},k=[];for(var l in i)if(i[l].params&&(e=g(i[l].params),e.length))for(var m in e)h(k,e[m])>=0||(k.push(e[m]),j[e[m]]=a[e[m]]);return N({},j,b)}function j(a,b,c){if(!c){c=[];for(var d in a)c.push(d)}for(var e=0;e<c.length;e++){var f=c[e];if(a[f]!=b[f])return!1}return!0}function k(a,b){var c={};return M(a,function(a){c[a]=b[a]}),c}function l(a){var b={},c=Array.prototype.concat.apply(Array.prototype,Array.prototype.slice.call(arguments,1));return M(c,function(c){c in a&&(b[c]=a[c])}),b}function m(a){var b={},c=Array.prototype.concat.apply(Array.prototype,Array.prototype.slice.call(arguments,1));for(var d in a)-1==h(c,d)&&(b[d]=a[d]);return b}function n(a,b){var c=L(a),d=c?[]:{};return M(a,function(a,e){b(a,e)&&(d[c?d.length:e]=a)}),d}function o(a,b){var c=L(a)?[]:{};return M(a,function(a,d){c[d]=b(a,d)}),c}function p(a,b){var d=1,f=2,i={},j=[],k=i,l=N(a.when(i),{$$promises:i,$$values:i});this.study=function(i){function n(a,c){if(s[c]!==f){if(r.push(c),s[c]===d)throw r.splice(0,h(r,c)),new Error("Cyclic dependency: "+r.join(" -> "));if(s[c]=d,J(a))q.push(c,[function(){return b.get(a)}],j);else{var e=b.annotate(a);M(e,function(a){a!==c&&i.hasOwnProperty(a)&&n(i[a],a)}),q.push(c,a,e)}r.pop(),s[c]=f}}function o(a){return K(a)&&a.then&&a.$$promises}if(!K(i))throw new Error("'invocables' must be an object");var p=g(i||{}),q=[],r=[],s={};return M(i,n),i=r=s=null,function(d,f,g){function h(){--u||(v||e(t,f.$$values),r.$$values=t,r.$$promises=r.$$promises||!0,delete r.$$inheritedValues,n.resolve(t))}function i(a){r.$$failure=a,n.reject(a)}function j(c,e,f){function j(a){l.reject(a),i(a)}function k(){if(!H(r.$$failure))try{l.resolve(b.invoke(e,g,t)),l.promise.then(function(a){t[c]=a,h()},j)}catch(a){j(a)}}var l=a.defer(),m=0;M(f,function(a){s.hasOwnProperty(a)&&!d.hasOwnProperty(a)&&(m++,s[a].then(function(b){t[a]=b,--m||k()},j))}),m||k(),s[c]=l.promise}if(o(d)&&g===c&&(g=f,f=d,d=null),d){if(!K(d))throw new Error("'locals' must be an object")}else d=k;if(f){if(!o(f))throw new Error("'parent' must be a promise returned by $resolve.resolve()")}else f=l;var n=a.defer(),r=n.promise,s=r.$$promises={},t=N({},d),u=1+q.length/3,v=!1;if(H(f.$$failure))return i(f.$$failure),r;f.$$inheritedValues&&e(t,m(f.$$inheritedValues,p)),N(s,f.$$promises),f.$$values?(v=e(t,m(f.$$values,p)),r.$$inheritedValues=m(f.$$values,p),h()):(f.$$inheritedValues&&(r.$$inheritedValues=m(f.$$inheritedValues,p)),f.then(h,i));for(var w=0,x=q.length;x>w;w+=3)d.hasOwnProperty(q[w])?h():j(q[w],q[w+1],q[w+2]);return r}},this.resolve=function(a,b,c,d){return this.study(a)(b,c,d)}}function q(a,b,c){this.fromConfig=function(a,b,c){return H(a.template)?this.fromString(a.template,b):H(a.templateUrl)?this.fromUrl(a.templateUrl,b):H(a.templateProvider)?this.fromProvider(a.templateProvider,b,c):null},this.fromString=function(a,b){return I(a)?a(b):a},this.fromUrl=function(c,d){return I(c)&&(c=c(d)),null==c?null:a.get(c,{cache:b,headers:{Accept:"text/html"}}).then(function(a){return a.data})},this.fromProvider=function(a,b,d){return c.invoke(a,null,d||{params:b})}}function r(a,b,e){function f(b,c,d,e){if(q.push(b),o[b])return o[b];if(!/^\w+(-+\w+)*(?:\[\])?$/.test(b))throw new Error("Invalid parameter name '"+b+"' in pattern '"+a+"'");if(p[b])throw new Error("Duplicate parameter name '"+b+"' in pattern '"+a+"'");return p[b]=new P.Param(b,c,d,e),p[b]}function g(a,b,c,d){var e=["",""],f=a.replace(/[\\\[\]\^$*+?.()|{}]/g,"\\$&");if(!b)return f;switch(c){case!1:e=["(",")"+(d?"?":"")];break;case!0:e=["?(",")?"];break;default:e=["("+c+"|",")?"]}return f+e[0]+b+e[1]}function h(e,f){var g,h,i,j,k;return g=e[2]||e[3],k=b.params[g],i=a.substring(m,e.index),h=f?e[4]:e[4]||("*"==e[1]?".*":null),j=P.type(h||"string")||d(P.type("string"),{pattern:new RegExp(h,b.caseInsensitive?"i":c)}),{id:g,regexp:h,segment:i,type:j,cfg:k}}b=N({params:{}},K(b)?b:{});var i,j=/([:*])([\w\[\]]+)|\{([\w\[\]]+)(?:\:((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,k=/([:]?)([\w\[\]-]+)|\{([\w\[\]-]+)(?:\:((?:[^{}\\]+|\\.|\{(?:[^{}\\]+|\\.)*\})+))?\}/g,l="^",m=0,n=this.segments=[],o=e?e.params:{},p=this.params=e?e.params.$$new():new P.ParamSet,q=[];this.source=a;for(var r,s,t;(i=j.exec(a))&&(r=h(i,!1),!(r.segment.indexOf("?")>=0));)s=f(r.id,r.type,r.cfg,"path"),l+=g(r.segment,s.type.pattern.source,s.squash,s.isOptional),n.push(r.segment),m=j.lastIndex;t=a.substring(m);var u=t.indexOf("?");if(u>=0){var v=this.sourceSearch=t.substring(u);if(t=t.substring(0,u),this.sourcePath=a.substring(0,m+u),v.length>0)for(m=0;i=k.exec(v);)r=h(i,!0),s=f(r.id,r.type,r.cfg,"search"),m=j.lastIndex}else this.sourcePath=a,this.sourceSearch="";l+=g(t)+(b.strict===!1?"/?":"")+"$",n.push(t),this.regexp=new RegExp(l,b.caseInsensitive?"i":c),this.prefix=n[0],this.$$paramNames=q}function s(a){N(this,a)}function t(){function a(a){return null!=a?a.toString().replace(/\//g,"%2F"):a}function e(a){return null!=a?a.toString().replace(/%2F/g,"/"):a}function f(){return{strict:p,caseInsensitive:m}}function i(a){return I(a)||L(a)&&I(a[a.length-1])}function j(){for(;w.length;){var a=w.shift();if(a.pattern)throw new Error("You cannot override a type's .pattern at runtime.");b.extend(u[a.name],l.invoke(a.def))}}function k(a){N(this,a||{})}P=this;var l,m=!1,p=!0,q=!1,u={},v=!0,w=[],x={string:{encode:a,decode:e,is:function(a){return null==a||!H(a)||"string"==typeof a},pattern:/[^/]*/},"int":{encode:a,decode:function(a){return parseInt(a,10)},is:function(a){return H(a)&&this.decode(a.toString())===a},pattern:/\d+/},bool:{encode:function(a){return a?1:0},decode:function(a){return 0!==parseInt(a,10)},is:function(a){return a===!0||a===!1},pattern:/0|1/},date:{encode:function(a){return this.is(a)?[a.getFullYear(),("0"+(a.getMonth()+1)).slice(-2),("0"+a.getDate()).slice(-2)].join("-"):c},decode:function(a){if(this.is(a))return a;var b=this.capture.exec(a);return b?new Date(b[1],b[2]-1,b[3]):c},is:function(a){return a instanceof Date&&!isNaN(a.valueOf())},equals:function(a,b){return this.is(a)&&this.is(b)&&a.toISOString()===b.toISOString()},pattern:/[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,capture:/([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/},json:{encode:b.toJson,decode:b.fromJson,is:b.isObject,equals:b.equals,pattern:/[^/]*/},any:{encode:b.identity,decode:b.identity,equals:b.equals,pattern:/.*/}};t.$$getDefaultValue=function(a){if(!i(a.value))return a.value;if(!l)throw new Error("Injectable functions cannot be called at configuration time");return l.invoke(a.value)},this.caseInsensitive=function(a){return H(a)&&(m=a),m},this.strictMode=function(a){return H(a)&&(p=a),p},this.defaultSquashPolicy=function(a){if(!H(a))return q;if(a!==!0&&a!==!1&&!J(a))throw new Error("Invalid squash policy: "+a+". Valid policies: false, true, arbitrary-string");return q=a,a},this.compile=function(a,b){return new r(a,N(f(),b))},this.isMatcher=function(a){if(!K(a))return!1;var b=!0;return M(r.prototype,function(c,d){I(c)&&(b=b&&H(a[d])&&I(a[d]))}),b},this.type=function(a,b,c){if(!H(b))return u[a];if(u.hasOwnProperty(a))throw new Error("A type named '"+a+"' has already been defined.");return u[a]=new s(N({name:a},b)),c&&(w.push({name:a,def:c}),v||j()),this},M(x,function(a,b){u[b]=new s(N({name:b},a))}),u=d(u,{}),this.$get=["$injector",function(a){return l=a,v=!1,j(),M(x,function(a,b){u[b]||(u[b]=new s(a))}),this}],this.Param=function(a,b,d,e){function f(a){var b=K(a)?g(a):[],c=-1===h(b,"value")&&-1===h(b,"type")&&-1===h(b,"squash")&&-1===h(b,"array");return c&&(a={value:a}),a.$$fn=i(a.value)?a.value:function(){return a.value},a}function j(b,c,d){if(b.type&&c)throw new Error("Param '"+a+"' has two type configurations.");return c?c:b.type?b.type instanceof s?b.type:new s(b.type):"config"===d?u.any:u.string}function k(){var b={array:"search"===e?"auto":!1},c=a.match(/\[\]$/)?{array:!0}:{};return N(b,c,d).array}function m(a,b){var c=a.squash;if(!b||c===!1)return!1;if(!H(c)||null==c)return q;if(c===!0||J(c))return c;throw new Error("Invalid squash policy: '"+c+"'. Valid policies: false, true, or arbitrary string")}function p(a,b,d,e){var f,g,i=[{from:"",to:d||b?c:""},{from:null,to:d||b?c:""}];return f=L(a.replace)?a.replace:[],J(e)&&f.push({from:e,to:c}),g=o(f,function(a){return a.from}),n(i,function(a){return-1===h(g,a.from)}).concat(f)}function r(){if(!l)throw new Error("Injectable functions cannot be called at configuration time");var a=l.invoke(d.$$fn);if(null!==a&&a!==c&&!w.type.is(a))throw new Error("Default value ("+a+") for parameter '"+w.id+"' is not an instance of Type ("+w.type.name+")");return a}function t(a){function b(a){return function(b){return b.from===a}}function c(a){var c=o(n(w.replace,b(a)),function(a){return a.to});return c.length?c[0]:a}return a=c(a),H(a)?w.type.$normalize(a):r()}function v(){return"{Param:"+a+" "+b+" squash: '"+z+"' optional: "+y+"}"}var w=this;d=f(d),b=j(d,b,e);var x=k();b=x?b.$asArray(x,"search"===e):b,"string"!==b.name||x||"path"!==e||d.value!==c||(d.value="");var y=d.value!==c,z=m(d,y),A=p(d,x,y,z);N(this,{id:a,type:b,location:e,array:x,squash:z,replace:A,isOptional:y,value:t,dynamic:c,config:d,toString:v})},k.prototype={$$new:function(){return d(this,N(new k,{$$parent:this}))},$$keys:function(){for(var a=[],b=[],c=this,d=g(k.prototype);c;)b.push(c),c=c.$$parent;return b.reverse(),M(b,function(b){M(g(b),function(b){-1===h(a,b)&&-1===h(d,b)&&a.push(b)})}),a},$$values:function(a){var b={},c=this;return M(c.$$keys(),function(d){b[d]=c[d].value(a&&a[d])}),b},$$equals:function(a,b){var c=!0,d=this;return M(d.$$keys(),function(e){var f=a&&a[e],g=b&&b[e];d[e].type.equals(f,g)||(c=!1)}),c},$$validates:function(a){var d,e,f,g,h,i=this.$$keys();for(d=0;d<i.length&&(e=this[i[d]],f=a[i[d]],f!==c&&null!==f||!e.isOptional);d++){if(g=e.type.$normalize(f),!e.type.is(g))return!1;if(h=e.type.encode(g),b.isString(h)&&!e.type.pattern.exec(h))return!1}return!0},$$parent:c},this.ParamSet=k}function u(a,d){function e(a){var b=/^\^((?:\\[^a-zA-Z0-9]|[^\\\[\]\^$*+?.()|{}]+)*)/.exec(a.source);return null!=b?b[1].replace(/\\(.)/g,"$1"):""}function f(a,b){return a.replace(/\$(\$|\d{1,2})/,function(a,c){return b["$"===c?0:Number(c)]})}function g(a,b,c){if(!c)return!1;var d=a.invoke(b,b,{$match:c});return H(d)?d:!0}function h(d,e,f,g){function h(a,b,c){return"/"===p?a:b?p.slice(0,-1)+a:c?p.slice(1)+a:a}function m(a){function b(a){var b=a(f,d);return b?(J(b)&&d.replace().url(b),!0):!1}if(!a||!a.defaultPrevented){o&&d.url()===o;o=c;var e,g=j.length;for(e=0;g>e;e++)if(b(j[e]))return;k&&b(k)}}function n(){return i=i||e.$on("$locationChangeSuccess",m)}var o,p=g.baseHref(),q=d.url();return l||n(),{sync:function(){m()},listen:function(){return n()},update:function(a){return a?void(q=d.url()):void(d.url()!==q&&(d.url(q),d.replace()))},push:function(a,b,e){var f=a.format(b||{});null!==f&&b&&b["#"]&&(f+="#"+b["#"]),d.url(f),o=e&&e.$$avoidResync?d.url():c,e&&e.replace&&d.replace()},href:function(c,e,f){if(!c.validates(e))return null;var g=a.html5Mode();b.isObject(g)&&(g=g.enabled);var i=c.format(e);if(f=f||{},g||null===i||(i="#"+a.hashPrefix()+i),null!==i&&e&&e["#"]&&(i+="#"+e["#"]),i=h(i,g,f.absolute),!f.absolute||!i)return i;var j=!g&&i?"/":"",k=d.port();return k=80===k||443===k?"":":"+k,[d.protocol(),"://",d.host(),k,j,i].join("")}}}var i,j=[],k=null,l=!1;this.rule=function(a){if(!I(a))throw new Error("'rule' must be a function");return j.push(a),this},this.otherwise=function(a){if(J(a)){var b=a;a=function(){return b}}else if(!I(a))throw new Error("'rule' must be a function");return k=a,this},this.when=function(a,b){var c,h=J(b);if(J(a)&&(a=d.compile(a)),!h&&!I(b)&&!L(b))throw new Error("invalid 'handler' in when()");var i={matcher:function(a,b){return h&&(c=d.compile(b),b=["$match",function(a){return c.format(a)}]),N(function(c,d){return g(c,b,a.exec(d.path(),d.search()))},{prefix:J(a.prefix)?a.prefix:""})},regex:function(a,b){if(a.global||a.sticky)throw new Error("when() RegExp must not be global or sticky");return h&&(c=b,b=["$match",function(a){return f(c,a)}]),N(function(c,d){return g(c,b,a.exec(d.path()))},{prefix:e(a)})}},j={matcher:d.isMatcher(a),regex:a instanceof RegExp};for(var k in j)if(j[k])return this.rule(i[k](a,b));throw new Error("invalid 'what' in when()")},this.deferIntercept=function(a){a===c&&(a=!0),l=a},this.$get=h,h.$inject=["$location","$rootScope","$injector","$browser"]}function v(a,e){function f(a){return 0===a.indexOf(".")||0===a.indexOf("^")}function m(a,b){if(!a)return c;var d=J(a),e=d?a:a.name,g=f(e);if(g){if(!b)throw new Error("No reference point given for path '"+e+"'");b=m(b);for(var h=e.split("."),i=0,j=h.length,k=b;j>i;i++)if(""!==h[i]||0!==i){if("^"!==h[i])break;if(!k.parent)throw new Error("Path '"+e+"' not valid for state '"+b.name+"'");k=k.parent}else k=b;h=h.slice(i).join("."),e=k.name+(k.name&&h?".":"")+h}var l=z[e];return!l||!d&&(d||l!==a&&l.self!==a)?c:l}function n(a,b){A[a]||(A[a]=[]),A[a].push(b)}function p(a){for(var b=A[a]||[];b.length;)q(b.shift())}function q(b){b=d(b,{self:b,resolve:b.resolve||{},toString:function(){return this.name}});var c=b.name;if(!J(c)||c.indexOf("@")>=0)throw new Error("State must have a valid name");if(z.hasOwnProperty(c))throw new Error("State '"+c+"'' is already defined");var e=-1!==c.indexOf(".")?c.substring(0,c.lastIndexOf(".")):J(b.parent)?b.parent:K(b.parent)&&J(b.parent.name)?b.parent.name:"";if(e&&!z[e])return n(e,b.self);for(var f in C)I(C[f])&&(b[f]=C[f](b,C.$delegates[f]));return z[c]=b,!b[B]&&b.url&&a.when(b.url,["$match","$stateParams",function(a,c){y.$current.navigable==b&&j(a,c)||y.transitionTo(b,a,{inherit:!0,location:!1})}]),p(c),b}function r(a){return a.indexOf("*")>-1}function s(a){for(var b=a.split("."),c=y.$current.name.split("."),d=0,e=b.length;e>d;d++)"*"===b[d]&&(c[d]="*");return"**"===b[0]&&(c=c.slice(h(c,b[1])),c.unshift("**")),"**"===b[b.length-1]&&(c.splice(h(c,b[b.length-2])+1,Number.MAX_VALUE),c.push("**")),b.length!=c.length?!1:c.join("")===b.join("")}function t(a,b){return J(a)&&!H(b)?C[a]:I(b)&&J(a)?(C[a]&&!C.$delegates[a]&&(C.$delegates[a]=C[a]),C[a]=b,this):this}function u(a,b){return K(a)?b=a:b.name=a,q(b),this}function v(a,e,f,h,l,n,p,q,t){function u(b,c,d,f){var g=a.$broadcast("$stateNotFound",b,c,d);if(g.defaultPrevented)return p.update(),D;if(!g.retry)return null;if(f.$retry)return p.update(),E;var h=y.transition=e.when(g.retry);return h.then(function(){return h!==y.transition?A:(b.options.$retry=!0,y.transitionTo(b.to,b.toParams,b.options))},function(){return D}),p.update(),h}function v(a,c,d,g,i,j){function m(){var c=[];return M(a.views,function(d,e){var g=d.resolve&&d.resolve!==a.resolve?d.resolve:{};g.$template=[function(){return f.load(e,{view:d,locals:i.globals,params:n,notify:j.notify})||""}],c.push(l.resolve(g,i.globals,i.resolve,a).then(function(c){if(I(d.controllerProvider)||L(d.controllerProvider)){var f=b.extend({},g,i.globals);c.$$controller=h.invoke(d.controllerProvider,null,f)}else c.$$controller=d.controller;c.$$state=a,c.$$controllerAs=d.controllerAs,i[e]=c}))}),e.all(c).then(function(){return i.globals})}var n=d?c:k(a.params.$$keys(),c),o={$stateParams:n};i.resolve=l.resolve(a.resolve,o,i.resolve,a);var p=[i.resolve.then(function(a){i.globals=a})];return g&&p.push(g),e.all(p).then(m).then(function(a){return i})}var A=e.reject(new Error("transition superseded")),C=e.reject(new Error("transition prevented")),D=e.reject(new Error("transition aborted")),E=e.reject(new Error("transition failed"));return x.locals={resolve:null,globals:{$stateParams:{}}},y={params:{},current:x.self,$current:x,transition:null},y.reload=function(a){return y.transitionTo(y.current,n,{reload:a||!0,inherit:!1,notify:!0})},y.go=function(a,b,c){return y.transitionTo(a,b,N({inherit:!0,relative:y.$current},c))},y.transitionTo=function(b,c,f){c=c||{},f=N({location:!0,inherit:!1,relative:null,notify:!0,reload:!1,$retry:!1},f||{});var g,j=y.$current,l=y.params,o=j.path,q=m(b,f.relative),r=c["#"];if(!H(q)){var s={to:b,toParams:c,options:f},t=u(s,j.self,l,f);if(t)return t;if(b=s.to,c=s.toParams,f=s.options,q=m(b,f.relative),!H(q)){if(!f.relative)throw new Error("No such state '"+b+"'");throw new Error("Could not resolve '"+b+"' from state '"+f.relative+"'")}}if(q[B])throw new Error("Cannot transition to abstract state '"+b+"'");if(f.inherit&&(c=i(n,c||{},y.$current,q)),!q.params.$$validates(c))return E;c=q.params.$$values(c),b=q;var z=b.path,D=0,F=z[D],G=x.locals,I=[];if(f.reload){if(J(f.reload)||K(f.reload)){if(K(f.reload)&&!f.reload.name)throw new Error("Invalid reload state object");var L=f.reload===!0?o[0]:m(f.reload);if(f.reload&&!L)throw new Error("No such reload state '"+(J(f.reload)?f.reload:f.reload.name)+"'");for(;F&&F===o[D]&&F!==L;)G=I[D]=F.locals,D++,F=z[D]}}else for(;F&&F===o[D]&&F.ownParams.$$equals(c,l);)G=I[D]=F.locals,D++,F=z[D];if(w(b,c,j,l,G,f))return r&&(c["#"]=r),y.params=c,O(y.params,n),f.location&&b.navigable&&b.navigable.url&&(p.push(b.navigable.url,c,{$$avoidResync:!0,replace:"replace"===f.location}),p.update(!0)),y.transition=null,e.when(y.current);if(c=k(b.params.$$keys(),c||{}),f.notify&&a.$broadcast("$stateChangeStart",b.self,c,j.self,l).defaultPrevented)return a.$broadcast("$stateChangeCancel",b.self,c,j.self,l),p.update(),C;for(var M=e.when(G),P=D;P<z.length;P++,F=z[P])G=I[P]=d(G),M=v(F,c,F===b,M,G,f);var Q=y.transition=M.then(function(){var d,e,g;if(y.transition!==Q)return A;for(d=o.length-1;d>=D;d--)g=o[d],g.self.onExit&&h.invoke(g.self.onExit,g.self,g.locals.globals),g.locals=null;for(d=D;d<z.length;d++)e=z[d],e.locals=I[d],e.self.onEnter&&h.invoke(e.self.onEnter,e.self,e.locals.globals);return r&&(c["#"]=r),y.transition!==Q?A:(y.$current=b,y.current=b.self,y.params=c,O(y.params,n),y.transition=null,f.location&&b.navigable&&p.push(b.navigable.url,b.navigable.locals.globals.$stateParams,{$$avoidResync:!0,replace:"replace"===f.location}),f.notify&&a.$broadcast("$stateChangeSuccess",b.self,c,j.self,l),p.update(!0),y.current)},function(d){return y.transition!==Q?A:(y.transition=null,g=a.$broadcast("$stateChangeError",b.self,c,j.self,l,d),g.defaultPrevented||p.update(),e.reject(d))});return Q},y.is=function(a,b,d){d=N({relative:y.$current},d||{});var e=m(a,d.relative);return H(e)?y.$current!==e?!1:b?j(e.params.$$values(b),n):!0:c},y.includes=function(a,b,d){if(d=N({relative:y.$current},d||{}),J(a)&&r(a)){if(!s(a))return!1;a=y.$current.name}var e=m(a,d.relative);return H(e)?H(y.$current.includes[e.name])?b?j(e.params.$$values(b),n,g(b)):!0:!1:c},y.href=function(a,b,d){d=N({lossy:!0,inherit:!0,absolute:!1,relative:y.$current},d||{});var e=m(a,d.relative);if(!H(e))return null;d.inherit&&(b=i(n,b||{},y.$current,e));var f=e&&d.lossy?e.navigable:e;return f&&f.url!==c&&null!==f.url?p.href(f.url,k(e.params.$$keys().concat("#"),b||{}),{absolute:d.absolute}):null},y.get=function(a,b){if(0===arguments.length)return o(g(z),function(a){return z[a].self});var c=m(a,b||y.$current);return c&&c.self?c.self:null},y}function w(a,b,c,d,e,f){function g(a,b,c){function d(b){return"search"!=a.params[b].location}var e=a.params.$$keys().filter(d),f=l.apply({},[a.params].concat(e)),g=new P.ParamSet(f);return g.$$equals(b,c)}return!f.reload&&a===c&&(e===c.locals||a.self.reloadOnSearch===!1&&g(c,d,b))?!0:void 0}var x,y,z={},A={},B="abstract",C={parent:function(a){if(H(a.parent)&&a.parent)return m(a.parent);var b=/^(.+)\.[^.]+$/.exec(a.name);return b?m(b[1]):x},data:function(a){return a.parent&&a.parent.data&&(a.data=a.self.data=N({},a.parent.data,a.data)),a.data},url:function(a){var b=a.url,c={params:a.params||{}};if(J(b))return"^"==b.charAt(0)?e.compile(b.substring(1),c):(a.parent.navigable||x).url.concat(b,c);if(!b||e.isMatcher(b))return b;throw new Error("Invalid url '"+b+"' in state '"+a+"'")},navigable:function(a){return a.url?a:a.parent?a.parent.navigable:null},ownParams:function(a){var b=a.url&&a.url.params||new P.ParamSet;return M(a.params||{},function(a,c){b[c]||(b[c]=new P.Param(c,null,a,"config"))}),b},params:function(a){return a.parent&&a.parent.params?N(a.parent.params.$$new(),a.ownParams):new P.ParamSet},views:function(a){var b={};return M(H(a.views)?a.views:{"":a},function(c,d){d.indexOf("@")<0&&(d+="@"+a.parent.name),b[d]=c}),b},path:function(a){return a.parent?a.parent.path.concat(a):[]},includes:function(a){var b=a.parent?N({},a.parent.includes):{};return b[a.name]=!0,b},$delegates:{}};x=q({name:"",url:"^",views:null,"abstract":!0}),x.navigable=null,this.decorator=t,this.state=u,this.$get=v,v.$inject=["$rootScope","$q","$view","$injector","$resolve","$stateParams","$urlRouter","$location","$urlMatcherFactory"]}function w(){function a(a,b){return{load:function(c,d){var e,f={template:null,controller:null,view:null,locals:null,notify:!0,async:!0,params:{}};return d=N(f,d),d.view&&(e=b.fromConfig(d.view,d.params,d.locals)),e&&d.notify&&a.$broadcast("$viewContentLoading",d),e}}}this.$get=a,a.$inject=["$rootScope","$templateFactory"]}function x(){var a=!1;this.useAnchorScroll=function(){a=!0},this.$get=["$anchorScroll","$timeout",function(b,c){return a?b:function(a){return c(function(){a[0].scrollIntoView()},0,!1)}}]}function y(a,c,d,e){function f(){return c.has?function(a){return c.has(a)?c.get(a):null}:function(a){try{return c.get(a)}catch(b){return null}}}function g(a,b){var c=function(){return{enter:function(a,b,c){b.after(a),c()},leave:function(a,b){a.remove(),b()}}};if(j)return{enter:function(a,b,c){var d=j.enter(a,null,b,c);d&&d.then&&d.then(c)},leave:function(a,b){var c=j.leave(a,b);c&&c.then&&c.then(b)}};if(i){var d=i&&i(b,a);return{enter:function(a,b,c){d.enter(a,null,b),c()},leave:function(a,b){d.leave(a),b()}}}return c()}var h=f(),i=h("$animator"),j=h("$animate"),k={restrict:"ECA",terminal:!0,priority:400,transclude:"element",compile:function(c,f,h){return function(c,f,i){function j(){l&&(l.remove(),l=null),n&&(n.$destroy(),n=null),m&&(r.leave(m,function(){l=null}),l=m,m=null)}function k(g){var k,l=A(c,i,f,e),s=l&&a.$current&&a.$current.locals[l];if(g||s!==o){k=c.$new(),o=a.$current.locals[l];var t=h(k,function(a){r.enter(a,f,function(){n&&n.$emit("$viewContentAnimationEnded"),(b.isDefined(q)&&!q||c.$eval(q))&&d(a)}),j()});m=t,n=k,n.$emit("$viewContentLoaded"),n.$eval(p)}}var l,m,n,o,p=i.onload||"",q=i.autoscroll,r=g(i,c);c.$on("$stateChangeSuccess",function(){k(!1)}),c.$on("$viewContentLoading",function(){k(!1)}),k(!0)}}};return k}function z(a,b,c,d){return{restrict:"ECA",priority:-400,compile:function(e){var f=e.html();return function(e,g,h){var i=c.$current,j=A(e,h,g,d),k=i&&i.locals[j];if(k){g.data("$uiView",{name:j,state:k.$$state}),g.html(k.$template?k.$template:f);var l=a(g.contents());if(k.$$controller){k.$scope=e,k.$element=g;var m=b(k.$$controller,k);k.$$controllerAs&&(e[k.$$controllerAs]=m),g.data("$ngControllerController",m),g.children().data("$ngControllerController",m)}l(e)}}}}}function A(a,b,c,d){var e=d(b.uiView||b.name||"")(a),f=c.inheritedData("$uiView");return e.indexOf("@")>=0?e:e+"@"+(f?f.state.name:"")}function B(a,b){var c,d=a.match(/^\s*({[^}]*})\s*$/);if(d&&(a=b+"("+d[1]+")"),c=a.replace(/\n/g," ").match(/^([^(]+?)\s*(\((.*)\))?$/),!c||4!==c.length)throw new Error("Invalid state ref '"+a+"'");return{state:c[1],paramExpr:c[3]||null}}function C(a){var b=a.parent().inheritedData("$uiView");return b&&b.state&&b.state.name?b.state:void 0}function D(a,c){var d=["location","inherit","reload","absolute"];return{restrict:"A",require:["?^uiSrefActive","?^uiSrefActiveEq"],link:function(e,f,g,h){var i=B(g.uiSref,a.current.name),j=null,k=C(f)||a.$current,l="[object SVGAnimatedString]"===Object.prototype.toString.call(f.prop("href"))?"xlink:href":"href",m=null,n="A"===f.prop("tagName").toUpperCase(),o="FORM"===f[0].nodeName,p=o?"action":l,q=!0,r={relative:k,inherit:!0},s=e.$eval(g.uiSrefOpts)||{};b.forEach(d,function(a){a in s&&(r[a]=s[a])});var t=function(c){if(c&&(j=b.copy(c)),q){m=a.href(i.state,j,r);var d=h[1]||h[0];return d&&d.$$addStateInfo(i.state,j),null===m?(q=!1,!1):void g.$set(p,m)}};i.paramExpr&&(e.$watch(i.paramExpr,function(a,b){a!==j&&t(a)},!0),j=b.copy(e.$eval(i.paramExpr))),t(),o||f.bind("click",function(b){var d=b.which||b.button;if(!(d>1||b.ctrlKey||b.metaKey||b.shiftKey||f.attr("target"))){var e=c(function(){a.go(i.state,j,r)});b.preventDefault();var g=n&&!m?1:0;b.preventDefault=function(){g--<=0&&c.cancel(e)}}})}}}function E(a,b,c){return{restrict:"A",controller:["$scope","$element","$attrs",function(b,d,e){function f(){g()?d.addClass(i):d.removeClass(i)}function g(){for(var a=0;a<j.length;a++)if(h(j[a].state,j[a].params))return!0;return!1}function h(b,c){return"undefined"!=typeof e.uiSrefActiveEq?a.is(b.name,c):a.includes(b.name,c)}var i,j=[];i=c(e.uiSrefActiveEq||e.uiSrefActive||"",!1)(b),this.$$addStateInfo=function(b,c){var e=a.get(b,C(d));j.push({state:e||{name:b},params:c}),f()},b.$on("$stateChangeSuccess",f)}]}}function F(a){var b=function(b){return a.is(b)};return b.$stateful=!0,b}function G(a){var b=function(b){return a.includes(b)};return b.$stateful=!0,b}var H=b.isDefined,I=b.isFunction,J=b.isString,K=b.isObject,L=b.isArray,M=b.forEach,N=b.extend,O=b.copy;b.module("ui.router.util",["ng"]),b.module("ui.router.router",["ui.router.util"]),b.module("ui.router.state",["ui.router.router","ui.router.util"]),b.module("ui.router",["ui.router.state"]),b.module("ui.router.compat",["ui.router"]),p.$inject=["$q","$injector"],b.module("ui.router.util").service("$resolve",p),q.$inject=["$http","$templateCache","$injector"],b.module("ui.router.util").service("$templateFactory",q);var P;r.prototype.concat=function(a,b){var c={caseInsensitive:P.caseInsensitive(),strict:P.strictMode(),squash:P.defaultSquashPolicy()};return new r(this.sourcePath+a+this.sourceSearch,N(c,b),this)},r.prototype.toString=function(){return this.source},r.prototype.exec=function(a,b){function c(a){function b(a){return a.split("").reverse().join("")}function c(a){return a.replace(/\\-/g,"-")}var d=b(a).split(/-(?!\\)/),e=o(d,b);return o(e,c).reverse()}var d=this.regexp.exec(a);if(!d)return null;b=b||{};var e,f,g,h=this.parameters(),i=h.length,j=this.segments.length-1,k={};if(j!==d.length-1)throw new Error("Unbalanced capture group in route '"+this.source+"'");for(e=0;j>e;e++){g=h[e];var l=this.params[g],m=d[e+1];for(f=0;f<l.replace;f++)l.replace[f].from===m&&(m=l.replace[f].to);m&&l.array===!0&&(m=c(m)),k[g]=l.value(m)}for(;i>e;e++)g=h[e],k[g]=this.params[g].value(b[g]);return k},r.prototype.parameters=function(a){return H(a)?this.params[a]||null:this.$$paramNames},r.prototype.validates=function(a){return this.params.$$validates(a)},r.prototype.format=function(a){function b(a){return encodeURIComponent(a).replace(/-/g,function(a){return"%5C%"+a.charCodeAt(0).toString(16).toUpperCase()})}a=a||{};var c=this.segments,d=this.parameters(),e=this.params;if(!this.validates(a))return null;var f,g=!1,h=c.length-1,i=d.length,j=c[0];for(f=0;i>f;f++){var k=h>f,l=d[f],m=e[l],n=m.value(a[l]),p=m.isOptional&&m.type.equals(m.value(),n),q=p?m.squash:!1,r=m.type.encode(n);if(k){var s=c[f+1];if(q===!1)null!=r&&(j+=L(r)?o(r,b).join("-"):encodeURIComponent(r)),j+=s;else if(q===!0){var t=j.match(/\/$/)?/\/?(.*)/:/(.*)/;j+=s.match(t)[1]}else J(q)&&(j+=q+s)}else{if(null==r||p&&q!==!1)continue;L(r)||(r=[r]),r=o(r,encodeURIComponent).join("&"+l+"="),j+=(g?"&":"?")+(l+"="+r),g=!0}}return j},s.prototype.is=function(a,b){return!0},s.prototype.encode=function(a,b){return a},s.prototype.decode=function(a,b){return a},s.prototype.equals=function(a,b){return a==b},s.prototype.$subPattern=function(){var a=this.pattern.toString();return a.substr(1,a.length-2)},s.prototype.pattern=/.*/,s.prototype.toString=function(){return"{Type:"+this.name+"}"},s.prototype.$normalize=function(a){return this.is(a)?a:this.decode(a)},s.prototype.$asArray=function(a,b){function d(a,b){function d(a,b){return function(){return a[b].apply(a,arguments)}}function e(a){return L(a)?a:H(a)?[a]:[]}function f(a){switch(a.length){case 0:return c;case 1:return"auto"===b?a[0]:a;default:return a}}function g(a){return!a}function h(a,b){return function(c){c=e(c);var d=o(c,a);return b===!0?0===n(d,g).length:f(d)}}function i(a){return function(b,c){var d=e(b),f=e(c);if(d.length!==f.length)return!1;for(var g=0;g<d.length;g++)if(!a(d[g],f[g]))return!1;return!0}}this.encode=h(d(a,"encode")),this.decode=h(d(a,"decode")),this.is=h(d(a,"is"),!0),this.equals=i(d(a,"equals")),this.pattern=a.pattern,this.$normalize=h(d(a,"$normalize")),this.name=a.name,this.$arrayMode=b}if(!a)return this;if("auto"===a&&!b)throw new Error("'auto' array mode is for query parameters only");return new d(this,a)},b.module("ui.router.util").provider("$urlMatcherFactory",t),b.module("ui.router.util").run(["$urlMatcherFactory",function(a){}]),u.$inject=["$locationProvider","$urlMatcherFactoryProvider"],b.module("ui.router.router").provider("$urlRouter",u),v.$inject=["$urlRouterProvider","$urlMatcherFactoryProvider"],b.module("ui.router.state").value("$stateParams",{}).provider("$state",v),w.$inject=[],b.module("ui.router.state").provider("$view",w),b.module("ui.router.state").provider("$uiViewScroll",x),y.$inject=["$state","$injector","$uiViewScroll","$interpolate"],z.$inject=["$compile","$controller","$state","$interpolate"],b.module("ui.router.state").directive("uiView",y),b.module("ui.router.state").directive("uiView",z),D.$inject=["$state","$timeout"],E.$inject=["$state","$stateParams","$interpolate"],b.module("ui.router.state").directive("uiSref",D).directive("uiSrefActive",E).directive("uiSrefActiveEq",E),F.$inject=["$state"],G.$inject=["$state"],b.module("ui.router.state").filter("isState",F).filter("includedByState",G)}(window,window.angular);
@@ -49,13 +49,13 @@ function ancestors(first, second) {
49
49
  * @param {Object} object A JavaScript object.
50
50
  * @return {Array} Returns the keys of the object as an array.
51
51
  */
52
- function keys(object) {
52
+ function objectKeys(object) {
53
53
  if (Object.keys) {
54
54
  return Object.keys(object);
55
55
  }
56
56
  var result = [];
57
57
 
58
- angular.forEach(object, function(val, key) {
58
+ forEach(object, function(val, key) {
59
59
  result.push(key);
60
60
  });
61
61
  return result;
@@ -68,7 +68,7 @@ function keys(object) {
68
68
  * @param {*} value A value to search the array for.
69
69
  * @return {Number} Returns the array index value of `value`, or `-1` if not present.
70
70
  */
71
- function arraySearch(array, value) {
71
+ function indexOf(array, value) {
72
72
  if (Array.prototype.indexOf) {
73
73
  return array.indexOf(value, Number(arguments[2]) || 0);
74
74
  }
@@ -96,11 +96,12 @@ function inheritParams(currentParams, newParams, $current, $to) {
96
96
  var parents = ancestors($current, $to), parentParams, inherited = {}, inheritList = [];
97
97
 
98
98
  for (var i in parents) {
99
- if (!parents[i].params || !parents[i].params.length) continue;
100
- parentParams = parents[i].params;
99
+ if (!parents[i].params) continue;
100
+ parentParams = objectKeys(parents[i].params);
101
+ if (!parentParams.length) continue;
101
102
 
102
103
  for (var j in parentParams) {
103
- if (arraySearch(inheritList, parentParams[j]) >= 0) continue;
104
+ if (indexOf(inheritList, parentParams[j]) >= 0) continue;
104
105
  inheritList.push(parentParams[j]);
105
106
  inherited[parentParams[j]] = currentParams[parentParams[j]];
106
107
  }
@@ -108,23 +109,6 @@ function inheritParams(currentParams, newParams, $current, $to) {
108
109
  return extend({}, inherited, newParams);
109
110
  }
110
111
 
111
- /**
112
- * Normalizes a set of values to string or `null`, filtering them by a list of keys.
113
- *
114
- * @param {Array} keys The list of keys to normalize/return.
115
- * @param {Object} values An object hash of values to normalize.
116
- * @return {Object} Returns an object hash of normalized string values.
117
- */
118
- function normalize(keys, values) {
119
- var normalized = {};
120
-
121
- forEach(keys, function (name) {
122
- var value = values[name];
123
- normalized[name] = (value != null) ? String(value) : null;
124
- });
125
- return normalized;
126
- }
127
-
128
112
  /**
129
113
  * Performs a non-strict comparison of the subset of two objects, defined by a list of keys.
130
114
  *
@@ -162,6 +146,68 @@ function filterByKeys(keys, values) {
162
146
  });
163
147
  return filtered;
164
148
  }
149
+
150
+ // like _.indexBy
151
+ // when you know that your index values will be unique, or you want last-one-in to win
152
+ function indexBy(array, propName) {
153
+ var result = {};
154
+ forEach(array, function(item) {
155
+ result[item[propName]] = item;
156
+ });
157
+ return result;
158
+ }
159
+
160
+ // extracted from underscore.js
161
+ // Return a copy of the object only containing the whitelisted properties.
162
+ function pick(obj) {
163
+ var copy = {};
164
+ var keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));
165
+ forEach(keys, function(key) {
166
+ if (key in obj) copy[key] = obj[key];
167
+ });
168
+ return copy;
169
+ }
170
+
171
+ // extracted from underscore.js
172
+ // Return a copy of the object omitting the blacklisted properties.
173
+ function omit(obj) {
174
+ var copy = {};
175
+ var keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));
176
+ for (var key in obj) {
177
+ if (indexOf(keys, key) == -1) copy[key] = obj[key];
178
+ }
179
+ return copy;
180
+ }
181
+
182
+ function pluck(collection, key) {
183
+ var result = isArray(collection) ? [] : {};
184
+
185
+ forEach(collection, function(val, i) {
186
+ result[i] = isFunction(key) ? key(val) : val[key];
187
+ });
188
+ return result;
189
+ }
190
+
191
+ function filter(collection, callback) {
192
+ var array = isArray(collection);
193
+ var result = array ? [] : {};
194
+ forEach(collection, function(val, i) {
195
+ if (callback(val, i)) {
196
+ result[array ? result.length : i] = val;
197
+ }
198
+ });
199
+ return result;
200
+ }
201
+
202
+ function map(collection, callback) {
203
+ var result = isArray(collection) ? [] : {};
204
+
205
+ forEach(collection, function(val, i) {
206
+ result[i] = callback(val, i);
207
+ });
208
+ return result;
209
+ }
210
+
165
211
  /**
166
212
  * @ngdoc overview
167
213
  * @name ui.router.util
@@ -41,6 +41,7 @@ function $Resolve( $q, $injector) {
41
41
  */
42
42
  this.study = function (invocables) {
43
43
  if (!isObject(invocables)) throw new Error("'invocables' must be an object");
44
+ var invocableKeys = objectKeys(invocables || {});
44
45
 
45
46
  // Perform a topological sort of invocables to build an ordered plan
46
47
  var plan = [], cycle = [], visited = {};
@@ -49,7 +50,7 @@ function $Resolve( $q, $injector) {
49
50
 
50
51
  cycle.push(key);
51
52
  if (visited[key] === VISIT_IN_PROGRESS) {
52
- cycle.splice(0, cycle.indexOf(key));
53
+ cycle.splice(0, indexOf(cycle, key));
53
54
  throw new Error("Cyclic dependency: " + cycle.join(" -> "));
54
55
  }
55
56
  visited[key] = VISIT_IN_PROGRESS;
@@ -101,7 +102,8 @@ function $Resolve( $q, $injector) {
101
102
  if (!--wait) {
102
103
  if (!merged) merge(values, parent.$$values);
103
104
  result.$$values = values;
104
- result.$$promises = true; // keep for isResolve()
105
+ result.$$promises = result.$$promises || true; // keep for isResolve()
106
+ delete result.$$inheritedValues;
105
107
  resolution.resolve(values);
106
108
  }
107
109
  }
@@ -110,20 +112,28 @@ function $Resolve( $q, $injector) {
110
112
  result.$$failure = reason;
111
113
  resolution.reject(reason);
112
114
  }
113
-
115
+
114
116
  // Short-circuit if parent has already failed
115
117
  if (isDefined(parent.$$failure)) {
116
118
  fail(parent.$$failure);
117
119
  return result;
118
120
  }
119
121
 
122
+ if (parent.$$inheritedValues) {
123
+ merge(values, omit(parent.$$inheritedValues, invocableKeys));
124
+ }
125
+
120
126
  // Merge parent values if the parent has already resolved, or merge
121
127
  // parent promises and wait if the parent resolve is still in progress.
128
+ extend(promises, parent.$$promises);
122
129
  if (parent.$$values) {
123
- merged = merge(values, parent.$$values);
130
+ merged = merge(values, omit(parent.$$values, invocableKeys));
131
+ result.$$inheritedValues = omit(parent.$$values, invocableKeys);
124
132
  done();
125
133
  } else {
126
- extend(promises, parent.$$promises);
134
+ if (parent.$$inheritedValues) {
135
+ result.$$inheritedValues = omit(parent.$$inheritedValues, invocableKeys);
136
+ }
127
137
  parent.then(done, fail);
128
138
  }
129
139
 
@@ -4,7 +4,6 @@
4
4
  *
5
5
  * @requires ui.router.router.$urlRouterProvider
6
6
  * @requires ui.router.util.$urlMatcherFactoryProvider
7
- * @requires $locationProvider
8
7
  *
9
8
  * @description
10
9
  * The new `$stateProvider` works similar to Angular's v1 router, but it focuses purely
@@ -20,8 +19,8 @@
20
19
  *
21
20
  * The `$stateProvider` provides interfaces to declare these states for your app.
22
21
  */
23
- $StateProvider.$inject = ['$urlRouterProvider', '$urlMatcherFactoryProvider', '$locationProvider'];
24
- function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $locationProvider) {
22
+ $StateProvider.$inject = ['$urlRouterProvider', '$urlMatcherFactoryProvider'];
23
+ function $StateProvider( $urlRouterProvider, $urlMatcherFactory) {
25
24
 
26
25
  var root, states = {}, $state, queue = {}, abstractKey = 'abstract';
27
26
 
@@ -49,18 +48,14 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
49
48
 
50
49
  // Build a URLMatcher if necessary, either via a relative or absolute URL
51
50
  url: function(state) {
52
- var url = state.url;
51
+ var url = state.url, config = { params: state.params || {} };
53
52
 
54
53
  if (isString(url)) {
55
- if (url.charAt(0) == '^') {
56
- return $urlMatcherFactory.compile(url.substring(1));
57
- }
58
- return (state.parent.navigable || root).url.concat(url);
54
+ if (url.charAt(0) == '^') return $urlMatcherFactory.compile(url.substring(1), config);
55
+ return (state.parent.navigable || root).url.concat(url, config);
59
56
  }
60
57
 
61
- if ($urlMatcherFactory.isMatcher(url) || url == null) {
62
- return url;
63
- }
58
+ if (!url || $urlMatcherFactory.isMatcher(url)) return url;
64
59
  throw new Error("Invalid url '" + url + "' in state '" + state + "'");
65
60
  },
66
61
 
@@ -69,14 +64,18 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
69
64
  return state.url ? state : (state.parent ? state.parent.navigable : null);
70
65
  },
71
66
 
67
+ // Own parameters for this state. state.url.params is already built at this point. Create and add non-url params
68
+ ownParams: function(state) {
69
+ var params = state.url && state.url.params || new $$UMFP.ParamSet();
70
+ forEach(state.params || {}, function(config, id) {
71
+ if (!params[id]) params[id] = new $$UMFP.Param(id, null, config, "config");
72
+ });
73
+ return params;
74
+ },
75
+
72
76
  // Derive parameters for this state and ensure they're a super-set of parent's parameters
73
77
  params: function(state) {
74
- if (!state.params) {
75
- return state.url ? state.url.parameters() : state.parent.params;
76
- }
77
- if (!isArray(state.params)) throw new Error("Invalid params in state '" + state + "'");
78
- if (state.url) throw new Error("Both params and url specicified in state '" + state + "'");
79
- return state.params;
78
+ return state.parent && state.parent.params ? extend(state.parent.params.$$new(), state.ownParams) : new $$UMFP.ParamSet();
80
79
  },
81
80
 
82
81
  // If there is no explicit multi-view configuration, make one up so we don't have
@@ -94,26 +93,6 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
94
93
  return views;
95
94
  },
96
95
 
97
- ownParams: function(state) {
98
- if (!state.parent) {
99
- return state.params;
100
- }
101
- var paramNames = {}; forEach(state.params, function (p) { paramNames[p] = true; });
102
-
103
- forEach(state.parent.params, function (p) {
104
- if (!paramNames[p]) {
105
- throw new Error("Missing required parameter '" + p + "' in state '" + state.name + "'");
106
- }
107
- paramNames[p] = false;
108
- });
109
- var ownParams = [];
110
-
111
- forEach(paramNames, function (own, p) {
112
- if (own) ownParams.push(p);
113
- });
114
- return ownParams;
115
- },
116
-
117
96
  // Keep a full path from the root down to this state as this is needed for state activation.
118
97
  path: function(state) {
119
98
  return state.parent ? state.parent.path.concat(state) : []; // exclude root from path
@@ -134,12 +113,16 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
134
113
  }
135
114
 
136
115
  function findState(stateOrName, base) {
116
+ if (!stateOrName) return undefined;
117
+
137
118
  var isStr = isString(stateOrName),
138
119
  name = isStr ? stateOrName : stateOrName.name,
139
120
  path = isRelative(name);
140
121
 
141
122
  if (path) {
142
123
  if (!base) throw new Error("No reference point given for path '" + name + "'");
124
+ base = findState(base);
125
+
143
126
  var rel = name.split("."), i = 0, pathLength = rel.length, current = base;
144
127
 
145
128
  for (; i < pathLength; i++) {
@@ -172,6 +155,13 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
172
155
  queue[parentName].push(state);
173
156
  }
174
157
 
158
+ function flushQueuedChildren(parentName) {
159
+ var queued = queue[parentName] || [];
160
+ while(queued.length) {
161
+ registerState(queued.shift());
162
+ }
163
+ }
164
+
175
165
  function registerState(state) {
176
166
  // Wrap a new object around the state so we can store our private details easily.
177
167
  state = inherit(state, {
@@ -187,6 +177,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
187
177
  // Get parent name
188
178
  var parentName = (name.indexOf('.') !== -1) ? name.substring(0, name.lastIndexOf('.'))
189
179
  : (isString(state.parent)) ? state.parent
180
+ : (isObject(state.parent) && isString(state.parent.name)) ? state.parent.name
190
181
  : '';
191
182
 
192
183
  // If parent is not registered yet, add state to queue and register later
@@ -203,17 +194,13 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
203
194
  if (!state[abstractKey] && state.url) {
204
195
  $urlRouterProvider.when(state.url, ['$match', '$stateParams', function ($match, $stateParams) {
205
196
  if ($state.$current.navigable != state || !equalForKeys($match, $stateParams)) {
206
- $state.transitionTo(state, $match, { location: false });
197
+ $state.transitionTo(state, $match, { inherit: true, location: false });
207
198
  }
208
199
  }]);
209
200
  }
210
201
 
211
202
  // Register any queued children
212
- if (queue[name]) {
213
- for (var i = 0; i < queue[name].length; i++) {
214
- registerState(queue[name][i]);
215
- }
216
- }
203
+ flushQueuedChildren(name);
217
204
 
218
205
  return state;
219
206
  }
@@ -228,14 +215,21 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
228
215
  var globSegments = glob.split('.'),
229
216
  segments = $state.$current.name.split('.');
230
217
 
218
+ //match single stars
219
+ for (var i = 0, l = globSegments.length; i < l; i++) {
220
+ if (globSegments[i] === '*') {
221
+ segments[i] = '*';
222
+ }
223
+ }
224
+
231
225
  //match greedy starts
232
226
  if (globSegments[0] === '**') {
233
- segments = segments.slice(segments.indexOf(globSegments[1]));
227
+ segments = segments.slice(indexOf(segments, globSegments[1]));
234
228
  segments.unshift('**');
235
229
  }
236
230
  //match greedy ends
237
231
  if (globSegments[globSegments.length - 1] === '**') {
238
- segments.splice(segments.indexOf(globSegments[globSegments.length - 2]) + 1, Number.MAX_VALUE);
232
+ segments.splice(indexOf(segments, globSegments[globSegments.length - 2]) + 1, Number.MAX_VALUE);
239
233
  segments.push('**');
240
234
  }
241
235
 
@@ -243,13 +237,6 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
243
237
  return false;
244
238
  }
245
239
 
246
- //match single stars
247
- for (var i = 0, l = globSegments.length; i < l; i++) {
248
- if (globSegments[i] === '*') {
249
- segments[i] = '*';
250
- }
251
- }
252
-
253
240
  return segments.join('') === globSegments.join('');
254
241
  }
255
242
 
@@ -297,7 +284,8 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
297
284
  * - **parent** `{object}` - returns the parent state object.
298
285
  * - **data** `{object}` - returns state data, including any inherited data that is not
299
286
  * overridden by own values (if any).
300
- * - **url** `{object}` - returns a {link ui.router.util.type:UrlMatcher} or null.
287
+ * - **url** `{object}` - returns a {@link ui.router.util.type:UrlMatcher UrlMatcher}
288
+ * or `null`.
301
289
  * - **navigable** `{object}` - returns closest ancestor state that has a URL (aka is
302
290
  * navigable).
303
291
  * - **params** `{object}` - returns an array of state params that are ensured to
@@ -313,17 +301,17 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
313
301
  * - **path** `{string}` - returns the full path from the root down to this state.
314
302
  * Needed for state activation.
315
303
  * - **includes** `{object}` - returns an object that includes every state that
316
- * would pass a '$state.includes()' test.
304
+ * would pass a `$state.includes()` test.
317
305
  *
318
306
  * @example
319
307
  * <pre>
320
308
  * // Override the internal 'views' builder with a function that takes the state
321
309
  * // definition, and a reference to the internal function being overridden:
322
- * $stateProvider.decorator('views', function ($state, parent) {
310
+ * $stateProvider.decorator('views', function (state, parent) {
323
311
  * var result = {},
324
312
  * views = parent(state);
325
313
  *
326
- * angular.forEach(view, function (config, name) {
314
+ * angular.forEach(views, function (config, name) {
327
315
  * var autoName = (state.name + '.' + name).replace('.', '/');
328
316
  * config.templateUrl = config.templateUrl || '/partials/' + autoName + '.html';
329
317
  * result[name] = config;
@@ -379,9 +367,12 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
379
367
  * Registers a state configuration under a given state name. The stateConfig object
380
368
  * has the following acceptable properties.
381
369
  *
370
+ * @param {string} name A unique state name, e.g. "home", "about", "contacts".
371
+ * To create a parent/child state use a dot, e.g. "about.sales", "home.newest".
372
+ * @param {object} stateConfig State configuration object.
373
+ * @param {string|function=} stateConfig.template
382
374
  * <a id='template'></a>
383
- *
384
- * - **`template`** - {string|function=} - html template as a string or a function that returns
375
+ * html template as a string or a function that returns
385
376
  * an html template as a string which should be used by the uiView directives. This property
386
377
  * takes precedence over templateUrl.
387
378
  *
@@ -390,9 +381,17 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
390
381
  * - {array.&lt;object&gt;} - state parameters extracted from the current $location.path() by
391
382
  * applying the current state
392
383
  *
384
+ * <pre>template:
385
+ * "<h1>inline template definition</h1>" +
386
+ * "<div ui-view></div>"</pre>
387
+ * <pre>template: function(params) {
388
+ * return "<h1>generated template</h1>"; }</pre>
389
+ * </div>
390
+ *
391
+ * @param {string|function=} stateConfig.templateUrl
393
392
  * <a id='templateUrl'></a>
394
393
  *
395
- * - **`templateUrl`** - {string|function=} - path or function that returns a path to an html
394
+ * path or function that returns a path to an html
396
395
  * template that should be used by uiView.
397
396
  *
398
397
  * If `templateUrl` is a function, it will be called with the following parameters:
@@ -400,82 +399,261 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
400
399
  * - {array.&lt;object&gt;} - state parameters extracted from the current $location.path() by
401
400
  * applying the current state
402
401
  *
403
- * <a id='templateProvider'></a>
402
+ * <pre>templateUrl: "home.html"</pre>
403
+ * <pre>templateUrl: function(params) {
404
+ * return myTemplates[params.pageId]; }</pre>
404
405
  *
405
- * - **`templateProvider`** - {function=} - Provider function that returns HTML content
406
- * string.
406
+ * @param {function=} stateConfig.templateProvider
407
+ * <a id='templateProvider'></a>
408
+ * Provider function that returns HTML content string.
409
+ * <pre> templateProvider:
410
+ * function(MyTemplateService, params) {
411
+ * return MyTemplateService.getTemplate(params.pageId);
412
+ * }</pre>
407
413
  *
414
+ * @param {string|function=} stateConfig.controller
408
415
  * <a id='controller'></a>
409
416
  *
410
- * - **`controller`** - {string|function=} - Controller fn that should be associated with newly
417
+ * Controller fn that should be associated with newly
411
418
  * related scope or the name of a registered controller if passed as a string.
419
+ * Optionally, the ControllerAs may be declared here.
420
+ * <pre>controller: "MyRegisteredController"</pre>
421
+ * <pre>controller:
422
+ * "MyRegisteredController as fooCtrl"}</pre>
423
+ * <pre>controller: function($scope, MyService) {
424
+ * $scope.data = MyService.getData(); }</pre>
412
425
  *
426
+ * @param {function=} stateConfig.controllerProvider
413
427
  * <a id='controllerProvider'></a>
414
428
  *
415
- * - **`controllerProvider`** - {function=} - Injectable provider function that returns
416
- * the actual controller or string.
429
+ * Injectable provider function that returns the actual controller or string.
430
+ * <pre>controllerProvider:
431
+ * function(MyResolveData) {
432
+ * if (MyResolveData.foo)
433
+ * return "FooCtrl"
434
+ * else if (MyResolveData.bar)
435
+ * return "BarCtrl";
436
+ * else return function($scope) {
437
+ * $scope.baz = "Qux";
438
+ * }
439
+ * }</pre>
417
440
  *
441
+ * @param {string=} stateConfig.controllerAs
418
442
  * <a id='controllerAs'></a>
419
443
  *
420
- * - **`controllerAs`** – {string=} – A controller alias name. If present the controller will be
444
+ * A controller alias name. If present the controller will be
421
445
  * published to scope under the controllerAs name.
446
+ * <pre>controllerAs: "myCtrl"</pre>
447
+ *
448
+ * @param {string|object=} stateConfig.parent
449
+ * <a id='parent'></a>
450
+ * Optionally specifies the parent state of this state.
451
+ *
452
+ * <pre>parent: 'parentState'</pre>
453
+ * <pre>parent: parentState // JS variable</pre>
422
454
  *
455
+ * @param {object=} stateConfig.resolve
423
456
  * <a id='resolve'></a>
424
457
  *
425
- * - **`resolve`** - {object.&lt;string, function&gt;=} - An optional map of dependencies which
458
+ * An optional map&lt;string, function&gt; of dependencies which
426
459
  * should be injected into the controller. If any of these dependencies are promises,
427
- * the router will wait for them all to be resolved or one to be rejected before the
428
- * controller is instantiated. If all the promises are resolved successfully, the values
429
- * of the resolved promises are injected and $stateChangeSuccess event is fired. If any
430
- * of the promises are rejected the $stateChangeError event is fired. The map object is:
460
+ * the router will wait for them all to be resolved before the controller is instantiated.
461
+ * If all the promises are resolved successfully, the $stateChangeSuccess event is fired
462
+ * and the values of the resolved promises are injected into any controllers that reference them.
463
+ * If any of the promises are rejected the $stateChangeError event is fired.
464
+ *
465
+ * The map object is:
431
466
  *
432
467
  * - key - {string}: name of dependency to be injected into controller
433
468
  * - factory - {string|function}: If string then it is alias for service. Otherwise if function,
434
469
  * it is injected and return value it treated as dependency. If result is a promise, it is
435
470
  * resolved before its value is injected into controller.
436
471
  *
472
+ * <pre>resolve: {
473
+ * myResolve1:
474
+ * function($http, $stateParams) {
475
+ * return $http.get("/api/foos/"+stateParams.fooID);
476
+ * }
477
+ * }</pre>
478
+ *
479
+ * @param {string=} stateConfig.url
437
480
  * <a id='url'></a>
438
481
  *
439
- * - **`url`** - {string=} - A url with optional parameters. When a state is navigated or
482
+ * A url fragment with optional parameters. When a state is navigated or
440
483
  * transitioned to, the `$stateParams` service will be populated with any
441
484
  * parameters that were passed.
442
485
  *
443
- * <a id='params'></a>
486
+ * (See {@link ui.router.util.type:UrlMatcher UrlMatcher} `UrlMatcher`} for
487
+ * more details on acceptable patterns )
444
488
  *
445
- * - **`params`** - {object=} - An array of parameter names or regular expressions. Only
446
- * use this within a state if you are not using url. Otherwise you can specify your
447
- * parameters within the url. When a state is navigated or transitioned to, the
448
- * $stateParams service will be populated with any parameters that were passed.
489
+ * examples:
490
+ * <pre>url: "/home"
491
+ * url: "/users/:userid"
492
+ * url: "/books/{bookid:[a-zA-Z_-]}"
493
+ * url: "/books/{categoryid:int}"
494
+ * url: "/books/{publishername:string}/{categoryid:int}"
495
+ * url: "/messages?before&after"
496
+ * url: "/messages?{before:date}&{after:date}"
497
+ * url: "/messages/:mailboxid?{before:date}&{after:date}"
498
+ * </pre>
449
499
  *
500
+ * @param {object=} stateConfig.views
450
501
  * <a id='views'></a>
502
+ * an optional map&lt;string, object&gt; which defined multiple views, or targets views
503
+ * manually/explicitly.
451
504
  *
452
- * - **`views`** - {object=} - Use the views property to set up multiple views or to target views
453
- * manually/explicitly.
505
+ * Examples:
454
506
  *
455
- * <a id='abstract'></a>
507
+ * Targets three named `ui-view`s in the parent state's template
508
+ * <pre>views: {
509
+ * header: {
510
+ * controller: "headerCtrl",
511
+ * templateUrl: "header.html"
512
+ * }, body: {
513
+ * controller: "bodyCtrl",
514
+ * templateUrl: "body.html"
515
+ * }, footer: {
516
+ * controller: "footCtrl",
517
+ * templateUrl: "footer.html"
518
+ * }
519
+ * }</pre>
456
520
  *
457
- * - **`abstract`** - {boolean=} - An abstract state will never be directly activated,
521
+ * Targets named `ui-view="header"` from grandparent state 'top''s template, and named `ui-view="body" from parent state's template.
522
+ * <pre>views: {
523
+ * 'header@top': {
524
+ * controller: "msgHeaderCtrl",
525
+ * templateUrl: "msgHeader.html"
526
+ * }, 'body': {
527
+ * controller: "messagesCtrl",
528
+ * templateUrl: "messages.html"
529
+ * }
530
+ * }</pre>
531
+ *
532
+ * @param {boolean=} [stateConfig.abstract=false]
533
+ * <a id='abstract'></a>
534
+ * An abstract state will never be directly activated,
458
535
  * but can provide inherited properties to its common children states.
536
+ * <pre>abstract: true</pre>
459
537
  *
538
+ * @param {function=} stateConfig.onEnter
460
539
  * <a id='onEnter'></a>
461
540
  *
462
- * - **`onEnter`** - {object=} - Callback function for when a state is entered. Good way
541
+ * Callback function for when a state is entered. Good way
463
542
  * to trigger an action or dispatch an event, such as opening a dialog.
543
+ * If minifying your scripts, make sure to explictly annotate this function,
544
+ * because it won't be automatically annotated by your build tools.
545
+ *
546
+ * <pre>onEnter: function(MyService, $stateParams) {
547
+ * MyService.foo($stateParams.myParam);
548
+ * }</pre>
464
549
  *
550
+ * @param {function=} stateConfig.onExit
465
551
  * <a id='onExit'></a>
466
552
  *
467
- * - **`onExit`** - {object=} - Callback function for when a state is exited. Good way to
553
+ * Callback function for when a state is exited. Good way to
468
554
  * trigger an action or dispatch an event, such as opening a dialog.
555
+ * If minifying your scripts, make sure to explictly annotate this function,
556
+ * because it won't be automatically annotated by your build tools.
469
557
  *
558
+ * <pre>onExit: function(MyService, $stateParams) {
559
+ * MyService.cleanup($stateParams.myParam);
560
+ * }</pre>
561
+ *
562
+ * @param {boolean=} [stateConfig.reloadOnSearch=true]
470
563
  * <a id='reloadOnSearch'></a>
471
564
  *
472
- * - **`reloadOnSearch = true`** - {boolean=} - If `false`, will not retrigger the same state
565
+ * If `false`, will not retrigger the same state
473
566
  * just because a search/query parameter has changed (via $location.search() or $location.hash()).
474
567
  * Useful for when you'd like to modify $location.search() without triggering a reload.
568
+ * <pre>reloadOnSearch: false</pre>
475
569
  *
570
+ * @param {object=} stateConfig.data
476
571
  * <a id='data'></a>
477
572
  *
478
- * - **`data`** - {object=} - Arbitrary data object, useful for custom configuration.
573
+ * Arbitrary data object, useful for custom configuration. The parent state's `data` is
574
+ * prototypally inherited. In other words, adding a data property to a state adds it to
575
+ * the entire subtree via prototypal inheritance.
576
+ *
577
+ * <pre>data: {
578
+ * requiredRole: 'foo'
579
+ * } </pre>
580
+ *
581
+ * @param {object=} stateConfig.params
582
+ * <a id='params'></a>
583
+ *
584
+ * A map which optionally configures parameters declared in the `url`, or
585
+ * defines additional non-url parameters. For each parameter being
586
+ * configured, add a configuration object keyed to the name of the parameter.
587
+ *
588
+ * Each parameter configuration object may contain the following properties:
589
+ *
590
+ * - ** value ** - {object|function=}: specifies the default value for this
591
+ * parameter. This implicitly sets this parameter as optional.
592
+ *
593
+ * When UI-Router routes to a state and no value is
594
+ * specified for this parameter in the URL or transition, the
595
+ * default value will be used instead. If `value` is a function,
596
+ * it will be injected and invoked, and the return value used.
597
+ *
598
+ * *Note*: `undefined` is treated as "no default value" while `null`
599
+ * is treated as "the default value is `null`".
600
+ *
601
+ * *Shorthand*: If you only need to configure the default value of the
602
+ * parameter, you may use a shorthand syntax. In the **`params`**
603
+ * map, instead mapping the param name to a full parameter configuration
604
+ * object, simply set map it to the default parameter value, e.g.:
605
+ *
606
+ * <pre>// define a parameter's default value
607
+ * params: {
608
+ * param1: { value: "defaultValue" }
609
+ * }
610
+ * // shorthand default values
611
+ * params: {
612
+ * param1: "defaultValue",
613
+ * param2: "param2Default"
614
+ * }</pre>
615
+ *
616
+ * - ** array ** - {boolean=}: *(default: false)* If true, the param value will be
617
+ * treated as an array of values. If you specified a Type, the value will be
618
+ * treated as an array of the specified Type. Note: query parameter values
619
+ * default to a special `"auto"` mode.
620
+ *
621
+ * For query parameters in `"auto"` mode, if multiple values for a single parameter
622
+ * are present in the URL (e.g.: `/foo?bar=1&bar=2&bar=3`) then the values
623
+ * are mapped to an array (e.g.: `{ foo: [ '1', '2', '3' ] }`). However, if
624
+ * only one value is present (e.g.: `/foo?bar=1`) then the value is treated as single
625
+ * value (e.g.: `{ foo: '1' }`).
626
+ *
627
+ * <pre>params: {
628
+ * param1: { array: true }
629
+ * }</pre>
630
+ *
631
+ * - ** squash ** - {bool|string=}: `squash` configures how a default parameter value is represented in the URL when
632
+ * the current parameter value is the same as the default value. If `squash` is not set, it uses the
633
+ * configured default squash policy.
634
+ * (See {@link ui.router.util.$urlMatcherFactory#methods_defaultSquashPolicy `defaultSquashPolicy()`})
635
+ *
636
+ * There are three squash settings:
637
+ *
638
+ * - false: The parameter's default value is not squashed. It is encoded and included in the URL
639
+ * - true: The parameter's default value is omitted from the URL. If the parameter is preceeded and followed
640
+ * by slashes in the state's `url` declaration, then one of those slashes are omitted.
641
+ * This can allow for cleaner looking URLs.
642
+ * - `"<arbitrary string>"`: The parameter's default value is replaced with an arbitrary placeholder of your choice.
643
+ *
644
+ * <pre>params: {
645
+ * param1: {
646
+ * value: "defaultId",
647
+ * squash: true
648
+ * } }
649
+ * // squash "defaultValue" to "~"
650
+ * params: {
651
+ * param1: {
652
+ * value: "defaultValue",
653
+ * squash: "~"
654
+ * } }
655
+ * </pre>
656
+ *
479
657
  *
480
658
  * @example
481
659
  * <pre>
@@ -484,7 +662,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
484
662
  * // stateName can be a single top-level name (must be unique).
485
663
  * $stateProvider.state("home", {});
486
664
  *
487
- * // Or it can be a nested state name. This state is a child of the
665
+ * // Or it can be a nested state name. This state is a child of the
488
666
  * // above "home" state.
489
667
  * $stateProvider.state("home.newest", {});
490
668
  *
@@ -498,9 +676,6 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
498
676
  * .state("contacts", {});
499
677
  * </pre>
500
678
  *
501
- * @param {string} name A unique state name, e.g. "home", "about", "contacts".
502
- * To create a parent/child state use a dot, e.g. "about.sales", "home.newest".
503
- * @param {object} definition State configuration object.
504
679
  */
505
680
  this.state = state;
506
681
  function state(name, definition) {
@@ -521,6 +696,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
521
696
  * @requires $injector
522
697
  * @requires ui.router.util.$resolve
523
698
  * @requires ui.router.state.$stateParams
699
+ * @requires ui.router.router.$urlRouter
524
700
  *
525
701
  * @property {object} params A param object, e.g. {sectionId: section.id)}, that
526
702
  * you'd like to test against the current active state.
@@ -534,26 +710,82 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
534
710
  * between them. It also provides interfaces to ask for current state or even states
535
711
  * you're coming from.
536
712
  */
537
- // $urlRouter is injected just to ensure it gets instantiated
538
713
  this.$get = $get;
539
- $get.$inject = ['$rootScope', '$q', '$view', '$injector', '$resolve', '$stateParams', '$location', '$urlRouter', '$browser'];
540
- function $get( $rootScope, $q, $view, $injector, $resolve, $stateParams, $location, $urlRouter, $browser) {
714
+ $get.$inject = ['$rootScope', '$q', '$view', '$injector', '$resolve', '$stateParams', '$urlRouter', '$location', '$urlMatcherFactory'];
715
+ function $get( $rootScope, $q, $view, $injector, $resolve, $stateParams, $urlRouter, $location, $urlMatcherFactory) {
541
716
 
542
717
  var TransitionSuperseded = $q.reject(new Error('transition superseded'));
543
718
  var TransitionPrevented = $q.reject(new Error('transition prevented'));
544
719
  var TransitionAborted = $q.reject(new Error('transition aborted'));
545
720
  var TransitionFailed = $q.reject(new Error('transition failed'));
546
- var currentLocation = $location.url();
547
- var baseHref = $browser.baseHref();
548
721
 
549
- function syncUrl() {
550
- if ($location.url() !== currentLocation) {
551
- $location.url(currentLocation);
552
- $location.replace();
722
+ // Handles the case where a state which is the target of a transition is not found, and the user
723
+ // can optionally retry or defer the transition
724
+ function handleRedirect(redirect, state, params, options) {
725
+ /**
726
+ * @ngdoc event
727
+ * @name ui.router.state.$state#$stateNotFound
728
+ * @eventOf ui.router.state.$state
729
+ * @eventType broadcast on root scope
730
+ * @description
731
+ * Fired when a requested state **cannot be found** using the provided state name during transition.
732
+ * The event is broadcast allowing any handlers a single chance to deal with the error (usually by
733
+ * lazy-loading the unfound state). A special `unfoundState` object is passed to the listener handler,
734
+ * you can see its three properties in the example. You can use `event.preventDefault()` to abort the
735
+ * transition and the promise returned from `go` will be rejected with a `'transition aborted'` value.
736
+ *
737
+ * @param {Object} event Event object.
738
+ * @param {Object} unfoundState Unfound State information. Contains: `to, toParams, options` properties.
739
+ * @param {State} fromState Current state object.
740
+ * @param {Object} fromParams Current state params.
741
+ *
742
+ * @example
743
+ *
744
+ * <pre>
745
+ * // somewhere, assume lazy.state has not been defined
746
+ * $state.go("lazy.state", {a:1, b:2}, {inherit:false});
747
+ *
748
+ * // somewhere else
749
+ * $scope.$on('$stateNotFound',
750
+ * function(event, unfoundState, fromState, fromParams){
751
+ * console.log(unfoundState.to); // "lazy.state"
752
+ * console.log(unfoundState.toParams); // {a:1, b:2}
753
+ * console.log(unfoundState.options); // {inherit:false} + default options
754
+ * })
755
+ * </pre>
756
+ */
757
+ var evt = $rootScope.$broadcast('$stateNotFound', redirect, state, params);
758
+
759
+ if (evt.defaultPrevented) {
760
+ $urlRouter.update();
761
+ return TransitionAborted;
762
+ }
763
+
764
+ if (!evt.retry) {
765
+ return null;
553
766
  }
767
+
768
+ // Allow the handler to return a promise to defer state lookup retry
769
+ if (options.$retry) {
770
+ $urlRouter.update();
771
+ return TransitionFailed;
772
+ }
773
+ var retryTransition = $state.transition = $q.when(evt.retry);
774
+
775
+ retryTransition.then(function() {
776
+ if (retryTransition !== $state.transition) return TransitionSuperseded;
777
+ redirect.options.$retry = true;
778
+ return $state.transitionTo(redirect.to, redirect.toParams, redirect.options);
779
+ }, function() {
780
+ return TransitionAborted;
781
+ });
782
+ $urlRouter.update();
783
+
784
+ return retryTransition;
554
785
  }
555
786
 
556
787
  root.locals = { resolve: null, globals: { $stateParams: {} } };
788
+
557
789
  $state = {
558
790
  params: {},
559
791
  current: root.self,
@@ -567,8 +799,8 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
567
799
  * @methodOf ui.router.state.$state
568
800
  *
569
801
  * @description
570
- * A method that force reloads the current state. All resolves are re-resolved, events are not re-fired,
571
- * and controllers reinstantiated (bug with controllers reinstantiating right now, fixing soon).
802
+ * A method that force reloads the current state. All resolves are re-resolved,
803
+ * controllers reinstantiated, and events re-fired.
572
804
  *
573
805
  * @example
574
806
  * <pre>
@@ -584,12 +816,37 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
584
816
  * `reload()` is just an alias for:
585
817
  * <pre>
586
818
  * $state.transitionTo($state.current, $stateParams, {
587
- * reload: true, inherit: false, notify: false
819
+ * reload: true, inherit: false, notify: true
820
+ * });
821
+ * </pre>
822
+ *
823
+ * @param {string=|object=} state - A state name or a state object, which is the root of the resolves to be re-resolved.
824
+ * @example
825
+ * <pre>
826
+ * //assuming app application consists of 3 states: 'contacts', 'contacts.detail', 'contacts.detail.item'
827
+ * //and current state is 'contacts.detail.item'
828
+ * var app angular.module('app', ['ui.router']);
829
+ *
830
+ * app.controller('ctrl', function ($scope, $state) {
831
+ * $scope.reload = function(){
832
+ * //will reload 'contact.detail' and 'contact.detail.item' states
833
+ * $state.reload('contact.detail');
834
+ * }
835
+ * });
836
+ * </pre>
837
+ *
838
+ * `reload()` is just an alias for:
839
+ * <pre>
840
+ * $state.transitionTo($state.current, $stateParams, {
841
+ * reload: true, inherit: false, notify: true
588
842
  * });
589
843
  * </pre>
844
+
845
+ * @returns {promise} A promise representing the state of the new transition. See
846
+ * {@link ui.router.state.$state#methods_go $state.go}.
590
847
  */
591
- $state.reload = function reload() {
592
- $state.transitionTo($state.current, $stateParams, { reload: true, inherit: false, notify: false });
848
+ $state.reload = function reload(state) {
849
+ return $state.transitionTo($state.current, $stateParams, { reload: state || true, inherit: false, notify: true});
593
850
  };
594
851
 
595
852
  /**
@@ -659,7 +916,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
659
916
  *
660
917
  */
661
918
  $state.go = function go(to, params, options) {
662
- return this.transitionTo(to, params, extend({ inherit: true, relative: $state.$current }, options));
919
+ return $state.transitionTo(to, params, extend({ inherit: true, relative: $state.$current }, options));
663
920
  };
664
921
 
665
922
  /**
@@ -693,9 +950,11 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
693
950
  * - **`relative`** - {object=}, When transitioning with relative path (e.g '^'),
694
951
  * defines which state to be relative from.
695
952
  * - **`notify`** - {boolean=true}, If `true` will broadcast $stateChangeStart and $stateChangeSuccess events.
696
- * - **`reload`** (v0.2.5) - {boolean=false}, If `true` will force transition even if the state or params
953
+ * - **`reload`** (v0.2.5) - {boolean=false|string=|object=}, If `true` will force transition even if the state or params
697
954
  * have not changed, aka a reload of the same state. It differs from reloadOnSearch because you'd
698
955
  * use this when you want to force a reload when *everything* is the same, including search params.
956
+ * if String, then will reload the state with the name given in reload, and any children.
957
+ * if Object, then a stateObj is expected, will reload the state found in stateObj, and any children.
699
958
  *
700
959
  * @returns {promise} A promise representing the state of the new transition. See
701
960
  * {@link ui.router.state.$state#methods_go $state.go}.
@@ -709,64 +968,15 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
709
968
  var from = $state.$current, fromParams = $state.params, fromPath = from.path;
710
969
  var evt, toState = findState(to, options.relative);
711
970
 
971
+ // Store the hash param for later (since it will be stripped out by various methods)
972
+ var hash = toParams['#'];
973
+
712
974
  if (!isDefined(toState)) {
713
- // Broadcast not found event and abort the transition if prevented
714
975
  var redirect = { to: to, toParams: toParams, options: options };
976
+ var redirectResult = handleRedirect(redirect, from.self, fromParams, options);
715
977
 
716
- /**
717
- * @ngdoc event
718
- * @name ui.router.state.$state#$stateNotFound
719
- * @eventOf ui.router.state.$state
720
- * @eventType broadcast on root scope
721
- * @description
722
- * Fired when a requested state **cannot be found** using the provided state name during transition.
723
- * The event is broadcast allowing any handlers a single chance to deal with the error (usually by
724
- * lazy-loading the unfound state). A special `unfoundState` object is passed to the listener handler,
725
- * you can see its three properties in the example. You can use `event.preventDefault()` to abort the
726
- * transition and the promise returned from `go` will be rejected with a `'transition aborted'` value.
727
- *
728
- * @param {Object} event Event object.
729
- * @param {Object} unfoundState Unfound State information. Contains: `to, toParams, options` properties.
730
- * @param {State} fromState Current state object.
731
- * @param {Object} fromParams Current state params.
732
- *
733
- * @example
734
- *
735
- * <pre>
736
- * // somewhere, assume lazy.state has not been defined
737
- * $state.go("lazy.state", {a:1, b:2}, {inherit:false});
738
- *
739
- * // somewhere else
740
- * $scope.$on('$stateNotFound',
741
- * function(event, unfoundState, fromState, fromParams){
742
- * console.log(unfoundState.to); // "lazy.state"
743
- * console.log(unfoundState.toParams); // {a:1, b:2}
744
- * console.log(unfoundState.options); // {inherit:false} + default options
745
- * })
746
- * </pre>
747
- */
748
- evt = $rootScope.$broadcast('$stateNotFound', redirect, from.self, fromParams);
749
- if (evt.defaultPrevented) {
750
- syncUrl();
751
- return TransitionAborted;
752
- }
753
-
754
- // Allow the handler to return a promise to defer state lookup retry
755
- if (evt.retry) {
756
- if (options.$retry) {
757
- syncUrl();
758
- return TransitionFailed;
759
- }
760
- var retryTransition = $state.transition = $q.when(evt.retry);
761
- retryTransition.then(function() {
762
- if (retryTransition !== $state.transition) return TransitionSuperseded;
763
- redirect.options.$retry = true;
764
- return $state.transitionTo(redirect.to, redirect.toParams, redirect.options);
765
- }, function() {
766
- return TransitionAborted;
767
- });
768
- syncUrl();
769
- return retryTransition;
978
+ if (redirectResult) {
979
+ return redirectResult;
770
980
  }
771
981
 
772
982
  // Always retry once if the $stateNotFound was not prevented
@@ -775,38 +985,68 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
775
985
  toParams = redirect.toParams;
776
986
  options = redirect.options;
777
987
  toState = findState(to, options.relative);
988
+
778
989
  if (!isDefined(toState)) {
779
- if (options.relative) throw new Error("Could not resolve '" + to + "' from state '" + options.relative + "'");
780
- throw new Error("No such state '" + to + "'");
990
+ if (!options.relative) throw new Error("No such state '" + to + "'");
991
+ throw new Error("Could not resolve '" + to + "' from state '" + options.relative + "'");
781
992
  }
782
993
  }
783
994
  if (toState[abstractKey]) throw new Error("Cannot transition to abstract state '" + to + "'");
784
995
  if (options.inherit) toParams = inheritParams($stateParams, toParams || {}, $state.$current, toState);
996
+ if (!toState.params.$$validates(toParams)) return TransitionFailed;
997
+
998
+ toParams = toState.params.$$values(toParams);
785
999
  to = toState;
786
1000
 
787
1001
  var toPath = to.path;
788
1002
 
789
1003
  // Starting from the root of the path, keep all levels that haven't changed
790
- var keep, state, locals = root.locals, toLocals = [];
791
- for (keep = 0, state = toPath[keep];
792
- state && state === fromPath[keep] && equalForKeys(toParams, fromParams, state.ownParams) && !options.reload;
793
- keep++, state = toPath[keep]) {
794
- locals = toLocals[keep] = state.locals;
1004
+ var keep = 0, state = toPath[keep], locals = root.locals, toLocals = [];
1005
+
1006
+ if (!options.reload) {
1007
+ while (state && state === fromPath[keep] && state.ownParams.$$equals(toParams, fromParams)) {
1008
+ locals = toLocals[keep] = state.locals;
1009
+ keep++;
1010
+ state = toPath[keep];
1011
+ }
1012
+ } else if (isString(options.reload) || isObject(options.reload)) {
1013
+ if (isObject(options.reload) && !options.reload.name) {
1014
+ throw new Error('Invalid reload state object');
1015
+ }
1016
+
1017
+ var reloadState = options.reload === true ? fromPath[0] : findState(options.reload);
1018
+ if (options.reload && !reloadState) {
1019
+ throw new Error("No such reload state '" + (isString(options.reload) ? options.reload : options.reload.name) + "'");
1020
+ }
1021
+
1022
+ while (state && state === fromPath[keep] && state !== reloadState) {
1023
+ locals = toLocals[keep] = state.locals;
1024
+ keep++;
1025
+ state = toPath[keep];
1026
+ }
795
1027
  }
796
1028
 
797
1029
  // If we're going to the same state and all locals are kept, we've got nothing to do.
798
1030
  // But clear 'transition', as we still want to cancel any other pending transitions.
799
- // TODO: We may not want to bump 'transition' if we're called from a location change that we've initiated ourselves,
800
- // because we might accidentally abort a legitimate transition initiated from code?
801
- if (shouldTriggerReload(to, from, locals, options) ) {
802
- if ( to.self.reloadOnSearch !== false )
803
- syncUrl();
1031
+ // TODO: We may not want to bump 'transition' if we're called from a location change
1032
+ // that we've initiated ourselves, because we might accidentally abort a legitimate
1033
+ // transition initiated from code?
1034
+ if (shouldSkipReload(to, toParams, from, fromParams, locals, options)) {
1035
+ if (hash) toParams['#'] = hash;
1036
+ $state.params = toParams;
1037
+ copy($state.params, $stateParams);
1038
+ if (options.location && to.navigable && to.navigable.url) {
1039
+ $urlRouter.push(to.navigable.url, toParams, {
1040
+ $$avoidResync: true, replace: options.location === 'replace'
1041
+ });
1042
+ $urlRouter.update(true);
1043
+ }
804
1044
  $state.transition = null;
805
1045
  return $q.when($state.current);
806
1046
  }
807
1047
 
808
- // Normalize/filter parameters before we pass them to event handlers etc.
809
- toParams = normalize(to.params, toParams || {});
1048
+ // Filter parameters before we pass them to event handlers etc.
1049
+ toParams = filterByKeys(to.params.$$keys(), toParams || {});
810
1050
 
811
1051
  // Broadcast start event and cancel the transition if requested
812
1052
  if (options.notify) {
@@ -837,9 +1077,9 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
837
1077
  * })
838
1078
  * </pre>
839
1079
  */
840
- evt = $rootScope.$broadcast('$stateChangeStart', to.self, toParams, from.self, fromParams);
841
- if (evt.defaultPrevented) {
842
- syncUrl();
1080
+ if ($rootScope.$broadcast('$stateChangeStart', to.self, toParams, from.self, fromParams).defaultPrevented) {
1081
+ $rootScope.$broadcast('$stateChangeCancel', to.self, toParams, from.self, fromParams);
1082
+ $urlRouter.update();
843
1083
  return TransitionPrevented;
844
1084
  }
845
1085
  }
@@ -852,9 +1092,10 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
852
1092
  // empty and gets filled asynchronously. We need to keep track of the promise for the
853
1093
  // (fully resolved) current locals, and pass this down the chain.
854
1094
  var resolved = $q.when(locals);
855
- for (var l=keep; l<toPath.length; l++, state=toPath[l]) {
1095
+
1096
+ for (var l = keep; l < toPath.length; l++, state = toPath[l]) {
856
1097
  locals = toLocals[l] = inherit(locals);
857
- resolved = resolveState(state, toParams, state===to, resolved, locals);
1098
+ resolved = resolveState(state, toParams, state === to, resolved, locals, options);
858
1099
  }
859
1100
 
860
1101
  // Once everything is resolved, we are ready to perform the actual transition
@@ -867,7 +1108,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
867
1108
  if ($state.transition !== transition) return TransitionSuperseded;
868
1109
 
869
1110
  // Exit 'from' states not kept
870
- for (l=fromPath.length-1; l>=keep; l--) {
1111
+ for (l = fromPath.length - 1; l >= keep; l--) {
871
1112
  exiting = fromPath[l];
872
1113
  if (exiting.self.onExit) {
873
1114
  $injector.invoke(exiting.self.onExit, exiting.self, exiting.locals.globals);
@@ -876,7 +1117,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
876
1117
  }
877
1118
 
878
1119
  // Enter 'to' states not kept
879
- for (l=keep; l<toPath.length; l++) {
1120
+ for (l = keep; l < toPath.length; l++) {
880
1121
  entering = toPath[l];
881
1122
  entering.locals = toLocals[l];
882
1123
  if (entering.self.onEnter) {
@@ -884,6 +1125,9 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
884
1125
  }
885
1126
  }
886
1127
 
1128
+ // Re-add the saved hash before we start returning things
1129
+ if (hash) toParams['#'] = hash;
1130
+
887
1131
  // Run it again, to catch any transitions in callbacks
888
1132
  if ($state.transition !== transition) return TransitionSuperseded;
889
1133
 
@@ -894,14 +1138,10 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
894
1138
  copy($state.params, $stateParams);
895
1139
  $state.transition = null;
896
1140
 
897
- // Update $location
898
- var toNav = to.navigable;
899
- if (options.location && toNav) {
900
- $location.url(toNav.url.format(toNav.locals.globals.$stateParams));
901
-
902
- if (options.location === 'replace') {
903
- $location.replace();
904
- }
1141
+ if (options.location && to.navigable) {
1142
+ $urlRouter.push(to.navigable.url, to.navigable.locals.globals.$stateParams, {
1143
+ $$avoidResync: true, replace: options.location === 'replace'
1144
+ });
905
1145
  }
906
1146
 
907
1147
  if (options.notify) {
@@ -921,7 +1161,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
921
1161
  */
922
1162
  $rootScope.$broadcast('$stateChangeSuccess', to.self, toParams, from.self, fromParams);
923
1163
  }
924
- currentLocation = $location.url();
1164
+ $urlRouter.update(true);
925
1165
 
926
1166
  return $state.current;
927
1167
  }, function (error) {
@@ -946,8 +1186,11 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
946
1186
  * @param {Object} fromParams The params supplied to the `fromState`.
947
1187
  * @param {Error} error The resolve error object.
948
1188
  */
949
- $rootScope.$broadcast('$stateChangeError', to.self, toParams, from.self, fromParams, error);
950
- syncUrl();
1189
+ evt = $rootScope.$broadcast('$stateChangeError', to.self, toParams, from.self, fromParams, error);
1190
+
1191
+ if (!evt.defaultPrevented) {
1192
+ $urlRouter.update();
1193
+ }
951
1194
 
952
1195
  return $q.reject(error);
953
1196
  });
@@ -962,35 +1205,40 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
962
1205
  *
963
1206
  * @description
964
1207
  * Similar to {@link ui.router.state.$state#methods_includes $state.includes},
965
- * but only checks for the full state name. If params is supplied then it will be
966
- * tested for strict equality against the current active params object, so all params
1208
+ * but only checks for the full state name. If params is supplied then it will be
1209
+ * tested for strict equality against the current active params object, so all params
967
1210
  * must match with none missing and no extras.
968
1211
  *
969
1212
  * @example
970
1213
  * <pre>
1214
+ * $state.$current.name = 'contacts.details.item';
1215
+ *
1216
+ * // absolute name
971
1217
  * $state.is('contact.details.item'); // returns true
972
1218
  * $state.is(contactDetailItemStateObject); // returns true
973
1219
  *
974
- * // everything else would return false
1220
+ * // relative name (. and ^), typically from a template
1221
+ * // E.g. from the 'contacts.details' template
1222
+ * <div ng-class="{highlighted: $state.is('.item')}">Item</div>
975
1223
  * </pre>
976
1224
  *
977
- * @param {string|object} stateName The state name or state object you'd like to check.
978
- * @param {object=} params A param object, e.g. `{sectionId: section.id}`, that you'd like
1225
+ * @param {string|object} stateOrName The state name (absolute or relative) or state object you'd like to check.
1226
+ * @param {object=} params A param object, e.g. `{sectionId: section.id}`, that you'd like
979
1227
  * to test against the current active state.
1228
+ * @param {object=} options An options object. The options are:
1229
+ *
1230
+ * - **`relative`** - {string|object} - If `stateOrName` is a relative state name and `options.relative` is set, .is will
1231
+ * test relative to `options.relative` state (or name).
1232
+ *
980
1233
  * @returns {boolean} Returns true if it is the state.
981
1234
  */
982
- $state.is = function is(stateOrName, params) {
983
- var state = findState(stateOrName);
984
-
985
- if (!isDefined(state)) {
986
- return undefined;
987
- }
988
-
989
- if ($state.$current !== state) {
990
- return false;
991
- }
1235
+ $state.is = function is(stateOrName, params, options) {
1236
+ options = extend({ relative: $state.$current }, options || {});
1237
+ var state = findState(stateOrName, options.relative);
992
1238
 
993
- return isDefined(params) && params !== null ? angular.equals($stateParams, params) : true;
1239
+ if (!isDefined(state)) { return undefined; }
1240
+ if ($state.$current !== state) { return false; }
1241
+ return params ? equalForKeys(state.params.$$values(params), $stateParams) : true;
994
1242
  };
995
1243
 
996
1244
  /**
@@ -999,25 +1247,28 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
999
1247
  * @methodOf ui.router.state.$state
1000
1248
  *
1001
1249
  * @description
1002
- * A method to determine if the current active state is equal to or is the child of the
1250
+ * A method to determine if the current active state is equal to or is the child of the
1003
1251
  * state stateName. If any params are passed then they will be tested for a match as well.
1004
1252
  * Not all the parameters need to be passed, just the ones you'd like to test for equality.
1005
1253
  *
1006
1254
  * @example
1255
+ * Partial and relative names
1007
1256
  * <pre>
1008
1257
  * $state.$current.name = 'contacts.details.item';
1009
1258
  *
1259
+ * // Using partial names
1010
1260
  * $state.includes("contacts"); // returns true
1011
1261
  * $state.includes("contacts.details"); // returns true
1012
1262
  * $state.includes("contacts.details.item"); // returns true
1013
1263
  * $state.includes("contacts.list"); // returns false
1014
1264
  * $state.includes("about"); // returns false
1015
- * </pre>
1016
1265
  *
1017
- * @description
1018
- * Basic globing patterns will also work.
1266
+ * // Using relative names (. and ^), typically from a template
1267
+ * // E.g. from the 'contacts.details' template
1268
+ * <div ng-class="{highlighted: $state.includes('.item')}">Item</div>
1269
+ * </pre>
1019
1270
  *
1020
- * @example
1271
+ * Basic globbing patterns
1021
1272
  * <pre>
1022
1273
  * $state.$current.name = 'contacts.details.item.url';
1023
1274
  *
@@ -1030,37 +1281,30 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
1030
1281
  * $state.includes("item.**"); // returns false
1031
1282
  * </pre>
1032
1283
  *
1033
- * @param {string} stateOrName A partial name to be searched for within the current state name.
1034
- * @param {object} params A param object, e.g. `{sectionId: section.id}`,
1284
+ * @param {string} stateOrName A partial name, relative name, or glob pattern
1285
+ * to be searched for within the current state name.
1286
+ * @param {object=} params A param object, e.g. `{sectionId: section.id}`,
1035
1287
  * that you'd like to test against the current active state.
1288
+ * @param {object=} options An options object. The options are:
1289
+ *
1290
+ * - **`relative`** - {string|object=} - If `stateOrName` is a relative state reference and `options.relative` is set,
1291
+ * .includes will test relative to `options.relative` state (or name).
1292
+ *
1036
1293
  * @returns {boolean} Returns true if it does include the state
1037
1294
  */
1038
-
1039
- $state.includes = function includes(stateOrName, params) {
1295
+ $state.includes = function includes(stateOrName, params, options) {
1296
+ options = extend({ relative: $state.$current }, options || {});
1040
1297
  if (isString(stateOrName) && isGlob(stateOrName)) {
1041
- if (doesStateMatchGlob(stateOrName)) {
1042
- stateOrName = $state.$current.name;
1043
- } else {
1298
+ if (!doesStateMatchGlob(stateOrName)) {
1044
1299
  return false;
1045
1300
  }
1301
+ stateOrName = $state.$current.name;
1046
1302
  }
1047
1303
 
1048
- var state = findState(stateOrName);
1049
- if (!isDefined(state)) {
1050
- return undefined;
1051
- }
1052
-
1053
- if (!isDefined($state.$current.includes[state.name])) {
1054
- return false;
1055
- }
1056
-
1057
- var validParams = true;
1058
- angular.forEach(params, function(value, key) {
1059
- if (!isDefined($stateParams[key]) || $stateParams[key] !== value) {
1060
- validParams = false;
1061
- }
1062
- });
1063
- return validParams;
1304
+ var state = findState(stateOrName, options.relative);
1305
+ if (!isDefined(state)) { return undefined; }
1306
+ if (!isDefined($state.$current.includes[state.name])) { return false; }
1307
+ return params ? equalForKeys(state.params.$$values(params), $stateParams, objectKeys(params)) : true;
1064
1308
  };
1065
1309
 
1066
1310
 
@@ -1084,7 +1328,7 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
1084
1328
  * - **`lossy`** - {boolean=true} - If true, and if there is no url associated with the state provided in the
1085
1329
  * first parameter, then the constructed href url will be built from the first navigable ancestor (aka
1086
1330
  * ancestor with a valid url).
1087
- * - **`inherit`** - {boolean=false}, If `true` will inherit url parameters from current url.
1331
+ * - **`inherit`** - {boolean=true}, If `true` will inherit url parameters from current url.
1088
1332
  * - **`relative`** - {object=$state.$current}, When transitioning with relative path (e.g '^'),
1089
1333
  * defines which state to be relative from.
1090
1334
  * - **`absolute`** - {boolean=false}, If true will generate an absolute url, e.g. "http://www.example.com/fullurl".
@@ -1092,33 +1336,26 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
1092
1336
  * @returns {string} compiled state url
1093
1337
  */
1094
1338
  $state.href = function href(stateOrName, params, options) {
1095
- options = extend({ lossy: true, inherit: false, absolute: false, relative: $state.$current }, options || {});
1339
+ options = extend({
1340
+ lossy: true,
1341
+ inherit: true,
1342
+ absolute: false,
1343
+ relative: $state.$current
1344
+ }, options || {});
1345
+
1096
1346
  var state = findState(stateOrName, options.relative);
1097
- if (!isDefined(state)) return null;
1098
1347
 
1099
- params = inheritParams($stateParams, params || {}, $state.$current, state);
1348
+ if (!isDefined(state)) return null;
1349
+ if (options.inherit) params = inheritParams($stateParams, params || {}, $state.$current, state);
1350
+
1100
1351
  var nav = (state && options.lossy) ? state.navigable : state;
1101
- var url = (nav && nav.url) ? nav.url.format(normalize(state.params, params || {})) : null;
1102
- if (!$locationProvider.html5Mode() && url) {
1103
- url = "#" + $locationProvider.hashPrefix() + url;
1104
- }
1105
1352
 
1106
- if (baseHref !== '/') {
1107
- if ($locationProvider.html5Mode()) {
1108
- url = baseHref.slice(0, -1) + url;
1109
- } else if (options.absolute){
1110
- url = baseHref.slice(1) + url;
1111
- }
1112
- }
1113
-
1114
- if (options.absolute && url) {
1115
- url = $location.protocol() + '://' +
1116
- $location.host() +
1117
- ($location.port() == 80 || $location.port() == 443 ? '' : ':' + $location.port()) +
1118
- (!$locationProvider.html5Mode() && url ? '/' : '') +
1119
- url;
1353
+ if (!nav || nav.url === undefined || nav.url === null) {
1354
+ return null;
1120
1355
  }
1121
- return url;
1356
+ return $urlRouter.href(nav.url, filterByKeys(state.params.$$keys().concat('#'), params || {}), {
1357
+ absolute: options.absolute
1358
+ });
1122
1359
  };
1123
1360
 
1124
1361
  /**
@@ -1129,26 +1366,23 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
1129
1366
  * @description
1130
1367
  * Returns the state configuration object for any specific state or all states.
1131
1368
  *
1132
- * @param {string|object=} stateOrName If provided, will only get the config for
1369
+ * @param {string|object=} stateOrName (absolute or relative) If provided, will only get the config for
1133
1370
  * the requested state. If not provided, returns an array of ALL state configs.
1134
- * @returns {object|array} State configuration object or array of all objects.
1371
+ * @param {string|object=} context When stateOrName is a relative state reference, the state will be retrieved relative to context.
1372
+ * @returns {Object|Array} State configuration object or array of all objects.
1135
1373
  */
1136
1374
  $state.get = function (stateOrName, context) {
1137
- if (!isDefined(stateOrName)) {
1138
- var list = [];
1139
- forEach(states, function(state) { list.push(state.self); });
1140
- return list;
1141
- }
1142
- var state = findState(stateOrName, context);
1375
+ if (arguments.length === 0) return map(objectKeys(states), function(name) { return states[name].self; });
1376
+ var state = findState(stateOrName, context || $state.$current);
1143
1377
  return (state && state.self) ? state.self : null;
1144
1378
  };
1145
1379
 
1146
- function resolveState(state, params, paramsAreFiltered, inherited, dst) {
1380
+ function resolveState(state, params, paramsAreFiltered, inherited, dst, options) {
1147
1381
  // Make a restricted $stateParams with only the parameters that apply to this state if
1148
1382
  // necessary. In addition to being available to the controller and onEnter/onExit callbacks,
1149
1383
  // we also need $stateParams to be available for any $injector calls we make during the
1150
1384
  // dependency resolution process.
1151
- var $stateParams = (paramsAreFiltered) ? params : filterByKeys(state.params, params);
1385
+ var $stateParams = (paramsAreFiltered) ? params : filterByKeys(state.params.$$keys(), params);
1152
1386
  var locals = { $stateParams: $stateParams };
1153
1387
 
1154
1388
  // Resolve 'global' dependencies for the state, i.e. those not specific to a view.
@@ -1156,35 +1390,43 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
1156
1390
  // to the set that should be visible to the state, and are independent of when we update
1157
1391
  // the global $state and $stateParams values.
1158
1392
  dst.resolve = $resolve.resolve(state.resolve, locals, dst.resolve, state);
1159
- var promises = [ dst.resolve.then(function (globals) {
1393
+ var promises = [dst.resolve.then(function (globals) {
1160
1394
  dst.globals = globals;
1161
- }) ];
1395
+ })];
1162
1396
  if (inherited) promises.push(inherited);
1163
1397
 
1164
- // Resolve template and dependencies for all views.
1165
- forEach(state.views, function (view, name) {
1166
- var injectables = (view.resolve && view.resolve !== state.resolve ? view.resolve : {});
1167
- injectables.$template = [ function () {
1168
- return $view.load(name, { view: view, locals: locals, params: $stateParams, notify: false }) || '';
1169
- }];
1170
-
1171
- promises.push($resolve.resolve(injectables, locals, dst.resolve, state).then(function (result) {
1172
- // References to the controller (only instantiated at link time)
1173
- if (isFunction(view.controllerProvider) || isArray(view.controllerProvider)) {
1174
- var injectLocals = angular.extend({}, injectables, locals);
1175
- result.$$controller = $injector.invoke(view.controllerProvider, null, injectLocals);
1176
- } else {
1177
- result.$$controller = view.controller;
1178
- }
1179
- // Provide access to the state itself for internal use
1180
- result.$$state = state;
1181
- result.$$controllerAs = view.controllerAs;
1182
- dst[name] = result;
1183
- }));
1184
- });
1398
+ function resolveViews() {
1399
+ var viewsPromises = [];
1400
+
1401
+ // Resolve template and dependencies for all views.
1402
+ forEach(state.views, function (view, name) {
1403
+ var injectables = (view.resolve && view.resolve !== state.resolve ? view.resolve : {});
1404
+ injectables.$template = [ function () {
1405
+ return $view.load(name, { view: view, locals: dst.globals, params: $stateParams, notify: options.notify }) || '';
1406
+ }];
1407
+
1408
+ viewsPromises.push($resolve.resolve(injectables, dst.globals, dst.resolve, state).then(function (result) {
1409
+ // References to the controller (only instantiated at link time)
1410
+ if (isFunction(view.controllerProvider) || isArray(view.controllerProvider)) {
1411
+ var injectLocals = angular.extend({}, injectables, dst.globals);
1412
+ result.$$controller = $injector.invoke(view.controllerProvider, null, injectLocals);
1413
+ } else {
1414
+ result.$$controller = view.controller;
1415
+ }
1416
+ // Provide access to the state itself for internal use
1417
+ result.$$state = state;
1418
+ result.$$controllerAs = view.controllerAs;
1419
+ dst[name] = result;
1420
+ }));
1421
+ });
1422
+
1423
+ return $q.all(viewsPromises).then(function(){
1424
+ return dst.globals;
1425
+ });
1426
+ }
1185
1427
 
1186
1428
  // Wait for all the promises and then return the activation object
1187
- return $q.all(promises).then(function (values) {
1429
+ return $q.all(promises).then(resolveViews).then(function (values) {
1188
1430
  return dst;
1189
1431
  });
1190
1432
  }
@@ -1192,8 +1434,27 @@ function $StateProvider( $urlRouterProvider, $urlMatcherFactory, $
1192
1434
  return $state;
1193
1435
  }
1194
1436
 
1195
- function shouldTriggerReload(to, from, locals, options) {
1196
- if ( to === from && ((locals === from.locals && !options.reload) || (to.self.reloadOnSearch === false)) ) {
1437
+ function shouldSkipReload(to, toParams, from, fromParams, locals, options) {
1438
+ // Return true if there are no differences in non-search (path/object) params, false if there are differences
1439
+ function nonSearchParamsEqual(fromAndToState, fromParams, toParams) {
1440
+ // Identify whether all the parameters that differ between `fromParams` and `toParams` were search params.
1441
+ function notSearchParam(key) {
1442
+ return fromAndToState.params[key].location != "search";
1443
+ }
1444
+ var nonQueryParamKeys = fromAndToState.params.$$keys().filter(notSearchParam);
1445
+ var nonQueryParams = pick.apply({}, [fromAndToState.params].concat(nonQueryParamKeys));
1446
+ var nonQueryParamSet = new $$UMFP.ParamSet(nonQueryParams);
1447
+ return nonQueryParamSet.$$equals(fromParams, toParams);
1448
+ }
1449
+
1450
+ // If reload was not explicitly requested
1451
+ // and we're transitioning to the same state we're already in
1452
+ // and the locals didn't change
1453
+ // or they changed in a way that doesn't merit reloading
1454
+ // (reloadOnParams:false, or reloadOnSearch.false and only search params changed)
1455
+ // Then return true.
1456
+ if (!options.reload && to === from &&
1457
+ (locals === from.locals || (to.self.reloadOnSearch === false && nonSearchParamsEqual(from, fromParams, toParams)))) {
1197
1458
  return true;
1198
1459
  }
1199
1460
  }