You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by er...@apache.org on 2015/02/23 06:42:38 UTC
svn commit: r1661606 [3/12] - in /lucene/dev/trunk/solr: ./ webapp/web/
webapp/web/css/angular/ webapp/web/js/angular/
webapp/web/js/angular/controllers/ webapp/web/libs/ webapp/web/partials/
Added: lucene/dev/trunk/solr/webapp/web/js/angular/controllers/index.js
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/webapp/web/js/angular/controllers/index.js?rev=1661606&view=auto
==============================================================================
--- lucene/dev/trunk/solr/webapp/web/js/angular/controllers/index.js (added)
+++ lucene/dev/trunk/solr/webapp/web/js/angular/controllers/index.js Mon Feb 23 05:42:36 2015
@@ -0,0 +1,95 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements. See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+solrAdminApp.controller('IndexController', ['$scope', 'System', 'Cores', function($scope, System, Cores) {
+ $scope.resetMenu("index");
+ $scope.reload = function() {
+ System.get(function(data) {
+ $scope.system = data;
+
+ // load average
+ load_average = ( data.system.uptime || '' ).match( /load averages?: (\d+[.,]\d\d),? (\d+[.,]\d\d),? (\d+[.,]\d\d)/ );
+ for (var i=0;i<2;i++) {
+ load_average[i]=load_average[i].replace(",","."); // for European users
+ }
+ $scope.load_average = load_average.slice(1);
+
+ // physical memory
+ var memoryMax = parse_memory_value(data.system.totalPhysicalMemorySize);
+ $scope.memoryTotal = parse_memory_value(data.system.totalPhysicalMemorySize - data.system.freePhysicalMemorySize);
+ $scope.memoryPercentage = ($scope.memoryTotal / memoryMax * 100).toFixed(1)+ "%";
+ $scope.memoryMax = pretty_print_bytes(memoryMax);
+ $scope.memoryTotalDisplay = pretty_print_bytes($scope.memoryTotal);
+
+ // swap space
+ var swapMax = parse_memory_value(data.system.totalSwapSpaceSize);
+ $scope.swapTotal = parse_memory_value(data.system.totalSwapSpaceSize - data.system.freeSwapSpaceSize);
+ $scope.swapPercentage = ($scope.swapTotal / swapMax * 100).toFixed(1)+ "%";
+ $scope.swapMax = pretty_print_bytes(swapMax);
+ $scope.swapTotalDisplay = pretty_print_bytes($scope.swapTotal);
+
+ // file handles
+ $scope.fileDescriptorPercentage = (data.system.openFileDescriptorCount / data.system.maxFileDescriptorCount *100).toFixed(1) + "%";
+
+ // java memory
+ var javaMemoryMax = parse_memory_value(data.jvm.memory.raw.max || data.jvm.memory.max);
+ $scope.javaMemoryTotal = parse_memory_value(data.jvm.memory.raw.total || data.jvm.memory.total);
+ $scope.javaMemoryUsed = parse_memory_value(data.jvm.memory.raw.used || data.jvm.memory.used);
+ $scope.javaMemoryTotalPercentage = ($scope.javaMemoryTotal / javaMemoryMax *100).toFixed(1) + "%";
+ $scope.javaMemoryUsedPercentage = ($scope.javaMemoryUsed / $scope.javaMemoryTotal *100).toFixed(1) + "%";
+ $scope.javaMemoryPercentage = ($scope.javaMemoryUsed / javaMemoryMax * 100).toFixed(1) + "%";
+ $scope.javaMemoryTotalDisplay = pretty_print_bytes($scope.javaMemoryTotal);
+ $scope.javaMemoryUsedDisplay = pretty_print_bytes($scope.javaMemoryUsed); // @todo These should really be an AngularJS Filter: {{ javaMemoryUsed | bytes }}
+ $scope.javaMemoryMax = pretty_print_bytes(javaMemoryMax);
+
+ // no info bar:
+ $scope.noInfo = !(
+ data.system.totalPhysicalMemorySize && data.system.freePhysicalMemorySize &&
+ data.system.totalSwapSpaceSize && data.system.freeSwapSpaceSize &&
+ data.system.openFileDescriptorCount && data.system.maxFileDescriptorCount);
+
+ // command line args:
+ $scope.commandLineArgs = data.jvm.jmx.commandLineArgs.sort();
+ });
+ };
+ $scope.reload();
+}]);
+
+var parse_memory_value = function( value ) {
+ if( value !== Number( value ) )
+ {
+ var units = 'BKMGTPEZY';
+ var match = value.match( /^(\d+([,\.]\d+)?) (\w).*$/ );
+ var value = parseFloat( match[1] ) * Math.pow( 1024, units.indexOf( match[3].toUpperCase() ) );
+ }
+
+ return value;
+};
+
+var pretty_print_bytes = function(byte_value) {
+ var unit = null;
+
+ byte_value /= 1024;
+ byte_value /= 1024;
+ unit = 'MB';
+
+ if( 1024 <= byte_value ) {
+ byte_value /= 1024;
+ unit = 'GB';
+ }
+ return byte_value.toFixed( 2 ) + ' ' + unit;
+};
Added: lucene/dev/trunk/solr/webapp/web/js/angular/controllers/java-properties.js
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/webapp/web/js/angular/controllers/java-properties.js?rev=1661606&view=auto
==============================================================================
--- lucene/dev/trunk/solr/webapp/web/js/angular/controllers/java-properties.js (added)
+++ lucene/dev/trunk/solr/webapp/web/js/angular/controllers/java-properties.js Mon Feb 23 05:42:36 2015
@@ -0,0 +1,40 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+solrAdminApp.controller('JavaPropertiesController',
+ function($scope, Properties){
+ $scope.resetMenu("java-props");
+ $scope.refresh = function() {
+ Properties.get(function(data) {
+ var sysprops = data["system.properties"];
+ var sep = sysprops["path.separator"]
+ var props = [];
+ for (var key in sysprops) {
+ var value = sysprops[key];
+ var key = key.replace(/\./g, '.​');
+ if (key.indexOf(".path")!=-1 || key.indexOf(".dirs")) {
+ props.push({name: key, values: value.split(sep)});
+ } else {
+ props.push({name: key, values: [value]});
+ }
+ }
+ $scope.props = props;
+ });
+ };
+
+ $scope.refresh();
+ });
Added: lucene/dev/trunk/solr/webapp/web/js/angular/controllers/logging.js
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/webapp/web/js/angular/controllers/logging.js?rev=1661606&view=auto
==============================================================================
--- lucene/dev/trunk/solr/webapp/web/js/angular/controllers/logging.js (added)
+++ lucene/dev/trunk/solr/webapp/web/js/angular/controllers/logging.js Mon Feb 23 05:42:36 2015
@@ -0,0 +1,146 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+var format_time_content = function( time, timeZone ) {
+ var format_time_options = {};
+ if (timeZone && timeZone!="Local") {
+ format_time_options.timeZone = timeZone;
+ }
+ return time.toLocaleString( undefined, format_time_options );
+}
+
+solrAdminApp.controller('LoggingController',
+ function($scope, $timeout, $cookies, Logging){
+ $scope.resetMenu("logging");
+ $scope.timezone = $cookies.logging_timezone || "Local";
+ $scope.refresh = function() {
+ Logging.events(function(data) {
+ $scope.since = new Date();
+ $scope.sinceDisplay = format_time_content($scope.since, "Local");
+ var events = data.history.docs;
+ for (var i=0; i<events.length; i++) {
+ var event = events[i];
+ var time = new Date(event.time);
+ event.local_time = format_time_content(time, "Local");
+ event.utc_time = format_time_content(time, "UTC");
+ event.loggerBase = event.logger.split( '.' ).pop();
+
+ if( !event.trace ) {
+ var lines = event.message.split( "\n" );
+ if( lines.length > 1) {
+ event.trace = event.message;
+ event.message = lines[0];
+ }
+ }
+ event.message = event.message.replace(/,/g, ',​');
+ event.showTrace = false;
+ }
+ $scope.events = events;
+ $scope.watcher = data.watcher;
+ /* @todo sticky_mode
+ // state element is in viewport
+ sticky_mode = ( state.position().top <= $( window ).scrollTop() + $( window ).height() - ( $( 'body' ).height() - state.position().top ) );
+ // initial request
+ if( 0 === since ) {
+ sticky_mode = true;
+ }
+ $scope.loggingEvents = events;
+
+ if( sticky_mode )
+ {
+ $( 'body' )
+ .animate
+ (
+ { scrollTop: state.position().top },
+ 1000
+ );
+ }
+ */
+ });
+ $timeout($scope.refresh, 10000);
+ };
+ $scope.refresh();
+
+ $scope.toggleTimezone = function() {
+ $scope.timezone = ($scope.timezone=="Local") ? "UTC":"Local";
+ $cookies.logging_timezone = $scope.timezone;
+ }
+ $scope.toggleRow = function(event) {
+ event.showTrace =! event.showTrace;
+ };
+ }
+)
+
+.controller('LoggingLevelController',
+ function($scope, Logging) {
+ $scope.resetMenu("logging-levels");
+
+ var packageOf = function(logger) {
+ var parts = logger.name.split(".");
+ return !parts.pop() ? "" : parts.join(".");
+ };
+
+ var shortNameOf = function(logger) {return logger.name.split(".").pop();}
+
+ var makeTree = function(loggers, packag) {
+ var tree = [];
+ for (var i=0; i<loggers.length; i++) {
+ var logger = loggers[i];
+ logger.packag = packageOf(logger);
+ logger.short = shortNameOf(logger);
+ if (logger.packag == packag) {
+ logger.children = makeTree(loggers, logger.name);
+ tree.push(logger);
+ }
+ }
+ return tree;
+ };
+
+ $scope.refresh = function() {
+ Logging.levels(function(data) {
+ $scope.logging = makeTree(data.loggers, "");
+ $scope.watcher = data.watcher;
+ $scope.levels = [];
+ for (level in data.levels) {
+ $scope.levels.push({name:data.levels[level], pos:level});
+ }
+ });
+ };
+
+ $scope.toggleOptions = function(logger) {
+ if (logger.showOptions) {
+ logger.showOptions = false;
+ delete $scope.currentLogger;
+ } else {
+ if ($scope.currentLogger) {
+ $scope.currentLogger.showOptions = false;
+ }
+ logger.showOptions = true;
+ $scope.currentLogger = logger;
+ }
+ };
+
+ $scope.setLevel = function(logger, newLevel) {
+ var setString = logger.name + ":" + newLevel;
+ logger.showOptions = false;
+ Logging.setLevel({set: setString}, function(data) {
+ $scope.refresh();
+ });
+ };
+
+ $scope.refresh();
+ });
Added: lucene/dev/trunk/solr/webapp/web/js/angular/controllers/query.js
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/webapp/web/js/angular/controllers/query.js?rev=1661606&view=auto
==============================================================================
--- lucene/dev/trunk/solr/webapp/web/js/angular/controllers/query.js (added)
+++ lucene/dev/trunk/solr/webapp/web/js/angular/controllers/query.js Mon Feb 23 05:42:36 2015
@@ -0,0 +1,87 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+solrAdminApp.controller('QueryController',
+ function($scope, $routeParams, $location, Query){
+ $scope.resetMenu("query");
+
+ // @todo read URL parameters into scope
+ $scope.query = {wt: 'json', q:'*:*', indent:'on'};
+ $scope.filters = [{fq:""}];
+ $scope.dismax = {defType: "dismax"};
+ $scope.edismax = {defType: "edismax", stopwords: true, lowercaseOperators: true};
+ $scope.hl = {hl:"on"};
+ $scope.facet = {facet: "on"};
+ $scope.spatial = {};
+ $scope.spellcheck = {spellcheck:"on"};
+ $scope.qt = "/select";
+
+ var copy = function(params, query) {
+ for (var key in query) {
+ terms = query[key];
+ if (terms.length > 0 && key[0]!="$") {
+ params.push(key + "=" + terms);
+ }
+ }
+ };
+
+ $scope.doQuery = function() {
+ var params = [];
+ copy(params, $scope.query);
+
+ if ($scope.isDismax) copy(params, $scope.dismax);
+ if ($scope.isEdismax) copy(params, $scope.edismax);
+ if ($scope.isHighlight) copy(params, $scope.hl);
+ if ($scope.isFacet) copy(params, $scope.facet);
+ if ($scope.isSpatial) copy(params, $scope.spatial);
+ if ($scope.isSpellcheck) copy(params, $scope.spellcheck);
+
+ if ($scope.rawParams) {
+ for (var param in $scope.rawParams.split("\n")) {
+ params.push(param);
+ }
+ }
+
+ var qt = $scope.qt ? $scope.qt : "/select";
+
+ for (var filter in $scope.filters) {
+ copy(params, $scope.filters[filter]);
+ }
+
+ var url = "/solr/" + $routeParams.core + qt + "?" + params.join("&");
+ Query.query(url, function(data) {
+ $scope.lang = $scope.query.wt;
+ $scope.response = data;
+ $scope.url = $location.protocol() + "://" +
+ $location.host() + ":" +
+ $location.port() + url;
+ });
+ };
+
+ $scope.removeFilter = function(index) {
+ if ($scope.filters.length === 1) {
+ $scope.filters = [{fq: ""}];
+ } else {
+ $scope.filters.splice(index, 1);
+ }
+ };
+
+ $scope.addFilter = function(index) {
+ $scope.filters.splice(index+1, 0, {fq:""});
+ };
+ }
+);
Added: lucene/dev/trunk/solr/webapp/web/js/angular/controllers/threads.js
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/webapp/web/js/angular/controllers/threads.js?rev=1661606&view=auto
==============================================================================
--- lucene/dev/trunk/solr/webapp/web/js/angular/controllers/threads.js (added)
+++ lucene/dev/trunk/solr/webapp/web/js/angular/controllers/threads.js Mon Feb 23 05:42:36 2015
@@ -0,0 +1,51 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+solrAdminApp.controller('ThreadsController',
+ ["$scope", "Threads",
+ function($scope, Threads){
+ $scope.resetMenu("threads");
+ $scope.refresh = function() {
+ Threads.get(function(data) {
+ var threadDump = data.system.threadDump;
+ var threads = [];
+ for (var i=1; i<threadDump.length; i+=2) {
+ var thread = threadDump[i];
+ if (!!thread.stackTrace) {
+ var stackTrace = [];
+ for (var j=0; j<thread.stackTrace.length; j++) {
+ var trace = thread.stackTrace[j].replace("(", "\u200B("); // allow wrapping to happen, \u200B is a zero-width space
+ stackTrace.push({id:thread.id + ":" + j, trace: trace});
+ }
+ thread.stackTrace = stackTrace;
+ }
+ threads.push(thread);
+ }
+ $scope.threads = threads;
+ });
+ };
+ $scope.toggleStacktrace = function(thread) {
+ thread.showStackTrace = !thread.showStackTrace;
+ };
+ $scope.toggleStacktraces = function() {
+ $scope.showAllStacktraces = !$scope.showAllStacktraces;
+ for (var i=0; i<$scope.threads.length; i++) {
+ $scope.threads[i].showStackTrace = $scope.showAllStacktraces;
+ }
+ };
+ $scope.refresh();
+}]);
Added: lucene/dev/trunk/solr/webapp/web/js/angular/services.js
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/webapp/web/js/angular/services.js?rev=1661606&view=auto
==============================================================================
--- lucene/dev/trunk/solr/webapp/web/js/angular/services.js (added)
+++ lucene/dev/trunk/solr/webapp/web/js/angular/services.js Mon Feb 23 05:42:36 2015
@@ -0,0 +1,131 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+var solrAdminServices = angular.module('solrAdminServices', ['ngResource']);
+
+solrAdminServices.factory('System',
+ ['$resource', function($resource) {
+ return $resource('/solr/admin/info/system', {"wt":"json", "_":Date.now()});
+ }])
+.factory('Cores',
+ ['$resource', function($resource) {
+ return $resource('/solr/admin/cores',
+ {'wt':'json', '_':Date.now()}, {
+ "query": {},
+ "list": {params:{indexInfo: false}},
+ "add": {params:{action: "CREATE"}},
+ "unload": {params:{action: "UNLOAD", core: "@core"}},
+ "rename": {params:{action: "RENAME"}},
+ "swap": {params:{}},
+ "reload": {method: "GET", params:{action:"RELOAD", core: "@core"}},
+ "optimize": {params:{}}
+ });
+ }])
+.factory('Logging',
+ ['$resource', function($resource) {
+ return $resource('/solr/admin/info/logging', {'wt':'json', '_':Date.now()}, {
+ "events": {params: {since:'0'}},
+ "levels": {},
+ "setLevel": {}
+ });
+ }])
+.factory('Zookeeper',
+ ['$resource', function($resource) {
+ return $resource('/solr/zookeeper', {wt:'json', _:Date.now()}, {
+ "simple": {},
+ "dump": {params: {dump: "true"}},
+ "liveNodes": {params: {path: '/live_nodes'}},
+ "clusterState": {params: {detail: "true", path: "/clusterstate.json"}},
+ "detail": {params: {detail: "true", path: "@path"}}
+ });
+ }])
+.factory('Properties',
+ ['$resource', function($resource) {
+ return $resource('/solr/admin/info/properties', {'wt':'json', '_':Date.now()});
+ }])
+.factory('Threads',
+ ['$resource', function($resource) {
+ return $resource('/solr/admin/info/threads', {'wt':'json', '_':Date.now()});
+ }])
+.factory('Properties',
+ ['$resource', function($resource) {
+ return $resource('/solr/admin/info/properties', {'wt':'json', '_':Date.now()});
+ }])
+.factory('Replication',
+ ['$resource', function($resource) {
+ return $resource('/solr/:core/replication', {'wt':'json', core: "@core", 'command': 'details', '_':Date.now()}, {
+ "details": {params: {command: "details"}}
+ });
+ }])
+.factory('CoreSystem',
+ ['$resource', function($resource) {
+ return $resource('/solr/:core/admin/system', {wt:'json', core: "@core", _:Date.now()});
+ }])
+.factory('Update',
+ ['$resource', function($resource) {
+ return $resource('/solr/:core/update', {core: '@core', wt:'json', _:Date.now()}, {
+ "optimize": {params: { optimize: "true"}},
+ "commit": {params: {commit: "true"}}
+ });
+ }])
+.factory('Luke',
+ ['$resource', function($resource) {
+ return $resource('/solr/:core/admin/luke', {core: '@core', wt:'json', _:Date.now()}, {
+ "schema": {params: {show:'schema'}},
+ "index": {params: {show:'index', numTerms: 0}}
+ });
+ }])
+.factory('Analysis',
+ ['$resource', function($resource) {
+ return $resource('/solr/:core/analysis/field', {core: '@core', wt:'json', _:Date.now()}, {
+ "field": {params: {"analysis.showmatch": true}}
+ });
+ }])
+.factory('Ping',
+ ['$resource', function($resource) {
+ return $resource('/solr/:core/admin/ping', {wt:'json', core: '@core', ts:Date.now(), _:Date.now()}, {
+ "ping": {},
+ "status": {params:{action:"status"}}
+ });
+ }])
+.factory('Mbeans',
+ ['$resource', function($resource) {
+ return $resource('/solr/:core/admin/mbeans', {'wt':'json', 'stats': true, '_':Date.now()}); // @core
+ }])
+.factory('Files',
+ ['$resource', function($resource) {
+ return $resource('/solr/:core/admin/file', {'wt':'json', '_':Date.now()}); // @core
+ }])
+.factory('Query', // use $http for Query, as we need complete control over the URL
+ ['$http', '$location', function($http, $location) {
+ return {
+ "query": function(url, callback) {
+ $http({
+ url:url,
+ method: 'GET',
+ transformResponse: [ function(data, headersGetter){ return {data:data}}]
+ }).success(callback);
+ }
+ }}
+]);
+/*
+http://localhost:8983/solr/techproducts/admin/mbeans?cat=QUERYHANDLER&wt=json&_=1419614354276
+PING:
+http://localhost:8983/solr/techproducts/admin/ping?wt=json&ts=1419614393324&_=1419614393325
+*/
+
+
Added: lucene/dev/trunk/solr/webapp/web/libs/angular-chosen.js
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/webapp/web/libs/angular-chosen.js?rev=1661606&view=auto
==============================================================================
--- lucene/dev/trunk/solr/webapp/web/libs/angular-chosen.js (added)
+++ lucene/dev/trunk/solr/webapp/web/libs/angular-chosen.js Mon Feb 23 05:42:36 2015
@@ -0,0 +1,139 @@
+/*
+The MIT License
+
+Copyright (c) 2013 Localytics http://www.localytics.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+// Generated by CoffeeScript 1.8.0
+(function() {
+ var __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
+
+ angular.module('localytics.directives', []);
+
+ angular.module('localytics.directives').directive('chosen', [
+ '$timeout', function($timeout) {
+ var CHOSEN_OPTION_WHITELIST, NG_OPTIONS_REGEXP, isEmpty, snakeCase;
+ NG_OPTIONS_REGEXP = /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/;
+ CHOSEN_OPTION_WHITELIST = ['noResultsText', 'allowSingleDeselect', 'disableSearchThreshold', 'disableSearch', 'enableSplitWordSearch', 'inheritSelectClasses', 'maxSelectedOptions', 'placeholderTextMultiple', 'placeholderTextSingle', 'searchContains', 'singleBackstrokeDelete', 'displayDisabledOptions', 'displaySelectedOptions', 'width'];
+ snakeCase = function(input) {
+ return input.replace(/[A-Z]/g, function($1) {
+ return "_" + ($1.toLowerCase());
+ });
+ };
+ isEmpty = function(value) {
+ var key;
+ if (angular.isArray(value)) {
+ return value.length === 0;
+ } else if (angular.isObject(value)) {
+ for (key in value) {
+ if (value.hasOwnProperty(key)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ };
+ return {
+ restrict: 'A',
+ require: '?ngModel',
+ terminal: true,
+ link: function(scope, element, attr, ngModel) {
+ var chosen, defaultText, disableWithMessage, empty, initOrUpdate, match, options, origRender, removeEmptyMessage, startLoading, stopLoading, valuesExpr, viewWatch;
+ element.addClass('localytics-chosen');
+ options = scope.$eval(attr.chosen) || {};
+ angular.forEach(attr, function(value, key) {
+ if (__indexOf.call(CHOSEN_OPTION_WHITELIST, key) >= 0) {
+ return options[snakeCase(key)] = scope.$eval(value);
+ }
+ });
+ startLoading = function() {
+ return element.addClass('loading').attr('disabled', true).trigger('chosen:updated');
+ };
+ stopLoading = function() {
+ return element.removeClass('loading').attr('disabled', false).trigger('chosen:updated');
+ };
+ chosen = null;
+ defaultText = null;
+ empty = false;
+ initOrUpdate = function() {
+ if (chosen) {
+ return element.trigger('chosen:updated');
+ } else {
+ chosen = element.chosen(options).data('chosen');
+ return defaultText = chosen.default_text;
+ }
+ };
+ removeEmptyMessage = function() {
+ empty = false;
+ return element.attr('data-placeholder', defaultText);
+ };
+ disableWithMessage = function() {
+ empty = true;
+ return element.attr('data-placeholder', chosen.results_none_found).attr('disabled', true).trigger('chosen:updated');
+ };
+ if (ngModel) {
+ origRender = ngModel.$render;
+ ngModel.$render = function() {
+ origRender();
+ return initOrUpdate();
+ };
+ if (attr.multiple) {
+ viewWatch = function() {
+ return ngModel.$viewValue;
+ };
+ scope.$watch(viewWatch, ngModel.$render, true);
+ }
+ } else {
+ initOrUpdate();
+ }
+ attr.$observe('disabled', function() {
+ return element.trigger('chosen:updated');
+ });
+ if (attr.ngOptions && ngModel) {
+ match = attr.ngOptions.match(NG_OPTIONS_REGEXP);
+ valuesExpr = match[7];
+ scope.$watchCollection(valuesExpr, function(newVal, oldVal) {
+ var timer;
+ return timer = $timeout(function() {
+ if (angular.isUndefined(newVal)) {
+ return startLoading();
+ } else {
+ if (empty) {
+ removeEmptyMessage();
+ }
+ stopLoading();
+ if (isEmpty(newVal)) {
+ return disableWithMessage();
+ }
+ }
+ });
+ });
+ return scope.$on('$destroy', function(event) {
+ if (typeof timer !== "undefined" && timer !== null) {
+ return $timeout.cancel(timer);
+ }
+ });
+ }
+ }
+ };
+ }
+ ]);
+
+}).call(this);
Added: lucene/dev/trunk/solr/webapp/web/libs/angular-cookies.js
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/webapp/web/libs/angular-cookies.js?rev=1661606&view=auto
==============================================================================
--- lucene/dev/trunk/solr/webapp/web/libs/angular-cookies.js (added)
+++ lucene/dev/trunk/solr/webapp/web/libs/angular-cookies.js Mon Feb 23 05:42:36 2015
@@ -0,0 +1,229 @@
+/**
+The MIT License
+
+Copyright (c) 2010-2015 Google, Inc. http://angularjs.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+/**
+ * @license AngularJS v1.3.8
+ * (c) 2010-2014 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular, undefined) {'use strict';
+
+/**
+ * @ngdoc module
+ * @name ngCookies
+ * @description
+ *
+ * # ngCookies
+ *
+ * The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies.
+ *
+ *
+ * <div doc-module-components="ngCookies"></div>
+ *
+ * See {@link ngCookies.$cookies `$cookies`} and
+ * {@link ngCookies.$cookieStore `$cookieStore`} for usage.
+ */
+
+
+angular.module('ngCookies', ['ng']).
+ /**
+ * @ngdoc service
+ * @name $cookies
+ *
+ * @description
+ * Provides read/write access to browser's cookies.
+ *
+ * Only a simple Object is exposed and by adding or removing properties to/from this object, new
+ * cookies are created/deleted at the end of current $eval.
+ * The object's properties can only be strings.
+ *
+ * Requires the {@link ngCookies `ngCookies`} module to be installed.
+ *
+ * @example
+ *
+ * ```js
+ * angular.module('cookiesExample', ['ngCookies'])
+ * .controller('ExampleController', ['$cookies', function($cookies) {
+ * // Retrieving a cookie
+ * var favoriteCookie = $cookies.myFavorite;
+ * // Setting a cookie
+ * $cookies.myFavorite = 'oatmeal';
+ * }]);
+ * ```
+ */
+ factory('$cookies', ['$rootScope', '$browser', function($rootScope, $browser) {
+ var cookies = {},
+ lastCookies = {},
+ lastBrowserCookies,
+ runEval = false,
+ copy = angular.copy,
+ isUndefined = angular.isUndefined;
+
+ //creates a poller fn that copies all cookies from the $browser to service & inits the service
+ $browser.addPollFn(function() {
+ var currentCookies = $browser.cookies();
+ if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl
+ lastBrowserCookies = currentCookies;
+ copy(currentCookies, lastCookies);
+ copy(currentCookies, cookies);
+ if (runEval) $rootScope.$apply();
+ }
+ })();
+
+ runEval = true;
+
+ //at the end of each eval, push cookies
+ //TODO: this should happen before the "delayed" watches fire, because if some cookies are not
+ // strings or browser refuses to store some cookies, we update the model in the push fn.
+ $rootScope.$watch(push);
+
+ return cookies;
+
+
+ /**
+ * Pushes all the cookies from the service to the browser and verifies if all cookies were
+ * stored.
+ */
+ function push() {
+ var name,
+ value,
+ browserCookies,
+ updated;
+
+ //delete any cookies deleted in $cookies
+ for (name in lastCookies) {
+ if (isUndefined(cookies[name])) {
+ $browser.cookies(name, undefined);
+ }
+ }
+
+ //update all cookies updated in $cookies
+ for (name in cookies) {
+ value = cookies[name];
+ if (!angular.isString(value)) {
+ value = '' + value;
+ cookies[name] = value;
+ }
+ if (value !== lastCookies[name]) {
+ $browser.cookies(name, value);
+ updated = true;
+ }
+ }
+
+ //verify what was actually stored
+ if (updated) {
+ updated = false;
+ browserCookies = $browser.cookies();
+
+ for (name in cookies) {
+ if (cookies[name] !== browserCookies[name]) {
+ //delete or reset all cookies that the browser dropped from $cookies
+ if (isUndefined(browserCookies[name])) {
+ delete cookies[name];
+ } else {
+ cookies[name] = browserCookies[name];
+ }
+ updated = true;
+ }
+ }
+ }
+ }
+ }]).
+
+
+ /**
+ * @ngdoc service
+ * @name $cookieStore
+ * @requires $cookies
+ *
+ * @description
+ * Provides a key-value (string-object) storage, that is backed by session cookies.
+ * Objects put or retrieved from this storage are automatically serialized or
+ * deserialized by angular's toJson/fromJson.
+ *
+ * Requires the {@link ngCookies `ngCookies`} module to be installed.
+ *
+ * @example
+ *
+ * ```js
+ * angular.module('cookieStoreExample', ['ngCookies'])
+ * .controller('ExampleController', ['$cookieStore', function($cookieStore) {
+ * // Put cookie
+ * $cookieStore.put('myFavorite','oatmeal');
+ * // Get cookie
+ * var favoriteCookie = $cookieStore.get('myFavorite');
+ * // Removing a cookie
+ * $cookieStore.remove('myFavorite');
+ * }]);
+ * ```
+ */
+ factory('$cookieStore', ['$cookies', function($cookies) {
+
+ return {
+ /**
+ * @ngdoc method
+ * @name $cookieStore#get
+ *
+ * @description
+ * Returns the value of given cookie key
+ *
+ * @param {string} key Id to use for lookup.
+ * @returns {Object} Deserialized cookie value.
+ */
+ get: function(key) {
+ var value = $cookies[key];
+ return value ? angular.fromJson(value) : value;
+ },
+
+ /**
+ * @ngdoc method
+ * @name $cookieStore#put
+ *
+ * @description
+ * Sets a value for given cookie key
+ *
+ * @param {string} key Id for the `value`.
+ * @param {Object} value Value to be stored.
+ */
+ put: function(key, value) {
+ $cookies[key] = angular.toJson(value);
+ },
+
+ /**
+ * @ngdoc method
+ * @name $cookieStore#remove
+ *
+ * @description
+ * Remove given cookie
+ *
+ * @param {string} key Id of the key-value pair to delete.
+ */
+ remove: function(key) {
+ delete $cookies[key];
+ }
+ };
+
+ }]);
+
+
+})(window, window.angular);
Added: lucene/dev/trunk/solr/webapp/web/libs/angular-cookies.min.js
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/webapp/web/libs/angular-cookies.min.js?rev=1661606&view=auto
==============================================================================
--- lucene/dev/trunk/solr/webapp/web/libs/angular-cookies.min.js (added)
+++ lucene/dev/trunk/solr/webapp/web/libs/angular-cookies.min.js Mon Feb 23 05:42:36 2015
@@ -0,0 +1,31 @@
+/**
+The MIT License
+
+Copyright (c) 2010-2015 Google, Inc. http://angularjs.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+/*
+ AngularJS v1.3.8
+ (c) 2010-2014 Google, Inc. http://angularjs.org
+ License: MIT
+*/
+(function(p,f,n){'use strict';f.module("ngCookies",["ng"]).factory("$cookies",["$rootScope","$browser",function(e,b){var c={},g={},h,k=!1,l=f.copy,m=f.isUndefined;b.addPollFn(function(){var a=b.cookies();h!=a&&(h=a,l(a,g),l(a,c),k&&e.$apply())})();k=!0;e.$watch(function(){var a,d,e;for(a in g)m(c[a])&&b.cookies(a,n);for(a in c)d=c[a],f.isString(d)||(d=""+d,c[a]=d),d!==g[a]&&(b.cookies(a,d),e=!0);if(e)for(a in d=b.cookies(),c)c[a]!==d[a]&&(m(d[a])?delete c[a]:c[a]=d[a])});return c}]).factory("$cookieStore",
+["$cookies",function(e){return{get:function(b){return(b=e[b])?f.fromJson(b):b},put:function(b,c){e[b]=f.toJson(c)},remove:function(b){delete e[b]}}}])})(window,window.angular);
+//# sourceMappingURL=angular-cookies.min.js.map
Added: lucene/dev/trunk/solr/webapp/web/libs/angular-resource.min.js
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/webapp/web/libs/angular-resource.min.js?rev=1661606&view=auto
==============================================================================
--- lucene/dev/trunk/solr/webapp/web/libs/angular-resource.min.js (added)
+++ lucene/dev/trunk/solr/webapp/web/libs/angular-resource.min.js Mon Feb 23 05:42:36 2015
@@ -0,0 +1,36 @@
+/**
+The MIT License
+
+Copyright (c) 2010-2015 Google, Inc. http://angularjs.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+/*
+ AngularJS v1.2.28
+ (c) 2010-2014 Google, Inc. http://angularjs.org
+ License: MIT
+*/
+(function(H,a,A){'use strict';function D(p,g){g=g||{};a.forEach(g,function(a,c){delete g[c]});for(var c in p)!p.hasOwnProperty(c)||"$"===c.charAt(0)&&"$"===c.charAt(1)||(g[c]=p[c]);return g}var v=a.$$minErr("$resource"),C=/^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;a.module("ngResource",["ng"]).factory("$resource",["$http","$q",function(p,g){function c(a,c){this.template=a;this.defaults=c||{};this.urlParams={}}function t(n,w,l){function r(h,d){var e={};d=x({},w,d);s(d,function(b,d){u(b)&&(b=b());var k;if(b&&
+b.charAt&&"@"==b.charAt(0)){k=h;var a=b.substr(1);if(null==a||""===a||"hasOwnProperty"===a||!C.test("."+a))throw v("badmember",a);for(var a=a.split("."),f=0,c=a.length;f<c&&k!==A;f++){var g=a[f];k=null!==k?k[g]:A}}else k=b;e[d]=k});return e}function e(a){return a.resource}function f(a){D(a||{},this)}var F=new c(n);l=x({},B,l);s(l,function(h,d){var c=/^(POST|PUT|PATCH)$/i.test(h.method);f[d]=function(b,d,k,w){var q={},n,l,y;switch(arguments.length){case 4:y=w,l=k;case 3:case 2:if(u(d)){if(u(b)){l=
+b;y=d;break}l=d;y=k}else{q=b;n=d;l=k;break}case 1:u(b)?l=b:c?n=b:q=b;break;case 0:break;default:throw v("badargs",arguments.length);}var t=this instanceof f,m=t?n:h.isArray?[]:new f(n),z={},B=h.interceptor&&h.interceptor.response||e,C=h.interceptor&&h.interceptor.responseError||A;s(h,function(a,b){"params"!=b&&("isArray"!=b&&"interceptor"!=b)&&(z[b]=G(a))});c&&(z.data=n);F.setUrlParams(z,x({},r(n,h.params||{}),q),h.url);q=p(z).then(function(b){var d=b.data,k=m.$promise;if(d){if(a.isArray(d)!==!!h.isArray)throw v("badcfg",
+h.isArray?"array":"object",a.isArray(d)?"array":"object");h.isArray?(m.length=0,s(d,function(b){"object"===typeof b?m.push(new f(b)):m.push(b)})):(D(d,m),m.$promise=k)}m.$resolved=!0;b.resource=m;return b},function(b){m.$resolved=!0;(y||E)(b);return g.reject(b)});q=q.then(function(b){var a=B(b);(l||E)(a,b.headers);return a},C);return t?q:(m.$promise=q,m.$resolved=!1,m)};f.prototype["$"+d]=function(b,a,k){u(b)&&(k=a,a=b,b={});b=f[d].call(this,b,this,a,k);return b.$promise||b}});f.bind=function(a){return t(n,
+x({},w,a),l)};return f}var B={get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}},E=a.noop,s=a.forEach,x=a.extend,G=a.copy,u=a.isFunction;c.prototype={setUrlParams:function(c,g,l){var r=this,e=l||r.template,f,p,h=r.urlParams={};s(e.split(/\W/),function(a){if("hasOwnProperty"===a)throw v("badname");!/^\d+$/.test(a)&&(a&&RegExp("(^|[^\\\\]):"+a+"(\\W|$)").test(e))&&(h[a]=!0)});e=e.replace(/\\:/g,":");g=g||{};s(r.urlParams,function(d,
+c){f=g.hasOwnProperty(c)?g[c]:r.defaults[c];a.isDefined(f)&&null!==f?(p=encodeURIComponent(f).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"%20").replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+"),e=e.replace(RegExp(":"+c+"(\\W|$)","g"),function(a,c){return p+c})):e=e.replace(RegExp("(/?):"+c+"(\\W|$)","g"),function(a,c,d){return"/"==d.charAt(0)?d:c+d})});e=e.replace(/\/+$/,"")||"/";e=e.replace(/\/\.(?=\w+($|\?))/,".");c.url=e.replace(/\/\\\./,
+"/.");s(g,function(a,e){r.urlParams[e]||(c.params=c.params||{},c.params[e]=a)})}};return t}])})(window,window.angular);
+//# sourceMappingURL=angular-resource.min.js.map
Added: lucene/dev/trunk/solr/webapp/web/libs/angular-route.js
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/webapp/web/libs/angular-route.js?rev=1661606&view=auto
==============================================================================
--- lucene/dev/trunk/solr/webapp/web/libs/angular-route.js (added)
+++ lucene/dev/trunk/solr/webapp/web/libs/angular-route.js Mon Feb 23 05:42:36 2015
@@ -0,0 +1,1018 @@
+/**
+The MIT License
+
+Copyright (c) 2010-2015 Google, Inc. http://angularjs.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+/**
+ * @license AngularJS v1.3.8
+ * (c) 2010-2014 Google, Inc. http://angularjs.org
+ * License: MIT
+ */
+(function(window, angular, undefined) {'use strict';
+
+/**
+ * @ngdoc module
+ * @name ngRoute
+ * @description
+ *
+ * # ngRoute
+ *
+ * The `ngRoute` module provides routing and deeplinking services and directives for angular apps.
+ *
+ * ## Example
+ * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`.
+ *
+ *
+ * <div doc-module-components="ngRoute"></div>
+ */
+ /* global -ngRouteModule */
+var ngRouteModule = angular.module('ngRoute', ['ng']).
+ provider('$route', $RouteProvider),
+ $routeMinErr = angular.$$minErr('ngRoute');
+
+/**
+ * @ngdoc provider
+ * @name $routeProvider
+ *
+ * @description
+ *
+ * Used for configuring routes.
+ *
+ * ## Example
+ * See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`.
+ *
+ * ## Dependencies
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
+ */
+function $RouteProvider() {
+ function inherit(parent, extra) {
+ return angular.extend(Object.create(parent), extra);
+ }
+
+ var routes = {};
+
+ /**
+ * @ngdoc method
+ * @name $routeProvider#when
+ *
+ * @param {string} path Route path (matched against `$location.path`). If `$location.path`
+ * contains redundant trailing slash or is missing one, the route will still match and the
+ * `$location.path` will be updated to add or drop the trailing slash to exactly match the
+ * route definition.
+ *
+ * * `path` can contain named groups starting with a colon: e.g. `:name`. All characters up
+ * to the next slash are matched and stored in `$routeParams` under the given `name`
+ * when the route matches.
+ * * `path` can contain named groups starting with a colon and ending with a star:
+ * e.g.`:name*`. All characters are eagerly stored in `$routeParams` under the given `name`
+ * when the route matches.
+ * * `path` can contain optional named groups with a question mark: e.g.`:name?`.
+ *
+ * For example, routes like `/color/:color/largecode/:largecode*\/edit` will match
+ * `/color/brown/largecode/code/with/slashes/edit` and extract:
+ *
+ * * `color: brown`
+ * * `largecode: code/with/slashes`.
+ *
+ *
+ * @param {Object} route Mapping information to be assigned to `$route.current` on route
+ * match.
+ *
+ * Object properties:
+ *
+ * - `controller` â `{(string|function()=}` â Controller fn that should be associated with
+ * newly created scope or the name of a {@link angular.Module#controller registered
+ * controller} if passed as a string.
+ * - `controllerAs` â `{string=}` â A controller alias name. If present the controller will be
+ * published to scope under the `controllerAs` name.
+ * - `template` â `{string=|function()=}` â html template as a string or a function that
+ * returns an html template as a string which should be used by {@link
+ * ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives.
+ * This property takes precedence over `templateUrl`.
+ *
+ * If `template` is a function, it will be called with the following parameters:
+ *
+ * - `{Array.<Object>}` - route parameters extracted from the current
+ * `$location.path()` by applying the current route
+ *
+ * - `templateUrl` â `{string=|function()=}` â path or function that returns a path to an html
+ * template that should be used by {@link ngRoute.directive:ngView ngView}.
+ *
+ * If `templateUrl` is a function, it will be called with the following parameters:
+ *
+ * - `{Array.<Object>}` - route parameters extracted from the current
+ * `$location.path()` by applying the current route
+ *
+ * - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
+ * be injected into the controller. If any of these dependencies are promises, the router
+ * will wait for them all to be resolved or one to be rejected before the controller is
+ * instantiated.
+ * If all the promises are resolved successfully, the values of the resolved promises are
+ * injected and {@link ngRoute.$route#$routeChangeSuccess $routeChangeSuccess} event is
+ * fired. If any of the promises are rejected the
+ * {@link ngRoute.$route#$routeChangeError $routeChangeError} event is fired. The map object
+ * is:
+ *
+ * - `key` â `{string}`: a name of a dependency to be injected into the controller.
+ * - `factory` - `{string|function}`: If `string` then it is an alias for a service.
+ * Otherwise if function, then it is {@link auto.$injector#invoke injected}
+ * and the return value is treated as the dependency. If the result is a promise, it is
+ * resolved before its value is injected into the controller. Be aware that
+ * `ngRoute.$routeParams` will still refer to the previous route within these resolve
+ * functions. Use `$route.current.params` to access the new route parameters, instead.
+ *
+ * - `redirectTo` â {(string|function())=} â value to update
+ * {@link ng.$location $location} path with and trigger route redirection.
+ *
+ * If `redirectTo` is a function, it will be called with the following parameters:
+ *
+ * - `{Object.<string>}` - route parameters extracted from the current
+ * `$location.path()` by applying the current route templateUrl.
+ * - `{string}` - current `$location.path()`
+ * - `{Object}` - current `$location.search()`
+ *
+ * The custom `redirectTo` function is expected to return a string which will be used
+ * to update `$location.path()` and `$location.search()`.
+ *
+ * - `[reloadOnSearch=true]` - {boolean=} - reload route when only `$location.search()`
+ * or `$location.hash()` changes.
+ *
+ * If the option is set to `false` and url in the browser changes, then
+ * `$routeUpdate` event is broadcasted on the root scope.
+ *
+ * - `[caseInsensitiveMatch=false]` - {boolean=} - match routes without being case sensitive
+ *
+ * If the option is set to `true`, then the particular route can be matched without being
+ * case sensitive
+ *
+ * @returns {Object} self
+ *
+ * @description
+ * Adds a new route definition to the `$route` service.
+ */
+ this.when = function(path, route) {
+ //copy original route object to preserve params inherited from proto chain
+ var routeCopy = angular.copy(route);
+ if (angular.isUndefined(routeCopy.reloadOnSearch)) {
+ routeCopy.reloadOnSearch = true;
+ }
+ if (angular.isUndefined(routeCopy.caseInsensitiveMatch)) {
+ routeCopy.caseInsensitiveMatch = this.caseInsensitiveMatch;
+ }
+ routes[path] = angular.extend(
+ routeCopy,
+ path && pathRegExp(path, routeCopy)
+ );
+
+ // create redirection for trailing slashes
+ if (path) {
+ var redirectPath = (path[path.length - 1] == '/')
+ ? path.substr(0, path.length - 1)
+ : path + '/';
+
+ routes[redirectPath] = angular.extend(
+ {redirectTo: path},
+ pathRegExp(redirectPath, routeCopy)
+ );
+ }
+
+ return this;
+ };
+
+ /**
+ * @ngdoc property
+ * @name $routeProvider#caseInsensitiveMatch
+ * @description
+ *
+ * A boolean property indicating if routes defined
+ * using this provider should be matched using a case insensitive
+ * algorithm. Defaults to `false`.
+ */
+ this.caseInsensitiveMatch = false;
+
+ /**
+ * @param path {string} path
+ * @param opts {Object} options
+ * @return {?Object}
+ *
+ * @description
+ * Normalizes the given path, returning a regular expression
+ * and the original path.
+ *
+ * Inspired by pathRexp in visionmedia/express/lib/utils.js.
+ */
+ function pathRegExp(path, opts) {
+ var insensitive = opts.caseInsensitiveMatch,
+ ret = {
+ originalPath: path,
+ regexp: path
+ },
+ keys = ret.keys = [];
+
+ path = path
+ .replace(/([().])/g, '\\$1')
+ .replace(/(\/)?:(\w+)([\?\*])?/g, function(_, slash, key, option) {
+ var optional = option === '?' ? option : null;
+ var star = option === '*' ? option : null;
+ keys.push({ name: key, optional: !!optional });
+ slash = slash || '';
+ return ''
+ + (optional ? '' : slash)
+ + '(?:'
+ + (optional ? slash : '')
+ + (star && '(.+?)' || '([^/]+)')
+ + (optional || '')
+ + ')'
+ + (optional || '');
+ })
+ .replace(/([\/$\*])/g, '\\$1');
+
+ ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : '');
+ return ret;
+ }
+
+ /**
+ * @ngdoc method
+ * @name $routeProvider#otherwise
+ *
+ * @description
+ * Sets route definition that will be used on route change when no other route definition
+ * is matched.
+ *
+ * @param {Object|string} params Mapping information to be assigned to `$route.current`.
+ * If called with a string, the value maps to `redirectTo`.
+ * @returns {Object} self
+ */
+ this.otherwise = function(params) {
+ if (typeof params === 'string') {
+ params = {redirectTo: params};
+ }
+ this.when(null, params);
+ return this;
+ };
+
+
+ this.$get = ['$rootScope',
+ '$location',
+ '$routeParams',
+ '$q',
+ '$injector',
+ '$templateRequest',
+ '$sce',
+ function($rootScope, $location, $routeParams, $q, $injector, $templateRequest, $sce) {
+
+ /**
+ * @ngdoc service
+ * @name $route
+ * @requires $location
+ * @requires $routeParams
+ *
+ * @property {Object} current Reference to the current route definition.
+ * The route definition contains:
+ *
+ * - `controller`: The controller constructor as define in route definition.
+ * - `locals`: A map of locals which is used by {@link ng.$controller $controller} service for
+ * controller instantiation. The `locals` contain
+ * the resolved values of the `resolve` map. Additionally the `locals` also contain:
+ *
+ * - `$scope` - The current route scope.
+ * - `$template` - The current route template HTML.
+ *
+ * @property {Object} routes Object with all route configuration Objects as its properties.
+ *
+ * @description
+ * `$route` is used for deep-linking URLs to controllers and views (HTML partials).
+ * It watches `$location.url()` and tries to map the path to an existing route definition.
+ *
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
+ *
+ * You can define routes through {@link ngRoute.$routeProvider $routeProvider}'s API.
+ *
+ * The `$route` service is typically used in conjunction with the
+ * {@link ngRoute.directive:ngView `ngView`} directive and the
+ * {@link ngRoute.$routeParams `$routeParams`} service.
+ *
+ * @example
+ * This example shows how changing the URL hash causes the `$route` to match a route against the
+ * URL, and the `ngView` pulls in the partial.
+ *
+ * <example name="$route-service" module="ngRouteExample"
+ * deps="angular-route.js" fixBase="true">
+ * <file name="index.html">
+ * <div ng-controller="MainController">
+ * Choose:
+ * <a href="Book/Moby">Moby</a> |
+ * <a href="Book/Moby/ch/1">Moby: Ch1</a> |
+ * <a href="Book/Gatsby">Gatsby</a> |
+ * <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
+ * <a href="Book/Scarlet">Scarlet Letter</a><br/>
+ *
+ * <div ng-view></div>
+ *
+ * <hr />
+ *
+ * <pre>$location.path() = {{$location.path()}}</pre>
+ * <pre>$route.current.templateUrl = {{$route.current.templateUrl}}</pre>
+ * <pre>$route.current.params = {{$route.current.params}}</pre>
+ * <pre>$route.current.scope.name = {{$route.current.scope.name}}</pre>
+ * <pre>$routeParams = {{$routeParams}}</pre>
+ * </div>
+ * </file>
+ *
+ * <file name="book.html">
+ * controller: {{name}}<br />
+ * Book Id: {{params.bookId}}<br />
+ * </file>
+ *
+ * <file name="chapter.html">
+ * controller: {{name}}<br />
+ * Book Id: {{params.bookId}}<br />
+ * Chapter Id: {{params.chapterId}}
+ * </file>
+ *
+ * <file name="script.js">
+ * angular.module('ngRouteExample', ['ngRoute'])
+ *
+ * .controller('MainController', function($scope, $route, $routeParams, $location) {
+ * $scope.$route = $route;
+ * $scope.$location = $location;
+ * $scope.$routeParams = $routeParams;
+ * })
+ *
+ * .controller('BookController', function($scope, $routeParams) {
+ * $scope.name = "BookController";
+ * $scope.params = $routeParams;
+ * })
+ *
+ * .controller('ChapterController', function($scope, $routeParams) {
+ * $scope.name = "ChapterController";
+ * $scope.params = $routeParams;
+ * })
+ *
+ * .config(function($routeProvider, $locationProvider) {
+ * $routeProvider
+ * .when('/Book/:bookId', {
+ * templateUrl: 'book.html',
+ * controller: 'BookController',
+ * resolve: {
+ * // I will cause a 1 second delay
+ * delay: function($q, $timeout) {
+ * var delay = $q.defer();
+ * $timeout(delay.resolve, 1000);
+ * return delay.promise;
+ * }
+ * }
+ * })
+ * .when('/Book/:bookId/ch/:chapterId', {
+ * templateUrl: 'chapter.html',
+ * controller: 'ChapterController'
+ * });
+ *
+ * // configure html5 to get links working on jsfiddle
+ * $locationProvider.html5Mode(true);
+ * });
+ *
+ * </file>
+ *
+ * <file name="protractor.js" type="protractor">
+ * it('should load and compile correct template', function() {
+ * element(by.linkText('Moby: Ch1')).click();
+ * var content = element(by.css('[ng-view]')).getText();
+ * expect(content).toMatch(/controller\: ChapterController/);
+ * expect(content).toMatch(/Book Id\: Moby/);
+ * expect(content).toMatch(/Chapter Id\: 1/);
+ *
+ * element(by.partialLinkText('Scarlet')).click();
+ *
+ * content = element(by.css('[ng-view]')).getText();
+ * expect(content).toMatch(/controller\: BookController/);
+ * expect(content).toMatch(/Book Id\: Scarlet/);
+ * });
+ * </file>
+ * </example>
+ */
+
+ /**
+ * @ngdoc event
+ * @name $route#$routeChangeStart
+ * @eventType broadcast on root scope
+ * @description
+ * Broadcasted before a route change. At this point the route services starts
+ * resolving all of the dependencies needed for the route change to occur.
+ * Typically this involves fetching the view template as well as any dependencies
+ * defined in `resolve` route property. Once all of the dependencies are resolved
+ * `$routeChangeSuccess` is fired.
+ *
+ * The route change (and the `$location` change that triggered it) can be prevented
+ * by calling `preventDefault` method of the event. See {@link ng.$rootScope.Scope#$on}
+ * for more details about event object.
+ *
+ * @param {Object} angularEvent Synthetic event object.
+ * @param {Route} next Future route information.
+ * @param {Route} current Current route information.
+ */
+
+ /**
+ * @ngdoc event
+ * @name $route#$routeChangeSuccess
+ * @eventType broadcast on root scope
+ * @description
+ * Broadcasted after a route dependencies are resolved.
+ * {@link ngRoute.directive:ngView ngView} listens for the directive
+ * to instantiate the controller and render the view.
+ *
+ * @param {Object} angularEvent Synthetic event object.
+ * @param {Route} current Current route information.
+ * @param {Route|Undefined} previous Previous route information, or undefined if current is
+ * first route entered.
+ */
+
+ /**
+ * @ngdoc event
+ * @name $route#$routeChangeError
+ * @eventType broadcast on root scope
+ * @description
+ * Broadcasted if any of the resolve promises are rejected.
+ *
+ * @param {Object} angularEvent Synthetic event object
+ * @param {Route} current Current route information.
+ * @param {Route} previous Previous route information.
+ * @param {Route} rejection Rejection of the promise. Usually the error of the failed promise.
+ */
+
+ /**
+ * @ngdoc event
+ * @name $route#$routeUpdate
+ * @eventType broadcast on root scope
+ * @description
+ *
+ * The `reloadOnSearch` property has been set to false, and we are reusing the same
+ * instance of the Controller.
+ */
+
+ var forceReload = false,
+ preparedRoute,
+ preparedRouteIsUpdateOnly,
+ $route = {
+ routes: routes,
+
+ /**
+ * @ngdoc method
+ * @name $route#reload
+ *
+ * @description
+ * Causes `$route` service to reload the current route even if
+ * {@link ng.$location $location} hasn't changed.
+ *
+ * As a result of that, {@link ngRoute.directive:ngView ngView}
+ * creates new scope and reinstantiates the controller.
+ */
+ reload: function() {
+ forceReload = true;
+ $rootScope.$evalAsync(function() {
+ // Don't support cancellation of a reload for now...
+ prepareRoute();
+ commitRoute();
+ });
+ },
+
+ /**
+ * @ngdoc method
+ * @name $route#updateParams
+ *
+ * @description
+ * Causes `$route` service to update the current URL, replacing
+ * current route parameters with those specified in `newParams`.
+ * Provided property names that match the route's path segment
+ * definitions will be interpolated into the location's path, while
+ * remaining properties will be treated as query params.
+ *
+ * @param {Object} newParams mapping of URL parameter names to values
+ */
+ updateParams: function(newParams) {
+ if (this.current && this.current.$$route) {
+ var searchParams = {}, self=this;
+
+ angular.forEach(Object.keys(newParams), function(key) {
+ if (!self.current.pathParams[key]) searchParams[key] = newParams[key];
+ });
+
+ newParams = angular.extend({}, this.current.params, newParams);
+ $location.path(interpolate(this.current.$$route.originalPath, newParams));
+ $location.search(angular.extend({}, $location.search(), searchParams));
+ }
+ else {
+ throw $routeMinErr('norout', 'Tried updating route when with no current route');
+ }
+ }
+ };
+
+ $rootScope.$on('$locationChangeStart', prepareRoute);
+ $rootScope.$on('$locationChangeSuccess', commitRoute);
+
+ return $route;
+
+ /////////////////////////////////////////////////////
+
+ /**
+ * @param on {string} current url
+ * @param route {Object} route regexp to match the url against
+ * @return {?Object}
+ *
+ * @description
+ * Check if the route matches the current url.
+ *
+ * Inspired by match in
+ * visionmedia/express/lib/router/router.js.
+ */
+ function switchRouteMatcher(on, route) {
+ var keys = route.keys,
+ params = {};
+
+ if (!route.regexp) return null;
+
+ var m = route.regexp.exec(on);
+ if (!m) return null;
+
+ for (var i = 1, len = m.length; i < len; ++i) {
+ var key = keys[i - 1];
+
+ var val = m[i];
+
+ if (key && val) {
+ params[key.name] = val;
+ }
+ }
+ return params;
+ }
+
+ function prepareRoute($locationEvent) {
+ var lastRoute = $route.current;
+
+ preparedRoute = parseRoute();
+ preparedRouteIsUpdateOnly = preparedRoute && lastRoute && preparedRoute.$$route === lastRoute.$$route
+ && angular.equals(preparedRoute.pathParams, lastRoute.pathParams)
+ && !preparedRoute.reloadOnSearch && !forceReload;
+
+ if (!preparedRouteIsUpdateOnly && (lastRoute || preparedRoute)) {
+ if ($rootScope.$broadcast('$routeChangeStart', preparedRoute, lastRoute).defaultPrevented) {
+ if ($locationEvent) {
+ $locationEvent.preventDefault();
+ }
+ }
+ }
+ }
+
+ function commitRoute() {
+ var lastRoute = $route.current;
+ var nextRoute = preparedRoute;
+
+ if (preparedRouteIsUpdateOnly) {
+ lastRoute.params = nextRoute.params;
+ angular.copy(lastRoute.params, $routeParams);
+ $rootScope.$broadcast('$routeUpdate', lastRoute);
+ } else if (nextRoute || lastRoute) {
+ forceReload = false;
+ $route.current = nextRoute;
+ if (nextRoute) {
+ if (nextRoute.redirectTo) {
+ if (angular.isString(nextRoute.redirectTo)) {
+ $location.path(interpolate(nextRoute.redirectTo, nextRoute.params)).search(nextRoute.params)
+ .replace();
+ } else {
+ $location.url(nextRoute.redirectTo(nextRoute.pathParams, $location.path(), $location.search()))
+ .replace();
+ }
+ }
+ }
+
+ $q.when(nextRoute).
+ then(function() {
+ if (nextRoute) {
+ var locals = angular.extend({}, nextRoute.resolve),
+ template, templateUrl;
+
+ angular.forEach(locals, function(value, key) {
+ locals[key] = angular.isString(value) ?
+ $injector.get(value) : $injector.invoke(value, null, null, key);
+ });
+
+ if (angular.isDefined(template = nextRoute.template)) {
+ if (angular.isFunction(template)) {
+ template = template(nextRoute.params);
+ }
+ } else if (angular.isDefined(templateUrl = nextRoute.templateUrl)) {
+ if (angular.isFunction(templateUrl)) {
+ templateUrl = templateUrl(nextRoute.params);
+ }
+ templateUrl = $sce.getTrustedResourceUrl(templateUrl);
+ if (angular.isDefined(templateUrl)) {
+ nextRoute.loadedTemplateUrl = templateUrl;
+ template = $templateRequest(templateUrl);
+ }
+ }
+ if (angular.isDefined(template)) {
+ locals['$template'] = template;
+ }
+ return $q.all(locals);
+ }
+ }).
+ // after route change
+ then(function(locals) {
+ if (nextRoute == $route.current) {
+ if (nextRoute) {
+ nextRoute.locals = locals;
+ angular.copy(nextRoute.params, $routeParams);
+ }
+ $rootScope.$broadcast('$routeChangeSuccess', nextRoute, lastRoute);
+ }
+ }, function(error) {
+ if (nextRoute == $route.current) {
+ $rootScope.$broadcast('$routeChangeError', nextRoute, lastRoute, error);
+ }
+ });
+ }
+ }
+
+
+ /**
+ * @returns {Object} the current active route, by matching it against the URL
+ */
+ function parseRoute() {
+ // Match a route
+ var params, match;
+ angular.forEach(routes, function(route, path) {
+ if (!match && (params = switchRouteMatcher($location.path(), route))) {
+ match = inherit(route, {
+ params: angular.extend({}, $location.search(), params),
+ pathParams: params});
+ match.$$route = route;
+ }
+ });
+ // No route matched; fallback to "otherwise" route
+ return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}});
+ }
+
+ /**
+ * @returns {string} interpolation of the redirect path with the parameters
+ */
+ function interpolate(string, params) {
+ var result = [];
+ angular.forEach((string || '').split(':'), function(segment, i) {
+ if (i === 0) {
+ result.push(segment);
+ } else {
+ var segmentMatch = segment.match(/(\w+)(?:[?*])?(.*)/);
+ var key = segmentMatch[1];
+ result.push(params[key]);
+ result.push(segmentMatch[2] || '');
+ delete params[key];
+ }
+ });
+ return result.join('');
+ }
+ }];
+}
+
+ngRouteModule.provider('$routeParams', $RouteParamsProvider);
+
+
+/**
+ * @ngdoc service
+ * @name $routeParams
+ * @requires $route
+ *
+ * @description
+ * The `$routeParams` service allows you to retrieve the current set of route parameters.
+ *
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
+ *
+ * The route parameters are a combination of {@link ng.$location `$location`}'s
+ * {@link ng.$location#search `search()`} and {@link ng.$location#path `path()`}.
+ * The `path` parameters are extracted when the {@link ngRoute.$route `$route`} path is matched.
+ *
+ * In case of parameter name collision, `path` params take precedence over `search` params.
+ *
+ * The service guarantees that the identity of the `$routeParams` object will remain unchanged
+ * (but its properties will likely change) even when a route change occurs.
+ *
+ * Note that the `$routeParams` are only updated *after* a route change completes successfully.
+ * This means that you cannot rely on `$routeParams` being correct in route resolve functions.
+ * Instead you can use `$route.current.params` to access the new route's parameters.
+ *
+ * @example
+ * ```js
+ * // Given:
+ * // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
+ * // Route: /Chapter/:chapterId/Section/:sectionId
+ * //
+ * // Then
+ * $routeParams ==> {chapterId:'1', sectionId:'2', search:'moby'}
+ * ```
+ */
+function $RouteParamsProvider() {
+ this.$get = function() { return {}; };
+}
+
+ngRouteModule.directive('ngView', ngViewFactory);
+ngRouteModule.directive('ngView', ngViewFillContentFactory);
+
+
+/**
+ * @ngdoc directive
+ * @name ngView
+ * @restrict ECA
+ *
+ * @description
+ * # Overview
+ * `ngView` is a directive that complements the {@link ngRoute.$route $route} service by
+ * including the rendered template of the current route into the main layout (`index.html`) file.
+ * Every time the current route changes, the included view changes with it according to the
+ * configuration of the `$route` service.
+ *
+ * Requires the {@link ngRoute `ngRoute`} module to be installed.
+ *
+ * @animations
+ * enter - animation is used to bring new content into the browser.
+ * leave - animation is used to animate existing content away.
+ *
+ * The enter and leave animation occur concurrently.
+ *
+ * @scope
+ * @priority 400
+ * @param {string=} onload Expression to evaluate whenever the view updates.
+ *
+ * @param {string=} autoscroll Whether `ngView` should call {@link ng.$anchorScroll
+ * $anchorScroll} to scroll the viewport after the view is updated.
+ *
+ * - If the attribute is not set, disable scrolling.
+ * - If the attribute is set without value, enable scrolling.
+ * - Otherwise enable scrolling only if the `autoscroll` attribute value evaluated
+ * as an expression yields a truthy value.
+ * @example
+ <example name="ngView-directive" module="ngViewExample"
+ deps="angular-route.js;angular-animate.js"
+ animations="true" fixBase="true">
+ <file name="index.html">
+ <div ng-controller="MainCtrl as main">
+ Choose:
+ <a href="Book/Moby">Moby</a> |
+ <a href="Book/Moby/ch/1">Moby: Ch1</a> |
+ <a href="Book/Gatsby">Gatsby</a> |
+ <a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
+ <a href="Book/Scarlet">Scarlet Letter</a><br/>
+
+ <div class="view-animate-container">
+ <div ng-view class="view-animate"></div>
+ </div>
+ <hr />
+
+ <pre>$location.path() = {{main.$location.path()}}</pre>
+ <pre>$route.current.templateUrl = {{main.$route.current.templateUrl}}</pre>
+ <pre>$route.current.params = {{main.$route.current.params}}</pre>
+ <pre>$routeParams = {{main.$routeParams}}</pre>
+ </div>
+ </file>
+
+ <file name="book.html">
+ <div>
+ controller: {{book.name}}<br />
+ Book Id: {{book.params.bookId}}<br />
+ </div>
+ </file>
+
+ <file name="chapter.html">
+ <div>
+ controller: {{chapter.name}}<br />
+ Book Id: {{chapter.params.bookId}}<br />
+ Chapter Id: {{chapter.params.chapterId}}
+ </div>
+ </file>
+
+ <file name="animations.css">
+ .view-animate-container {
+ position:relative;
+ height:100px!important;
+ background:white;
+ border:1px solid black;
+ height:40px;
+ overflow:hidden;
+ }
+
+ .view-animate {
+ padding:10px;
+ }
+
+ .view-animate.ng-enter, .view-animate.ng-leave {
+ -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
+ transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
+
+ display:block;
+ width:100%;
+ border-left:1px solid black;
+
+ position:absolute;
+ top:0;
+ left:0;
+ right:0;
+ bottom:0;
+ padding:10px;
+ }
+
+ .view-animate.ng-enter {
+ left:100%;
+ }
+ .view-animate.ng-enter.ng-enter-active {
+ left:0;
+ }
+ .view-animate.ng-leave.ng-leave-active {
+ left:-100%;
+ }
+ </file>
+
+ <file name="script.js">
+ angular.module('ngViewExample', ['ngRoute', 'ngAnimate'])
+ .config(['$routeProvider', '$locationProvider',
+ function($routeProvider, $locationProvider) {
+ $routeProvider
+ .when('/Book/:bookId', {
+ templateUrl: 'book.html',
+ controller: 'BookCtrl',
+ controllerAs: 'book'
+ })
+ .when('/Book/:bookId/ch/:chapterId', {
+ templateUrl: 'chapter.html',
+ controller: 'ChapterCtrl',
+ controllerAs: 'chapter'
+ });
+
+ $locationProvider.html5Mode(true);
+ }])
+ .controller('MainCtrl', ['$route', '$routeParams', '$location',
+ function($route, $routeParams, $location) {
+ this.$route = $route;
+ this.$location = $location;
+ this.$routeParams = $routeParams;
+ }])
+ .controller('BookCtrl', ['$routeParams', function($routeParams) {
+ this.name = "BookCtrl";
+ this.params = $routeParams;
+ }])
+ .controller('ChapterCtrl', ['$routeParams', function($routeParams) {
+ this.name = "ChapterCtrl";
+ this.params = $routeParams;
+ }]);
+
+ </file>
+
+ <file name="protractor.js" type="protractor">
+ it('should load and compile correct template', function() {
+ element(by.linkText('Moby: Ch1')).click();
+ var content = element(by.css('[ng-view]')).getText();
+ expect(content).toMatch(/controller\: ChapterCtrl/);
+ expect(content).toMatch(/Book Id\: Moby/);
+ expect(content).toMatch(/Chapter Id\: 1/);
+
+ element(by.partialLinkText('Scarlet')).click();
+
+ content = element(by.css('[ng-view]')).getText();
+ expect(content).toMatch(/controller\: BookCtrl/);
+ expect(content).toMatch(/Book Id\: Scarlet/);
+ });
+ </file>
+ </example>
+ */
+
+
+/**
+ * @ngdoc event
+ * @name ngView#$viewContentLoaded
+ * @eventType emit on the current ngView scope
+ * @description
+ * Emitted every time the ngView content is reloaded.
+ */
+ngViewFactory.$inject = ['$route', '$anchorScroll', '$animate'];
+function ngViewFactory($route, $anchorScroll, $animate) {
+ return {
+ restrict: 'ECA',
+ terminal: true,
+ priority: 400,
+ transclude: 'element',
+ link: function(scope, $element, attr, ctrl, $transclude) {
+ var currentScope,
+ currentElement,
+ previousLeaveAnimation,
+ autoScrollExp = attr.autoscroll,
+ onloadExp = attr.onload || '';
+
+ scope.$on('$routeChangeSuccess', update);
+ update();
+
+ function cleanupLastView() {
+ if (previousLeaveAnimation) {
+ $animate.cancel(previousLeaveAnimation);
+ previousLeaveAnimation = null;
+ }
+
+ if (currentScope) {
+ currentScope.$destroy();
+ currentScope = null;
+ }
+ if (currentElement) {
+ previousLeaveAnimation = $animate.leave(currentElement);
+ previousLeaveAnimation.then(function() {
+ previousLeaveAnimation = null;
+ });
+ currentElement = null;
+ }
+ }
+
+ function update() {
+ var locals = $route.current && $route.current.locals,
+ template = locals && locals.$template;
+
+ if (angular.isDefined(template)) {
+ var newScope = scope.$new();
+ var current = $route.current;
+
+ // Note: This will also link all children of ng-view that were contained in the original
+ // html. If that content contains controllers, ... they could pollute/change the scope.
+ // However, using ng-view on an element with additional content does not make sense...
+ // Note: We can't remove them in the cloneAttchFn of $transclude as that
+ // function is called before linking the content, which would apply child
+ // directives to non existing elements.
+ var clone = $transclude(newScope, function(clone) {
+ $animate.enter(clone, null, currentElement || $element).then(function onNgViewEnter() {
+ if (angular.isDefined(autoScrollExp)
+ && (!autoScrollExp || scope.$eval(autoScrollExp))) {
+ $anchorScroll();
+ }
+ });
+ cleanupLastView();
+ });
+
+ currentElement = clone;
+ currentScope = current.scope = newScope;
+ currentScope.$emit('$viewContentLoaded');
+ currentScope.$eval(onloadExp);
+ } else {
+ cleanupLastView();
+ }
+ }
+ }
+ };
+}
+
+// This directive is called during the $transclude call of the first `ngView` directive.
+// It will replace and compile the content of the element with the loaded template.
+// We need this directive so that the element content is already filled when
+// the link function of another directive on the same element as ngView
+// is called.
+ngViewFillContentFactory.$inject = ['$compile', '$controller', '$route'];
+function ngViewFillContentFactory($compile, $controller, $route) {
+ return {
+ restrict: 'ECA',
+ priority: -400,
+ link: function(scope, $element) {
+ var current = $route.current,
+ locals = current.locals;
+
+ $element.html(locals.$template);
+
+ var link = $compile($element.contents());
+
+ if (current.controller) {
+ locals.$scope = scope;
+ var controller = $controller(current.controller, locals);
+ if (current.controllerAs) {
+ scope[current.controllerAs] = controller;
+ }
+ $element.data('$ngControllerController', controller);
+ $element.children().data('$ngControllerController', controller);
+ }
+
+ link(scope);
+ }
+ };
+}
+
+
+})(window, window.angular);
Added: lucene/dev/trunk/solr/webapp/web/libs/angular-route.min.js
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/webapp/web/libs/angular-route.min.js?rev=1661606&view=auto
==============================================================================
--- lucene/dev/trunk/solr/webapp/web/libs/angular-route.min.js (added)
+++ lucene/dev/trunk/solr/webapp/web/libs/angular-route.min.js Mon Feb 23 05:42:36 2015
@@ -0,0 +1,38 @@
+/**
+The MIT License
+
+Copyright (c) 2010-2015 Google, Inc. http://angularjs.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+/*
+ AngularJS v1.3.8
+ (c) 2010-2014 Google, Inc. http://angularjs.org
+ License: MIT
+*/
+(function(p,d,C){'use strict';function v(r,h,g){return{restrict:"ECA",terminal:!0,priority:400,transclude:"element",link:function(a,c,b,f,y){function z(){k&&(g.cancel(k),k=null);l&&(l.$destroy(),l=null);m&&(k=g.leave(m),k.then(function(){k=null}),m=null)}function x(){var b=r.current&&r.current.locals;if(d.isDefined(b&&b.$template)){var b=a.$new(),f=r.current;m=y(b,function(b){g.enter(b,null,m||c).then(function(){!d.isDefined(t)||t&&!a.$eval(t)||h()});z()});l=f.scope=b;l.$emit("$viewContentLoaded");
+l.$eval(w)}else z()}var l,m,k,t=b.autoscroll,w=b.onload||"";a.$on("$routeChangeSuccess",x);x()}}}function A(d,h,g){return{restrict:"ECA",priority:-400,link:function(a,c){var b=g.current,f=b.locals;c.html(f.$template);var y=d(c.contents());b.controller&&(f.$scope=a,f=h(b.controller,f),b.controllerAs&&(a[b.controllerAs]=f),c.data("$ngControllerController",f),c.children().data("$ngControllerController",f));y(a)}}}p=d.module("ngRoute",["ng"]).provider("$route",function(){function r(a,c){return d.extend(Object.create(a),
+c)}function h(a,d){var b=d.caseInsensitiveMatch,f={originalPath:a,regexp:a},g=f.keys=[];a=a.replace(/([().])/g,"\\$1").replace(/(\/)?:(\w+)([\?\*])?/g,function(a,d,b,c){a="?"===c?c:null;c="*"===c?c:null;g.push({name:b,optional:!!a});d=d||"";return""+(a?"":d)+"(?:"+(a?d:"")+(c&&"(.+?)"||"([^/]+)")+(a||"")+")"+(a||"")}).replace(/([\/$\*])/g,"\\$1");f.regexp=new RegExp("^"+a+"$",b?"i":"");return f}var g={};this.when=function(a,c){var b=d.copy(c);d.isUndefined(b.reloadOnSearch)&&(b.reloadOnSearch=!0);
+d.isUndefined(b.caseInsensitiveMatch)&&(b.caseInsensitiveMatch=this.caseInsensitiveMatch);g[a]=d.extend(b,a&&h(a,b));if(a){var f="/"==a[a.length-1]?a.substr(0,a.length-1):a+"/";g[f]=d.extend({redirectTo:a},h(f,b))}return this};this.caseInsensitiveMatch=!1;this.otherwise=function(a){"string"===typeof a&&(a={redirectTo:a});this.when(null,a);return this};this.$get=["$rootScope","$location","$routeParams","$q","$injector","$templateRequest","$sce",function(a,c,b,f,h,p,x){function l(b){var e=s.current;
+(v=(n=k())&&e&&n.$$route===e.$$route&&d.equals(n.pathParams,e.pathParams)&&!n.reloadOnSearch&&!w)||!e&&!n||a.$broadcast("$routeChangeStart",n,e).defaultPrevented&&b&&b.preventDefault()}function m(){var u=s.current,e=n;if(v)u.params=e.params,d.copy(u.params,b),a.$broadcast("$routeUpdate",u);else if(e||u)w=!1,(s.current=e)&&e.redirectTo&&(d.isString(e.redirectTo)?c.path(t(e.redirectTo,e.params)).search(e.params).replace():c.url(e.redirectTo(e.pathParams,c.path(),c.search())).replace()),f.when(e).then(function(){if(e){var a=
+d.extend({},e.resolve),b,c;d.forEach(a,function(b,e){a[e]=d.isString(b)?h.get(b):h.invoke(b,null,null,e)});d.isDefined(b=e.template)?d.isFunction(b)&&(b=b(e.params)):d.isDefined(c=e.templateUrl)&&(d.isFunction(c)&&(c=c(e.params)),c=x.getTrustedResourceUrl(c),d.isDefined(c)&&(e.loadedTemplateUrl=c,b=p(c)));d.isDefined(b)&&(a.$template=b);return f.all(a)}}).then(function(c){e==s.current&&(e&&(e.locals=c,d.copy(e.params,b)),a.$broadcast("$routeChangeSuccess",e,u))},function(b){e==s.current&&a.$broadcast("$routeChangeError",
+e,u,b)})}function k(){var a,b;d.forEach(g,function(f,g){var q;if(q=!b){var h=c.path();q=f.keys;var l={};if(f.regexp)if(h=f.regexp.exec(h)){for(var k=1,m=h.length;k<m;++k){var n=q[k-1],p=h[k];n&&p&&(l[n.name]=p)}q=l}else q=null;else q=null;q=a=q}q&&(b=r(f,{params:d.extend({},c.search(),a),pathParams:a}),b.$$route=f)});return b||g[null]&&r(g[null],{params:{},pathParams:{}})}function t(a,b){var c=[];d.forEach((a||"").split(":"),function(a,d){if(0===d)c.push(a);else{var f=a.match(/(\w+)(?:[?*])?(.*)/),
+g=f[1];c.push(b[g]);c.push(f[2]||"");delete b[g]}});return c.join("")}var w=!1,n,v,s={routes:g,reload:function(){w=!0;a.$evalAsync(function(){l();m()})},updateParams:function(a){if(this.current&&this.current.$$route){var b={},f=this;d.forEach(Object.keys(a),function(c){f.current.pathParams[c]||(b[c]=a[c])});a=d.extend({},this.current.params,a);c.path(t(this.current.$$route.originalPath,a));c.search(d.extend({},c.search(),b))}else throw B("norout");}};a.$on("$locationChangeStart",l);a.$on("$locationChangeSuccess",
+m);return s}]});var B=d.$$minErr("ngRoute");p.provider("$routeParams",function(){this.$get=function(){return{}}});p.directive("ngView",v);p.directive("ngView",A);v.$inject=["$route","$anchorScroll","$animate"];A.$inject=["$compile","$controller","$route"]})(window,window.angular);
+//# sourceMappingURL=angular-route.min.js.map