Commit 8aea0e3c authored by Benoit Lavenier's avatar Benoit Lavenier

- upgrade to Ionic 1.2.4

- Fix logout
- Replace ion-slide-box (deprecated) by ion-slides
parent 054128a3
# http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false
\ No newline at end of file
......@@ -2,7 +2,7 @@
"name": "HelloIonic",
"private": "true",
"devDependencies": {
"ionic": "driftyco/ionic-bower#1.0.1"
"ionic": "driftyco/ionic-bower#1.2.4"
},
"dependencies": {
"angular-messages": "1.3.13"
......
......@@ -6,7 +6,7 @@
</description>
<author email="admin@ucoin.io" href="http://ucoin.io">
cgeek
</author>
</author>
<content src="index.html"/>
<access origin="*"/>
<preference name="webviewbounce" value="false"/>
......@@ -39,4 +39,4 @@
<splash src="resources/android/splash/drawable-port-xxhdpi-screen.png" density="port-xxhdpi"/>
<splash src="resources/android/splash/drawable-port-xxxhdpi-screen.png" density="port-xxxhdpi"/>
</platform>
</widget>
\ No newline at end of file
</widget>
......@@ -22,9 +22,8 @@ gulp.task('default', ['sass', 'config']);
gulp.task('sass', function(done) {
gulp.src('./scss/ionic.app.scss')
.pipe(sass({
errLogToConsole: true
}))
.pipe(sass()).on('error', sass.logError)
.pipe(gulp.dest('./www/css/'))
.pipe(minifyCss({
keepSpecialComments: 0
......@@ -88,4 +87,4 @@ gulp.task('config', function (done) {
.pipe(rename('config.js'))
.pipe(gulp.dest('www/js'))
;
});
\ No newline at end of file
});
......@@ -4,26 +4,26 @@
"description": "A webapp client for uCoin network",
"dependencies": {
"gulp": "^3.5.6",
"gulp-sass": "^2.2.0",
"gulp-concat": "^2.2.0",
"gulp-minify-css": "^0.3.0",
"gulp-rename": "^1.2.0",
"gulp-sass": "^2.2.0",
"node-sass": "^3.3.3"
},
"devDependencies": {
"bower": "^1.3.3",
"shelljs": "^0.3.0",
"gulp-util": "^2.2.14",
"gulp-ng-constant": "^1.1.0",
"shelljs": "^0.3.0",
"yargs": "^4.3.1",
"gulp-header": "^1.7.1"
},
"cordovaPlugins": [
"cordova-plugin-device",
"cordova-plugin-console",
"cordova-plugin-whitelist",
"cordova-plugin-splashscreen",
"com.ionic.keyboard"
"cordova-plugin-console",
"ionic-plugin-keyboard",
"cordova-plugin-device"
],
"cordovaPlatforms": [
"android"
......
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -14,7 +14,6 @@
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="lib/ionic/js/angular/angular-resource.min.js"></script>
<script src="lib/ionic/js/angular/angular-sanitize.min.js"></script>
<script src="lib/ionic/js/angular/angular-translate.min.js"></script>
<script src="lib/ionic/js/angular/angular-translate-loader-static-files.min.js"></script>
<script src="lib/ionic/js/angular/angular-messages.min.js"></script>
......
......@@ -60,10 +60,11 @@ function LoginController($scope, $ionicModal, Wallet, CryptoUtils, UIUtils, $q,
if ($scope.loginModal != "undefined" && $scope.loginModal != null) {
$scope.loginModal.show();
$scope.loginData.callback = callback;
UIUtils.loading.hide();
}
else{
$timeout($scope.login, 2000);
}
}
};
// Login and load wallet
......@@ -186,11 +187,18 @@ function LoginController($scope, $ionicModal, Wallet, CryptoUtils, UIUtils, $q,
}
function NewAccountWizardController($scope, $ionicSlideBoxDelegate, $ionicModal, $state, $ionicSideMenuDelegate, UIUtils, $q, $timeout, CryptoUtils, BMA, Wallet, Registry) {
function NewAccountWizardController($scope, $ionicModal, $state, $ionicSideMenuDelegate, UIUtils, $q, $timeout, CryptoUtils, BMA, Wallet, Registry) {
$scope.slideIndex = 0;
$scope.accountData = {};
$scope.accountForm = {};
$scope.slides = {
slider: null,
options: {
loop: false,
effect: 'slide',
speed: 500
}
};
// Called to navigate to the main app
$scope.cancel = function() {
......@@ -198,6 +206,8 @@ function NewAccountWizardController($scope, $ionicSlideBoxDelegate, $ionicModal,
$timeout(function(){
$scope.accountData = {};
$scope.accountForm = {};
$scope.slides.slider.destroy();
delete $scope.slides.slider;
}, 200);
};
......@@ -205,33 +215,31 @@ function NewAccountWizardController($scope, $ionicSlideBoxDelegate, $ionicModal,
$scope.accountForm = accountForm;
};
// Called each time the slide changes
$scope.slide = function(index) {
$ionicSlideBoxDelegate.slide(index);
$scope.slideIndex = index;
$scope.nextStep = $scope.slideIndex == 2 ? 'Start' : 'Next';
};
$scope.next = function() {
$scope.slide($scope.slideIndex + 1);
$scope.slidePrev = function() {
$scope.slides.slider.unlockSwipes()
$scope.slides.slider.slidePrev();
$scope.slides.slider.lockSwipes()
};
$scope.previous = function() {
$scope.slide($scope.slideIndex - 1);
};
$scope.slideNext = function() {
$scope.slides.slider.unlockSwipes()
$scope.slides.slider.slideNext();
$scope.slides.slider.lockSwipes()
};
$scope.newAccount = function() {
var showModal = function() {
$ionicSlideBoxDelegate.enableSlide(false);
$scope.slide(0);
$scope.newAccountModal.show();
// TODO: remove default
/*$timeout(function() {
$scope.accountData.currency = $scope.knownCurrencies[0];
$scope.accountData.isMember = true;
$scope.next();
$scope.next();
}, 300);*/
$scope.slides.slider.lockSwipes();
$scope.slides.slider.slideTo(0);
UIUtils.loading.hide();
$scope.newAccountModal.show();
// TODO: remove default
/*$timeout(function() {
$scope.accountData.currency = $scope.knownCurrencies[0];
$scope.accountData.isMember = true;
$scope.next();
$scope.next();
}, 300);*/
}
if (!$scope.newAccountModal) {
......@@ -243,7 +251,6 @@ function NewAccountWizardController($scope, $ionicSlideBoxDelegate, $ionicModal,
$scope.newAccountModal = modal;
$scope.newAccountModal.hide()
.then(function(){
UIUtils.loading.hide();
showModal();
});
......@@ -256,13 +263,12 @@ function NewAccountWizardController($scope, $ionicSlideBoxDelegate, $ionicModal,
$scope.selectCurrency = function(currency) {
$scope.accountData.currency = currency;
$ionicSlideBoxDelegate.slide(1);
$scope.next();
$scope.slideNext()
};
$scope.selectAccountTypeMember = function(bool) {
$scope.accountData.isMember = bool;
$scope.next();
$scope.slideNext()
};
$scope.showAccountPubkey = function() {
......@@ -292,9 +298,7 @@ function NewAccountWizardController($scope, $ionicSlideBoxDelegate, $ionicModal,
Wallet.login($scope.accountData.username, $scope.accountData.password)
.then(function() {
// Reset account data
delete $scope.accountForm;
$scope.accountData = {};
UIUtils.loading.hide();
$scope.cancel();
$state.go('app.view_wallet');
})
.catch(function(err) {
......@@ -314,7 +318,7 @@ function NewAccountWizardController($scope, $ionicSlideBoxDelegate, $ionicModal,
function HomeController($scope, $ionicSlideBoxDelegate, $ionicModal, $state, $ionicSideMenuDelegate, UIUtils, $q, $timeout, CryptoUtils, BMA, Wallet, Registry, APP_CONFIG) {
function HomeController($scope, $ionicModal, $state, $ionicSideMenuDelegate, UIUtils, $q, $timeout, CryptoUtils, BMA, Wallet, Registry, APP_CONFIG) {
// With the new view caching in Ionic, Controllers are only called
// when they are recreated or on app start, instead of every page change.
......@@ -339,6 +343,6 @@ function HomeController($scope, $ionicSlideBoxDelegate, $ionicModal, $state, $io
LoginController.call(this, $scope, $ionicModal, Wallet, CryptoUtils, UIUtils, $q, $state, $timeout, $ionicSideMenuDelegate);
NewAccountWizardController.call(this, $scope, $ionicSlideBoxDelegate, $ionicModal, $state, $ionicSideMenuDelegate, UIUtils, $q, $timeout, CryptoUtils, BMA, Wallet, Registry);
NewAccountWizardController.call(this, $scope, $ionicModal, $state, $ionicSideMenuDelegate, UIUtils, $q, $timeout, CryptoUtils, BMA, Wallet, Registry);
}
......@@ -121,10 +121,10 @@ function RegistryCategoryModalController($scope, Registry, $state, $ionicModal)
};
}
function RegistryLookupController($scope, $ionicSlideBoxDelegate, $state, $ionicModal, $focus, $q, $timeout, Registry, UIUtils, $sanitize) {
function RegistryLookupController($scope, $state, $ionicModal, $focus, $q, $timeout, Registry, UIUtils, $sanitize) {
RegistryCategoryModalController.call(this, $scope, Registry, $state, $ionicModal);
RegistryNewRecordWizardController.call(this, $scope, $ionicSlideBoxDelegate, $ionicModal, $state, UIUtils, $q, $timeout, Registry);
RegistryNewRecordWizardController.call(this, $scope, $ionicModal, $state, UIUtils, $q, $timeout, Registry);
$scope.search = {
text: '',
......@@ -269,6 +269,7 @@ function RegistryLookupController($scope, $ionicSlideBoxDelegate, $state, $ionic
};
$scope.select = function(id, title) {
UIUtils.loading.show();
$state.go('app.registry_view_record', {id: id, title: title});
};
......@@ -347,6 +348,7 @@ function RegistryRecordViewController($scope, $ionicModal, Wallet, Registry, UIU
// Edit click
$scope.edit = function() {
UIUtils.loading.show();
$state.go('app.registry_edit_record', {id: $scope.id});
};
......@@ -571,43 +573,54 @@ function RegistryRecordEditController($scope, $ionicModal, Wallet, Registry, UIU
};
}
function RegistryNewRecordWizardController($scope, $ionicSlideBoxDelegate, $ionicModal, $state, UIUtils, $q, $timeout, Registry) {
function RegistryNewRecordWizardController($scope, $ionicModal, $state, UIUtils, $q, $timeout, Registry) {
$scope.slideIndex = 0;
$scope.recordData = {
isCompany: null
};
$scope.recordForm = {};
$scope.pictures = [];
$scope.slides = {
slider: null,
options: {
loop: false,
effect: 'slide',
speed: 500
}
};
// Called to navigate to the main app
$scope.cancel = function() {
$scope.newRecordModal.hide();
$timeout(function(){
$scope.recordData = {
isCompany: null
};
$scope.recordForm = {};
}, 200);
if ($scope.newRecordModal) {
$scope.newRecordModal.hide();
$scope.newRecordModal.remove();
$scope.newRecordModal = null;
$timeout(function(){
$scope.recordData = {
isCompany: null
};
$scope.recordForm = {};
$scope.pictures = [];
$scope.slides.slider.destroy();
delete $scope.slides.slider;
}, 200);
}
};
$scope.setRecordForm = function(recordForm) {
$scope.recordForm = recordForm;
};
// Called each time the slide changes
$scope.slide = function(index) {
$ionicSlideBoxDelegate.slide(index);
$scope.slideIndex = index;
$scope.nextStep = $scope.slideIndex == 2 ? 'Start' : 'Next';
$scope.slidePrev = function() {
$scope.slides.slider.unlockSwipes()
$scope.slides.slider.slidePrev();
$scope.slides.slider.lockSwipes()
};
$scope.next = function() {
$scope.slide($scope.slideIndex + 1);
};
$scope.previous = function() {
$scope.slide($scope.slideIndex - 1);
$scope.slideNext = function() {
$scope.slides.slider.unlockSwipes()
$scope.slides.slider.slideNext();
$scope.slides.slider.lockSwipes()
};
$scope.newRecord = function() {
......@@ -615,16 +628,15 @@ function RegistryNewRecordWizardController($scope, $ionicSlideBoxDelegate, $ioni
$scope.loadWallet()
.then(function(walletData) {
$scope.walletData = walletData;
$scope.slides.slider.slideTo(0);
$scope.slides.slider.lockSwipes();
UIUtils.loading.hide();
$ionicSlideBoxDelegate.enableSlide(false);
$scope.slide(0);
$scope.newRecordModal.show();
// TODO: remove default
/*$timeout(function() {
$scope.recordData.isCompany = false;
$scope.recordData.title="Benoit Lavenier";
$scope.recordData.description="J'aime le Sou !";
$scope.next();
$scope.setIsCompany(false);
}, 300);*/
});
}
......@@ -639,10 +651,10 @@ function RegistryNewRecordWizardController($scope, $ionicSlideBoxDelegate, $ioni
$scope.newRecordModal = modal;
$scope.newRecordModal.hide()
.then(function(){
UIUtils.loading.hide();
showModal();
});
});
}
else {
......@@ -652,7 +664,7 @@ function RegistryNewRecordWizardController($scope, $ionicSlideBoxDelegate, $ioni
$scope.setIsCompany = function(bool) {
$scope.recordData.isCompany = bool;
$scope.next();
$scope.slideNext();
};
$scope.doNewRecord = function() {
......@@ -668,9 +680,7 @@ function RegistryNewRecordWizardController($scope, $ionicSlideBoxDelegate, $ioni
}, []);
Registry.record.add($scope.recordData, $scope.walletData.keypair)
.then(function(id) {
//UIUtils.loading.hide();
$scope.newRecordModal.hide();
$scope.newRecordModal.remove();
$scope.cancel();
$state.go('app.registry_view_record', {id: id})
resolve();
})
......@@ -680,8 +690,7 @@ function RegistryNewRecordWizardController($scope, $ionicSlideBoxDelegate, $ioni
//Cleanup the modal when hidden
$scope.$on('newRecordModal.hidden', function() {
$scope.newRecordModal.remove();
$scope.newRecordModal = null;
$scope.cancel();
});
// TODO: remove auto add account when done
......@@ -689,4 +698,4 @@ function RegistryNewRecordWizardController($scope, $ionicSlideBoxDelegate, $ioni
$scope.newRecord();
}, 400);
*/
}
\ No newline at end of file
}
......@@ -30,6 +30,22 @@ angular.module('cesium.wallet.services', ['ngResource', 'cesium.bma.services', '
data = createData(),
resetData = function() {
data.pubkey= null;
data.keypair ={
signSk: null,
signPk: null
};
data.balance = 0;
data.sources = null;
data.useRelative = USE_RELATIVE_DEFAULT;
data.currency= null;
data.currentUD= null;
data.history= {};
data.requirements= null;
data.loaded= false;
},
reduceTx = function(txArray) {
var list = [];
txArray.forEach(function(tx) {
......@@ -77,7 +93,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'cesium.bma.services', '
logout = function(username, password) {
return $q(function(resolve, reject) {
data = createData();
resetData();
resolve();
});
},
......@@ -129,7 +145,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'cesium.bma.services', '
// Get sources
BMA.tx.sources({pubkey: data.pubkey})
.then(function(res){
data.sources = res.sources;
data.sources = res.sources;
var balance = 0;
if (res.sources.length) {
......@@ -179,7 +195,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'cesium.bma.services', '
])
.then(function() {
data.loaded = true;
resolve(data);
resolve(data);
})
.catch(function(err) {
data.loaded = false;
......@@ -243,7 +259,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'cesium.bma.services', '
}
}
data.sources = res.sources;
}
}
data.balance = balance;
})
])
......@@ -282,7 +298,7 @@ angular.module('cesium.wallet.services', ['ngResource', 'cesium.bma.services', '
+ "Issuers:\n"
+ data.pubkey + "\n"
+ "Inputs:\n";
var sourceAmount = 0;
var sourceAmount = 0;
var inputs = [];
for (var i = 0; i<data.sources.length; i++) {
var input = data.sources[i];
......@@ -302,13 +318,13 @@ angular.module('cesium.wallet.services', ['ngResource', 'cesium.bma.services', '
if (sourceAmount < amount) {
reject('Not enought sources (max amount: '
+(data.useRelative ? (sourceAmount / data.currentUD)+' UD' : sourceAmount)
+'). Please wait next block computation.');
+'). Please wait next block computation.');
return;
}
tx += "Outputs:\n"
// ISSUERS:AMOUNT
+ destPub +":" + amount + "\n";
+ destPub +":" + amount + "\n";
if (sourceAmount > amount) {
tx += data.pubkey+":"+(sourceAmount-amount)+"\n";
}
......
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
/**
* @license AngularJS v1.3.13
* (c) 2010-2014 Google, Inc. http://angularjs.org
* @license AngularJS v1.4.3
* (c) 2010-2015 Google, Inc. http://angularjs.org
* License: MIT
*/
(function(window, angular, undefined) {'use strict';
......@@ -10,7 +10,7 @@ var $resourceMinErr = angular.$$minErr('$resource');
// Helper functions and regex to lookup a dotted path on an object
// stopping at undefined/null. The path must be composed of ASCII
// identifiers (just like $parse)
var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;
var MEMBER_NAME_REGEX = /^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;
function isValidDottedPath(path) {
return (path != null && path !== '' && path !== 'hasOwnProperty' &&
......@@ -90,7 +90,7 @@ function shallowClearAndCopy(src, dst) {
}]);
* ```
*
* @param {string} url A parametrized URL template with parameters prefixed by `:` as in
* @param {string} url A parameterized URL template with parameters prefixed by `:` as in
* `/user/:username`. If you are using a URL with a port number (e.g.
* `http://example.com:8080/api`), it will be respected.
*
......@@ -213,7 +213,9 @@ function shallowClearAndCopy(src, dst) {
* - non-GET "class" actions: `Resource.action([parameters], postData, [success], [error])`
* - non-GET instance actions: `instance.$action([parameters], [success], [error])`
*
* Success callback is called with (value, responseHeaders) arguments. Error callback is called
*
* Success callback is called with (value, responseHeaders) arguments, where the value is
* the populated resource instance or collection object. The error callback is called
* with (httpResponse) argument.
*
* Class actions return empty instance (with additional properties below).
......@@ -585,8 +587,8 @@ angular.module('ngResource', ['ng']).
if (angular.isArray(data) !== (!!action.isArray)) {
throw $resourceMinErr('badcfg',
'Error in resource configuration for action `{0}`. Expected response to ' +
'contain an {1} but got an {2}', name, action.isArray ? 'array' : 'object',
angular.isArray(data) ? 'array' : 'object');
'contain an {1} but got an {2} (Request: {3} {4})', name, action.isArray ? 'array' : 'object',
angular.isArray(data) ? 'array' : 'object', httpConfig.method, httpConfig.url);
}
// jshint +W018
if (action.isArray) {
......
/*
AngularJS v1.3.13
(c) 2010-2014 Google, Inc. http://angularjs.org
AngularJS v1.4.3
(c) 2010-2015 Google, Inc. http://angularjs.org
License: MIT
*/
(function(I,d,B){'use strict';function D(f,q){q=q||{};d.forEach(q,function(d,h){delete q[h]});for(var h in f)!f.hasOwnProperty(h)||"$"===h.charAt(0)&&"$"===h.charAt(1)||(q[h]=f[h]);return q}var w=d.$$minErr("$resource"),C=/^(\.[a-zA-Z_$][0-9a-zA-Z_$]*)+$/;d.module("ngResource",["ng"]).provider("$resource",function(){var f=this;this.defaults={stripTrailingSlashes:!0,actions:{get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}}};
this.$get=["$http","$q",function(q,h){function t(d,g){this.template=d;this.defaults=s({},f.defaults,g);this.urlParams={}}function v(x,g,l,m){function c(b,k){var c={};k=s({},g,k);r(k,function(a,k){u(a)&&(a=a());var d;if(a&&a.charAt&&"@"==a.charAt(0)){d=b;var e=a.substr(1);if(null==e||""===e||"hasOwnProperty"===e||!C.test("."+e))throw w("badmember",e);for(var e=e.split("."),n=0,g=e.length;n<g&&d!==B;n++){var h=e[n];d=null!==d?d[h]:B}}else d=a;c[k]=d});return c}function F(b){return b.resource}function e(b){D(b||
{},this)}var G=new t(x,m);l=s({},f.defaults.actions,l);e.prototype.toJSON=function(){var b=s({},this);delete b.$promise;delete b.$resolved;return b};r(l,function(b,k){var g=/^(POST|PUT|PATCH)$/i.test(b.method);e[k]=function(a,y,m,x){var n={},f,l,z;switch(arguments.length){case 4:z=x,l=m;case 3:case 2:if(u(y)){if(u(a)){l=a;z=y;break}l=y;z=m}else{n=a;f=y;l=m;break}case 1:u(a)?l=a:g?f=a:n=a;break;case 0:break;default:throw w("badargs",arguments.length);}var t=this instanceof e,p=t?f:b.isArray?[]:new e(f),
A={},v=b.interceptor&&b.interceptor.response||F,C=b.interceptor&&b.interceptor.responseError||B;r(b,function(b,a){"params"!=a&&"isArray"!=a&&"interceptor"!=a&&(A[a]=H(b))});g&&(A.data=f);G.setUrlParams(A,s({},c(f,b.params||{}),n),b.url);n=q(A).then(function(a){var c=a.data,g=p.$promise;if(c){if(d.isArray(c)!==!!b.isArray)throw w("badcfg",k,b.isArray?"array":"object",d.isArray(c)?"array":"object");b.isArray?(p.length=0,r(c,function(a){"object"===typeof a?p.push(new e(a)):p.push(a)})):(D(c,p),p.$promise=
g)}p.$resolved=!0;a.resource=p;return a},function(a){p.$resolved=!0;(z||E)(a);return h.reject(a)});n=n.then(function(a){var b=v(a);(l||E)(b,a.headers);return b},C);return t?n:(p.$promise=n,p.$resolved=!1,p)};e.prototype["$"+k]=function(a,b,c){u(a)&&(c=b,b=a,a={});a=e[k].call(this,a,this,b,c);return a.$promise||a}});e.bind=function(b){return v(x,s({},g,b),l)};return e}var E=d.noop,r=d.forEach,s=d.extend,H=d.copy,u=d.isFunction;t.prototype={setUrlParams:function(f,g,l){var m=this,c=l||m.template,h,
e,q=m.urlParams={};r(c.split(/\W/),function(b){if("hasOwnProperty"===b)throw w("badname");!/^\d+$/.test(b)&&b&&(new RegExp("(^|[^\\\\]):"+b+"(\\W|$)")).test(c)&&(q[b]=!0)});c=c.replace(/\\:/g,":");g=g||{};r(m.urlParams,function(b,k){h=g.hasOwnProperty(k)?g[k]:m.defaults[k];d.isDefined(h)&&null!==h?(e=encodeURIComponent(h).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"%20").replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+"),c=c.replace(new RegExp(":"+
k+"(\\W|$)","g"),function(b,a){return e+a})):c=c.replace(new RegExp("(/?):"+k+"(\\W|$)","g"),function(b,a,c){return"/"==c.charAt(0)?c:a+c})});m.defaults.stripTrailingSlashes&&(c=c.replace(/\/+$/,"")||"/");c=c.replace(/\/\.(?=\w+($|\?))/,".");f.url=c.replace(/\/\\\./,"/.");r(g,function(b,c){m.urlParams[c]||(f.params=f.params||{},f.params[c]=b)})}};return v}]})})(window,window.angular);
(function(I,d,B){'use strict';function D(f,q){q=q||{};d.forEach(q,function(d,h){delete q[h]});for(var h in f)!f.hasOwnProperty(h)||"$"===h.charAt(0)&&"$"===h.charAt(1)||(q[h]=f[h]);return q}var x=d.$$minErr("$resource"),C=/^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;d.module("ngResource",["ng"]).provider("$resource",function(){var f=this;this.defaults={stripTrailingSlashes:!0,actions:{get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}}};
this.$get=["$http","$q",function(q,h){function u(d,g){this.template=d;this.defaults=s({},f.defaults,g);this.urlParams={}}function w(y,g,l,m){function c(b,k){var c={};k=s({},g,k);r(k,function(a,k){v(a)&&(a=a());var d;if(a&&a.charAt&&"@"==a.charAt(0)){d=b;var e=a.substr(1);if(null==e||""===e||"hasOwnProperty"===e||!C.test("."+e))throw x("badmember",e);for(var e=e.split("."),n=0,g=e.length;n<g&&d!==B;n++){var h=e[n];d=null!==d?d[h]:B}}else d=a;c[k]=d});return c}function F(b){return b.resource}function e(b){D(b||
{},this)}var G=new u(y,m);l=s({},f.defaults.actions,l);e.prototype.toJSON=function(){var b=s({},this);delete b.$promise;delete b.$resolved;return b};r(l,function(b,k){var g=/^(POST|PUT|PATCH)$/i.test(b.method);e[k]=function(a,z,m,y){var n={},f,l,A;switch(arguments.length){case 4:A=y,l=m;case 3:case 2:if(v(z)){if(v(a)){l=a;A=z;break}l=z;A=m}else{n=a;f=z;l=m;break}case 1:v(a)?l=a:g?f=a:n=a;break;case 0:break;default:throw x("badargs",arguments.length);}var u=this instanceof e,p=u?f:b.isArray?[]:new e(f),
t={},w=b.interceptor&&b.interceptor.response||F,C=b.interceptor&&b.interceptor.responseError||B;r(b,function(b,a){"params"!=a&&"isArray"!=a&&"interceptor"!=a&&(t[a]=H(b))});g&&(t.data=f);G.setUrlParams(t,s({},c(f,b.params||{}),n),b.url);n=q(t).then(function(a){var c=a.data,g=p.$promise;if(c){if(d.isArray(c)!==!!b.isArray)throw x("badcfg",k,b.isArray?"array":"object",d.isArray(c)?"array":"object",t.method,t.url);b.isArray?(p.length=0,r(c,function(a){"object"===typeof a?p.push(new e(a)):p.push(a)})):
(D(c,p),p.$promise=g)}p.$resolved=!0;a.resource=p;return a},function(a){p.$resolved=!0;(A||E)(a);return h.reject(a)});n=n.then(function(a){var b=w(a);(l||E)(b,a.headers);return b},C);return u?n:(p.$promise=n,p.$resolved=!1,p)};e.prototype["$"+k]=function(a,b,c){v(a)&&(c=b,b=a,a={});a=e[k].call(this,a,this,b,c);return a.$promise||a}});e.bind=function(b){return w(y,s({},g,b),l)};return e}var E=d.noop,r=d.forEach,s=d.extend,H=d.copy,v=d.isFunction;u.prototype={setUrlParams:function(f,g,l){var m=this,
c=l||m.template,h,e,q=m.urlParams={};r(c.split(/\W/),function(b){if("hasOwnProperty"===b)throw x("badname");!/^\d+$/.test(b)&&b&&(new RegExp("(^|[^\\\\]):"+b+"(\\W|$)")).test(c)&&(q[b]=!0)});c=c.replace(/\\:/g,":");g=g||{};r(m.urlParams,function(b,k){h=g.hasOwnProperty(k)?g[k]:m.defaults[k];d.isDefined(h)&&null!==h?(e=encodeURIComponent(h).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"%20").replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,
"+"),c=c.replace(new RegExp(":"+k+"(\\W|$)","g"),function(b,a){return e+a})):c=c.replace(new RegExp("(/?):"+k+"(\\W|$)","g"),function(b,a,c){return"/"==c.charAt(0)?c:a+c})});m.defaults.stripTrailingSlashes&&(c=c.replace(/\/+$/,"")||"/");c=c.replace(/\/\.(?=\w+($|\?))/,".");f.url=c.replace(/\/\\\./,"/.");r(g,function(b,c){m.urlParams[c]||(f.params=f.params||{},f.params[c]=b)})}};return w}]})})(window,window.angular);
//# sourceMappingURL=angular-resource.min.js.map
/**
* @license AngularJS v1.3.13
* (c) 2010-2014 Google, Inc. http://angularjs.org
* @license AngularJS v1.4.3
* (c) 2010-2015 Google, Inc. http://angularjs.org
* License: MIT
*/
(function(window, angular, undefined) {'use strict';
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Any commits to this file should be reviewed with security in mind. *
* Changes to this file can potentially create security vulnerabilities. *
* An approval from 2 Core members with history of modifying *
* this file is required. *
* *
* Does the change somehow allow for arbitrary javascript to be executed? *
* Or allows for someone to change the prototype of built-in objects? *
* Or gives undesired access to variables likes document or window? *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
var $sanitizeMinErr = angular.$$minErr('$sanitize');