├── www ├── lib │ ├── js │ │ ├── angular │ │ │ ├── version.txt │ │ │ ├── version.json │ │ │ ├── angular-csp.css │ │ │ ├── angular-cookies.min.js │ │ │ ├── angular-loader.min.js │ │ │ ├── angular-cookies.min.js.map │ │ │ ├── angular-loader.min.js.map │ │ │ ├── angular-touch.min.js │ │ │ ├── angular-resource.min.js │ │ │ ├── angular-route.min.js │ │ │ ├── angular-sanitize.min.js │ │ │ ├── errors.json │ │ │ ├── angular-cookies.js │ │ │ ├── angular-resource.min.js.map │ │ │ ├── angular-touch.min.js.map │ │ │ ├── angular-animate.min.js │ │ │ ├── angular-route.min.js.map │ │ │ ├── angular-sanitize.min.js.map │ │ │ ├── angular-loader.js │ │ │ ├── angular-touch.js │ │ │ ├── angular-sanitize.js │ │ │ └── angular-resource.js │ │ └── angular-ui │ │ │ └── angular-ui-router.min.js │ ├── fonts │ │ ├── ionicons.eot │ │ ├── ionicons.ttf │ │ └── ionicons.woff │ └── version.json ├── img │ └── ionic.png ├── res │ ├── screen │ │ ├── tizen │ │ │ └── README.md │ │ ├── webos │ │ │ └── screen-64.png │ │ ├── bada-wac │ │ │ ├── screen-type3.png │ │ │ ├── screen-type4.png │ │ │ └── screen-type5.png │ │ ├── bada │ │ │ └── screen-portrait.png │ │ ├── blackberry │ │ │ └── screen-225.png │ │ ├── ios │ │ │ ├── screen-ipad-landscape.png │ │ │ ├── screen-ipad-portrait.png │ │ │ ├── screen-iphone-portrait.png │ │ │ ├── screen-ipad-landscape-2x.png │ │ │ ├── screen-ipad-portrait-2x.png │ │ │ ├── screen-iphone-landscape.png │ │ │ ├── screen-iphone-landscape-2x.png │ │ │ ├── screen-iphone-portrait-2x.png │ │ │ └── screen-iphone-portrait-568h-2x.png │ │ ├── android │ │ │ ├── screen-hdpi-portrait.png │ │ │ ├── screen-ldpi-portrait.png │ │ │ ├── screen-mdpi-portrait.png │ │ │ ├── screen-hdpi-landscape.png │ │ │ ├── screen-ldpi-landscape.png │ │ │ ├── screen-mdpi-landscape.png │ │ │ ├── screen-xhdpi-landscape.png │ │ │ └── screen-xhdpi-portrait.png │ │ └── windows-phone │ │ │ └── screen-portrait.jpg │ └── icon │ │ ├── bada │ │ └── icon-128.png │ │ ├── ios │ │ ├── icon-57.png │ │ ├── icon-72.png │ │ ├── icon-57-2x.png │ │ └── icon-72-2x.png │ │ ├── webos │ │ └── icon-64.png │ │ ├── tizen │ │ └── icon-128.png │ │ ├── blackberry │ │ └── icon-80.png │ │ ├── android │ │ ├── icon-36-ldpi.png │ │ ├── icon-48-mdpi.png │ │ ├── icon-72-hdpi.png │ │ └── icon-96-xhdpi.png │ │ ├── bada-wac │ │ ├── icon-48-type5.png │ │ ├── icon-50-type3.png │ │ └── icon-80-type4.png │ │ └── windows-phone │ │ ├── icon-48.png │ │ ├── icon-173-tile.png │ │ └── icon-62-tile.png ├── css │ └── app.css ├── templates │ ├── pet-detail.html │ ├── pet-index.html │ ├── adopt.html │ ├── tabs.html │ └── about.html ├── js │ ├── controllers.js │ ├── services.js │ └── app.js └── index.html ├── .gitignore ├── .cordova └── config.json ├── platforms └── .gitignore ├── plugins └── .gitignore ├── README.md ├── config.xml └── LICENSE /www/lib/js/angular/version.txt: -------------------------------------------------------------------------------- 1 | 1.2.10 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.keystore 2 | *.sw* 3 | platforms/^.* 4 | -------------------------------------------------------------------------------- /.cordova/config.json: -------------------------------------------------------------------------------- 1 | {"id":"com.ionicframework.starter","name":"StarterApp"} -------------------------------------------------------------------------------- /platforms/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore 5 | -------------------------------------------------------------------------------- /plugins/.gitignore: -------------------------------------------------------------------------------- 1 | # Ignore everything in this directory 2 | * 3 | # Except this file 4 | !.gitignore 5 | -------------------------------------------------------------------------------- /www/img/ionic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/img/ionic.png -------------------------------------------------------------------------------- /www/res/screen/tizen/README.md: -------------------------------------------------------------------------------- 1 | # Tizen Splash Screen 2 | 3 | Splash screens are unsupported on the Tizen platform. 4 | -------------------------------------------------------------------------------- /www/lib/fonts/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/lib/fonts/ionicons.eot -------------------------------------------------------------------------------- /www/lib/fonts/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/lib/fonts/ionicons.ttf -------------------------------------------------------------------------------- /www/lib/fonts/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/lib/fonts/ionicons.woff -------------------------------------------------------------------------------- /www/lib/js/angular/version.json: -------------------------------------------------------------------------------- 1 | {"full":"1.2.10","major":"1","minor":"2","dot":"10","codename":"augmented-serendipity","cdn":"1.2.9"} -------------------------------------------------------------------------------- /www/res/icon/bada/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/bada/icon-128.png -------------------------------------------------------------------------------- /www/res/icon/ios/icon-57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/ios/icon-57.png -------------------------------------------------------------------------------- /www/res/icon/ios/icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/ios/icon-72.png -------------------------------------------------------------------------------- /www/res/icon/webos/icon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/webos/icon-64.png -------------------------------------------------------------------------------- /www/res/icon/ios/icon-57-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/ios/icon-57-2x.png -------------------------------------------------------------------------------- /www/res/icon/ios/icon-72-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/ios/icon-72-2x.png -------------------------------------------------------------------------------- /www/res/icon/tizen/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/tizen/icon-128.png -------------------------------------------------------------------------------- /www/res/icon/blackberry/icon-80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/blackberry/icon-80.png -------------------------------------------------------------------------------- /www/res/screen/webos/screen-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/webos/screen-64.png -------------------------------------------------------------------------------- /www/res/icon/android/icon-36-ldpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/android/icon-36-ldpi.png -------------------------------------------------------------------------------- /www/res/icon/android/icon-48-mdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/android/icon-48-mdpi.png -------------------------------------------------------------------------------- /www/res/icon/android/icon-72-hdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/android/icon-72-hdpi.png -------------------------------------------------------------------------------- /www/res/icon/android/icon-96-xhdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/android/icon-96-xhdpi.png -------------------------------------------------------------------------------- /www/res/icon/bada-wac/icon-48-type5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/bada-wac/icon-48-type5.png -------------------------------------------------------------------------------- /www/res/icon/bada-wac/icon-50-type3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/bada-wac/icon-50-type3.png -------------------------------------------------------------------------------- /www/res/icon/bada-wac/icon-80-type4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/bada-wac/icon-80-type4.png -------------------------------------------------------------------------------- /www/res/icon/windows-phone/icon-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/windows-phone/icon-48.png -------------------------------------------------------------------------------- /www/res/screen/bada-wac/screen-type3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/bada-wac/screen-type3.png -------------------------------------------------------------------------------- /www/res/screen/bada-wac/screen-type4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/bada-wac/screen-type4.png -------------------------------------------------------------------------------- /www/res/screen/bada-wac/screen-type5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/bada-wac/screen-type5.png -------------------------------------------------------------------------------- /www/res/screen/bada/screen-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/bada/screen-portrait.png -------------------------------------------------------------------------------- /www/res/screen/blackberry/screen-225.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/blackberry/screen-225.png -------------------------------------------------------------------------------- /www/lib/version.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0-beta.6", 3 | "codename": "darmstadtium-dingo", 4 | "date": "2014-05-21", 5 | "time": "19:50:15" 6 | } 7 | -------------------------------------------------------------------------------- /www/res/icon/windows-phone/icon-173-tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/windows-phone/icon-173-tile.png -------------------------------------------------------------------------------- /www/res/icon/windows-phone/icon-62-tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/icon/windows-phone/icon-62-tile.png -------------------------------------------------------------------------------- /www/res/screen/ios/screen-ipad-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/ios/screen-ipad-landscape.png -------------------------------------------------------------------------------- /www/res/screen/ios/screen-ipad-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/ios/screen-ipad-portrait.png -------------------------------------------------------------------------------- /www/res/screen/ios/screen-iphone-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/ios/screen-iphone-portrait.png -------------------------------------------------------------------------------- /www/res/screen/android/screen-hdpi-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/android/screen-hdpi-portrait.png -------------------------------------------------------------------------------- /www/res/screen/android/screen-ldpi-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/android/screen-ldpi-portrait.png -------------------------------------------------------------------------------- /www/res/screen/android/screen-mdpi-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/android/screen-mdpi-portrait.png -------------------------------------------------------------------------------- /www/res/screen/ios/screen-ipad-landscape-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/ios/screen-ipad-landscape-2x.png -------------------------------------------------------------------------------- /www/res/screen/ios/screen-ipad-portrait-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/ios/screen-ipad-portrait-2x.png -------------------------------------------------------------------------------- /www/res/screen/ios/screen-iphone-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/ios/screen-iphone-landscape.png -------------------------------------------------------------------------------- /www/res/screen/android/screen-hdpi-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/android/screen-hdpi-landscape.png -------------------------------------------------------------------------------- /www/res/screen/android/screen-ldpi-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/android/screen-ldpi-landscape.png -------------------------------------------------------------------------------- /www/res/screen/android/screen-mdpi-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/android/screen-mdpi-landscape.png -------------------------------------------------------------------------------- /www/res/screen/android/screen-xhdpi-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/android/screen-xhdpi-landscape.png -------------------------------------------------------------------------------- /www/res/screen/android/screen-xhdpi-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/android/screen-xhdpi-portrait.png -------------------------------------------------------------------------------- /www/res/screen/ios/screen-iphone-landscape-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/ios/screen-iphone-landscape-2x.png -------------------------------------------------------------------------------- /www/res/screen/ios/screen-iphone-portrait-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/ios/screen-iphone-portrait-2x.png -------------------------------------------------------------------------------- /www/res/screen/windows-phone/screen-portrait.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/windows-phone/screen-portrait.jpg -------------------------------------------------------------------------------- /www/css/app.css: -------------------------------------------------------------------------------- 1 | /* Your app's CSS, go crazy, make it your own */ 2 | 3 | .ionic-logo { 4 | display: block; 5 | margin: 15px auto; 6 | width: 96px; 7 | height: 96px; 8 | } 9 | -------------------------------------------------------------------------------- /www/res/screen/ios/screen-iphone-portrait-568h-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ionic-team/ionic-angular-cordova-seed/HEAD/www/res/screen/ios/screen-iphone-portrait-568h-2x.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ionic-angular-cordova-seed 2 | ========================== 3 | 4 | The perfect starting point for an Ionic project. 5 | 6 | - [Ionic Tutorials](http://ionicframework.com/tutorials/) -------------------------------------------------------------------------------- /www/lib/js/angular/angular-csp.css: -------------------------------------------------------------------------------- 1 | /* Include this file in your html if you are using the CSP mode. */ 2 | 3 | @charset "UTF-8"; 4 | 5 | [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], 6 | .ng-cloak, .x-ng-cloak, 7 | .ng-hide { 8 | display: none !important; 9 | } 10 | 11 | ng\:form { 12 | display: block; 13 | } 14 | -------------------------------------------------------------------------------- /www/templates/pet-detail.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 |

{{ pet.description }}

10 |

All Pets

11 |
12 |
13 | -------------------------------------------------------------------------------- /www/js/controllers.js: -------------------------------------------------------------------------------- 1 | angular.module('starter.controllers', []) 2 | 3 | 4 | // A simple controller that fetches a list of data from a service 5 | .controller('PetIndexCtrl', function($scope, PetService) { 6 | // "Pets" is a service returning mock data (services.js) 7 | $scope.pets = PetService.all(); 8 | }) 9 | 10 | 11 | // A simple controller that shows a tapped item's data 12 | .controller('PetDetailCtrl', function($scope, $stateParams, PetService) { 13 | // "Pets" is a service returning mock data (services.js) 14 | $scope.pet = PetService.get($stateParams.petId); 15 | }); 16 | -------------------------------------------------------------------------------- /www/templates/pet-index.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |

{{pet.title}}

13 |

{{pet.description}}

14 |
15 | 16 |
17 | 18 |
19 |
20 | -------------------------------------------------------------------------------- /www/templates/adopt.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 |
7 | 11 | 15 | Subscribe To Newsletter 16 | 17 |
18 |
19 |
20 | -------------------------------------------------------------------------------- /config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | StarterApp 4 | 5 | A sample Ionic Framework app using Cordova and AngularJS 6 | 7 | 8 | Ionic Framework Team 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /www/templates/tabs.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /www/lib/js/angular/angular-cookies.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.10 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(p,f,n){'use strict';f.module("ngCookies",["ng"]).factory("$cookies",["$rootScope","$browser",function(d,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&&d.$apply())})();k=!0;d.$watch(function(){var a,e,d;for(a in g)m(c[a])&&b.cookies(a,n);for(a in c)(e=c[a],f.isString(e))?e!==g[a]&&(b.cookies(a,e),d=!0):f.isDefined(g[a])?c[a]=g[a]:delete c[a];if(d)for(a in e=b.cookies(),c)c[a]!==e[a]&&(m(e[a])?delete c[a]:c[a]=e[a])}); 7 | return c}]).factory("$cookieStore",["$cookies",function(d){return{get:function(b){return(b=d[b])?f.fromJson(b):b},put:function(b,c){d[b]=f.toJson(c)},remove:function(b){delete d[b]}}}])})(window,window.angular); 8 | //# sourceMappingURL=angular-cookies.min.js.map 9 | -------------------------------------------------------------------------------- /www/js/services.js: -------------------------------------------------------------------------------- 1 | angular.module('starter.services', []) 2 | 3 | /** 4 | * A simple example service that returns some data. 5 | */ 6 | .factory('PetService', function() { 7 | // Might use a resource here that returns a JSON array 8 | 9 | // Some fake testing data 10 | var pets = [ 11 | { id: 0, title: 'Cats', description: 'Furry little creatures. Obsessed with plotting assassination, but never following through on it.' }, 12 | { id: 1, title: 'Dogs', description: 'Lovable. Loyal almost to a fault. Smarter than they let on.' }, 13 | { id: 2, title: 'Turtles', description: 'Everyone likes turtles.' }, 14 | { id: 3, title: 'Sharks', description: 'An advanced pet. Needs millions of gallons of salt water. Will happily eat you.' } 15 | ]; 16 | 17 | return { 18 | all: function() { 19 | return pets; 20 | }, 21 | get: function(petId) { 22 | // Simple index lookup 23 | return pets[petId]; 24 | } 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Drifty 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /www/templates/about.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 |

8 | This is a sample seed project for the Ionic Framework. Please cut it up and make it your own. 9 | Check out the docs 10 | for more info. 11 |

12 |

13 | Questions? Hit up the 14 | forum. 15 |

16 |

17 | Find a bug? Create an 18 | issue. 19 |

20 |

21 | What to help improve Ionic? 22 | Contribute. 23 |

24 |

25 | Stay up-to-date with the Ionic 26 | newsletter and 27 | twitter account. 28 |

29 |

30 | MIT Licensed. Happy coding. 31 |

32 |
33 |
34 | -------------------------------------------------------------------------------- /www/lib/js/angular/angular-loader.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.10 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(){'use strict';function d(a){return function(){var c=arguments[0],b,c="["+(a?a+":":"")+c+"] http://errors.angularjs.org/1.2.10/"+(a?a+"/":"")+c;for(b=1;b 2 | 3 | 4 | 5 | 6 | Ionic Seed App 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 36 | 37 | 38 | 39 | 40 | 41 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /www/js/app.js: -------------------------------------------------------------------------------- 1 | // Ionic Starter App 2 | 3 | // angular.module is a global place for creating, registering and retrieving Angular modules 4 | // 'starter' is the name of this angular module example (also set in a attribute in index.html) 5 | // the 2nd parameter is an array of 'requires' 6 | // 'starter.services' is found in services.js 7 | // 'starter.controllers' is found in controllers.js 8 | angular.module('starter', ['ionic', 'starter.services', 'starter.controllers']) 9 | 10 | 11 | .config(function($stateProvider, $urlRouterProvider) { 12 | 13 | // Ionic uses AngularUI Router which uses the concept of states 14 | // Learn more here: https://github.com/angular-ui/ui-router 15 | // Set up the various states which the app can be in. 16 | // Each state's controller can be found in controllers.js 17 | $stateProvider 18 | 19 | // setup an abstract state for the tabs directive 20 | .state('tab', { 21 | url: '/tab', 22 | abstract: true, 23 | templateUrl: 'templates/tabs.html' 24 | }) 25 | 26 | // the pet tab has its own child nav-view and history 27 | .state('tab.pet-index', { 28 | url: '/pets', 29 | views: { 30 | 'pets-tab': { 31 | templateUrl: 'templates/pet-index.html', 32 | controller: 'PetIndexCtrl' 33 | } 34 | } 35 | }) 36 | 37 | .state('tab.pet-detail', { 38 | url: '/pet/:petId', 39 | views: { 40 | 'pets-tab': { 41 | templateUrl: 'templates/pet-detail.html', 42 | controller: 'PetDetailCtrl' 43 | } 44 | } 45 | }) 46 | 47 | .state('tab.adopt', { 48 | url: '/adopt', 49 | views: { 50 | 'adopt-tab': { 51 | templateUrl: 'templates/adopt.html' 52 | } 53 | } 54 | }) 55 | 56 | .state('tab.about', { 57 | url: '/about', 58 | views: { 59 | 'about-tab': { 60 | templateUrl: 'templates/about.html' 61 | } 62 | } 63 | }); 64 | 65 | // if none of the above states are matched, use this as the fallback 66 | $urlRouterProvider.otherwise('/tab/pets'); 67 | 68 | }); 69 | 70 | -------------------------------------------------------------------------------- /www/lib/js/angular/angular-cookies.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"angular-cookies.min.js", 4 | "lineCount":7, 5 | "mappings":"A;;;;;aAKC,SAAQ,CAACA,CAAD,CAASC,CAAT,CAAkBC,CAAlB,CAA6B,CAoBtCD,CAAAE,OAAA,CAAe,WAAf,CAA4B,CAAC,IAAD,CAA5B,CAAAC,QAAA,CA4BW,UA5BX,CA4BuB,CAAC,YAAD,CAAe,UAAf,CAA2B,QAAS,CAACC,CAAD,CAAaC,CAAb,CAAuB,CAAA,IACxEC,EAAU,EAD8D,CAExEC,EAAc,EAF0D,CAGxEC,CAHwE,CAIxEC,EAAU,CAAA,CAJ8D,CAKxEC,EAAOV,CAAAU,KALiE,CAMxEC,EAAcX,CAAAW,YAGlBN,EAAAO,UAAA,CAAmB,QAAQ,EAAG,CAC5B,IAAIC,EAAiBR,CAAAC,QAAA,EACjBE,EAAJ,EAA0BK,CAA1B,GACEL,CAGA,CAHqBK,CAGrB,CAFAH,CAAA,CAAKG,CAAL,CAAqBN,CAArB,CAEA,CADAG,CAAA,CAAKG,CAAL,CAAqBP,CAArB,CACA,CAAIG,CAAJ,EAAaL,CAAAU,OAAA,EAJf,CAF4B,CAA9B,CAAA,EAUAL,EAAA,CAAU,CAAA,CAKVL,EAAAW,OAAA,CASAC,QAAa,EAAG,CAAA,IACVC,CADU,CAEVC,CAFU,CAIVC,CAGJ,KAAKF,CAAL,GAAaV,EAAb,CACMI,CAAA,CAAYL,CAAA,CAAQW,CAAR,CAAZ,CAAJ,EACEZ,CAAAC,QAAA,CAAiBW,CAAjB,CAAuBhB,CAAvB,CAKJ,KAAIgB,CAAJ,GAAYX,EAAZ,CAEE,CADAY,CACK,CADGZ,CAAA,CAAQW,CAAR,CACH,CAAAjB,CAAAoB,SAAA,CAAiBF,CAAjB,CAAL,EAMWA,CANX,GAMqBX,CAAA,CAAYU,CAAZ,CANrB,GAOEZ,CAAAC,QAAA,CAAiBW,CAAjB,CAAuBC,CAAvB,CACA,CAAAC,CAAA,CAAU,CAAA,CARZ,EACMnB,CAAAqB,UAAA,CAAkBd,CAAA,CAAYU,CAAZ,CAAlB,CAAJ,CACEX,CAAA,CAAQW,CAAR,CADF,CACkBV,CAAA,CAAYU,CAAZ,CADlB,CAGE,OAAOX,CAAA,CAAQW,CAAR,CASb,IAAIE,CAAJ,CAIE,IAAKF,CAAL,GAFAK,EAEahB,CAFID,CAAAC,QAAA,EAEJA,CAAAA,CAAb,CACMA,CAAA,CAAQW,CAAR,CAAJ,GAAsBK,CAAA,CAAeL,CAAf,CAAtB,GAEMN,CAAA,CAAYW,CAAA,CAAeL,CAAf,CAAZ,CAAJ,CACE,OAAOX,CAAA,CAAQW,CAAR,CADT,CAGEX,CAAA,CAAQW,CAAR,CAHF,CAGkBK,CAAA,CAAeL,CAAf,CALpB,CAlCU,CAThB,CAEA;MAAOX,EA1BqE,CAA3D,CA5BvB,CAAAH,QAAA,CA4HW,cA5HX,CA4H2B,CAAC,UAAD,CAAa,QAAQ,CAACoB,CAAD,CAAW,CAErD,MAAO,KAYAC,QAAQ,CAACC,CAAD,CAAM,CAEjB,MAAO,CADHP,CACG,CADKK,CAAA,CAASE,CAAT,CACL,EAAQzB,CAAA0B,SAAA,CAAiBR,CAAjB,CAAR,CAAkCA,CAFxB,CAZd,KA4BAS,QAAQ,CAACF,CAAD,CAAMP,CAAN,CAAa,CACxBK,CAAA,CAASE,CAAT,CAAA,CAAgBzB,CAAA4B,OAAA,CAAeV,CAAf,CADQ,CA5BrB,QA0CGW,QAAQ,CAACJ,CAAD,CAAM,CACpB,OAAOF,CAAA,CAASE,CAAT,CADa,CA1CjB,CAF8C,CAAhC,CA5H3B,CApBsC,CAArC,CAAA,CAoME1B,MApMF,CAoMUA,MAAAC,QApMV;", 6 | "sources":["angular-cookies.js"], 7 | "names":["window","angular","undefined","module","factory","$rootScope","$browser","cookies","lastCookies","lastBrowserCookies","runEval","copy","isUndefined","addPollFn","currentCookies","$apply","$watch","push","name","value","updated","isString","isDefined","browserCookies","$cookies","get","key","fromJson","put","toJson","remove"] 8 | } 9 | -------------------------------------------------------------------------------- /www/lib/js/angular/angular-loader.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"angular-loader.min.js", 4 | "lineCount":8, 5 | "mappings":"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", 6 | "sources":["angular-loader.js","MINERR_ASSET"], 7 | "names":["minErr","setupModuleLoader","window","$injectorMinErr","ngMinErr","angular","$$minErr","factory","modules","module","name","requires","configFn","context","hasOwnProperty","invokeLater","provider","method","insertMethod","invokeQueue","arguments","moduleInstance","runBlocks","config","run","block","push"] 8 | } 9 | -------------------------------------------------------------------------------- /www/lib/js/angular/angular-touch.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.10 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(y,v,z){'use strict';function t(g,a,b){q.directive(g,["$parse","$swipe",function(l,n){var r=75,h=0.3,d=30;return function(p,m,k){function e(e){if(!u)return!1;var c=Math.abs(e.y-u.y);e=(e.x-u.x)*a;return f&&cd&&c/el&&10>n|| 8 | (n>l?(d=!1,b.cancel&&b.cancel(a)):(a.preventDefault(),b.move&&b.move(m,a)))}});a.on("touchend mouseup",function(a){d&&(d=!1,b.end&&b.end(g(a),a))})}}}]);q.config(["$provide",function(g){g.decorator("ngClickDirective",["$delegate",function(a){a.shift();return a}])}]);q.directive("ngClick",["$parse","$timeout","$rootElement",function(g,a,b){function l(a,c,b){for(var f=0;fh)){var c= 9 | a.touches&&a.touches.length?a.touches:[a],b=c[0].clientX,c=c[0].clientY;1>b&&1>c||l(k,b,c)||(a.stopPropagation(),a.preventDefault(),a.target&&a.target.blur())}}function r(b){b=b.touches&&b.touches.length?b.touches:[b];var c=b[0].clientX,d=b[0].clientY;k.push(c,d);a(function(){for(var a=0;ah&&12>p)&&(k||(b[0].addEventListener("click",n,!0),b[0].addEventListener("touchstart",r,!0),k=[]),m=Date.now(),l(k,e,g),s&&s.blur(),v.isDefined(d.disabled)&&!1!==d.disabled||c.triggerHandler("click",[a]));f()});c.onclick=function(a){};c.on("click",function(b,c){a.$apply(function(){h(a,{$event:c||b})})});c.on("mousedown",function(a){c.addClass(p)});c.on("mousemove mouseup",function(a){c.removeClass(p)})}}]);t("ngSwipeLeft",-1,"swipeleft");t("ngSwipeRight",1,"swiperight")})(window, 12 | window.angular); 13 | //# sourceMappingURL=angular-touch.min.js.map 14 | -------------------------------------------------------------------------------- /www/lib/js/angular/angular-resource.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.12 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (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&& 7 | 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;d--)e.end&&e.end(f[d]);f.length=c}}var b,g,f=[],l=a;for(f.last=function(){return f[f.length-1]};a;){g=!0;if(f.last()&&x[f.last()])a=a.replace(RegExp("(.*)<\\s*\\/\\s*"+f.last()+"[^>]*>","i"),function(b,a){a=a.replace(H,"$1").replace(I,"$1");e.chars&&e.chars(r(a));return""}),c("",f.last());else{if(0===a.indexOf("\x3c!--"))b=a.indexOf("--",4),0<=b&&a.lastIndexOf("--\x3e",b)===b&&(e.comment&&e.comment(a.substring(4,b)),a=a.substring(b+3),g=!1);else if(y.test(a)){if(b=a.match(y))a= 8 | a.replace(b[0],""),g=!1}else if(J.test(a)){if(b=a.match(z))a=a.substring(b[0].length),b[0].replace(z,c),g=!1}else K.test(a)&&(b=a.match(A))&&(a=a.substring(b[0].length),b[0].replace(A,d),g=!1);g&&(b=a.indexOf("<"),g=0>b?a:a.substring(0,b),a=0>b?"":a.substring(b),e.chars&&e.chars(r(g)))}if(a==l)throw L("badparse",a);l=a}c()}function r(a){if(!a)return"";var e=M.exec(a);a=e[1];var d=e[3];if(e=e[2])n.innerHTML=e.replace(//g,">")}function s(a,e){var d=!1,c=h.bind(a,a.push);return{start:function(a,g,f){a=h.lowercase(a);!d&&x[a]&&(d=a);d||!0!==C[a]||(c("<"),c(a),h.forEach(g,function(d,f){var g=h.lowercase(f),k="img"===a&&"src"===g||"background"===g;!0!==O[g]||!0===D[g]&&!e(d,k)||(c(" "),c(f),c('="'),c(B(d)),c('"'))}),c(f?"/>":">"))},end:function(a){a=h.lowercase(a);d||!0!==C[a]||(c(""));a==d&&(d=!1)},chars:function(a){d|| 10 | c(B(a))}}}var L=h.$$minErr("$sanitize"),A=/^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/,z=/^<\s*\/\s*([\w:-]+)[^>]*>/,G=/([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g,K=/^]*?)>/i,I=/]/,d=/^mailto:/;return function(c,b){function g(a){a&&m.push(E(a))}function f(a,c){m.push("');g(c);m.push("")}if(!c)return c;for(var l,k=c,m=[],n,p;l=k.match(e);)n=l[0],l[2]==l[3]&&(n="mailto:"+n),p=l.index,g(k.substr(0,p)),f(n,l[0].replace(d,"")),k=k.substring(p+l[0].length);g(k);return a(m.join(""))}}])})(window,window.angular); 14 | //# sourceMappingURL=angular-sanitize.min.js.map 15 | -------------------------------------------------------------------------------- /www/lib/js/angular/errors.json: -------------------------------------------------------------------------------- 1 | {"id":"ng","generated":"Fri Jan 24 2014 15:29:18 GMT-0800 (PST)","errors":{"$cacheFactory":{"iid":"CacheId '{0}' is already taken!"},"ngModel":{"nonassign":"Expression '{0}' is non-assignable. Element: {1}"},"$sce":{"iequirks":"Strict Contextual Escaping does not support Internet Explorer version < 9 in quirks mode. You can fix this by adding the text to the top of your HTML document. See http://docs.angularjs.org/api/ng.$sce for more information.","insecurl":"Blocked loading resource from url not allowed by $sceDelegate policy. URL: {0}","icontext":"Attempted to trust a value in invalid context. Context: {0}; Value: {1}","imatcher":"Matchers may only be \"self\", string patterns or RegExp objects","iwcard":"Illegal sequence *** in string matcher. String: {0}","itype":"Attempted to trust a non-string value in a content requiring a string: Context: {0}","unsafe":"Attempting to use an unsafe value in a safe context."},"$controller":{"noscp":"Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`."},"$compile":{"nodomevents":"Interpolations for HTML DOM event attributes are disallowed. Please use the ng- versions (such as ng-click instead of onclick) instead.","multidir":"Multiple directives [{0}, {1}] asking for {2} on: {3}","nonassign":"Expression '{0}' used with directive '{1}' is non-assignable!","tplrt":"Template for directive '{0}' must have exactly one root element. {1}","selmulti":"Binding to the 'multiple' attribute is not supported. Element: {0}","tpload":"Failed to load template: {0}","iscp":"Invalid isolate scope definition for directive '{0}'. Definition: {... {1}: '{2}' ...}","ctreq":"Controller '{0}', required by directive '{1}', can't be found!","uterdir":"Unterminated attribute, found '{0}' but no matching '{1}' found."},"$injector":{"modulerr":"Failed to instantiate module {0} due to:\n{1}","unpr":"Unknown provider: {0}","itkn":"Incorrect injection token! Expected service name as string, got {0}","cdep":"Circular dependency found: {0}","nomod":"Module '{0}' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.","pget":"Provider '{0}' must define $get factory method."},"ngPattern":{"noregexp":"Expected {0} to be a RegExp but was {1}. Element: {2}"},"$rootScope":{"inprog":"{0} already in progress","infdig":"{0} $digest() iterations reached. Aborting!\nWatchers fired in the last 5 iterations: {1}"},"$interpolate":{"noconcat":"Error while interpolating: {0}\nStrict Contextual Escaping disallows interpolations that concatenate multiple expressions when a trusted value is required. See http://docs.angularjs.org/api/ng.$sce","interr":"Can't interpolate: {0}\n{1}"},"jqLite":{"offargs":"jqLite#off() does not support the `selector` argument","onargs":"jqLite#on() does not support the `selector` or `eventData` parameters","nosel":"Looking up elements via selectors is not supported by jqLite! See: http://docs.angularjs.org/api/angular.element"},"ngOptions":{"iexp":"Expected expression in form of '_select_ (as _label_)? for (_key_,)?_value_ in _collection_' but got '{0}'. Element: {1}"},"ngRepeat":{"iidexp":"'_item_' in '_item_ in _collection_' should be an identifier or '(_key_, _value_)' expression, but got '{0}'.","dupes":"Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: {0}, Duplicate key: {1}","iexp":"Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '{0}'."},"ng":{"areq":"Argument '{0}' is {1}","cpws":"Can't copy! Making copies of Window or Scope instances is not supported.","badname":"hasOwnProperty is not a valid {0} name","btstrpd":"App Already Bootstrapped with this Element '{0}'","cpi":"Can't copy! Source and destination are identical."},"$animate":{"notcsel":"Expecting class selector starting with '.' got '{0}'."},"ngTransclude":{"orphan":"Illegal use of ngTransclude directive in the template! No parent directive that requires a transclusion found. Element: {0}"},"$parse":{"isecfld":"Referencing \"constructor\" field in Angular expressions is disallowed! Expression: {0}","syntax":"Syntax Error: Token '{0}' {1} at column {2} of the expression [{3}] starting at [{4}].","isecdom":"Referencing DOM nodes in Angular expressions is disallowed! Expression: {0}","lexerr":"Lexer Error: {0} at column{1} in expression [{2}].","ueoe":"Unexpected end of expression: {0}","isecwindow":"Referencing the Window in Angular expressions is disallowed! Expression: {0}","isecfn":"Referencing Function in Angular expressions is disallowed! Expression: {0}"},"$location":{"ipthprfx":"Invalid url \"{0}\", missing path prefix \"{1}\".","isrcharg":"The first argument of the `$location#search()` call must be a string or an object.","ihshprfx":"Invalid url \"{0}\", missing hash prefix \"{1}\"."},"$resource":{"badargs":"Expected up to 4 arguments [params, data, success, error], got {0} arguments","badmember":"Dotted member path \"@{0}\" is invalid.","badcfg":"Error in resource configuration. Expected response to contain an {0} but got an {1}","badname":"hasOwnProperty is not a valid parameter name."},"$sanitize":{"badparse":"The sanitizer was unable to parse the following block of html: {0}"}}} -------------------------------------------------------------------------------- /www/lib/js/angular/angular-cookies.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license AngularJS v1.2.10 3 | * (c) 2010-2014 Google, Inc. http://angularjs.org 4 | * License: MIT 5 | */ 6 | (function(window, angular, undefined) {'use strict'; 7 | 8 | /** 9 | * @ngdoc overview 10 | * @name ngCookies 11 | * @description 12 | * 13 | * # ngCookies 14 | * 15 | * The `ngCookies` module provides a convenient wrapper for reading and writing browser cookies. 16 | * 17 | * {@installModule cookies} 18 | * 19 | *
20 | * 21 | * See {@link ngCookies.$cookies `$cookies`} and 22 | * {@link ngCookies.$cookieStore `$cookieStore`} for usage. 23 | */ 24 | 25 | 26 | angular.module('ngCookies', ['ng']). 27 | /** 28 | * @ngdoc object 29 | * @name ngCookies.$cookies 30 | * @requires $browser 31 | * 32 | * @description 33 | * Provides read/write access to browser's cookies. 34 | * 35 | * Only a simple Object is exposed and by adding or removing properties to/from 36 | * this object, new cookies are created/deleted at the end of current $eval. 37 | * 38 | * Requires the {@link ngCookies `ngCookies`} module to be installed. 39 | * 40 | * @example 41 | 42 | 43 | 51 | 52 | 53 | */ 54 | factory('$cookies', ['$rootScope', '$browser', function ($rootScope, $browser) { 55 | var cookies = {}, 56 | lastCookies = {}, 57 | lastBrowserCookies, 58 | runEval = false, 59 | copy = angular.copy, 60 | isUndefined = angular.isUndefined; 61 | 62 | //creates a poller fn that copies all cookies from the $browser to service & inits the service 63 | $browser.addPollFn(function() { 64 | var currentCookies = $browser.cookies(); 65 | if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl 66 | lastBrowserCookies = currentCookies; 67 | copy(currentCookies, lastCookies); 68 | copy(currentCookies, cookies); 69 | if (runEval) $rootScope.$apply(); 70 | } 71 | })(); 72 | 73 | runEval = true; 74 | 75 | //at the end of each eval, push cookies 76 | //TODO: this should happen before the "delayed" watches fire, because if some cookies are not 77 | // strings or browser refuses to store some cookies, we update the model in the push fn. 78 | $rootScope.$watch(push); 79 | 80 | return cookies; 81 | 82 | 83 | /** 84 | * Pushes all the cookies from the service to the browser and verifies if all cookies were 85 | * stored. 86 | */ 87 | function push() { 88 | var name, 89 | value, 90 | browserCookies, 91 | updated; 92 | 93 | //delete any cookies deleted in $cookies 94 | for (name in lastCookies) { 95 | if (isUndefined(cookies[name])) { 96 | $browser.cookies(name, undefined); 97 | } 98 | } 99 | 100 | //update all cookies updated in $cookies 101 | for(name in cookies) { 102 | value = cookies[name]; 103 | if (!angular.isString(value)) { 104 | if (angular.isDefined(lastCookies[name])) { 105 | cookies[name] = lastCookies[name]; 106 | } else { 107 | delete cookies[name]; 108 | } 109 | } else if (value !== lastCookies[name]) { 110 | $browser.cookies(name, value); 111 | updated = true; 112 | } 113 | } 114 | 115 | //verify what was actually stored 116 | if (updated){ 117 | updated = false; 118 | browserCookies = $browser.cookies(); 119 | 120 | for (name in cookies) { 121 | if (cookies[name] !== browserCookies[name]) { 122 | //delete or reset all cookies that the browser dropped from $cookies 123 | if (isUndefined(browserCookies[name])) { 124 | delete cookies[name]; 125 | } else { 126 | cookies[name] = browserCookies[name]; 127 | } 128 | updated = true; 129 | } 130 | } 131 | } 132 | } 133 | }]). 134 | 135 | 136 | /** 137 | * @ngdoc object 138 | * @name ngCookies.$cookieStore 139 | * @requires $cookies 140 | * 141 | * @description 142 | * Provides a key-value (string-object) storage, that is backed by session cookies. 143 | * Objects put or retrieved from this storage are automatically serialized or 144 | * deserialized by angular's toJson/fromJson. 145 | * 146 | * Requires the {@link ngCookies `ngCookies`} module to be installed. 147 | * 148 | * @example 149 | */ 150 | factory('$cookieStore', ['$cookies', function($cookies) { 151 | 152 | return { 153 | /** 154 | * @ngdoc method 155 | * @name ngCookies.$cookieStore#get 156 | * @methodOf ngCookies.$cookieStore 157 | * 158 | * @description 159 | * Returns the value of given cookie key 160 | * 161 | * @param {string} key Id to use for lookup. 162 | * @returns {Object} Deserialized cookie value. 163 | */ 164 | get: function(key) { 165 | var value = $cookies[key]; 166 | return value ? angular.fromJson(value) : value; 167 | }, 168 | 169 | /** 170 | * @ngdoc method 171 | * @name ngCookies.$cookieStore#put 172 | * @methodOf ngCookies.$cookieStore 173 | * 174 | * @description 175 | * Sets a value for given cookie key 176 | * 177 | * @param {string} key Id for the `value`. 178 | * @param {Object} value Value to be stored. 179 | */ 180 | put: function(key, value) { 181 | $cookies[key] = angular.toJson(value); 182 | }, 183 | 184 | /** 185 | * @ngdoc method 186 | * @name ngCookies.$cookieStore#remove 187 | * @methodOf ngCookies.$cookieStore 188 | * 189 | * @description 190 | * Remove given cookie 191 | * 192 | * @param {string} key Id of the key-value pair to delete. 193 | */ 194 | remove: function(key) { 195 | delete $cookies[key]; 196 | } 197 | }; 198 | 199 | }]); 200 | 201 | 202 | })(window, window.angular); 203 | -------------------------------------------------------------------------------- /www/lib/js/angular/angular-resource.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"angular-resource.min.js", 4 | "lineCount":12, 5 | "mappings":"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", 6 | "sources":["angular-resource.js"], 7 | "names":["window","angular","undefined","shallowClearAndCopy","src","dst","forEach","value","key","hasOwnProperty","charAt","$resourceMinErr","$$minErr","MEMBER_NAME_REGEX","module","factory","$http","$q","Route","template","defaults","urlParams","resourceFactory","url","paramDefaults","actions","extractParams","data","actionParams","ids","extend","isFunction","path","test","keys","split","i","ii","length","obj","defaultResponseInterceptor","response","resource","Resource","route","DEFAULT_ACTIONS","action","name","hasBody","method","a1","a2","a3","a4","params","success","error","arguments","isInstanceCall","isArray","httpConfig","responseInterceptor","interceptor","responseErrorInterceptor","responseError","copy","setUrlParams","promise","then","$promise","item","push","$resolved","noop","reject","headers","prototype","result","call","bind","Resource.bind","additionalParamDefaults","config","actionUrl","self","val","encodedVal","param","RegExp","replace","_","urlParam","isDefined","encodeURIComponent","match","leadingSlashes","tail"] 8 | } 9 | -------------------------------------------------------------------------------- /www/lib/js/angular/angular-touch.min.js.map: -------------------------------------------------------------------------------- 1 | { 2 | "version":3, 3 | "file":"angular-touch.min.js", 4 | "lineCount":12, 5 | "mappings":"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", 6 | "sources":["angular-touch.js"], 7 | "names":["window","angular","undefined","makeSwipeDirective","directiveName","direction","eventName","ngTouch","directive","$parse","$swipe","MAX_VERTICAL_DISTANCE","MAX_VERTICAL_RATIO","MIN_HORIZONTAL_DISTANCE","scope","element","attr","validSwipe","coords","startCoords","deltaY","Math","abs","y","deltaX","x","valid","swipeHandler","bind","start","event","cancel","end","$apply","triggerHandler","module","factory","getCoordinates","touches","length","e","changedTouches","originalEvent","clientX","clientY","eventHandlers","totalX","totalY","lastPos","active","on","MOVE_BUFFER_RADIUS","preventDefault","config","$provide","decorator","$delegate","shift","$timeout","$rootElement","checkAllowableRegions","touchCoordinates","i","x1","CLICKBUSTER_THRESHOLD","y1","splice","onClick","Date","now","lastPreventedTime","PREVENT_DURATION","stopPropagation","target","blur","onTouchStart","push","ACTIVE_CLASS_NAME","resetState","tapping","removeClass","clickHandler","ngClick","tapElement","startTime","touchStartX","touchStartY","srcElement","nodeType","parentNode","addClass","diff","dist","sqrt","pow","TAP_DURATION","MOVE_TOLERANCE","addEventListener","isDefined","disabled","onclick","element.onclick","touchend"] 8 | } 9 | -------------------------------------------------------------------------------- /www/lib/js/angular/angular-animate.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.12 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(v,k,t){'use strict';k.module("ngAnimate",["ng"]).factory("$$animateReflow",["$window","$timeout",function(k,B){var d=k.requestAnimationFrame||k.webkitRequestAnimationFrame||function(d){return B(d,10,!1)},q=k.cancelAnimationFrame||k.webkitCancelAnimationFrame||function(d){return B.cancel(d)};return function(p){var k=d(p);return function(){q(k)}}}]).config(["$provide","$animateProvider",function(R,B){function d(d){for(var k=0;k=u&&a>=p&&h()}var f=b.data(n),g=d(b);if(-1!=g.className.indexOf(a)&&f){var l=f.timings,m=f.stagger,p=f.maxDuration,r=f.activeClassName,u=Math.max(l.transitionDelay, 19 | l.animationDelay)*x,w=Date.now(),v=T+" "+S,t=f.itemIndex,q="",s=[];if(0} */ 107 | var modules = {}; 108 | 109 | /** 110 | * @ngdoc function 111 | * @name angular.module 112 | * @description 113 | * 114 | * The `angular.module` is a global place for creating, registering and retrieving Angular 115 | * modules. 116 | * All modules (angular core or 3rd party) that should be available to an application must be 117 | * registered using this mechanism. 118 | * 119 | * When passed two or more arguments, a new module is created. If passed only one argument, an 120 | * existing module (the name passed as the first argument to `module`) is retrieved. 121 | * 122 | * 123 | * # Module 124 | * 125 | * A module is a collection of services, directives, filters, and configuration information. 126 | * `angular.module` is used to configure the {@link AUTO.$injector $injector}. 127 | * 128 | *
129 |      * // Create a new module
130 |      * var myModule = angular.module('myModule', []);
131 |      *
132 |      * // register a new service
133 |      * myModule.value('appName', 'MyCoolApp');
134 |      *
135 |      * // configure existing services inside initialization blocks.
136 |      * myModule.config(function($locationProvider) {
137 |      *   // Configure existing providers
138 |      *   $locationProvider.hashPrefix('!');
139 |      * });
140 |      * 
141 | * 142 | * Then you can create an injector and load your modules like this: 143 | * 144 | *
145 |      * var injector = angular.injector(['ng', 'MyModule'])
146 |      * 
147 | * 148 | * However it's more likely that you'll just use 149 | * {@link ng.directive:ngApp ngApp} or 150 | * {@link angular.bootstrap} to simplify this process for you. 151 | * 152 | * @param {!string} name The name of the module to create or retrieve. 153 | * @param {Array.=} requires If specified then new module is being created. If 154 | * unspecified then the the module is being retrieved for further configuration. 155 | * @param {Function} configFn Optional configuration function for the module. Same as 156 | * {@link angular.Module#methods_config Module#config()}. 157 | * @returns {module} new module with the {@link angular.Module} api. 158 | */ 159 | return function module(name, requires, configFn) { 160 | var assertNotHasOwnProperty = function(name, context) { 161 | if (name === 'hasOwnProperty') { 162 | throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context); 163 | } 164 | }; 165 | 166 | assertNotHasOwnProperty(name, 'module'); 167 | if (requires && modules.hasOwnProperty(name)) { 168 | modules[name] = null; 169 | } 170 | return ensure(modules, name, function() { 171 | if (!requires) { 172 | throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " + 173 | "the module name or forgot to load it. If registering a module ensure that you " + 174 | "specify the dependencies as the second argument.", name); 175 | } 176 | 177 | /** @type {!Array.>} */ 178 | var invokeQueue = []; 179 | 180 | /** @type {!Array.} */ 181 | var runBlocks = []; 182 | 183 | var config = invokeLater('$injector', 'invoke'); 184 | 185 | /** @type {angular.Module} */ 186 | var moduleInstance = { 187 | // Private state 188 | _invokeQueue: invokeQueue, 189 | _runBlocks: runBlocks, 190 | 191 | /** 192 | * @ngdoc property 193 | * @name angular.Module#requires 194 | * @propertyOf angular.Module 195 | * @returns {Array.} List of module names which must be loaded before this module. 196 | * @description 197 | * Holds the list of modules which the injector will load before the current module is 198 | * loaded. 199 | */ 200 | requires: requires, 201 | 202 | /** 203 | * @ngdoc property 204 | * @name angular.Module#name 205 | * @propertyOf angular.Module 206 | * @returns {string} Name of the module. 207 | * @description 208 | */ 209 | name: name, 210 | 211 | 212 | /** 213 | * @ngdoc method 214 | * @name angular.Module#provider 215 | * @methodOf angular.Module 216 | * @param {string} name service name 217 | * @param {Function} providerType Construction function for creating new instance of the 218 | * service. 219 | * @description 220 | * See {@link AUTO.$provide#provider $provide.provider()}. 221 | */ 222 | provider: invokeLater('$provide', 'provider'), 223 | 224 | /** 225 | * @ngdoc method 226 | * @name angular.Module#factory 227 | * @methodOf angular.Module 228 | * @param {string} name service name 229 | * @param {Function} providerFunction Function for creating new instance of the service. 230 | * @description 231 | * See {@link AUTO.$provide#factory $provide.factory()}. 232 | */ 233 | factory: invokeLater('$provide', 'factory'), 234 | 235 | /** 236 | * @ngdoc method 237 | * @name angular.Module#service 238 | * @methodOf angular.Module 239 | * @param {string} name service name 240 | * @param {Function} constructor A constructor function that will be instantiated. 241 | * @description 242 | * See {@link AUTO.$provide#service $provide.service()}. 243 | */ 244 | service: invokeLater('$provide', 'service'), 245 | 246 | /** 247 | * @ngdoc method 248 | * @name angular.Module#value 249 | * @methodOf angular.Module 250 | * @param {string} name service name 251 | * @param {*} object Service instance object. 252 | * @description 253 | * See {@link AUTO.$provide#value $provide.value()}. 254 | */ 255 | value: invokeLater('$provide', 'value'), 256 | 257 | /** 258 | * @ngdoc method 259 | * @name angular.Module#constant 260 | * @methodOf angular.Module 261 | * @param {string} name constant name 262 | * @param {*} object Constant value. 263 | * @description 264 | * Because the constant are fixed, they get applied before other provide methods. 265 | * See {@link AUTO.$provide#constant $provide.constant()}. 266 | */ 267 | constant: invokeLater('$provide', 'constant', 'unshift'), 268 | 269 | /** 270 | * @ngdoc method 271 | * @name angular.Module#animation 272 | * @methodOf angular.Module 273 | * @param {string} name animation name 274 | * @param {Function} animationFactory Factory function for creating new instance of an 275 | * animation. 276 | * @description 277 | * 278 | * **NOTE**: animations take effect only if the **ngAnimate** module is loaded. 279 | * 280 | * 281 | * Defines an animation hook that can be later used with 282 | * {@link ngAnimate.$animate $animate} service and directives that use this service. 283 | * 284 | *
285 |            * module.animation('.animation-name', function($inject1, $inject2) {
286 |            *   return {
287 |            *     eventName : function(element, done) {
288 |            *       //code to run the animation
289 |            *       //once complete, then run done()
290 |            *       return function cancellationFunction(element) {
291 |            *         //code to cancel the animation
292 |            *       }
293 |            *     }
294 |            *   }
295 |            * })
296 |            * 
297 | * 298 | * See {@link ngAnimate.$animateProvider#register $animateProvider.register()} and 299 | * {@link ngAnimate ngAnimate module} for more information. 300 | */ 301 | animation: invokeLater('$animateProvider', 'register'), 302 | 303 | /** 304 | * @ngdoc method 305 | * @name angular.Module#filter 306 | * @methodOf angular.Module 307 | * @param {string} name Filter name. 308 | * @param {Function} filterFactory Factory function for creating new instance of filter. 309 | * @description 310 | * See {@link ng.$filterProvider#register $filterProvider.register()}. 311 | */ 312 | filter: invokeLater('$filterProvider', 'register'), 313 | 314 | /** 315 | * @ngdoc method 316 | * @name angular.Module#controller 317 | * @methodOf angular.Module 318 | * @param {string|Object} name Controller name, or an object map of controllers where the 319 | * keys are the names and the values are the constructors. 320 | * @param {Function} constructor Controller constructor function. 321 | * @description 322 | * See {@link ng.$controllerProvider#register $controllerProvider.register()}. 323 | */ 324 | controller: invokeLater('$controllerProvider', 'register'), 325 | 326 | /** 327 | * @ngdoc method 328 | * @name angular.Module#directive 329 | * @methodOf angular.Module 330 | * @param {string|Object} name Directive name, or an object map of directives where the 331 | * keys are the names and the values are the factories. 332 | * @param {Function} directiveFactory Factory function for creating new instance of 333 | * directives. 334 | * @description 335 | * See {@link ng.$compileProvider#methods_directive $compileProvider.directive()}. 336 | */ 337 | directive: invokeLater('$compileProvider', 'directive'), 338 | 339 | /** 340 | * @ngdoc method 341 | * @name angular.Module#config 342 | * @methodOf angular.Module 343 | * @param {Function} configFn Execute this function on module load. Useful for service 344 | * configuration. 345 | * @description 346 | * Use this method to register work which needs to be performed on module loading. 347 | */ 348 | config: config, 349 | 350 | /** 351 | * @ngdoc method 352 | * @name angular.Module#run 353 | * @methodOf angular.Module 354 | * @param {Function} initializationFn Execute this function after injector creation. 355 | * Useful for application initialization. 356 | * @description 357 | * Use this method to register work which should be performed when the injector is done 358 | * loading all modules. 359 | */ 360 | run: function(block) { 361 | runBlocks.push(block); 362 | return this; 363 | } 364 | }; 365 | 366 | if (configFn) { 367 | config(configFn); 368 | } 369 | 370 | return moduleInstance; 371 | 372 | /** 373 | * @param {string} provider 374 | * @param {string} method 375 | * @param {String=} insertMethod 376 | * @returns {angular.Module} 377 | */ 378 | function invokeLater(provider, method, insertMethod) { 379 | return function() { 380 | invokeQueue[insertMethod || 'push']([provider, method, arguments]); 381 | return moduleInstance; 382 | }; 383 | } 384 | }); 385 | }; 386 | }); 387 | 388 | } 389 | 390 | setupModuleLoader(window); 391 | })(window); 392 | 393 | /** 394 | * Closure compiler type information 395 | * 396 | * @typedef { { 397 | * requires: !Array., 398 | * invokeQueue: !Array.>, 399 | * 400 | * service: function(string, Function):angular.Module, 401 | * factory: function(string, Function):angular.Module, 402 | * value: function(string, *):angular.Module, 403 | * 404 | * filter: function(string, Function):angular.Module, 405 | * 406 | * init: function(Function):angular.Module 407 | * } } 408 | */ 409 | angular.Module; 410 | 411 | -------------------------------------------------------------------------------- /www/lib/js/angular-ui/angular-ui-router.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * State-based routing for AngularJS 3 | * @version v0.2.10 4 | * @link http://angular-ui.github.com/ 5 | * @license MIT License, http://www.opensource.org/licenses/MIT 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 "));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-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=x;d--)g=o[d],g.self.onExit&&m.invoke(g.self.onExit,g.self,g.locals.globals),g.locals=null;for(d=x;d1||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); -------------------------------------------------------------------------------- /www/lib/js/angular/angular-touch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license AngularJS v1.2.10 3 | * (c) 2010-2014 Google, Inc. http://angularjs.org 4 | * License: MIT 5 | */ 6 | (function(window, angular, undefined) {'use strict'; 7 | 8 | /** 9 | * @ngdoc overview 10 | * @name ngTouch 11 | * @description 12 | * 13 | * # ngTouch 14 | * 15 | * The `ngTouch` module provides touch events and other helpers for touch-enabled devices. 16 | * The implementation is based on jQuery Mobile touch event handling 17 | * ([jquerymobile.com](http://jquerymobile.com/)). 18 | * 19 | * {@installModule touch} 20 | * 21 | * See {@link ngTouch.$swipe `$swipe`} for usage. 22 | * 23 | *
24 | * 25 | */ 26 | 27 | // define ngTouch module 28 | /* global -ngTouch */ 29 | var ngTouch = angular.module('ngTouch', []); 30 | 31 | /* global ngTouch: false */ 32 | 33 | /** 34 | * @ngdoc object 35 | * @name ngTouch.$swipe 36 | * 37 | * @description 38 | * The `$swipe` service is a service that abstracts the messier details of hold-and-drag swipe 39 | * behavior, to make implementing swipe-related directives more convenient. 40 | * 41 | * Requires the {@link ngTouch `ngTouch`} module to be installed. 42 | * 43 | * `$swipe` is used by the `ngSwipeLeft` and `ngSwipeRight` directives in `ngTouch`, and by 44 | * `ngCarousel` in a separate component. 45 | * 46 | * # Usage 47 | * The `$swipe` service is an object with a single method: `bind`. `bind` takes an element 48 | * which is to be watched for swipes, and an object with four handler functions. See the 49 | * documentation for `bind` below. 50 | */ 51 | 52 | ngTouch.factory('$swipe', [function() { 53 | // The total distance in any direction before we make the call on swipe vs. scroll. 54 | var MOVE_BUFFER_RADIUS = 10; 55 | 56 | function getCoordinates(event) { 57 | var touches = event.touches && event.touches.length ? event.touches : [event]; 58 | var e = (event.changedTouches && event.changedTouches[0]) || 59 | (event.originalEvent && event.originalEvent.changedTouches && 60 | event.originalEvent.changedTouches[0]) || 61 | touches[0].originalEvent || touches[0]; 62 | 63 | return { 64 | x: e.clientX, 65 | y: e.clientY 66 | }; 67 | } 68 | 69 | return { 70 | /** 71 | * @ngdoc method 72 | * @name ngTouch.$swipe#bind 73 | * @methodOf ngTouch.$swipe 74 | * 75 | * @description 76 | * The main method of `$swipe`. It takes an element to be watched for swipe motions, and an 77 | * object containing event handlers. 78 | * 79 | * The four events are `start`, `move`, `end`, and `cancel`. `start`, `move`, and `end` 80 | * receive as a parameter a coordinates object of the form `{ x: 150, y: 310 }`. 81 | * 82 | * `start` is called on either `mousedown` or `touchstart`. After this event, `$swipe` is 83 | * watching for `touchmove` or `mousemove` events. These events are ignored until the total 84 | * distance moved in either dimension exceeds a small threshold. 85 | * 86 | * Once this threshold is exceeded, either the horizontal or vertical delta is greater. 87 | * - If the horizontal distance is greater, this is a swipe and `move` and `end` events follow. 88 | * - If the vertical distance is greater, this is a scroll, and we let the browser take over. 89 | * A `cancel` event is sent. 90 | * 91 | * `move` is called on `mousemove` and `touchmove` after the above logic has determined that 92 | * a swipe is in progress. 93 | * 94 | * `end` is called when a swipe is successfully completed with a `touchend` or `mouseup`. 95 | * 96 | * `cancel` is called either on a `touchcancel` from the browser, or when we begin scrolling 97 | * as described above. 98 | * 99 | */ 100 | bind: function(element, eventHandlers) { 101 | // Absolute total movement, used to control swipe vs. scroll. 102 | var totalX, totalY; 103 | // Coordinates of the start position. 104 | var startCoords; 105 | // Last event's position. 106 | var lastPos; 107 | // Whether a swipe is active. 108 | var active = false; 109 | 110 | element.on('touchstart mousedown', function(event) { 111 | startCoords = getCoordinates(event); 112 | active = true; 113 | totalX = 0; 114 | totalY = 0; 115 | lastPos = startCoords; 116 | eventHandlers['start'] && eventHandlers['start'](startCoords, event); 117 | }); 118 | 119 | element.on('touchcancel', function(event) { 120 | active = false; 121 | eventHandlers['cancel'] && eventHandlers['cancel'](event); 122 | }); 123 | 124 | element.on('touchmove mousemove', function(event) { 125 | if (!active) return; 126 | 127 | // Android will send a touchcancel if it thinks we're starting to scroll. 128 | // So when the total distance (+ or - or both) exceeds 10px in either direction, 129 | // we either: 130 | // - On totalX > totalY, we send preventDefault() and treat this as a swipe. 131 | // - On totalY > totalX, we let the browser handle it as a scroll. 132 | 133 | if (!startCoords) return; 134 | var coords = getCoordinates(event); 135 | 136 | totalX += Math.abs(coords.x - lastPos.x); 137 | totalY += Math.abs(coords.y - lastPos.y); 138 | 139 | lastPos = coords; 140 | 141 | if (totalX < MOVE_BUFFER_RADIUS && totalY < MOVE_BUFFER_RADIUS) { 142 | return; 143 | } 144 | 145 | // One of totalX or totalY has exceeded the buffer, so decide on swipe vs. scroll. 146 | if (totalY > totalX) { 147 | // Allow native scrolling to take over. 148 | active = false; 149 | eventHandlers['cancel'] && eventHandlers['cancel'](event); 150 | return; 151 | } else { 152 | // Prevent the browser from scrolling. 153 | event.preventDefault(); 154 | eventHandlers['move'] && eventHandlers['move'](coords, event); 155 | } 156 | }); 157 | 158 | element.on('touchend mouseup', function(event) { 159 | if (!active) return; 160 | active = false; 161 | eventHandlers['end'] && eventHandlers['end'](getCoordinates(event), event); 162 | }); 163 | } 164 | }; 165 | }]); 166 | 167 | /* global ngTouch: false */ 168 | 169 | /** 170 | * @ngdoc directive 171 | * @name ngTouch.directive:ngClick 172 | * 173 | * @description 174 | * A more powerful replacement for the default ngClick designed to be used on touchscreen 175 | * devices. Most mobile browsers wait about 300ms after a tap-and-release before sending 176 | * the click event. This version handles them immediately, and then prevents the 177 | * following click event from propagating. 178 | * 179 | * Requires the {@link ngTouch `ngTouch`} module to be installed. 180 | * 181 | * This directive can fall back to using an ordinary click event, and so works on desktop 182 | * browsers as well as mobile. 183 | * 184 | * This directive also sets the CSS class `ng-click-active` while the element is being held 185 | * down (by a mouse click or touch) so you can restyle the depressed element if you wish. 186 | * 187 | * @element ANY 188 | * @param {expression} ngClick {@link guide/expression Expression} to evaluate 189 | * upon tap. (Event object is available as `$event`) 190 | * 191 | * @example 192 | 193 | 194 | 197 | count: {{ count }} 198 | 199 | 200 | */ 201 | 202 | ngTouch.config(['$provide', function($provide) { 203 | $provide.decorator('ngClickDirective', ['$delegate', function($delegate) { 204 | // drop the default ngClick directive 205 | $delegate.shift(); 206 | return $delegate; 207 | }]); 208 | }]); 209 | 210 | ngTouch.directive('ngClick', ['$parse', '$timeout', '$rootElement', 211 | function($parse, $timeout, $rootElement) { 212 | var TAP_DURATION = 750; // Shorter than 750ms is a tap, longer is a taphold or drag. 213 | var MOVE_TOLERANCE = 12; // 12px seems to work in most mobile browsers. 214 | var PREVENT_DURATION = 2500; // 2.5 seconds maximum from preventGhostClick call to click 215 | var CLICKBUSTER_THRESHOLD = 25; // 25 pixels in any dimension is the limit for busting clicks. 216 | 217 | var ACTIVE_CLASS_NAME = 'ng-click-active'; 218 | var lastPreventedTime; 219 | var touchCoordinates; 220 | 221 | 222 | // TAP EVENTS AND GHOST CLICKS 223 | // 224 | // Why tap events? 225 | // Mobile browsers detect a tap, then wait a moment (usually ~300ms) to see if you're 226 | // double-tapping, and then fire a click event. 227 | // 228 | // This delay sucks and makes mobile apps feel unresponsive. 229 | // So we detect touchstart, touchmove, touchcancel and touchend ourselves and determine when 230 | // the user has tapped on something. 231 | // 232 | // What happens when the browser then generates a click event? 233 | // The browser, of course, also detects the tap and fires a click after a delay. This results in 234 | // tapping/clicking twice. So we do "clickbusting" to prevent it. 235 | // 236 | // How does it work? 237 | // We attach global touchstart and click handlers, that run during the capture (early) phase. 238 | // So the sequence for a tap is: 239 | // - global touchstart: Sets an "allowable region" at the point touched. 240 | // - element's touchstart: Starts a touch 241 | // (- touchmove or touchcancel ends the touch, no click follows) 242 | // - element's touchend: Determines if the tap is valid (didn't move too far away, didn't hold 243 | // too long) and fires the user's tap handler. The touchend also calls preventGhostClick(). 244 | // - preventGhostClick() removes the allowable region the global touchstart created. 245 | // - The browser generates a click event. 246 | // - The global click handler catches the click, and checks whether it was in an allowable region. 247 | // - If preventGhostClick was called, the region will have been removed, the click is busted. 248 | // - If the region is still there, the click proceeds normally. Therefore clicks on links and 249 | // other elements without ngTap on them work normally. 250 | // 251 | // This is an ugly, terrible hack! 252 | // Yeah, tell me about it. The alternatives are using the slow click events, or making our users 253 | // deal with the ghost clicks, so I consider this the least of evils. Fortunately Angular 254 | // encapsulates this ugly logic away from the user. 255 | // 256 | // Why not just put click handlers on the element? 257 | // We do that too, just to be sure. The problem is that the tap event might have caused the DOM 258 | // to change, so that the click fires in the same position but something else is there now. So 259 | // the handlers are global and care only about coordinates and not elements. 260 | 261 | // Checks if the coordinates are close enough to be within the region. 262 | function hit(x1, y1, x2, y2) { 263 | return Math.abs(x1 - x2) < CLICKBUSTER_THRESHOLD && Math.abs(y1 - y2) < CLICKBUSTER_THRESHOLD; 264 | } 265 | 266 | // Checks a list of allowable regions against a click location. 267 | // Returns true if the click should be allowed. 268 | // Splices out the allowable region from the list after it has been used. 269 | function checkAllowableRegions(touchCoordinates, x, y) { 270 | for (var i = 0; i < touchCoordinates.length; i += 2) { 271 | if (hit(touchCoordinates[i], touchCoordinates[i+1], x, y)) { 272 | touchCoordinates.splice(i, i + 2); 273 | return true; // allowable region 274 | } 275 | } 276 | return false; // No allowable region; bust it. 277 | } 278 | 279 | // Global click handler that prevents the click if it's in a bustable zone and preventGhostClick 280 | // was called recently. 281 | function onClick(event) { 282 | if (Date.now() - lastPreventedTime > PREVENT_DURATION) { 283 | return; // Too old. 284 | } 285 | 286 | var touches = event.touches && event.touches.length ? event.touches : [event]; 287 | var x = touches[0].clientX; 288 | var y = touches[0].clientY; 289 | // Work around desktop Webkit quirk where clicking a label will fire two clicks (on the label 290 | // and on the input element). Depending on the exact browser, this second click we don't want 291 | // to bust has either (0,0) or negative coordinates. 292 | if (x < 1 && y < 1) { 293 | return; // offscreen 294 | } 295 | 296 | // Look for an allowable region containing this click. 297 | // If we find one, that means it was created by touchstart and not removed by 298 | // preventGhostClick, so we don't bust it. 299 | if (checkAllowableRegions(touchCoordinates, x, y)) { 300 | return; 301 | } 302 | 303 | // If we didn't find an allowable region, bust the click. 304 | event.stopPropagation(); 305 | event.preventDefault(); 306 | 307 | // Blur focused form elements 308 | event.target && event.target.blur(); 309 | } 310 | 311 | 312 | // Global touchstart handler that creates an allowable region for a click event. 313 | // This allowable region can be removed by preventGhostClick if we want to bust it. 314 | function onTouchStart(event) { 315 | var touches = event.touches && event.touches.length ? event.touches : [event]; 316 | var x = touches[0].clientX; 317 | var y = touches[0].clientY; 318 | touchCoordinates.push(x, y); 319 | 320 | $timeout(function() { 321 | // Remove the allowable region. 322 | for (var i = 0; i < touchCoordinates.length; i += 2) { 323 | if (touchCoordinates[i] == x && touchCoordinates[i+1] == y) { 324 | touchCoordinates.splice(i, i + 2); 325 | return; 326 | } 327 | } 328 | }, PREVENT_DURATION, false); 329 | } 330 | 331 | // On the first call, attaches some event handlers. Then whenever it gets called, it creates a 332 | // zone around the touchstart where clicks will get busted. 333 | function preventGhostClick(x, y) { 334 | if (!touchCoordinates) { 335 | $rootElement[0].addEventListener('click', onClick, true); 336 | $rootElement[0].addEventListener('touchstart', onTouchStart, true); 337 | touchCoordinates = []; 338 | } 339 | 340 | lastPreventedTime = Date.now(); 341 | 342 | checkAllowableRegions(touchCoordinates, x, y); 343 | } 344 | 345 | // Actual linking function. 346 | return function(scope, element, attr) { 347 | var clickHandler = $parse(attr.ngClick), 348 | tapping = false, 349 | tapElement, // Used to blur the element after a tap. 350 | startTime, // Used to check if the tap was held too long. 351 | touchStartX, 352 | touchStartY; 353 | 354 | function resetState() { 355 | tapping = false; 356 | element.removeClass(ACTIVE_CLASS_NAME); 357 | } 358 | 359 | element.on('touchstart', function(event) { 360 | tapping = true; 361 | tapElement = event.target ? event.target : event.srcElement; // IE uses srcElement. 362 | // Hack for Safari, which can target text nodes instead of containers. 363 | if(tapElement.nodeType == 3) { 364 | tapElement = tapElement.parentNode; 365 | } 366 | 367 | element.addClass(ACTIVE_CLASS_NAME); 368 | 369 | startTime = Date.now(); 370 | 371 | var touches = event.touches && event.touches.length ? event.touches : [event]; 372 | var e = touches[0].originalEvent || touches[0]; 373 | touchStartX = e.clientX; 374 | touchStartY = e.clientY; 375 | }); 376 | 377 | element.on('touchmove', function(event) { 378 | resetState(); 379 | }); 380 | 381 | element.on('touchcancel', function(event) { 382 | resetState(); 383 | }); 384 | 385 | element.on('touchend', function(event) { 386 | var diff = Date.now() - startTime; 387 | 388 | var touches = (event.changedTouches && event.changedTouches.length) ? event.changedTouches : 389 | ((event.touches && event.touches.length) ? event.touches : [event]); 390 | var e = touches[0].originalEvent || touches[0]; 391 | var x = e.clientX; 392 | var y = e.clientY; 393 | var dist = Math.sqrt( Math.pow(x - touchStartX, 2) + Math.pow(y - touchStartY, 2) ); 394 | 395 | if (tapping && diff < TAP_DURATION && dist < MOVE_TOLERANCE) { 396 | // Call preventGhostClick so the clickbuster will catch the corresponding click. 397 | preventGhostClick(x, y); 398 | 399 | // Blur the focused element (the button, probably) before firing the callback. 400 | // This doesn't work perfectly on Android Chrome, but seems to work elsewhere. 401 | // I couldn't get anything to work reliably on Android Chrome. 402 | if (tapElement) { 403 | tapElement.blur(); 404 | } 405 | 406 | if (!angular.isDefined(attr.disabled) || attr.disabled === false) { 407 | element.triggerHandler('click', [event]); 408 | } 409 | } 410 | 411 | resetState(); 412 | }); 413 | 414 | // Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click 415 | // something else nearby. 416 | element.onclick = function(event) { }; 417 | 418 | // Actual click handler. 419 | // There are three different kinds of clicks, only two of which reach this point. 420 | // - On desktop browsers without touch events, their clicks will always come here. 421 | // - On mobile browsers, the simulated "fast" click will call this. 422 | // - But the browser's follow-up slow click will be "busted" before it reaches this handler. 423 | // Therefore it's safe to use this directive on both mobile and desktop. 424 | element.on('click', function(event, touchend) { 425 | scope.$apply(function() { 426 | clickHandler(scope, {$event: (touchend || event)}); 427 | }); 428 | }); 429 | 430 | element.on('mousedown', function(event) { 431 | element.addClass(ACTIVE_CLASS_NAME); 432 | }); 433 | 434 | element.on('mousemove mouseup', function(event) { 435 | element.removeClass(ACTIVE_CLASS_NAME); 436 | }); 437 | 438 | }; 439 | }]); 440 | 441 | /* global ngTouch: false */ 442 | 443 | /** 444 | * @ngdoc directive 445 | * @name ngTouch.directive:ngSwipeLeft 446 | * 447 | * @description 448 | * Specify custom behavior when an element is swiped to the left on a touchscreen device. 449 | * A leftward swipe is a quick, right-to-left slide of the finger. 450 | * Though ngSwipeLeft is designed for touch-based devices, it will work with a mouse click and drag 451 | * too. 452 | * 453 | * Requires the {@link ngTouch `ngTouch`} module to be installed. 454 | * 455 | * @element ANY 456 | * @param {expression} ngSwipeLeft {@link guide/expression Expression} to evaluate 457 | * upon left swipe. (Event object is available as `$event`) 458 | * 459 | * @example 460 | 461 | 462 |
463 | Some list content, like an email in the inbox 464 |
465 |
466 | 467 | 468 |
469 |
470 |
471 | */ 472 | 473 | /** 474 | * @ngdoc directive 475 | * @name ngTouch.directive:ngSwipeRight 476 | * 477 | * @description 478 | * Specify custom behavior when an element is swiped to the right on a touchscreen device. 479 | * A rightward swipe is a quick, left-to-right slide of the finger. 480 | * Though ngSwipeRight is designed for touch-based devices, it will work with a mouse click and drag 481 | * too. 482 | * 483 | * Requires the {@link ngTouch `ngTouch`} module to be installed. 484 | * 485 | * @element ANY 486 | * @param {expression} ngSwipeRight {@link guide/expression Expression} to evaluate 487 | * upon right swipe. (Event object is available as `$event`) 488 | * 489 | * @example 490 | 491 | 492 |
493 | Some list content, like an email in the inbox 494 |
495 |
496 | 497 | 498 |
499 |
500 |
501 | */ 502 | 503 | function makeSwipeDirective(directiveName, direction, eventName) { 504 | ngTouch.directive(directiveName, ['$parse', '$swipe', function($parse, $swipe) { 505 | // The maximum vertical delta for a swipe should be less than 75px. 506 | var MAX_VERTICAL_DISTANCE = 75; 507 | // Vertical distance should not be more than a fraction of the horizontal distance. 508 | var MAX_VERTICAL_RATIO = 0.3; 509 | // At least a 30px lateral motion is necessary for a swipe. 510 | var MIN_HORIZONTAL_DISTANCE = 30; 511 | 512 | return function(scope, element, attr) { 513 | var swipeHandler = $parse(attr[directiveName]); 514 | 515 | var startCoords, valid; 516 | 517 | function validSwipe(coords) { 518 | // Check that it's within the coordinates. 519 | // Absolute vertical distance must be within tolerances. 520 | // Horizontal distance, we take the current X - the starting X. 521 | // This is negative for leftward swipes and positive for rightward swipes. 522 | // After multiplying by the direction (-1 for left, +1 for right), legal swipes 523 | // (ie. same direction as the directive wants) will have a positive delta and 524 | // illegal ones a negative delta. 525 | // Therefore this delta must be positive, and larger than the minimum. 526 | if (!startCoords) return false; 527 | var deltaY = Math.abs(coords.y - startCoords.y); 528 | var deltaX = (coords.x - startCoords.x) * direction; 529 | return valid && // Short circuit for already-invalidated swipes. 530 | deltaY < MAX_VERTICAL_DISTANCE && 531 | deltaX > 0 && 532 | deltaX > MIN_HORIZONTAL_DISTANCE && 533 | deltaY / deltaX < MAX_VERTICAL_RATIO; 534 | } 535 | 536 | $swipe.bind(element, { 537 | 'start': function(coords, event) { 538 | startCoords = coords; 539 | valid = true; 540 | }, 541 | 'cancel': function(event) { 542 | valid = false; 543 | }, 544 | 'end': function(coords, event) { 545 | if (validSwipe(coords)) { 546 | scope.$apply(function() { 547 | element.triggerHandler(eventName); 548 | swipeHandler(scope, {$event: event}); 549 | }); 550 | } 551 | } 552 | }); 553 | }; 554 | }]); 555 | } 556 | 557 | // Left is negative X-coordinate, right is positive. 558 | makeSwipeDirective('ngSwipeLeft', -1, 'swipeleft'); 559 | makeSwipeDirective('ngSwipeRight', 1, 'swiperight'); 560 | 561 | 562 | 563 | })(window, window.angular); 564 | -------------------------------------------------------------------------------- /www/lib/js/angular/angular-sanitize.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license AngularJS v1.2.12 3 | * (c) 2010-2014 Google, Inc. http://angularjs.org 4 | * License: MIT 5 | */ 6 | (function(window, angular, undefined) {'use strict'; 7 | 8 | var $sanitizeMinErr = angular.$$minErr('$sanitize'); 9 | 10 | /** 11 | * @ngdoc overview 12 | * @name ngSanitize 13 | * @description 14 | * 15 | * # ngSanitize 16 | * 17 | * The `ngSanitize` module provides functionality to sanitize HTML. 18 | * 19 | * {@installModule sanitize} 20 | * 21 | *
22 | * 23 | * See {@link ngSanitize.$sanitize `$sanitize`} for usage. 24 | */ 25 | 26 | /* 27 | * HTML Parser By Misko Hevery (misko@hevery.com) 28 | * based on: HTML Parser By John Resig (ejohn.org) 29 | * Original code by Erik Arvidsson, Mozilla Public License 30 | * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js 31 | * 32 | * // Use like so: 33 | * htmlParser(htmlString, { 34 | * start: function(tag, attrs, unary) {}, 35 | * end: function(tag) {}, 36 | * chars: function(text) {}, 37 | * comment: function(text) {} 38 | * }); 39 | * 40 | */ 41 | 42 | 43 | /** 44 | * @ngdoc service 45 | * @name ngSanitize.$sanitize 46 | * @function 47 | * 48 | * @description 49 | * The input is sanitized by parsing the html into tokens. All safe tokens (from a whitelist) are 50 | * then serialized back to properly escaped html string. This means that no unsafe input can make 51 | * it into the returned string, however, since our parser is more strict than a typical browser 52 | * parser, it's possible that some obscure input, which would be recognized as valid HTML by a 53 | * browser, won't make it through the sanitizer. 54 | * The whitelist is configured using the functions `aHrefSanitizationWhitelist` and 55 | * `imgSrcSanitizationWhitelist` of {@link ng.$compileProvider `$compileProvider`}. 56 | * 57 | * @param {string} html Html input. 58 | * @returns {string} Sanitized html. 59 | * 60 | * @example 61 | 62 | 63 | 74 |
75 | Snippet: 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 |
DirectiveHowSourceRendered
ng-bind-htmlAutomatically uses $sanitize
<div ng-bind-html="snippet">
</div>
ng-bind-htmlBypass $sanitize by explicitly trusting the dangerous value 93 |
<div ng-bind-html="deliberatelyTrustDangerousSnippet()">
 94 | </div>
95 |
ng-bindAutomatically escapes
<div ng-bind="snippet">
</div>
105 |
106 |
107 | 108 | it('should sanitize the html snippet by default', function() { 109 | expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()). 110 | toBe('

an html\nclick here\nsnippet

'); 111 | }); 112 | 113 | it('should inline raw snippet if bound to a trusted value', function() { 114 | expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()). 115 | toBe("

an html\n" + 116 | "click here\n" + 117 | "snippet

"); 118 | }); 119 | 120 | it('should escape snippet without any filter', function() { 121 | expect(element(by.css('#bind-default div')).getInnerHtml()). 122 | toBe("<p style=\"color:blue\">an html\n" + 123 | "<em onmouseover=\"this.textContent='PWN3D!'\">click here</em>\n" + 124 | "snippet</p>"); 125 | }); 126 | 127 | it('should update', function() { 128 | element(by.model('snippet')).clear(); 129 | element(by.model('snippet')).sendKeys('new text'); 130 | expect(element(by.css('#bind-html-with-sanitize div')).getInnerHtml()). 131 | toBe('new text'); 132 | expect(element(by.css('#bind-html-with-trust div')).getInnerHtml()).toBe( 133 | 'new text'); 134 | expect(element(by.css('#bind-default div')).getInnerHtml()).toBe( 135 | "new <b onclick=\"alert(1)\">text</b>"); 136 | }); 137 |
138 |
139 | */ 140 | function $SanitizeProvider() { 141 | this.$get = ['$$sanitizeUri', function($$sanitizeUri) { 142 | return function(html) { 143 | var buf = []; 144 | htmlParser(html, htmlSanitizeWriter(buf, function(uri, isImage) { 145 | return !/^unsafe/.test($$sanitizeUri(uri, isImage)); 146 | })); 147 | return buf.join(''); 148 | }; 149 | }]; 150 | } 151 | 152 | function sanitizeText(chars) { 153 | var buf = []; 154 | var writer = htmlSanitizeWriter(buf, angular.noop); 155 | writer.chars(chars); 156 | return buf.join(''); 157 | } 158 | 159 | 160 | // Regular Expressions for parsing tags and attributes 161 | var START_TAG_REGEXP = 162 | /^<\s*([\w:-]+)((?:\s+[\w:-]+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)\s*>/, 163 | END_TAG_REGEXP = /^<\s*\/\s*([\w:-]+)[^>]*>/, 164 | ATTR_REGEXP = /([\w:-]+)(?:\s*=\s*(?:(?:"((?:[^"])*)")|(?:'((?:[^'])*)')|([^>\s]+)))?/g, 165 | BEGIN_TAG_REGEXP = /^/g, 168 | DOCTYPE_REGEXP = /]*?)>/i, 169 | CDATA_REGEXP = //g, 170 | // Match everything outside of normal chars and " (quote character) 171 | NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g; 172 | 173 | 174 | // Good source of info about elements and attributes 175 | // http://dev.w3.org/html5/spec/Overview.html#semantics 176 | // http://simon.html5.org/html-elements 177 | 178 | // Safe Void Elements - HTML5 179 | // http://dev.w3.org/html5/spec/Overview.html#void-elements 180 | var voidElements = makeMap("area,br,col,hr,img,wbr"); 181 | 182 | // Elements that you can, intentionally, leave open (and which close themselves) 183 | // http://dev.w3.org/html5/spec/Overview.html#optional-tags 184 | var optionalEndTagBlockElements = makeMap("colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr"), 185 | optionalEndTagInlineElements = makeMap("rp,rt"), 186 | optionalEndTagElements = angular.extend({}, 187 | optionalEndTagInlineElements, 188 | optionalEndTagBlockElements); 189 | 190 | // Safe Block Elements - HTML5 191 | var blockElements = angular.extend({}, optionalEndTagBlockElements, makeMap("address,article," + 192 | "aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5," + 193 | "h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul")); 194 | 195 | // Inline Elements - HTML5 196 | var inlineElements = angular.extend({}, optionalEndTagInlineElements, makeMap("a,abbr,acronym,b," + 197 | "bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s," + 198 | "samp,small,span,strike,strong,sub,sup,time,tt,u,var")); 199 | 200 | 201 | // Special Elements (can contain anything) 202 | var specialElements = makeMap("script,style"); 203 | 204 | var validElements = angular.extend({}, 205 | voidElements, 206 | blockElements, 207 | inlineElements, 208 | optionalEndTagElements); 209 | 210 | //Attributes that have href and hence need to be sanitized 211 | var uriAttrs = makeMap("background,cite,href,longdesc,src,usemap"); 212 | var validAttrs = angular.extend({}, uriAttrs, makeMap( 213 | 'abbr,align,alt,axis,bgcolor,border,cellpadding,cellspacing,class,clear,'+ 214 | 'color,cols,colspan,compact,coords,dir,face,headers,height,hreflang,hspace,'+ 215 | 'ismap,lang,language,nohref,nowrap,rel,rev,rows,rowspan,rules,'+ 216 | 'scope,scrolling,shape,size,span,start,summary,target,title,type,'+ 217 | 'valign,value,vspace,width')); 218 | 219 | function makeMap(str) { 220 | var obj = {}, items = str.split(','), i; 221 | for (i = 0; i < items.length; i++) obj[items[i]] = true; 222 | return obj; 223 | } 224 | 225 | 226 | /** 227 | * @example 228 | * htmlParser(htmlString, { 229 | * start: function(tag, attrs, unary) {}, 230 | * end: function(tag) {}, 231 | * chars: function(text) {}, 232 | * comment: function(text) {} 233 | * }); 234 | * 235 | * @param {string} html string 236 | * @param {object} handler 237 | */ 238 | function htmlParser( html, handler ) { 239 | var index, chars, match, stack = [], last = html; 240 | stack.last = function() { return stack[ stack.length - 1 ]; }; 241 | 242 | while ( html ) { 243 | chars = true; 244 | 245 | // Make sure we're not in a script or style element 246 | if ( !stack.last() || !specialElements[ stack.last() ] ) { 247 | 248 | // Comment 249 | if ( html.indexOf("", index) === index) { 254 | if (handler.comment) handler.comment( html.substring( 4, index ) ); 255 | html = html.substring( index + 3 ); 256 | chars = false; 257 | } 258 | // DOCTYPE 259 | } else if ( DOCTYPE_REGEXP.test(html) ) { 260 | match = html.match( DOCTYPE_REGEXP ); 261 | 262 | if ( match ) { 263 | html = html.replace( match[0] , ''); 264 | chars = false; 265 | } 266 | // end tag 267 | } else if ( BEGING_END_TAGE_REGEXP.test(html) ) { 268 | match = html.match( END_TAG_REGEXP ); 269 | 270 | if ( match ) { 271 | html = html.substring( match[0].length ); 272 | match[0].replace( END_TAG_REGEXP, parseEndTag ); 273 | chars = false; 274 | } 275 | 276 | // start tag 277 | } else if ( BEGIN_TAG_REGEXP.test(html) ) { 278 | match = html.match( START_TAG_REGEXP ); 279 | 280 | if ( match ) { 281 | html = html.substring( match[0].length ); 282 | match[0].replace( START_TAG_REGEXP, parseStartTag ); 283 | chars = false; 284 | } 285 | } 286 | 287 | if ( chars ) { 288 | index = html.indexOf("<"); 289 | 290 | var text = index < 0 ? html : html.substring( 0, index ); 291 | html = index < 0 ? "" : html.substring( index ); 292 | 293 | if (handler.chars) handler.chars( decodeEntities(text) ); 294 | } 295 | 296 | } else { 297 | html = html.replace(new RegExp("(.*)<\\s*\\/\\s*" + stack.last() + "[^>]*>", 'i'), 298 | function(all, text){ 299 | text = text.replace(COMMENT_REGEXP, "$1").replace(CDATA_REGEXP, "$1"); 300 | 301 | if (handler.chars) handler.chars( decodeEntities(text) ); 302 | 303 | return ""; 304 | }); 305 | 306 | parseEndTag( "", stack.last() ); 307 | } 308 | 309 | if ( html == last ) { 310 | throw $sanitizeMinErr('badparse', "The sanitizer was unable to parse the following block " + 311 | "of html: {0}", html); 312 | } 313 | last = html; 314 | } 315 | 316 | // Clean up any remaining tags 317 | parseEndTag(); 318 | 319 | function parseStartTag( tag, tagName, rest, unary ) { 320 | tagName = angular.lowercase(tagName); 321 | if ( blockElements[ tagName ] ) { 322 | while ( stack.last() && inlineElements[ stack.last() ] ) { 323 | parseEndTag( "", stack.last() ); 324 | } 325 | } 326 | 327 | if ( optionalEndTagElements[ tagName ] && stack.last() == tagName ) { 328 | parseEndTag( "", tagName ); 329 | } 330 | 331 | unary = voidElements[ tagName ] || !!unary; 332 | 333 | if ( !unary ) 334 | stack.push( tagName ); 335 | 336 | var attrs = {}; 337 | 338 | rest.replace(ATTR_REGEXP, 339 | function(match, name, doubleQuotedValue, singleQuotedValue, unquotedValue) { 340 | var value = doubleQuotedValue 341 | || singleQuotedValue 342 | || unquotedValue 343 | || ''; 344 | 345 | attrs[name] = decodeEntities(value); 346 | }); 347 | if (handler.start) handler.start( tagName, attrs, unary ); 348 | } 349 | 350 | function parseEndTag( tag, tagName ) { 351 | var pos = 0, i; 352 | tagName = angular.lowercase(tagName); 353 | if ( tagName ) 354 | // Find the closest opened tag of the same type 355 | for ( pos = stack.length - 1; pos >= 0; pos-- ) 356 | if ( stack[ pos ] == tagName ) 357 | break; 358 | 359 | if ( pos >= 0 ) { 360 | // Close all the open elements, up the stack 361 | for ( i = stack.length - 1; i >= pos; i-- ) 362 | if (handler.end) handler.end( stack[ i ] ); 363 | 364 | // Remove the open elements from the stack 365 | stack.length = pos; 366 | } 367 | } 368 | } 369 | 370 | var hiddenPre=document.createElement("pre"); 371 | var spaceRe = /^(\s*)([\s\S]*?)(\s*)$/; 372 | /** 373 | * decodes all entities into regular string 374 | * @param value 375 | * @returns {string} A string with decoded entities. 376 | */ 377 | function decodeEntities(value) { 378 | if (!value) { return ''; } 379 | 380 | // Note: IE8 does not preserve spaces at the start/end of innerHTML 381 | // so we must capture them and reattach them afterward 382 | var parts = spaceRe.exec(value); 383 | var spaceBefore = parts[1]; 384 | var spaceAfter = parts[3]; 385 | var content = parts[2]; 386 | if (content) { 387 | hiddenPre.innerHTML=content.replace(//g, '>'); 413 | } 414 | 415 | /** 416 | * create an HTML/XML writer which writes to buffer 417 | * @param {Array} buf use buf.jain('') to get out sanitized html string 418 | * @returns {object} in the form of { 419 | * start: function(tag, attrs, unary) {}, 420 | * end: function(tag) {}, 421 | * chars: function(text) {}, 422 | * comment: function(text) {} 423 | * } 424 | */ 425 | function htmlSanitizeWriter(buf, uriValidator){ 426 | var ignore = false; 427 | var out = angular.bind(buf, buf.push); 428 | return { 429 | start: function(tag, attrs, unary){ 430 | tag = angular.lowercase(tag); 431 | if (!ignore && specialElements[tag]) { 432 | ignore = tag; 433 | } 434 | if (!ignore && validElements[tag] === true) { 435 | out('<'); 436 | out(tag); 437 | angular.forEach(attrs, function(value, key){ 438 | var lkey=angular.lowercase(key); 439 | var isImage = (tag === 'img' && lkey === 'src') || (lkey === 'background'); 440 | if (validAttrs[lkey] === true && 441 | (uriAttrs[lkey] !== true || uriValidator(value, isImage))) { 442 | out(' '); 443 | out(key); 444 | out('="'); 445 | out(encodeEntities(value)); 446 | out('"'); 447 | } 448 | }); 449 | out(unary ? '/>' : '>'); 450 | } 451 | }, 452 | end: function(tag){ 453 | tag = angular.lowercase(tag); 454 | if (!ignore && validElements[tag] === true) { 455 | out(''); 458 | } 459 | if (tag == ignore) { 460 | ignore = false; 461 | } 462 | }, 463 | chars: function(chars){ 464 | if (!ignore) { 465 | out(encodeEntities(chars)); 466 | } 467 | } 468 | }; 469 | } 470 | 471 | 472 | // define ngSanitize module and register $sanitize service 473 | angular.module('ngSanitize', []).provider('$sanitize', $SanitizeProvider); 474 | 475 | /* global sanitizeText: false */ 476 | 477 | /** 478 | * @ngdoc filter 479 | * @name ngSanitize.filter:linky 480 | * @function 481 | * 482 | * @description 483 | * Finds links in text input and turns them into html links. Supports http/https/ftp/mailto and 484 | * plain email address links. 485 | * 486 | * Requires the {@link ngSanitize `ngSanitize`} module to be installed. 487 | * 488 | * @param {string} text Input text. 489 | * @param {string} target Window (_blank|_self|_parent|_top) or named frame to open links in. 490 | * @returns {string} Html-linkified text. 491 | * 492 | * @usage 493 | 494 | * 495 | * @example 496 | 497 | 498 | 509 |
510 | Snippet: 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 522 | 525 | 526 | 527 | 528 | 531 | 534 | 535 | 536 | 537 | 538 | 539 | 540 |
FilterSourceRendered
linky filter 520 |
<div ng-bind-html="snippet | linky">
</div>
521 |
523 |
524 |
linky target 529 |
<div ng-bind-html="snippetWithTarget | linky:'_blank'">
</div>
530 |
532 |
533 |
no filter
<div ng-bind="snippet">
</div>
541 | 542 | 543 | it('should linkify the snippet with urls', function() { 544 | expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()). 545 | toBe('Pretty text with some links: http://angularjs.org/, us@somewhere.org, ' + 546 | 'another@somewhere.org, and one more: ftp://127.0.0.1/.'); 547 | expect(element.all(by.css('#linky-filter a')).count()).toEqual(4); 548 | }); 549 | 550 | it('should not linkify snippet without the linky filter', function() { 551 | expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()). 552 | toBe('Pretty text with some links: http://angularjs.org/, mailto:us@somewhere.org, ' + 553 | 'another@somewhere.org, and one more: ftp://127.0.0.1/.'); 554 | expect(element.all(by.css('#escaped-html a')).count()).toEqual(0); 555 | }); 556 | 557 | it('should update', function() { 558 | element(by.model('snippet')).clear(); 559 | element(by.model('snippet')).sendKeys('new http://link.'); 560 | expect(element(by.id('linky-filter')).element(by.binding('snippet | linky')).getText()). 561 | toBe('new http://link.'); 562 | expect(element.all(by.css('#linky-filter a')).count()).toEqual(1); 563 | expect(element(by.id('escaped-html')).element(by.binding('snippet')).getText()) 564 | .toBe('new http://link.'); 565 | }); 566 | 567 | it('should work with the target property', function() { 568 | expect(element(by.id('linky-target')). 569 | element(by.binding("snippetWithTarget | linky:'_blank'")).getText()). 570 | toBe('http://angularjs.org/'); 571 | expect(element(by.css('#linky-target a')).getAttribute('target')).toEqual('_blank'); 572 | }); 573 | 574 | 575 | */ 576 | angular.module('ngSanitize').filter('linky', ['$sanitize', function($sanitize) { 577 | var LINKY_URL_REGEXP = 578 | /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s.;,(){}<>]/, 579 | MAILTO_REGEXP = /^mailto:/; 580 | 581 | return function(text, target) { 582 | if (!text) return text; 583 | var match; 584 | var raw = text; 585 | var html = []; 586 | var url; 587 | var i; 588 | while ((match = raw.match(LINKY_URL_REGEXP))) { 589 | // We can not end in these as they are sometimes found at the end of the sentence 590 | url = match[0]; 591 | // if we did not match ftp/http/mailto then assume mailto 592 | if (match[2] == match[3]) url = 'mailto:' + url; 593 | i = match.index; 594 | addText(raw.substr(0, i)); 595 | addLink(url, match[0].replace(MAILTO_REGEXP, '')); 596 | raw = raw.substring(i + match[0].length); 597 | } 598 | addText(raw); 599 | return $sanitize(html.join('')); 600 | 601 | function addText(text) { 602 | if (!text) { 603 | return; 604 | } 605 | html.push(sanitizeText(text)); 606 | } 607 | 608 | function addLink(url, text) { 609 | html.push(''); 618 | addText(text); 619 | html.push(''); 620 | } 621 | }; 622 | }]); 623 | 624 | 625 | })(window, window.angular); 626 | -------------------------------------------------------------------------------- /www/lib/js/angular/angular-resource.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license AngularJS v1.2.12 3 | * (c) 2010-2014 Google, Inc. http://angularjs.org 4 | * License: MIT 5 | */ 6 | (function(window, angular, undefined) {'use strict'; 7 | 8 | var $resourceMinErr = angular.$$minErr('$resource'); 9 | 10 | // Helper functions and regex to lookup a dotted path on an object 11 | // stopping at undefined/null. The path must be composed of ASCII 12 | // identifiers (just like $parse) 13 | var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/; 14 | 15 | function isValidDottedPath(path) { 16 | return (path != null && path !== '' && path !== 'hasOwnProperty' && 17 | MEMBER_NAME_REGEX.test('.' + path)); 18 | } 19 | 20 | function lookupDottedPath(obj, path) { 21 | if (!isValidDottedPath(path)) { 22 | throw $resourceMinErr('badmember', 'Dotted member path "@{0}" is invalid.', path); 23 | } 24 | var keys = path.split('.'); 25 | for (var i = 0, ii = keys.length; i < ii && obj !== undefined; i++) { 26 | var key = keys[i]; 27 | obj = (obj !== null) ? obj[key] : undefined; 28 | } 29 | return obj; 30 | } 31 | 32 | /** 33 | * Create a shallow copy of an object and clear other fields from the destination 34 | */ 35 | function shallowClearAndCopy(src, dst) { 36 | dst = dst || {}; 37 | 38 | angular.forEach(dst, function(value, key){ 39 | delete dst[key]; 40 | }); 41 | 42 | for (var key in src) { 43 | if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) { 44 | dst[key] = src[key]; 45 | } 46 | } 47 | 48 | return dst; 49 | } 50 | 51 | /** 52 | * @ngdoc overview 53 | * @name ngResource 54 | * @description 55 | * 56 | * # ngResource 57 | * 58 | * The `ngResource` module provides interaction support with RESTful services 59 | * via the $resource service. 60 | * 61 | * {@installModule resource} 62 | * 63 | *
64 | * 65 | * See {@link ngResource.$resource `$resource`} for usage. 66 | */ 67 | 68 | /** 69 | * @ngdoc object 70 | * @name ngResource.$resource 71 | * @requires $http 72 | * 73 | * @description 74 | * A factory which creates a resource object that lets you interact with 75 | * [RESTful](http://en.wikipedia.org/wiki/Representational_State_Transfer) server-side data sources. 76 | * 77 | * The returned resource object has action methods which provide high-level behaviors without 78 | * the need to interact with the low level {@link ng.$http $http} service. 79 | * 80 | * Requires the {@link ngResource `ngResource`} module to be installed. 81 | * 82 | * @param {string} url A parametrized URL template with parameters prefixed by `:` as in 83 | * `/user/:username`. If you are using a URL with a port number (e.g. 84 | * `http://example.com:8080/api`), it will be respected. 85 | * 86 | * If you are using a url with a suffix, just add the suffix, like this: 87 | * `$resource('http://example.com/resource.json')` or `$resource('http://example.com/:id.json')` 88 | * or even `$resource('http://example.com/resource/:resource_id.:format')` 89 | * If the parameter before the suffix is empty, :resource_id in this case, then the `/.` will be 90 | * collapsed down to a single `.`. If you need this sequence to appear and not collapse then you 91 | * can escape it with `/\.`. 92 | * 93 | * @param {Object=} paramDefaults Default values for `url` parameters. These can be overridden in 94 | * `actions` methods. If any of the parameter value is a function, it will be executed every time 95 | * when a param value needs to be obtained for a request (unless the param was overridden). 96 | * 97 | * Each key value in the parameter object is first bound to url template if present and then any 98 | * excess keys are appended to the url search query after the `?`. 99 | * 100 | * Given a template `/path/:verb` and parameter `{verb:'greet', salutation:'Hello'}` results in 101 | * URL `/path/greet?salutation=Hello`. 102 | * 103 | * If the parameter value is prefixed with `@` then the value of that parameter is extracted from 104 | * the data object (useful for non-GET operations). 105 | * 106 | * @param {Object.=} actions Hash with declaration of custom action that should extend the 107 | * default set of resource actions. The declaration should be created in the format of {@link 108 | * ng.$http#usage_parameters $http.config}: 109 | * 110 | * {action1: {method:?, params:?, isArray:?, headers:?, ...}, 111 | * action2: {method:?, params:?, isArray:?, headers:?, ...}, 112 | * ...} 113 | * 114 | * Where: 115 | * 116 | * - **`action`** – {string} – The name of action. This name becomes the name of the method on 117 | * your resource object. 118 | * - **`method`** – {string} – HTTP request method. Valid methods are: `GET`, `POST`, `PUT`, 119 | * `DELETE`, and `JSONP`. 120 | * - **`params`** – {Object=} – Optional set of pre-bound parameters for this action. If any of 121 | * the parameter value is a function, it will be executed every time when a param value needs to 122 | * be obtained for a request (unless the param was overridden). 123 | * - **`url`** – {string} – action specific `url` override. The url templating is supported just 124 | * like for the resource-level urls. 125 | * - **`isArray`** – {boolean=} – If true then the returned object for this action is an array, 126 | * see `returns` section. 127 | * - **`transformRequest`** – 128 | * `{function(data, headersGetter)|Array.}` – 129 | * transform function or an array of such functions. The transform function takes the http 130 | * request body and headers and returns its transformed (typically serialized) version. 131 | * - **`transformResponse`** – 132 | * `{function(data, headersGetter)|Array.}` – 133 | * transform function or an array of such functions. The transform function takes the http 134 | * response body and headers and returns its transformed (typically deserialized) version. 135 | * - **`cache`** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the 136 | * GET request, otherwise if a cache instance built with 137 | * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for 138 | * caching. 139 | * - **`timeout`** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise} that 140 | * should abort the request when resolved. 141 | * - **`withCredentials`** - `{boolean}` - whether to set the `withCredentials` flag on the 142 | * XHR object. See {@link https://developer.mozilla.org/en/http_access_control#section_5 143 | * requests with credentials} for more information. 144 | * - **`responseType`** - `{string}` - see {@link 145 | * https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest#responseType requestType}. 146 | * - **`interceptor`** - `{Object=}` - The interceptor object has two optional methods - 147 | * `response` and `responseError`. Both `response` and `responseError` interceptors get called 148 | * with `http response` object. See {@link ng.$http $http interceptors}. 149 | * 150 | * @returns {Object} A resource "class" object with methods for the default set of resource actions 151 | * optionally extended with custom `actions`. The default set contains these actions: 152 | * 153 | * { 'get': {method:'GET'}, 154 | * 'save': {method:'POST'}, 155 | * 'query': {method:'GET', isArray:true}, 156 | * 'remove': {method:'DELETE'}, 157 | * 'delete': {method:'DELETE'} }; 158 | * 159 | * Calling these methods invoke an {@link ng.$http} with the specified http method, 160 | * destination and parameters. When the data is returned from the server then the object is an 161 | * instance of the resource class. The actions `save`, `remove` and `delete` are available on it 162 | * as methods with the `$` prefix. This allows you to easily perform CRUD operations (create, 163 | * read, update, delete) on server-side data like this: 164 | *
165 |         var User = $resource('/user/:userId', {userId:'@id'});
166 |         var user = User.get({userId:123}, function() {
167 |           user.abc = true;
168 |           user.$save();
169 |         });
170 |      
171 | * 172 | * It is important to realize that invoking a $resource object method immediately returns an 173 | * empty reference (object or array depending on `isArray`). Once the data is returned from the 174 | * server the existing reference is populated with the actual data. This is a useful trick since 175 | * usually the resource is assigned to a model which is then rendered by the view. Having an empty 176 | * object results in no rendering, once the data arrives from the server then the object is 177 | * populated with the data and the view automatically re-renders itself showing the new data. This 178 | * means that in most cases one never has to write a callback function for the action methods. 179 | * 180 | * The action methods on the class object or instance object can be invoked with the following 181 | * parameters: 182 | * 183 | * - HTTP GET "class" actions: `Resource.action([parameters], [success], [error])` 184 | * - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])` 185 | * - non-GET instance actions: `instance.$action([parameters], [success], [error])` 186 | * 187 | * Success callback is called with (value, responseHeaders) arguments. Error callback is called 188 | * with (httpResponse) argument. 189 | * 190 | * Class actions return empty instance (with additional properties below). 191 | * Instance actions return promise of the action. 192 | * 193 | * The Resource instances and collection have these additional properties: 194 | * 195 | * - `$promise`: the {@link ng.$q promise} of the original server interaction that created this 196 | * instance or collection. 197 | * 198 | * On success, the promise is resolved with the same resource instance or collection object, 199 | * updated with data from server. This makes it easy to use in 200 | * {@link ngRoute.$routeProvider resolve section of $routeProvider.when()} to defer view 201 | * rendering until the resource(s) are loaded. 202 | * 203 | * On failure, the promise is resolved with the {@link ng.$http http response} object, without 204 | * the `resource` property. 205 | * 206 | * - `$resolved`: `true` after first server interaction is completed (either with success or 207 | * rejection), `false` before that. Knowing if the Resource has been resolved is useful in 208 | * data-binding. 209 | * 210 | * @example 211 | * 212 | * # Credit card resource 213 | * 214 | *
215 |      // Define CreditCard class
216 |      var CreditCard = $resource('/user/:userId/card/:cardId',
217 |       {userId:123, cardId:'@id'}, {
218 |        charge: {method:'POST', params:{charge:true}}
219 |       });
220 | 
221 |      // We can retrieve a collection from the server
222 |      var cards = CreditCard.query(function() {
223 |        // GET: /user/123/card
224 |        // server returns: [ {id:456, number:'1234', name:'Smith'} ];
225 | 
226 |        var card = cards[0];
227 |        // each item is an instance of CreditCard
228 |        expect(card instanceof CreditCard).toEqual(true);
229 |        card.name = "J. Smith";
230 |        // non GET methods are mapped onto the instances
231 |        card.$save();
232 |        // POST: /user/123/card/456 {id:456, number:'1234', name:'J. Smith'}
233 |        // server returns: {id:456, number:'1234', name: 'J. Smith'};
234 | 
235 |        // our custom method is mapped as well.
236 |        card.$charge({amount:9.99});
237 |        // POST: /user/123/card/456?amount=9.99&charge=true {id:456, number:'1234', name:'J. Smith'}
238 |      });
239 | 
240 |      // we can create an instance as well
241 |      var newCard = new CreditCard({number:'0123'});
242 |      newCard.name = "Mike Smith";
243 |      newCard.$save();
244 |      // POST: /user/123/card {number:'0123', name:'Mike Smith'}
245 |      // server returns: {id:789, number:'0123', name: 'Mike Smith'};
246 |      expect(newCard.id).toEqual(789);
247 |  * 
248 | * 249 | * The object returned from this function execution is a resource "class" which has "static" method 250 | * for each action in the definition. 251 | * 252 | * Calling these methods invoke `$http` on the `url` template with the given `method`, `params` and 253 | * `headers`. 254 | * When the data is returned from the server then the object is an instance of the resource type and 255 | * all of the non-GET methods are available with `$` prefix. This allows you to easily support CRUD 256 | * operations (create, read, update, delete) on server-side data. 257 | 258 |
259 |      var User = $resource('/user/:userId', {userId:'@id'});
260 |      var user = User.get({userId:123}, function() {
261 |        user.abc = true;
262 |        user.$save();
263 |      });
264 |    
265 | * 266 | * It's worth noting that the success callback for `get`, `query` and other methods gets passed 267 | * in the response that came from the server as well as $http header getter function, so one 268 | * could rewrite the above example and get access to http headers as: 269 | * 270 |
271 |      var User = $resource('/user/:userId', {userId:'@id'});
272 |      User.get({userId:123}, function(u, getResponseHeaders){
273 |        u.abc = true;
274 |        u.$save(function(u, putResponseHeaders) {
275 |          //u => saved user object
276 |          //putResponseHeaders => $http header getter
277 |        });
278 |      });
279 |    
280 | 281 | * # Creating a custom 'PUT' request 282 | * In this example we create a custom method on our resource to make a PUT request 283 | *
284 |  *		var app = angular.module('app', ['ngResource', 'ngRoute']);
285 |  *
286 |  *		// Some APIs expect a PUT request in the format URL/object/ID
287 |  *		// Here we are creating an 'update' method 
288 |  *		app.factory('Notes', ['$resource', function($resource) {
289 |  *    return $resource('/notes/:id', null,
290 |  *        {
291 |  *            'update': { method:'PUT' }
292 |  *        });
293 |  *		}]);
294 |  *
295 |  *		// In our controller we get the ID from the URL using ngRoute and $routeParams
296 |  *		// We pass in $routeParams and our Notes factory along with $scope
297 |  *		app.controller('NotesCtrl', ['$scope', '$routeParams', 'Notes',
298 |                                       function($scope, $routeParams, Notes) {
299 |  *    // First get a note object from the factory
300 |  *    var note = Notes.get({ id:$routeParams.id });
301 |  *    $id = note.id;
302 |  *
303 |  *    // Now call update passing in the ID first then the object you are updating
304 |  *    Notes.update({ id:$id }, note);
305 |  *
306 |  *    // This will PUT /notes/ID with the note object in the request payload
307 |  *		}]);
308 |  * 
309 | */ 310 | angular.module('ngResource', ['ng']). 311 | factory('$resource', ['$http', '$q', function($http, $q) { 312 | 313 | var DEFAULT_ACTIONS = { 314 | 'get': {method:'GET'}, 315 | 'save': {method:'POST'}, 316 | 'query': {method:'GET', isArray:true}, 317 | 'remove': {method:'DELETE'}, 318 | 'delete': {method:'DELETE'} 319 | }; 320 | var noop = angular.noop, 321 | forEach = angular.forEach, 322 | extend = angular.extend, 323 | copy = angular.copy, 324 | isFunction = angular.isFunction; 325 | 326 | /** 327 | * We need our custom method because encodeURIComponent is too aggressive and doesn't follow 328 | * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path 329 | * segments: 330 | * segment = *pchar 331 | * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" 332 | * pct-encoded = "%" HEXDIG HEXDIG 333 | * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 334 | * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" 335 | * / "*" / "+" / "," / ";" / "=" 336 | */ 337 | function encodeUriSegment(val) { 338 | return encodeUriQuery(val, true). 339 | replace(/%26/gi, '&'). 340 | replace(/%3D/gi, '='). 341 | replace(/%2B/gi, '+'); 342 | } 343 | 344 | 345 | /** 346 | * This method is intended for encoding *key* or *value* parts of query component. We need a 347 | * custom method because encodeURIComponent is too aggressive and encodes stuff that doesn't 348 | * have to be encoded per http://tools.ietf.org/html/rfc3986: 349 | * query = *( pchar / "/" / "?" ) 350 | * pchar = unreserved / pct-encoded / sub-delims / ":" / "@" 351 | * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 352 | * pct-encoded = "%" HEXDIG HEXDIG 353 | * sub-delims = "!" / "$" / "&" / "'" / "(" / ")" 354 | * / "*" / "+" / "," / ";" / "=" 355 | */ 356 | function encodeUriQuery(val, pctEncodeSpaces) { 357 | return encodeURIComponent(val). 358 | replace(/%40/gi, '@'). 359 | replace(/%3A/gi, ':'). 360 | replace(/%24/g, '$'). 361 | replace(/%2C/gi, ','). 362 | replace(/%20/g, (pctEncodeSpaces ? '%20' : '+')); 363 | } 364 | 365 | function Route(template, defaults) { 366 | this.template = template; 367 | this.defaults = defaults || {}; 368 | this.urlParams = {}; 369 | } 370 | 371 | Route.prototype = { 372 | setUrlParams: function(config, params, actionUrl) { 373 | var self = this, 374 | url = actionUrl || self.template, 375 | val, 376 | encodedVal; 377 | 378 | var urlParams = self.urlParams = {}; 379 | forEach(url.split(/\W/), function(param){ 380 | if (param === 'hasOwnProperty') { 381 | throw $resourceMinErr('badname', "hasOwnProperty is not a valid parameter name."); 382 | } 383 | if (!(new RegExp("^\\d+$").test(param)) && param && 384 | (new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) { 385 | urlParams[param] = true; 386 | } 387 | }); 388 | url = url.replace(/\\:/g, ':'); 389 | 390 | params = params || {}; 391 | forEach(self.urlParams, function(_, urlParam){ 392 | val = params.hasOwnProperty(urlParam) ? params[urlParam] : self.defaults[urlParam]; 393 | if (angular.isDefined(val) && val !== null) { 394 | encodedVal = encodeUriSegment(val); 395 | url = url.replace(new RegExp(":" + urlParam + "(\\W|$)", "g"), function(match, p1) { 396 | return encodedVal + p1; 397 | }); 398 | } else { 399 | url = url.replace(new RegExp("(\/?):" + urlParam + "(\\W|$)", "g"), function(match, 400 | leadingSlashes, tail) { 401 | if (tail.charAt(0) == '/') { 402 | return tail; 403 | } else { 404 | return leadingSlashes + tail; 405 | } 406 | }); 407 | } 408 | }); 409 | 410 | // strip trailing slashes and set the url 411 | url = url.replace(/\/+$/, '') || '/'; 412 | // then replace collapse `/.` if found in the last URL path segment before the query 413 | // E.g. `http://url.com/id./format?q=x` becomes `http://url.com/id.format?q=x` 414 | url = url.replace(/\/\.(?=\w+($|\?))/, '.'); 415 | // replace escaped `/\.` with `/.` 416 | config.url = url.replace(/\/\\\./, '/.'); 417 | 418 | 419 | // set params - delegate param encoding to $http 420 | forEach(params, function(value, key){ 421 | if (!self.urlParams[key]) { 422 | config.params = config.params || {}; 423 | config.params[key] = value; 424 | } 425 | }); 426 | } 427 | }; 428 | 429 | 430 | function resourceFactory(url, paramDefaults, actions) { 431 | var route = new Route(url); 432 | 433 | actions = extend({}, DEFAULT_ACTIONS, actions); 434 | 435 | function extractParams(data, actionParams){ 436 | var ids = {}; 437 | actionParams = extend({}, paramDefaults, actionParams); 438 | forEach(actionParams, function(value, key){ 439 | if (isFunction(value)) { value = value(); } 440 | ids[key] = value && value.charAt && value.charAt(0) == '@' ? 441 | lookupDottedPath(data, value.substr(1)) : value; 442 | }); 443 | return ids; 444 | } 445 | 446 | function defaultResponseInterceptor(response) { 447 | return response.resource; 448 | } 449 | 450 | function Resource(value){ 451 | shallowClearAndCopy(value || {}, this); 452 | } 453 | 454 | forEach(actions, function(action, name) { 455 | var hasBody = /^(POST|PUT|PATCH)$/i.test(action.method); 456 | 457 | Resource[name] = function(a1, a2, a3, a4) { 458 | var params = {}, data, success, error; 459 | 460 | /* jshint -W086 */ /* (purposefully fall through case statements) */ 461 | switch(arguments.length) { 462 | case 4: 463 | error = a4; 464 | success = a3; 465 | //fallthrough 466 | case 3: 467 | case 2: 468 | if (isFunction(a2)) { 469 | if (isFunction(a1)) { 470 | success = a1; 471 | error = a2; 472 | break; 473 | } 474 | 475 | success = a2; 476 | error = a3; 477 | //fallthrough 478 | } else { 479 | params = a1; 480 | data = a2; 481 | success = a3; 482 | break; 483 | } 484 | case 1: 485 | if (isFunction(a1)) success = a1; 486 | else if (hasBody) data = a1; 487 | else params = a1; 488 | break; 489 | case 0: break; 490 | default: 491 | throw $resourceMinErr('badargs', 492 | "Expected up to 4 arguments [params, data, success, error], got {0} arguments", 493 | arguments.length); 494 | } 495 | /* jshint +W086 */ /* (purposefully fall through case statements) */ 496 | 497 | var isInstanceCall = this instanceof Resource; 498 | var value = isInstanceCall ? data : (action.isArray ? [] : new Resource(data)); 499 | var httpConfig = {}; 500 | var responseInterceptor = action.interceptor && action.interceptor.response || 501 | defaultResponseInterceptor; 502 | var responseErrorInterceptor = action.interceptor && action.interceptor.responseError || 503 | undefined; 504 | 505 | forEach(action, function(value, key) { 506 | if (key != 'params' && key != 'isArray' && key != 'interceptor') { 507 | httpConfig[key] = copy(value); 508 | } 509 | }); 510 | 511 | if (hasBody) httpConfig.data = data; 512 | route.setUrlParams(httpConfig, 513 | extend({}, extractParams(data, action.params || {}), params), 514 | action.url); 515 | 516 | var promise = $http(httpConfig).then(function(response) { 517 | var data = response.data, 518 | promise = value.$promise; 519 | 520 | if (data) { 521 | // Need to convert action.isArray to boolean in case it is undefined 522 | // jshint -W018 523 | if (angular.isArray(data) !== (!!action.isArray)) { 524 | throw $resourceMinErr('badcfg', 'Error in resource configuration. Expected ' + 525 | 'response to contain an {0} but got an {1}', 526 | action.isArray?'array':'object', angular.isArray(data)?'array':'object'); 527 | } 528 | // jshint +W018 529 | if (action.isArray) { 530 | value.length = 0; 531 | forEach(data, function(item) { 532 | value.push(new Resource(item)); 533 | }); 534 | } else { 535 | shallowClearAndCopy(data, value); 536 | value.$promise = promise; 537 | } 538 | } 539 | 540 | value.$resolved = true; 541 | 542 | response.resource = value; 543 | 544 | return response; 545 | }, function(response) { 546 | value.$resolved = true; 547 | 548 | (error||noop)(response); 549 | 550 | return $q.reject(response); 551 | }); 552 | 553 | promise = promise.then( 554 | function(response) { 555 | var value = responseInterceptor(response); 556 | (success||noop)(value, response.headers); 557 | return value; 558 | }, 559 | responseErrorInterceptor); 560 | 561 | if (!isInstanceCall) { 562 | // we are creating instance / collection 563 | // - set the initial promise 564 | // - return the instance / collection 565 | value.$promise = promise; 566 | value.$resolved = false; 567 | 568 | return value; 569 | } 570 | 571 | // instance call 572 | return promise; 573 | }; 574 | 575 | 576 | Resource.prototype['$' + name] = function(params, success, error) { 577 | if (isFunction(params)) { 578 | error = success; success = params; params = {}; 579 | } 580 | var result = Resource[name].call(this, params, this, success, error); 581 | return result.$promise || result; 582 | }; 583 | }); 584 | 585 | Resource.bind = function(additionalParamDefaults){ 586 | return resourceFactory(url, extend({}, paramDefaults, additionalParamDefaults), actions); 587 | }; 588 | 589 | return Resource; 590 | } 591 | 592 | return resourceFactory; 593 | }]); 594 | 595 | 596 | })(window, window.angular); 597 | --------------------------------------------------------------------------------