소스 검색

[FIX] Eliminado dependencia de la libreria moment-timezones

Rodney Elpidio Enciso Arias 6 년 전
부모
커밋
016c7e2111

BIN
__init__.pyc


BIN
models/__init__.pyc


BIN
models/chart_config.pyc


+ 17 - 32
static/src/js/widgets/chart_pos_order_customer.js

@@ -22,12 +22,9 @@ function chart_pos_order_customer (widget) {
         },
         fetchInitial:function() {
             var self = this;
-            self.fetchCurrentUser().then(function (CurrentUser) {
-                return CurrentUser;
-            }).then(function (CurrentUser) {
-                self.CurrentUser = CurrentUser;
-                return self.fetchResUser(CurrentUser);
-            }).then(function(ResUser) {
+            self.fetchResUser().then(function (ResUser) {
+                return ResUser;
+            }).then(function (ResUser) {
                 self.ResUser = ResUser;
                 return self.fetchAccountJournal();
             }).then(function(AccountJournal) {
@@ -55,19 +52,11 @@ function chart_pos_order_customer (widget) {
             USER
         */
 
-        fetchCurrentUser: function() {
-            var self = this;
-            var ResUser = new model.web.Model('res.users');
-            return ResUser.call('get_user', {
-                context: new model.web.CompoundContext()
-            });
-        },
-
-        fetchResUser: function(id) {
+        fetchResUser: function() {
             var self = this;
             var defer = $.Deferred();
             var fields = ['id','name','store_id'];
-            var domain = [['id','=',id]];
+            var domain = [['id','=',self.session.uid]];
             var ResUser = new model.web.Model('res.users');
             ResUser.query(fields).filter(domain).all().then(function (results) {
                 defer.resolve(results);
@@ -91,32 +80,30 @@ function chart_pos_order_customer (widget) {
 
         fetchPosOrder: function() {
             var self = this;
+            var defer = $.Deferred();
             var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
                 return item.id;
             }));
-            var desde = moment().format('YYYY-MM-01 00:00:00');
-            var hasta = moment().add(1,'months').format('YYYY-MM-01 00:00:00');
-            var defer = $.Deferred();
+            var date = moment().add(-1, 'month').format('YYYY-MM-23 00:00:00');
             var fields = ['id','date_order','partner_id','amount_total'];
-            var domain = [['state', 'in', ['paid','done','invoiced']], ['partner_id', '!=', false], ['date_order', '>=', desde], ['date_order', '<', hasta],['sale_journal','in',journal_ids]];
+            var domain = [['state', 'in', ['paid','done','invoiced']], ['partner_id', '!=', false],['date_order', '>=', date],['sale_journal','in',journal_ids]];
             var PosOrder = new model.web.Model('pos.order');
             PosOrder.query(fields).filter(domain).all().then(function (results) {
                 defer.resolve(results);
             });
             return defer;
-        },
-        
+        },        
 
         fetchAccountInvoice: function() {
             var self = this;
+            var defer = $.Deferred();
             var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
                 return item.id;
             }));
-            var desde = moment().format('YYYY-MM-01 00:00:00');
-            var hasta = moment().add(1,'months').format('YYYY-MM-01 00:00:00');
-            var defer = $.Deferred();
+            var desde = moment().format('YYYY-MM-01');
+            var hasta = moment().add(1,'months').format('YYYY-MM-01');
             var fields = ['id','date_invoice','partner_id','amount_total','currency_id'];
-            var domain = [['state', 'in', ['open','paid']], ['date_invoice', '>=', desde],['date_invoice', '<', hasta],['type','=','out_invoice'],['journal_id','in',journal_ids]];
+            var domain = [['date_invoice', '>=', desde], ['date_invoice', '<', hasta],['state', 'in', ['open','paid']],['type','=','out_invoice'],['journal_id','in',journal_ids]];
             var AccountInvoice = new model.web.Model('account.invoice');
             AccountInvoice.query(fields).filter(domain).all().then(function (results) {
                 defer.resolve(results);
@@ -140,7 +127,7 @@ function chart_pos_order_customer (widget) {
             var self = this;
             var defer = $.Deferred();
             var fields = ['id','name', 'currency_id'];
-            var domain = [['id', '=', 1]];
+            var domain = [['id', '=', self.session.company_id]];
             var ResCompany = new model.web.Model('res.company');
             ResCompany.query(fields).filter(domain).all().then(function (results) {
                 defer.resolve(results);
@@ -170,10 +157,9 @@ function chart_pos_order_customer (widget) {
 
         getPosOrder:function(id) {
             var self = this;
-            var tz = moment.tz.guess();
             return _.flatten(_.filter(self.PosOrder,function (inv) {
                 var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
-                return inv.partner_id[0] === id & utc.clone().tz(tz).format("YYYY-MM") === moment().format('YYYY-MM');
+                return inv.partner_id[0] === id & moment(utc._d).format('YYYY-MM') === moment().format('YYYY-MM');
             }));
         },
 
@@ -187,7 +173,6 @@ function chart_pos_order_customer (widget) {
         // Generar el Ranking
         fetchCustomerRanking: function() {
             var self = this;
-            console.log(self);
             var PosOrder;
             var AccountInvoice;
             var countPosOrder = 0
@@ -222,7 +207,7 @@ function chart_pos_order_customer (widget) {
                     ranking.push({
                         id: self.ResPartner[i].id,
                         name: self.ResPartner[i].name,
-                        countPosOrder: amount
+                        countPosOrder: accounting.formatNumber(amount,0,"",","),
                     });    
                 }
             }
@@ -277,7 +262,7 @@ function chart_pos_order_customer (widget) {
                         {
                             label: 'Ranking  ',
                             backgroundColor: '#bbdefb',
-                            borderColor: '#0288d1',
+                            borderColor: '#0288d1', 
                             borderWidth: 1,
                             data: body,
                             fill: false,

+ 12 - 23
static/src/js/widgets/chart_pos_order_product.js

@@ -22,12 +22,9 @@ function chart_pos_order_product (widget) {
         },
         fetchInitial: function() {
             var self = this;
-            self.fetchCurrentUser().then(function (CurrentUser) {
-                return CurrentUser;
-            }).then(function (CurrentUser) {
-                self.CurrentUser = CurrentUser;
-                return self.fetchResUser(CurrentUser);
-            }).then(function(ResUser) {
+            self.fetchResUser().then(function (ResUser) {
+                return ResUser;
+            }).then(function (ResUser) {
                 self.ResUser = ResUser;
                 return self.fetchAccountJournal();
             }).then(function(AccountJournal) {
@@ -55,19 +52,11 @@ function chart_pos_order_product (widget) {
             USER
         */
 
-        fetchCurrentUser: function() {
-            var self = this;
-            var ResUser = new model.web.Model('res.users');
-            return ResUser.call('get_user', {
-                context: new model.web.CompoundContext()
-            });
-        },
-
-        fetchResUser: function(id) {
+        fetchResUser: function() {
             var self = this;
             var defer = $.Deferred();
             var fields = ['id','name','store_id'];
-            var domain = [['id','=',id]];
+            var domain = [['id','=',self.session.uid]];
             var ResUser = new model.web.Model('res.users');
             ResUser.query(fields).filter(domain).all().then(function (results) {
                 defer.resolve(results);
@@ -95,8 +84,9 @@ function chart_pos_order_product (widget) {
             var journal_ids = _.flatten(_.map(self.AccountJournal, function (item) {
                 return item.id;
             }));
+            var date = moment().format('YYYY-MM-01 00:00:00');
             var fields = ['id', 'lines', 'date_order'];
-            var domain = [['state', 'in', ['paid','done','invoiced']],['sale_journal','in',journal_ids]];
+            var domain = [['state', 'in', ['paid','done','invoiced']],['sale_journal','in',journal_ids],['date_order','>=',date]];
             var PosOrder = new model.web.Model('pos.order');
             PosOrder.query(fields).filter(domain).all().then(function (results) {
                 defer.resolve(results);
@@ -130,7 +120,7 @@ function chart_pos_order_product (widget) {
             var desde = moment().format('YYYY-MM-01');
             var hasta = moment().add(1,'months').format('YYYY-MM-01');
             var fields = ['id', 'invoice_line', 'date_order'];
-            var domain = [['date_invoice', '>=', desde], ['date_invoice', '<', hasta], ['state', 'in', ['open','paid']],['journal_id','in',journal_ids],['type','=','out_invoice']];
+            var domain = [['date_invoice', '>=', desde],['date_invoice', '<', hasta],['state', 'in', ['open','paid']],['journal_id','in',journal_ids],['type','=','out_invoice']];
             var AccountInvoice = new model.web.Model('account.invoice');
             AccountInvoice.query(fields).filter(domain).all().then(function (results) {
                 defer.resolve(results);
@@ -168,10 +158,9 @@ function chart_pos_order_product (widget) {
 
         getPosOrderLine: function (id) {
             var self = this;
-            var tz = moment.tz.guess();
             return _.flatten(_.filter(self.PosOrderLine,function (item) {
                 var utc = moment.utc(item.create_date,'YYYY-MM-DD h:mm:ss A');
-                return item.product_id[0] === id & utc.clone().tz(tz).format("YYYY-MM") === moment().format('YYYY-MM');
+                return item.product_id[0] === id & moment(utc._d).format('YYYY-MM') === moment().format('YYYY-MM');
             }));
         },
 
@@ -214,7 +203,7 @@ function chart_pos_order_product (widget) {
                     ranking.push({
                         id: self.ProductProduct[i].id,
                         product: self.ProductProduct[i].name_template + ' ' + attribute,
-                        qty: qty,
+                        qty: accounting.formatNumber(qty,0,"",","),
                     });
                 }
             }
@@ -222,8 +211,7 @@ function chart_pos_order_product (widget) {
                 return b.qty - a.qty
             });
             self.fetchChart(ranking);
-        },     
-
+        },
 
         fetchChart: function (ranking){
             var self = this;
@@ -288,5 +276,6 @@ function chart_pos_order_product (widget) {
                 }
             });
         },
+        
     });
 }

+ 12 - 28
static/src/js/widgets/chart_pos_order_salesman.js

@@ -21,14 +21,11 @@ function chart_pos_order_salesman (widget) {
         },
         fetchInitial:function() {
             var self = this;
-            self.fetchCurrentUser().then(function (CurrentUser) {
-                return CurrentUser;
-            }).then(function (CurrentUser) {
-                self.CurrentUser = CurrentUser;
-                return self.fetchResUser();
-            }).then(function(ResUser) {
+            self.fetchResUser().then(function (ResUser) {
+                return ResUser;
+            }).then(function (ResUser) {
                 self.ResUser = ResUser;
-                return self.fetchAccountJournal(self.CurrentUser);
+                return self.fetchAccountJournal();
             }).then(function(AccountJournal) {
                 self.AccountJournal = AccountJournal;
                 return self.fecthPosOrder();
@@ -51,14 +48,6 @@ function chart_pos_order_salesman (widget) {
             USER
         */
 
-        fetchCurrentUser: function() {
-            var self = this;
-            var ResUser = new model.web.Model('res.users');
-            return ResUser.call('get_user', {
-                context: new model.web.CompoundContext()
-            });
-        },
-
         fetchResUser: function() {
             var self = this;
             var defer = $.Deferred();
@@ -72,11 +61,11 @@ function chart_pos_order_salesman (widget) {
             return defer;
         },
 
-        fetchAccountJournal: function(id) {
+        fetchAccountJournal: function() {
             var self = this;
             var defer = $.Deferred();
             var user = _.flatten(_.filter(self.ResUser,function (inv) {
-                return inv.id === id;
+                return inv.id === self.session.uid;
             }));
             var store_ids = user[0].store_id[0];
             var fields = ['id', 'name', 'store_ids'];
@@ -90,11 +79,10 @@ function chart_pos_order_salesman (widget) {
 
         fecthPosOrder: function() {
             var self = this;
-            var desde = moment().format('YYYY-MM-01 00:00:00');
-            var hasta = moment().add(1,'months').format('YYYY-MM-01 00:00:00');
             var defer = $.Deferred();
+            var date = moment().add(-1, 'month').format('YYYY-MM-23 00:00:00');
             var fields = ['id','date_order','partner_id','amount_total','user_id'];
-            var domain = [['state', 'in', ['paid','done','invoiced']],['date_order', '>=', desde], ['date_order', '<', hasta]];
+            var domain = [['state', 'in', ['paid','done','invoiced']],['date_order','>=',date]];
             var PosOrder = new model.web.Model('pos.order');
             PosOrder.query(fields).filter(domain).all().then(function (results) {
                 defer.resolve(results);
@@ -111,7 +99,7 @@ function chart_pos_order_salesman (widget) {
             var desde = moment().format('YYYY-MM-01');
             var hasta = moment().add(1,'months').format('YYYY-MM-01');
             var fields = ['id', 'invoice_line', 'date_order','user_id','amount_total','currency_id'];
-            var domain = [['date_invoice', '>=', desde], ['date_invoice', '<', hasta], ['state', 'in', ['open','paid']],['journal_id','in',journal_ids],['type','=','out_invoice']];
+            var domain = [['date_invoice', '>=', desde], ['date_invoice', '<', hasta],['state', 'in', ['open','paid']],['journal_id','in',journal_ids],['type','=','out_invoice']];
             var AccountInvoice = new model.web.Model('account.invoice');
             AccountInvoice.query(fields).filter(domain).all().then(function (results) {
                 defer.resolve(results);
@@ -119,14 +107,11 @@ function chart_pos_order_salesman (widget) {
             return defer;
         },
 
-        fetchResCompany: function(id) {
+        fetchResCompany: function() {
             var self = this;
             var defer = $.Deferred();
-            var user = _.flatten(_.filter(self.ResUser,function (inv) {
-                return inv.id === id;
-            }));
             var fields = ['id','name', 'currency_id'];
-            var domain = [['id', '=', user[0].company_id[0]]];
+            var domain = [['id', '=', self.session.company_id]];
             var ResCompany = new model.web.Model('res.company');
             ResCompany.query(fields).filter(domain).all().then(function (results) {
                 defer.resolve(results);
@@ -155,10 +140,9 @@ function chart_pos_order_salesman (widget) {
        
         getPosOrder:function(id) {
             var self = this;
-            var tz = moment.tz.guess();
             return _.flatten(_.filter(self.PosOrder,function (inv) {
                 var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
-                return inv.user_id[0] === id & utc.clone().tz(tz).format("YYYY-MM") === moment().format('YYYY-MM');
+                return inv.user_id[0] === id & moment(utc._d).format('YYYY-MM') === moment().format('YYYY-MM');
             }));
         },
 

+ 21 - 18
static/src/js/widgets/chart_sale_by_store.js

@@ -26,15 +26,6 @@ function chart_sale_by_store (widget) {
 
         fetchInitial:function() {
             var self = this;
-            self.$el.block({
-                message: null,
-                overlayCSS: {
-                    backgroundColor: '#FAFAFA'
-                }
-            });
-
-            self.$el.find('.widget-content.widget-loading').css('display','flex');
-
             self.fetchAccountJournal().then(function (AccountJournal) {
                 return AccountJournal;
             }).then(function (AccountJournal) {
@@ -68,8 +59,9 @@ function chart_sale_by_store (widget) {
         fetchPosOrder: function() {
             var self = this;
             var defer = $.Deferred();
+            var date = moment().add(-1, 'month').format('YYYY-MM-20 00:00:00');
             var fields = ['id','date_order','amount_total','sale_journal'];
-            var domain = [['state','not in',['draft','cancel']]];
+            var domain = [['state','not in',['draft','cancel']],['date_order','>',date]];
             var PosOrder = new model.web.Model('pos.order');
             PosOrder.query(fields).filter(domain).all().then(function (results) {
                 defer.resolve(results);
@@ -81,13 +73,14 @@ function chart_sale_by_store (widget) {
         fetchAccountInvoice: function() {
             var self = this;
             var defer = $.Deferred();
+            var desde = moment().format('YYYY-MM-01');
+            var hasta = moment().add(1,'months').format('YYYY-MM-01');
             var fields = ['id', 'name', 'date_invoice', 'amount_total','journal_id'];
-            var domain = [['state', 'not in', ['draft','cancel']],['type','=','out_invoice']];
+            var domain = [['date_invoice','>=',desde], ['date_invoice','<',hasta],['state', 'not in', ['draft','cancel']],['type','=','out_invoice']];
             var AccountInvoice = new model.web.Model('account.invoice');
             AccountInvoice.query(fields).filter(domain).all().then(function(results) {
                 defer.resolve(results);
             });
-
             return defer;
         },
 
@@ -103,13 +96,18 @@ function chart_sale_by_store (widget) {
             return defer;
         },
 
+        /*===================================================
+        POS ORDER
+        ===================================================*/
+
         getMonthPosOrder:function(id) {
             var self = this;
             var journal_id  = _.filter(self.AccountJournal,function (inv) {
                 return inv.store_ids[0] === id;
             });
             return _.flatten(_.filter(self.PosOrder,function (inv) {
-                return moment(inv.date_order).format('YYYY-MM') === moment().format('YYYY-MM') & inv.sale_journal[0] == journal_id[0].id;
+                var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+                return moment(utc._d).format('YYYY-MM') === moment().format('YYYY-MM') & inv.sale_journal[0] == journal_id[0].id;
             }));
         },
 
@@ -120,7 +118,9 @@ function chart_sale_by_store (widget) {
                 return inv.store_ids[0] === id;
             });
             return _.flatten(_.filter(self.PosOrder,function (inv) {
-                return moment(inv.date_order).week() === week & inv.sale_journal[0] == journal_id[0].id;
+                var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+                utc = moment(utc._d).format('YYYY-MM-DD');
+                return moment(utc).week() === week & inv.sale_journal[0] == journal_id[0].id;
             }));
         },
 
@@ -131,10 +131,15 @@ function chart_sale_by_store (widget) {
                 return inv.store_ids[0] === id;
             });
             return _.flatten(_.filter(self.PosOrder,function (inv) {
-                return moment(inv.date_order).format('YYYY-MM-DD') === today & inv.sale_journal[0] == journal_id[0].id;
+                var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
+                return moment(utc._d).format('YYYY-MM-DD') === today & inv.sale_journal[0] == journal_id[0].id;
             }));
         },
 
+        /*===================================================
+        ACCOUNT INVOICE
+        ===================================================*/
+
         getMonthAccountInvoice:function(id) {
             var self = this;
             var journal_id  = _.filter(self.AccountJournal,function (inv) {
@@ -190,8 +195,6 @@ function chart_sale_by_store (widget) {
                 var total = order_total + invoice_total;
                 data.push(total); 
             });
-            self.$el.unblock();
-            self.$el.find('.widget-content.widget-loading').css('display','none');
             self.fetchChart(data,title);
         },
 
@@ -264,7 +267,7 @@ function chart_sale_by_store (widget) {
                         {
                             label: false,
                             data: body,
-                            backgroundColor: '#0288d1',
+                            backgroundColor: '#bbdefb',
                             borderColor: '#0288d1',
                             borderWidth: 1,
                             fill: true,

+ 0 - 1
static/src/js/widgets/chart_sale_order_salesman.js

@@ -176,7 +176,6 @@ function chart_sale_order_salesman (widget) {
             ranking.sort(function (a, b) {
                 return b.amount - a.amount
             });
-            console.log(ranking);
             self.fetchChart(ranking);
         },
 

+ 12 - 24
static/src/js/widgets/widget_balance.js

@@ -31,12 +31,9 @@ function widget_balance(widget) {
 
         fetchInitial: function(){
             var self = this;
-            self.fetchCurrentUser().then(function (CurrentUser) {
-                return CurrentUser;
-            }).then(function (CurrentUser) {
-                self.CurrentUser = CurrentUser;
-                return self.fetchResUser(CurrentUser);
-            }).then(function(ResUser) {
+            self.fetchResUser().then(function (ResUser) {
+                return ResUser;
+            }).then(function (ResUser) {
                 self.ResUser = ResUser;
                 return self.fetchAccountJournal();
             }).then(function(AccountJournal) {
@@ -64,19 +61,11 @@ function widget_balance(widget) {
             USER
         */
 
-        fetchCurrentUser: function() {
-            var self = this;
-            var ResUser = new model.web.Model('res.users');
-            return ResUser.call('get_user', {
-                context: new model.web.CompoundContext()
-            });
-        },
-
         fetchResUser: function(id) {
             var self = this;
             var defer = $.Deferred();
             var fields = ['id','name','store_id'];
-            var domain = [['id','=',id]];
+            var domain = [['id','=',self.session.uid]];
             var ResUser = new model.web.Model('res.users');
             ResUser.query(fields).filter(domain).all().then(function (results) {
                 defer.resolve(results);
@@ -104,8 +93,9 @@ function widget_balance(widget) {
             var journal_ids = _.flatten(_.map(this.AccountJournal, function (item) {
                 return item.id;
             }));
+             var date = moment().add(-1, 'month').format('YYYY-MM-23 HH:mm:ss');
             var fields = ['id','type','date_invoice','amount_total','currency_id'];
-            var domain = [['state', 'not in', ['draft','cancel']],['type','in',['in_invoice','out_invoice']],['journal_id','in',journal_ids]];
+            var domain = [['state', 'not in', ['draft','cancel']],['type','in',['in_invoice','out_invoice']],['journal_id','in',journal_ids],['date_invoice','>',date]];
             var AccountInvoice = new model.web.Model('account.invoice');
             AccountInvoice.query(fields).filter(domain).all().then(function(results) {
                 defer.resolve(results);
@@ -119,8 +109,9 @@ function widget_balance(widget) {
             var journal_ids = _.flatten(_.map(this.AccountJournal, function (item) {
                 return item.id;
             }));
+            var date = moment().add(-1, 'month').format('YYYY-MM-23 HH:mm:ss');
             var fields = ['id', 'name', 'date_order', 'amount_total','sale_journal'];
-            var domain = [['state', 'not in', ['draft','cancel']],['sale_journal','in',journal_ids]];
+            var domain = [['state', 'not in', ['draft','cancel']],['sale_journal','in',journal_ids],['date_order','>',date]];
             var PosOrder = new model.web.Model('pos.order');
             PosOrder.query(fields).filter(domain).all().then(function(results) {
                 defer.resolve(results);
@@ -133,7 +124,7 @@ function widget_balance(widget) {
             var self = this;
             var defer = $.Deferred();
             var fields = ['id','name', 'currency_id'];
-            var domain = [['id', '=', 1]];
+            var domain = [['id', '=', self.session.company_id]];
             var ResCompany = new model.web.Model('res.company');
             ResCompany.query(fields).filter(domain).all().then(function (results) {
                 defer.resolve(results);
@@ -241,30 +232,27 @@ function widget_balance(widget) {
         getTodayPosOrder:function() {
             var self = this;
             var date = moment().format('YYYY-MM-DD');
-            var tz = moment.tz.guess();
             return _.flatten(_.filter(self.PosOrder,function (inv) {
                 var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
-                return utc.clone().tz(tz).format("YYYY-MM-DD") === date;
+                return moment(utc._d).format('YYYY-MM-DD') === date;
             }));
         },
 
         getThisWeekPosOrder:function() {
             var self = this;
             var week = moment().week();
-            var tz = moment.tz.guess();
             return _.flatten(_.filter(self.PosOrder,function (inv) {
                 var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
-                utc = utc.clone().tz(tz).format("YYYY-MM-DD"); 
+                utc = moment(utc._d).format('YYYY-MM-DD');
                 return moment(utc).week() === week & moment(utc).format('YYYY')=== moment().format('YYYY');
             }));
         },
 
         getThisMonthPosOrder:function() {
             var self = this;
-            var tz = moment.tz.guess();
             return _.flatten(_.filter(self.PosOrder,function (inv) {
                 var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
-                return utc.clone().tz(tz).format("YYYY-MM") === moment().format('YYYY-MM');
+                return moment(utc._d).format('YYYY-MM') === moment().format('YYYY-MM');
             }));
         }, 
 

+ 16 - 28
static/src/js/widgets/widget_pos_order.js

@@ -31,12 +31,9 @@ function widget_pos_order(widget) {
 
         fetchInitial: function(){
             var self = this;
-            self.fetchCurrentUser().then(function (CurrentUser) {
-                return CurrentUser;
-            }).then(function (CurrentUser) {
-                self.CurrentUser = CurrentUser;
-                return self.fetchResUser(CurrentUser);
-            }).then(function(ResUser) {
+            self.fetchResUser().then(function (ResUser) {
+                return ResUser;
+            }).then(function (ResUser) {
                 self.ResUser = ResUser;
                 return self.fetchAccountJournal();
             }).then(function(AccountJournal) {
@@ -64,24 +61,15 @@ function widget_pos_order(widget) {
             USER
         */
 
-        fetchCurrentUser: function() {
-            var self = this;
-            var ResUser = new model.web.Model('res.users');
-            return ResUser.call('get_user', {
-                context: new model.web.CompoundContext()
-            });
-        },
-
-        fetchResUser: function(id) {
+        fetchResUser: function() {
             var self = this;
             var defer = $.Deferred();
             var fields = ['id','name','store_id'];
-            var domain = [['id','=',id]];
+            var domain = [['id','=',self.session.uid]];
             var ResUser = new model.web.Model('res.users');
             ResUser.query(fields).filter(domain).all().then(function (results) {
                 defer.resolve(results);
             });
-
             return defer;
         },
 
@@ -105,8 +93,9 @@ function widget_pos_order(widget) {
             var journal_ids = _.flatten(_.map(this.AccountJournal, function (item) {
                 return item.id;
             }));
+            var date = moment().add(-1, 'month').format('YYYY-MM-23 00:00:00');
             var fields = ['id', 'name', 'date_order', 'amount_total','sale_journal'];
-            var domain = [['state', 'not in', ['draft','cancel']],['sale_journal','in',journal_ids]];
+            var domain = [['state', 'not in', ['draft','cancel']],['sale_journal','in',journal_ids],['date_order','>',date]];
             var PosOrder = new model.web.Model('pos.order');
             PosOrder.query(fields).filter(domain).all().then(function(results) {
                 defer.resolve(results);
@@ -120,8 +109,10 @@ function widget_pos_order(widget) {
             var journal_ids = _.flatten(_.map(this.AccountJournal, function (item) {
                 return item.id;
             }));
+            var desde = moment().format('YYYY-MM-01');
+            var hasta = moment().add(1,'months').format('YYYY-MM-01');
             var fields = ['id','name','amount_total','date_invoice','currency_id'];
-            var domain = [['state', 'not in', ['draft','cancel']],['type','=','out_invoice'],['journal_id','in',journal_ids]];
+            var domain = [['state', 'not in', ['draft','cancel']],['type','=','out_invoice'],['journal_id','in',journal_ids],['date_invoice','>=',desde],['date_invoice','<',hasta]];
             var AccountInvoice = new model.web.Model('account.invoice');
             AccountInvoice.query(fields).filter(domain).all().then(function(results) {
                 defer.resolve(results);
@@ -134,7 +125,7 @@ function widget_pos_order(widget) {
             var self = this;
             var defer = $.Deferred();
             var fields = ['id','name', 'currency_id'];
-            var domain = [['id', '=', 1]];
+            var domain = [['id', '=', self.session.company_id]];
             var ResCompany = new model.web.Model('res.company');
             ResCompany.query(fields).filter(domain).all().then(function (results) {
                 defer.resolve(results);
@@ -184,30 +175,27 @@ function widget_pos_order(widget) {
         getTodayPosOrder:function() {
             var self = this;
             var date = moment().format('YYYY-MM-DD');
-            var tz = moment.tz.guess();
             return _.flatten(_.filter(self.PosOrder,function (inv) {
                 var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
-                return utc.clone().tz(tz).format("YYYY-MM-DD") === date;
+                return moment(utc._d).format('YYYY-MM-DD') === date;
             }));
         },
 
         getThisWeekPosOrder:function() {
             var self = this;
             var week = moment().week();
-            var tz = moment.tz.guess();
             return _.flatten(_.filter(self.PosOrder,function (inv) {
                 var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
-                utc = utc.clone().tz(tz).format("YYYY-MM-DD"); 
+                utc = moment(utc._d).format('YYYY-MM-DD'); 
                 return moment(utc).week() === week & moment(utc).format('YYYY')=== moment().format('YYYY');
             }));
         },
 
         getThisMonthPosOrder:function() {
             var self = this;
-            var tz = moment.tz.guess();
             return _.flatten(_.filter(self.PosOrder,function (inv) {
                 var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
-                return utc.clone().tz(tz).format("YYYY-MM") === moment().format('YYYY-MM');
+                return moment(utc._d).format('YYYY-MM') === moment().format('YYYY-MM');
             }));
         },
 
@@ -222,10 +210,9 @@ function widget_pos_order(widget) {
             }else{
                 var fecha = moment().format('YYYY')+'-'+mes;    
             }
-            var tz = moment.tz.guess();
             return _.flatten(_.filter(self.PosOrder,function (inv) {
                 var utc = moment.utc(inv.date_order,'YYYY-MM-DD h:mm:ss A');
-                return utc.clone().tz(tz).format("YYYY-MM") === fecha;
+                return moment(utc._d).format('YYYY-MM') === fecha;
             }));
         },
 
@@ -399,6 +386,7 @@ function widget_pos_order(widget) {
                 'stroke':'#43a047',
                 'stroke-width':'10'
             });
+            
             chart1.set(percentage);
 
             self.percentage = percentage;

+ 0 - 437
static/src/lib/jquery.circliful.js

@@ -1,437 +0,0 @@
-"use strict";
-
-(function ($) {
-
-    $.fn.circliful = function (options, callback) {
-
-        var settings = $.extend({
-            // These are the defaults.
-            foregroundColor: "#3498DB",
-            backgroundColor: "#ccc",
-            pointColor: "none",
-            fillColor: 'none',
-            foregroundBorderWidth: 15,
-            backgroundBorderWidth: 15,
-            pointSize: 28.5,
-            fontColor: '#aaa',
-            percent: 75,
-            animation: 1,
-            animationStep: 5,
-            icon: 'none',
-            iconSize: '30',
-            iconColor: '#ccc',
-            iconPosition: 'top',
-            iconDecoration: true,
-            target: 0,
-            start: 0,
-            showPercent: 1,
-            percentageTextSize: 22,
-            percentageX: 100,
-            percentageY: 113,
-            textAdditionalCss: '',
-            targetPercent: 0,
-            targetTextSize: 17,
-            targetColor: '#2980B9',
-            text: null,
-            textStyle: null,
-            textColor: '#666',
-            textY: null,
-            textX: null,
-            multiPercentage: 0,
-            percentages: [],
-            multiPercentageLegend: 0,
-            textBelow: false,
-            noPercentageSign: false,
-            replacePercentageByText: null,
-            halfCircle: false,
-            animateInView: false,
-            decimals: 0,
-            alwaysDecimals: false,
-            title: 'Circle Chart',
-            description: '',
-            progressColor: null
-        }, options);
-
-        return this.each(function () {
-            var circleContainer = $(this);
-
-            mergeDataAttributes(settings, circleContainer.data());
-
-            var percent = settings.percent;
-            var iconY = 83;
-            var iconX = 100;
-            var percentageY = settings.percentageY;
-            var percentageX = settings.percentageX;
-            var additionalCss;
-            var elements;
-            var icon;
-            var backgroundBorderWidth = settings.backgroundBorderWidth;
-            var progressColor = settings.progressColor
-
-            if (settings.halfCircle) {
-                if (settings.iconPosition === 'left') {
-                    iconX = 80;
-                    iconY = 100;
-                    percentageX = 117;
-                    percentageY = 100;
-                } else if (settings.halfCircle) {
-                    iconY = 80;
-                    percentageY = 100;
-                }
-            } else {
-                if (settings.iconPosition === 'bottom') {
-                    iconY = 124;
-                    percentageY = 95;
-                } else if (settings.iconPosition === 'left') {
-                    iconX = 80;
-                    iconY = 110;
-                    percentageX = 117;
-                } else if (settings.iconPosition === 'middle') {
-                    if (settings.multiPercentage !== 1) {
-                        if (settings.iconDecoration) {
-                          elements = '<g stroke="' + (settings.backgroundColor !== 'none' ? settings.backgroundColor : '#ccc') + '" ><line x1="133" y1="50" x2="140" y2="40" stroke-width="2"  /></g>';
-                          elements += '<g stroke="' + (settings.backgroundColor !== 'none' ? settings.backgroundColor : '#ccc') + '" ><line x1="140" y1="40" x2="200" y2="40" stroke-width="2"  /></g>';
-                        }
-                        percentageX = 170; // To center the percentage exactly in the center.
-                        percentageY = 35;
-                    }
-                    iconY = 110;
-                } else if (settings.iconPosition === 'right') {
-                    iconX = 120;
-                    iconY = 110;
-                    percentageX = 80;
-                } else if (settings.iconPosition === 'top' && settings.icon !== 'none') {
-                    percentageY = 120;
-                }
-            }
-
-            if (settings.targetPercent > 0 && settings.halfCircle !== true) {
-                percentageY = 95;
-                elements = '<g stroke="' + (settings.backgroundColor !== 'none' ? settings.backgroundColor : '#ccc') + '" ><line x1="75" y1="101" x2="125" y2="101" stroke-width="1"  /></g>';
-                elements += '<text text-anchor="middle" x="' + percentageX + '" y="120" style="font-size: ' + settings.targetTextSize + 'px;" fill="' + settings.targetColor + '">' + settings.targetPercent + (settings.noPercentageSign && settings.replacePercentageByText === null ? '' : '%') + '</text>';
-                elements += '<circle cx="100" cy="100" r="69" fill="none" stroke="' + settings.backgroundColor + '" stroke-width="3" stroke-dasharray="450" transform="rotate(-90,100,100)" />';
-                elements += '<circle cx="100" cy="100" r="69" fill="none" stroke="' + settings.targetColor + '" stroke-width="3" stroke-dasharray="' + (435 / 100 * settings.targetPercent) + ', 20000" transform="rotate(-90,100,100)" />';
-            }
-
-            if (settings.text !== null) {
-                if (settings.halfCircle) {
-                    if (settings.textBelow) {
-                        elements += '<text text-anchor="middle" x="' + (settings.textX !== null ? settings.textX : '100') + '" y="' + (settings.textY !== null ? settings.textY : '64%') + '" style="' + settings.textStyle + '" fill="' + settings.textColor + '">' + settings.text + '</text>';
-                    }
-                    else {
-                        elements += '<text text-anchor="middle" x="' + (settings.textX !== null ? settings.textX : '100' ) + '" y="' + (settings.textY !== null ? settings.textY : '115') + '" style="' + settings.textStyle + '" fill="' + settings.textColor + '">' + settings.text + '</text>';
-                    }
-                } else {
-                    if (settings.textBelow) {
-                        elements += '<text text-anchor="middle" x="' + (settings.textX !== null ? settings.textX : '100' ) + '" y="' + (settings.textY !== null ? settings.textY : '99%') + '" style="' + settings.textStyle + '" fill="' + settings.textColor + '">' + settings.text + '</text>';
-                    }
-                    else {
-                        elements += '<text text-anchor="middle" x="' + (settings.textX !== null ? settings.textX : '100' ) + '" y="' + (settings.textY !== null ? settings.textY : '115') + '" style="' + settings.textStyle + '" fill="' + settings.textColor + '">' + settings.text + '</text>';
-                    }
-                }
-            }
-
-            if (settings.icon !== 'none') {
-                icon = '<text text-anchor="middle" x="' + iconX + '" y="' + iconY + '" class="icon" style="font-size: ' + settings.iconSize + 'px" fill="' + settings.iconColor + '">&#x' + settings.icon + '</text>';
-            }
-
-            if (settings.halfCircle) {
-                var rotate = 'transform="rotate(-180,100,100)"';
-                circleContainer
-                    .addClass('svg-container')
-                    .append(
-                        $('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 194 186" class="circliful">' +
-                            (typeof elements !== 'undefined' ? elements : '') +
-                            '<clipPath id="cut-off-bottom"> <rect x="100" y="0" width="100" height="200" /> </clipPath>' +
-                            '<circle cx="100" cy="100" r="57" class="border" fill="' + settings.fillColor + '" stroke="' + settings.backgroundColor + '" stroke-width="' + backgroundBorderWidth + '" stroke-dasharray="360" clip-path="url(#cut-off-bottom)" transform="rotate(-90,100,100)" />' +
-                            '<circle class="circle" cx="100" cy="100" r="57" class="border" fill="none" stroke="' + settings.foregroundColor + '" stroke-width="' + settings.foregroundBorderWidth + '" stroke-dasharray="0,20000" ' + rotate + ' />' +
-                            '<circle cx="100" cy="100" r="' + settings.pointSize + '" fill="' + settings.pointColor + '" clip-path="url(#cut-off-bottom)" transform="rotate(-90,100,100)" />' +
-                            icon +
-                            '<text class="timer" text-anchor="middle" x="' + percentageX + '" y="' + percentageY + '" style="font-size: ' + settings.percentageTextSize + 'px; ' + additionalCss + ';' + settings.textAdditionalCss + '" fill="' + settings.fontColor + '"><tspan class="number">' + (settings.replacePercentageByText === null ? 0 : settings.replacePercentageByText) + '</tspan><tspan class="percent">' + (settings.noPercentageSign || settings.replacePercentageByText !== null ? '' : '%') + '</tspan></text>')
-                    );
-            } else {
-                drawCircles();
-            }
-
-            var circle = circleContainer.find('.circle');
-            var myTimer = circleContainer.find('.timer');
-            var interval = 30;
-            var angle = 0;
-            var angleIncrement = settings.animationStep;
-            var last = 0;
-            var summary = 0;
-            var oneStep = 0;
-            var text = percent;
-            var calculateFill = (360 / 100 * percent);
-
-            if (settings.halfCircle) {
-                calculateFill = (360 / 100 * percent) / 2;
-            }
-
-            if (settings.replacePercentageByText !== null) {
-                text = settings.replacePercentageByText;
-            }
-
-            if (settings.start > 0 && settings.target > 0) {
-                percent = settings.start / (settings.target / 100);
-                oneStep = settings.target / 100;
-            }
-
-            if (settings.animation === 1) {
-                if (settings.animateInView) {
-                    $(window).scroll(function () {
-                        checkAnimation();
-                    });
-                } else {
-                    animate();
-                }
-            } else {
-                if (settings.multiPercentage !== 1) {
-                    circle
-                        .attr("stroke-dasharray", calculateFill + ", 20000");
-
-                    if (settings.showPercent === 1) {
-                        myTimer
-                            .find('.number')
-                            .text(text);
-                    } else {
-                        myTimer
-                            .find('.number')
-                            .text(settings.target);
-                        myTimer
-                            .find('.percent')
-                            .text('');
-                    }
-                } else {
-                    if (settings.replacePercentageByText !== null) {
-                        myTimer
-                            .find('.number')
-                            .text(settings.replacePercentageByText);
-                        myTimer
-                            .find('.percent')
-                            .text('');
-                    }
-                }
-            }
-
-            function animate() {
-                var currentCircle = circle;
-                var currentCalculateFill = calculateFill;
-
-                if (settings.multiPercentage === 1) {
-                    var index;
-                    var percentages = settings.percentages;
-                    var circleRadius = 360;
-                    for (index = 0; index < percentages.length; ++index) {
-                        percent = percentages[index].percent;
-                        currentCalculateFill = (circleRadius / 100 * percent);
-                        currentCircle = circleContainer.find('#circle' + (index + 1));
-
-                        if (index > 0) {
-                            circleRadius = circleRadius + 62.5;
-                            currentCalculateFill = (circleRadius / 100 * percent);
-                        }
-
-                        animateCircle(currentCircle, currentCalculateFill, circleRadius, percent);
-                    }
-                } else {
-                    animateCircle(currentCircle, currentCalculateFill, 360, percent);
-                }
-            }
-
-            function animateCircle(currentCircle, currentCalculateFill, circleRadius, percent) {
-                var timer = window.setInterval(function () {
-                    if ((angle) >= currentCalculateFill) {
-                        window.clearInterval(timer);
-                        last = 1;
-                        if (typeof callback === 'function') {
-                            callback.call(this);
-                        }
-                    } else {
-                        angle += angleIncrement;
-                        summary += oneStep;
-                    }
-                    if (settings.halfCircle) {
-                        if (angle * 2 / (circleRadius / 100) >= percent && last === 1) {
-                            angle = ((circleRadius / 100) * percent) / 2
-                        }
-                    } else {
-                        if (angle / (circleRadius / 100) >= percent && last === 1) {
-                            angle = (circleRadius / 100) * percent;
-                        }
-                    }
-
-                    if (summary > settings.target && last === 1) {
-                        summary = settings.target;
-                    }
-
-                    if (settings.replacePercentageByText === null) {
-                        if (settings.halfCircle) {
-                            text = parseFloat((100 * angle / circleRadius) * 2);
-                        } else {
-                            text = parseFloat((100 * angle / circleRadius));
-                        }
-                        text = text.toFixed(settings.decimals);
-                        if (!settings.alwaysDecimals && (percent === 0 || (percent > 1 && last !== 1))) {
-                            text = parseInt(text);
-                        }
-                    }
-
-                    currentCircle
-                        .attr("stroke-dasharray", angle + ", 20000");
-
-                    if (settings.multiPercentage !== 1) {
-                        if (settings.showPercent === 1) {
-                            myTimer
-                                .find('.number')
-                                .text(text);
-                        } else {
-
-                            myTimer
-                                .find('.number')
-                                .text(summary);
-                            myTimer
-                                .find('.percent')
-                                .text('');
-                        }
-                    } else {
-                        myTimer
-                            .find('.number')
-                            .text('');
-                        myTimer
-                            .find('.percent')
-                            .text('');
-                    }
-
-                    if (progressColor !== null) {
-                        $.each(progressColor, function (key, color) {
-                            if (settings.halfCircle) {
-                                key /= 2
-                            }
-                            if (angle >= key * (circleRadius / 100)) {
-                                currentCircle.css({
-                                    stroke: color,
-                                    transition: 'stroke 0.1s linear'
-                                });
-                            }
-                        });
-                    }
-                }.bind(currentCircle), interval);
-            }
-
-            function isElementInViewport() {
-                // Get the scroll position of the page.
-                var scrollElem = ((navigator.userAgent.toLowerCase().indexOf('webkit') !== -1) ? 'body' : 'html');
-                var viewportTop = $(scrollElem).scrollTop();
-                var viewportBottom = viewportTop + $(window).height();
-
-                // Get the position of the element on the page.
-                var elemTop = Math.round(circle.offset().top);
-                var elemBottom = elemTop + circle.height();
-
-                return ((elemTop < viewportBottom) && (elemBottom > viewportTop));
-            }
-
-            function checkAnimation() {
-                // If the animation has already been started
-                if (circle.hasClass('start')) return;
-
-                if (isElementInViewport(circle)) {
-                    // Start the animation
-                    circle.addClass('start');
-                    setTimeout(animate, 250)
-                }
-            }
-
-            function mergeDataAttributes(settings, dataAttributes) {
-                $.each(settings, function (key, value) {
-                    if (key.toLowerCase() in dataAttributes) {
-                        settings[key] = dataAttributes[key.toLowerCase()];
-                    }
-                });
-            }
-
-            /**
-             * Draws the initial circles before animate gets called
-             */
-            function drawCircles() {
-                if (settings.multiPercentage === 1) {
-                    var index, calculateFillMulti, percent, color, circles;
-                    var percentages = settings.percentages;
-                    var radius = 47;
-                    var circleRadius = 360;
-                    var rotate = -90;
-                    for (index = 0; index < percentages.length; ++index) {
-                        percent = percentages[index].percent;
-                        color = percentages[index].color;
-                        calculateFillMulti = (circleRadius / 100 * percent);
-                        if (index > 0) {
-                            circleRadius = circleRadius + 62.5;
-                            calculateFillMulti = (circleRadius / 100 * percent);
-                        }
-                        radius += 10;
-                        circles += '<circle cx="100" cy="100" r="' + radius + '" class="border" fill="' + settings.fillColor + '" stroke="' + settings.backgroundColor + '" stroke-width="' + backgroundBorderWidth + '" stroke-dasharray="' + circleRadius + '" transform="rotate(' + rotate + ',100,100)" />' +
-                            '<circle class="circle" id="circle' + (index + 1) + '" data-percent="' + percent + '" cx="100" cy="100" r="' + radius + '" class="border" fill="none" stroke="' + color + '" stroke-width="' + settings.foregroundBorderWidth + '" stroke-dasharray="' + calculateFillMulti + ',20000" transform="rotate(' + rotate + ',100,100)" />';
-                    }
-
-                    circleContainer
-                        .addClass('svg-container')
-                        .append(
-                            $('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 194 186" class="circliful">' +
-                                (typeof elements !== 'undefined' ? elements : '') +
-                                circles +
-                                icon +
-                                '<text class="timer" text-anchor="middle" x="' + percentageX + '" y="' + percentageY + '" style="font-size: ' + settings.percentageTextSize + 'px; ' + additionalCss + ';' + settings.textAdditionalCss + '" fill="' + settings.fontColor + '">' +
-                                '<tspan class="number">' + (settings.replacePercentageByText === null ? 0 : settings.replacePercentageByText) + '</tspan>' +
-                                '<tspan class="percent">' + (settings.noPercentageSign || settings.replacePercentageByText !== null ? '' : '%') + '</tspan>' +
-                                '</text>')
-                        );
-
-                    if (settings.multiPercentageLegend === 1) {
-                        showLegend();
-                    }
-                } else {
-                    circleContainer
-                        .addClass('svg-container')
-                        .append(
-                            $('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 194 186" class="circliful">' +
-                                (typeof elements !== 'undefined' ? elements : '') +
-                                '<circle cx="100" cy="100" r="57" class="border" fill="' + settings.fillColor + '" stroke="' + settings.backgroundColor + '" stroke-width="' + backgroundBorderWidth + '" stroke-dasharray="360" transform="rotate(-90,100,100)" />' +
-                                '<circle class="circle" cx="100" cy="100" r="57" class="border" fill="none" stroke="' + settings.foregroundColor + '" stroke-width="' + settings.foregroundBorderWidth + '" stroke-dasharray="0,20000" transform="rotate(-90,100,100)" />' +
-                                '<circle cx="100" cy="100" r="' + settings.pointSize + '" fill="' + settings.pointColor + '" />' +
-                                icon +
-                                '<text class="timer" text-anchor="middle" x="' + percentageX + '" y="' + percentageY + '" style="font-size: ' + settings.percentageTextSize + 'px; ' + additionalCss + ';' + settings.textAdditionalCss + '" fill="' + settings.fontColor + '">' +
-                                '<tspan class="number">' + (settings.replacePercentageByText === null ? 0 : settings.replacePercentageByText) + '</tspan>' +
-                                '<tspan class="percent">' + (settings.noPercentageSign || settings.replacePercentageByText !== null ? '' : '%') + '</tspan>' +
-                                '</text>')
-                        );
-                }
-            }
-
-            /**
-             * Show the legend only for multi percentage circles
-             */
-            function showLegend() {
-                var height = circleContainer.height();
-                var width = circleContainer.width();
-                var percentages = settings.percentages;
-                var index;
-                var lines = '';
-                for (index = 0; index < percentages.length; ++index) {
-                    var title = percentages[index].title;
-                    var color = percentages[index].color;
-                    var percent = percentages[index].percent;
-
-                    lines += '<div><span class="color-box" style="background: ' + color + '"></span>' + title + ', ' + percent + '%</div>';
-                }
-
-                circleContainer.append(
-                    $('<div/>')
-                        .append(lines)
-                        .attr('style', 'position:absolute;top:' + height / 3 + 'px;left:' + (width + 20) + 'px')
-                        .attr('class', 'legend-line')
-                );
-            }
-        });
-    }
-}(jQuery));

+ 0 - 2484
static/src/lib/progressbar.js

@@ -1,2484 +0,0 @@
-(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.ProgressBar = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-/* shifty - v1.5.3 - 2016-11-29 - http://jeremyckahn.github.io/shifty */
-;(function () {
-  var root = this || Function('return this')();
-
-/**
- * Shifty Core
- * By Jeremy Kahn - jeremyckahn@gmail.com
- */
-
-var Tweenable = (function () {
-
-  'use strict';
-
-  // Aliases that get defined later in this function
-  var formula;
-
-  // CONSTANTS
-  var DEFAULT_SCHEDULE_FUNCTION;
-  var DEFAULT_EASING = 'linear';
-  var DEFAULT_DURATION = 500;
-  var UPDATE_TIME = 1000 / 60;
-
-  var _now = Date.now
-       ? Date.now
-       : function () {return +new Date();};
-
-  var now = typeof SHIFTY_DEBUG_NOW !== 'undefined' ? SHIFTY_DEBUG_NOW : _now;
-
-  if (typeof window !== 'undefined') {
-    // requestAnimationFrame() shim by Paul Irish (modified for Shifty)
-    // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
-    DEFAULT_SCHEDULE_FUNCTION = window.requestAnimationFrame
-       || window.webkitRequestAnimationFrame
-       || window.oRequestAnimationFrame
-       || window.msRequestAnimationFrame
-       || (window.mozCancelRequestAnimationFrame
-       && window.mozRequestAnimationFrame)
-       || setTimeout;
-  } else {
-    DEFAULT_SCHEDULE_FUNCTION = setTimeout;
-  }
-
-  function noop () {
-    // NOOP!
-  }
-
-  /**
-   * Handy shortcut for doing a for-in loop. This is not a "normal" each
-   * function, it is optimized for Shifty.  The iterator function only receives
-   * the property name, not the value.
-   * @param {Object} obj
-   * @param {Function(string)} fn
-   * @private
-   */
-  function each (obj, fn) {
-    var key;
-    for (key in obj) {
-      if (Object.hasOwnProperty.call(obj, key)) {
-        fn(key);
-      }
-    }
-  }
-
-  /**
-   * Perform a shallow copy of Object properties.
-   * @param {Object} targetObject The object to copy into
-   * @param {Object} srcObject The object to copy from
-   * @return {Object} A reference to the augmented `targetObj` Object
-   * @private
-   */
-  function shallowCopy (targetObj, srcObj) {
-    each(srcObj, function (prop) {
-      targetObj[prop] = srcObj[prop];
-    });
-
-    return targetObj;
-  }
-
-  /**
-   * Copies each property from src onto target, but only if the property to
-   * copy to target is undefined.
-   * @param {Object} target Missing properties in this Object are filled in
-   * @param {Object} src
-   * @private
-   */
-  function defaults (target, src) {
-    each(src, function (prop) {
-      if (typeof target[prop] === 'undefined') {
-        target[prop] = src[prop];
-      }
-    });
-  }
-
-  /**
-   * Calculates the interpolated tween values of an Object for a given
-   * timestamp.
-   * @param {Number} forPosition The position to compute the state for.
-   * @param {Object} currentState Current state properties.
-   * @param {Object} originalState: The original state properties the Object is
-   * tweening from.
-   * @param {Object} targetState: The destination state properties the Object
-   * is tweening to.
-   * @param {number} duration: The length of the tween in milliseconds.
-   * @param {number} timestamp: The UNIX epoch time at which the tween began.
-   * @param {Object} easing: This Object's keys must correspond to the keys in
-   * targetState.
-   * @private
-   */
-  function tweenProps (forPosition, currentState, originalState, targetState,
-    duration, timestamp, easing) {
-    var normalizedPosition =
-        forPosition < timestamp ? 0 : (forPosition - timestamp) / duration;
-
-
-    var prop;
-    var easingObjectProp;
-    var easingFn;
-    for (prop in currentState) {
-      if (currentState.hasOwnProperty(prop)) {
-        easingObjectProp = easing[prop];
-        easingFn = typeof easingObjectProp === 'function'
-          ? easingObjectProp
-          : formula[easingObjectProp];
-
-        currentState[prop] = tweenProp(
-          originalState[prop],
-          targetState[prop],
-          easingFn,
-          normalizedPosition
-        );
-      }
-    }
-
-    return currentState;
-  }
-
-  /**
-   * Tweens a single property.
-   * @param {number} start The value that the tween started from.
-   * @param {number} end The value that the tween should end at.
-   * @param {Function} easingFunc The easing curve to apply to the tween.
-   * @param {number} position The normalized position (between 0.0 and 1.0) to
-   * calculate the midpoint of 'start' and 'end' against.
-   * @return {number} The tweened value.
-   * @private
-   */
-  function tweenProp (start, end, easingFunc, position) {
-    return start + (end - start) * easingFunc(position);
-  }
-
-  /**
-   * Applies a filter to Tweenable instance.
-   * @param {Tweenable} tweenable The `Tweenable` instance to call the filter
-   * upon.
-   * @param {String} filterName The name of the filter to apply.
-   * @private
-   */
-  function applyFilter (tweenable, filterName) {
-    var filters = Tweenable.prototype.filter;
-    var args = tweenable._filterArgs;
-
-    each(filters, function (name) {
-      if (typeof filters[name][filterName] !== 'undefined') {
-        filters[name][filterName].apply(tweenable, args);
-      }
-    });
-  }
-
-  var timeoutHandler_endTime;
-  var timeoutHandler_currentTime;
-  var timeoutHandler_isEnded;
-  var timeoutHandler_offset;
-  /**
-   * Handles the update logic for one step of a tween.
-   * @param {Tweenable} tweenable
-   * @param {number} timestamp
-   * @param {number} delay
-   * @param {number} duration
-   * @param {Object} currentState
-   * @param {Object} originalState
-   * @param {Object} targetState
-   * @param {Object} easing
-   * @param {Function(Object, *, number)} step
-   * @param {Function(Function,number)}} schedule
-   * @param {number=} opt_currentTimeOverride Needed for accurate timestamp in
-   * Tweenable#seek.
-   * @private
-   */
-  function timeoutHandler (tweenable, timestamp, delay, duration, currentState,
-    originalState, targetState, easing, step, schedule,
-    opt_currentTimeOverride) {
-
-    timeoutHandler_endTime = timestamp + delay + duration;
-
-    timeoutHandler_currentTime =
-    Math.min(opt_currentTimeOverride || now(), timeoutHandler_endTime);
-
-    timeoutHandler_isEnded =
-      timeoutHandler_currentTime >= timeoutHandler_endTime;
-
-    timeoutHandler_offset = duration - (
-      timeoutHandler_endTime - timeoutHandler_currentTime);
-
-    if (tweenable.isPlaying()) {
-      if (timeoutHandler_isEnded) {
-        step(targetState, tweenable._attachment, timeoutHandler_offset);
-        tweenable.stop(true);
-      } else {
-        tweenable._scheduleId =
-          schedule(tweenable._timeoutHandler, UPDATE_TIME);
-
-        applyFilter(tweenable, 'beforeTween');
-
-        // If the animation has not yet reached the start point (e.g., there was
-        // delay that has not yet completed), just interpolate the starting
-        // position of the tween.
-        if (timeoutHandler_currentTime < (timestamp + delay)) {
-          tweenProps(1, currentState, originalState, targetState, 1, 1, easing);
-        } else {
-          tweenProps(timeoutHandler_currentTime, currentState, originalState,
-            targetState, duration, timestamp + delay, easing);
-        }
-
-        applyFilter(tweenable, 'afterTween');
-
-        step(currentState, tweenable._attachment, timeoutHandler_offset);
-      }
-    }
-  }
-
-
-  /**
-   * Creates a usable easing Object from a string, a function or another easing
-   * Object.  If `easing` is an Object, then this function clones it and fills
-   * in the missing properties with `"linear"`.
-   * @param {Object.<string|Function>} fromTweenParams
-   * @param {Object|string|Function} easing
-   * @return {Object.<string|Function>}
-   * @private
-   */
-  function composeEasingObject (fromTweenParams, easing) {
-    var composedEasing = {};
-    var typeofEasing = typeof easing;
-
-    if (typeofEasing === 'string' || typeofEasing === 'function') {
-      each(fromTweenParams, function (prop) {
-        composedEasing[prop] = easing;
-      });
-    } else {
-      each(fromTweenParams, function (prop) {
-        if (!composedEasing[prop]) {
-          composedEasing[prop] = easing[prop] || DEFAULT_EASING;
-        }
-      });
-    }
-
-    return composedEasing;
-  }
-
-  /**
-   * Tweenable constructor.
-   * @class Tweenable
-   * @param {Object=} opt_initialState The values that the initial tween should
-   * start at if a `from` object is not provided to `{{#crossLink
-   * "Tweenable/tween:method"}}{{/crossLink}}` or `{{#crossLink
-   * "Tweenable/setConfig:method"}}{{/crossLink}}`.
-   * @param {Object=} opt_config Configuration object to be passed to
-   * `{{#crossLink "Tweenable/setConfig:method"}}{{/crossLink}}`.
-   * @module Tweenable
-   * @constructor
-   */
-  function Tweenable (opt_initialState, opt_config) {
-    this._currentState = opt_initialState || {};
-    this._configured = false;
-    this._scheduleFunction = DEFAULT_SCHEDULE_FUNCTION;
-
-    // To prevent unnecessary calls to setConfig do not set default
-    // configuration here.  Only set default configuration immediately before
-    // tweening if none has been set.
-    if (typeof opt_config !== 'undefined') {
-      this.setConfig(opt_config);
-    }
-  }
-
-  /**
-   * Configure and start a tween.
-   * @method tween
-   * @param {Object=} opt_config Configuration object to be passed to
-   * `{{#crossLink "Tweenable/setConfig:method"}}{{/crossLink}}`.
-   * @chainable
-   */
-  Tweenable.prototype.tween = function (opt_config) {
-    if (this._isTweening) {
-      return this;
-    }
-
-    // Only set default config if no configuration has been set previously and
-    // none is provided now.
-    if (opt_config !== undefined || !this._configured) {
-      this.setConfig(opt_config);
-    }
-
-    this._timestamp = now();
-    this._start(this.get(), this._attachment);
-    return this.resume();
-  };
-
-  /**
-   * Configure a tween that will start at some point in the future.
-   *
-   * @method setConfig
-   * @param {Object} config The following values are valid:
-   * - __from__ (_Object=_): Starting position.  If omitted, `{{#crossLink
-   *   "Tweenable/get:method"}}get(){{/crossLink}}` is used.
-   * - __to__ (_Object=_): Ending position.
-   * - __duration__ (_number=_): How many milliseconds to animate for.
-   * - __delay__ (_delay=_): How many milliseconds to wait before starting the
-   *   tween.
-   * - __start__ (_Function(Object, *)_): Function to execute when the tween
-   *   begins.  Receives the state of the tween as the first parameter and
-   *   `attachment` as the second parameter.
-   * - __step__ (_Function(Object, *, number)_): Function to execute on every
-   *   tick.  Receives `{{#crossLink
-   *   "Tweenable/get:method"}}get(){{/crossLink}}` as the first parameter,
-   *   `attachment` as the second parameter, and the time elapsed since the
-   *   start of the tween as the third. This function is not called on the
-   *   final step of the animation, but `finish` is.
-   * - __finish__ (_Function(Object, *)_): Function to execute upon tween
-   *   completion.  Receives the state of the tween as the first parameter and
-   *   `attachment` as the second parameter.
-   * - __easing__ (_Object.<string|Function>|string|Function=_): Easing curve
-   *   name(s) or function(s) to use for the tween.
-   * - __attachment__ (_*_): Cached value that is passed to the
-   *   `step`/`start`/`finish` methods.
-   * @chainable
-   */
-  Tweenable.prototype.setConfig = function (config) {
-    config = config || {};
-    this._configured = true;
-
-    // Attach something to this Tweenable instance (e.g.: a DOM element, an
-    // object, a string, etc.);
-    this._attachment = config.attachment;
-
-    // Init the internal state
-    this._pausedAtTime = null;
-    this._scheduleId = null;
-    this._delay = config.delay || 0;
-    this._start = config.start || noop;
-    this._step = config.step || noop;
-    this._finish = config.finish || noop;
-    this._duration = config.duration || DEFAULT_DURATION;
-    this._currentState = shallowCopy({}, config.from || this.get());
-    this._originalState = this.get();
-    this._targetState = shallowCopy({}, config.to || this.get());
-
-    var self = this;
-    this._timeoutHandler = function () {
-      timeoutHandler(self,
-        self._timestamp,
-        self._delay,
-        self._duration,
-        self._currentState,
-        self._originalState,
-        self._targetState,
-        self._easing,
-        self._step,
-        self._scheduleFunction
-      );
-    };
-
-    // Aliases used below
-    var currentState = this._currentState;
-    var targetState = this._targetState;
-
-    // Ensure that there is always something to tween to.
-    defaults(targetState, currentState);
-
-    this._easing = composeEasingObject(
-      currentState, config.easing || DEFAULT_EASING);
-
-    this._filterArgs =
-      [currentState, this._originalState, targetState, this._easing];
-
-    applyFilter(this, 'tweenCreated');
-    return this;
-  };
-
-  /**
-   * @method get
-   * @return {Object} The current state.
-   */
-  Tweenable.prototype.get = function () {
-    return shallowCopy({}, this._currentState);
-  };
-
-  /**
-   * @method set
-   * @param {Object} state The current state.
-   */
-  Tweenable.prototype.set = function (state) {
-    this._currentState = state;
-  };
-
-  /**
-   * Pause a tween.  Paused tweens can be resumed from the point at which they
-   * were paused.  This is different from `{{#crossLink
-   * "Tweenable/stop:method"}}{{/crossLink}}`, as that method
-   * causes a tween to start over when it is resumed.
-   * @method pause
-   * @chainable
-   */
-  Tweenable.prototype.pause = function () {
-    this._pausedAtTime = now();
-    this._isPaused = true;
-    return this;
-  };
-
-  /**
-   * Resume a paused tween.
-   * @method resume
-   * @chainable
-   */
-  Tweenable.prototype.resume = function () {
-    if (this._isPaused) {
-      this._timestamp += now() - this._pausedAtTime;
-    }
-
-    this._isPaused = false;
-    this._isTweening = true;
-
-    this._timeoutHandler();
-
-    return this;
-  };
-
-  /**
-   * Move the state of the animation to a specific point in the tween's
-   * timeline.  If the animation is not running, this will cause the `step`
-   * handlers to be called.
-   * @method seek
-   * @param {millisecond} millisecond The millisecond of the animation to seek
-   * to.  This must not be less than `0`.
-   * @chainable
-   */
-  Tweenable.prototype.seek = function (millisecond) {
-    millisecond = Math.max(millisecond, 0);
-    var currentTime = now();
-
-    if ((this._timestamp + millisecond) === 0) {
-      return this;
-    }
-
-    this._timestamp = currentTime - millisecond;
-
-    if (!this.isPlaying()) {
-      this._isTweening = true;
-      this._isPaused = false;
-
-      // If the animation is not running, call timeoutHandler to make sure that
-      // any step handlers are run.
-      timeoutHandler(this,
-        this._timestamp,
-        this._delay,
-        this._duration,
-        this._currentState,
-        this._originalState,
-        this._targetState,
-        this._easing,
-        this._step,
-        this._scheduleFunction,
-        currentTime
-      );
-
-      this.pause();
-    }
-
-    return this;
-  };
-
-  /**
-   * Stops and cancels a tween.
-   * @param {boolean=} gotoEnd If `false` or omitted, the tween just stops at
-   * its current state, and the `finish` handler is not invoked.  If `true`,
-   * the tweened object's values are instantly set to the target values, and
-   * `finish` is invoked.
-   * @method stop
-   * @chainable
-   */
-  Tweenable.prototype.stop = function (gotoEnd) {
-    this._isTweening = false;
-    this._isPaused = false;
-    this._timeoutHandler = noop;
-
-    (root.cancelAnimationFrame            ||
-    root.webkitCancelAnimationFrame     ||
-    root.oCancelAnimationFrame          ||
-    root.msCancelAnimationFrame         ||
-    root.mozCancelRequestAnimationFrame ||
-    root.clearTimeout)(this._scheduleId);
-
-    if (gotoEnd) {
-      applyFilter(this, 'beforeTween');
-      tweenProps(
-        1,
-        this._currentState,
-        this._originalState,
-        this._targetState,
-        1,
-        0,
-        this._easing
-      );
-      applyFilter(this, 'afterTween');
-      applyFilter(this, 'afterTweenEnd');
-      this._finish.call(this, this._currentState, this._attachment);
-    }
-
-    return this;
-  };
-
-  /**
-   * @method isPlaying
-   * @return {boolean} Whether or not a tween is running.
-   */
-  Tweenable.prototype.isPlaying = function () {
-    return this._isTweening && !this._isPaused;
-  };
-
-  /**
-   * Set a custom schedule function.
-   *
-   * If a custom function is not set,
-   * [`requestAnimationFrame`](https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame)
-   * is used if available, otherwise
-   * [`setTimeout`](https://developer.mozilla.org/en-US/docs/Web/API/Window.setTimeout)
-   * is used.
-   * @method setScheduleFunction
-   * @param {Function(Function,number)} scheduleFunction The function to be
-   * used to schedule the next frame to be rendered.
-   */
-  Tweenable.prototype.setScheduleFunction = function (scheduleFunction) {
-    this._scheduleFunction = scheduleFunction;
-  };
-
-  /**
-   * `delete` all "own" properties.  Call this when the `Tweenable` instance
-   * is no longer needed to free memory.
-   * @method dispose
-   */
-  Tweenable.prototype.dispose = function () {
-    var prop;
-    for (prop in this) {
-      if (this.hasOwnProperty(prop)) {
-        delete this[prop];
-      }
-    }
-  };
-
-  /**
-   * Filters are used for transforming the properties of a tween at various
-   * points in a Tweenable's life cycle.  See the README for more info on this.
-   * @private
-   */
-  Tweenable.prototype.filter = {};
-
-  /**
-   * This object contains all of the tweens available to Shifty.  It is
-   * extensible - simply attach properties to the `Tweenable.prototype.formula`
-   * Object following the same format as `linear`.
-   *
-   * `pos` should be a normalized `number` (between 0 and 1).
-   * @property formula
-   * @type {Object(function)}
-   */
-  Tweenable.prototype.formula = {
-    linear: function (pos) {
-      return pos;
-    }
-  };
-
-  formula = Tweenable.prototype.formula;
-
-  shallowCopy(Tweenable, {
-    'now': now
-    ,'each': each
-    ,'tweenProps': tweenProps
-    ,'tweenProp': tweenProp
-    ,'applyFilter': applyFilter
-    ,'shallowCopy': shallowCopy
-    ,'defaults': defaults
-    ,'composeEasingObject': composeEasingObject
-  });
-
-  // `root` is provided in the intro/outro files.
-
-  // A hook used for unit testing.
-  if (typeof SHIFTY_DEBUG_NOW === 'function') {
-    root.timeoutHandler = timeoutHandler;
-  }
-
-  // Bootstrap Tweenable appropriately for the environment.
-  if (typeof exports === 'object') {
-    // CommonJS
-    module.exports = Tweenable;
-  } else if (typeof define === 'function' && define.amd) {
-    // AMD
-    define(function () {return Tweenable;});
-  } else if (typeof root.Tweenable === 'undefined') {
-    // Browser: Make `Tweenable` globally accessible.
-    root.Tweenable = Tweenable;
-  }
-
-  return Tweenable;
-
-} ());
-
-/*!
- * All equations are adapted from Thomas Fuchs'
- * [Scripty2](https://github.com/madrobby/scripty2/blob/master/src/effects/transitions/penner.js).
- *
- * Based on Easing Equations (c) 2003 [Robert
- * Penner](http://www.robertpenner.com/), all rights reserved. This work is
- * [subject to terms](http://www.robertpenner.com/easing_terms_of_use.html).
- */
-
-/*!
- *  TERMS OF USE - EASING EQUATIONS
- *  Open source under the BSD License.
- *  Easing Equations (c) 2003 Robert Penner, all rights reserved.
- */
-
-;(function () {
-
-  Tweenable.shallowCopy(Tweenable.prototype.formula, {
-    easeInQuad: function (pos) {
-      return Math.pow(pos, 2);
-    },
-
-    easeOutQuad: function (pos) {
-      return -(Math.pow((pos - 1), 2) - 1);
-    },
-
-    easeInOutQuad: function (pos) {
-      if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(pos,2);}
-      return -0.5 * ((pos -= 2) * pos - 2);
-    },
-
-    easeInCubic: function (pos) {
-      return Math.pow(pos, 3);
-    },
-
-    easeOutCubic: function (pos) {
-      return (Math.pow((pos - 1), 3) + 1);
-    },
-
-    easeInOutCubic: function (pos) {
-      if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(pos,3);}
-      return 0.5 * (Math.pow((pos - 2),3) + 2);
-    },
-
-    easeInQuart: function (pos) {
-      return Math.pow(pos, 4);
-    },
-
-    easeOutQuart: function (pos) {
-      return -(Math.pow((pos - 1), 4) - 1);
-    },
-
-    easeInOutQuart: function (pos) {
-      if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(pos,4);}
-      return -0.5 * ((pos -= 2) * Math.pow(pos,3) - 2);
-    },
-
-    easeInQuint: function (pos) {
-      return Math.pow(pos, 5);
-    },
-
-    easeOutQuint: function (pos) {
-      return (Math.pow((pos - 1), 5) + 1);
-    },
-
-    easeInOutQuint: function (pos) {
-      if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(pos,5);}
-      return 0.5 * (Math.pow((pos - 2),5) + 2);
-    },
-
-    easeInSine: function (pos) {
-      return -Math.cos(pos * (Math.PI / 2)) + 1;
-    },
-
-    easeOutSine: function (pos) {
-      return Math.sin(pos * (Math.PI / 2));
-    },
-
-    easeInOutSine: function (pos) {
-      return (-0.5 * (Math.cos(Math.PI * pos) - 1));
-    },
-
-    easeInExpo: function (pos) {
-      return (pos === 0) ? 0 : Math.pow(2, 10 * (pos - 1));
-    },
-
-    easeOutExpo: function (pos) {
-      return (pos === 1) ? 1 : -Math.pow(2, -10 * pos) + 1;
-    },
-
-    easeInOutExpo: function (pos) {
-      if (pos === 0) {return 0;}
-      if (pos === 1) {return 1;}
-      if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(2,10 * (pos - 1));}
-      return 0.5 * (-Math.pow(2, -10 * --pos) + 2);
-    },
-
-    easeInCirc: function (pos) {
-      return -(Math.sqrt(1 - (pos * pos)) - 1);
-    },
-
-    easeOutCirc: function (pos) {
-      return Math.sqrt(1 - Math.pow((pos - 1), 2));
-    },
-
-    easeInOutCirc: function (pos) {
-      if ((pos /= 0.5) < 1) {return -0.5 * (Math.sqrt(1 - pos * pos) - 1);}
-      return 0.5 * (Math.sqrt(1 - (pos -= 2) * pos) + 1);
-    },
-
-    easeOutBounce: function (pos) {
-      if ((pos) < (1 / 2.75)) {
-        return (7.5625 * pos * pos);
-      } else if (pos < (2 / 2.75)) {
-        return (7.5625 * (pos -= (1.5 / 2.75)) * pos + 0.75);
-      } else if (pos < (2.5 / 2.75)) {
-        return (7.5625 * (pos -= (2.25 / 2.75)) * pos + 0.9375);
-      } else {
-        return (7.5625 * (pos -= (2.625 / 2.75)) * pos + 0.984375);
-      }
-    },
-
-    easeInBack: function (pos) {
-      var s = 1.70158;
-      return (pos) * pos * ((s + 1) * pos - s);
-    },
-
-    easeOutBack: function (pos) {
-      var s = 1.70158;
-      return (pos = pos - 1) * pos * ((s + 1) * pos + s) + 1;
-    },
-
-    easeInOutBack: function (pos) {
-      var s = 1.70158;
-      if ((pos /= 0.5) < 1) {
-        return 0.5 * (pos * pos * (((s *= (1.525)) + 1) * pos - s));
-      }
-      return 0.5 * ((pos -= 2) * pos * (((s *= (1.525)) + 1) * pos + s) + 2);
-    },
-
-    elastic: function (pos) {
-      // jshint maxlen:90
-      return -1 * Math.pow(4,-8 * pos) * Math.sin((pos * 6 - 1) * (2 * Math.PI) / 2) + 1;
-    },
-
-    swingFromTo: function (pos) {
-      var s = 1.70158;
-      return ((pos /= 0.5) < 1) ?
-          0.5 * (pos * pos * (((s *= (1.525)) + 1) * pos - s)) :
-          0.5 * ((pos -= 2) * pos * (((s *= (1.525)) + 1) * pos + s) + 2);
-    },
-
-    swingFrom: function (pos) {
-      var s = 1.70158;
-      return pos * pos * ((s + 1) * pos - s);
-    },
-
-    swingTo: function (pos) {
-      var s = 1.70158;
-      return (pos -= 1) * pos * ((s + 1) * pos + s) + 1;
-    },
-
-    bounce: function (pos) {
-      if (pos < (1 / 2.75)) {
-        return (7.5625 * pos * pos);
-      } else if (pos < (2 / 2.75)) {
-        return (7.5625 * (pos -= (1.5 / 2.75)) * pos + 0.75);
-      } else if (pos < (2.5 / 2.75)) {
-        return (7.5625 * (pos -= (2.25 / 2.75)) * pos + 0.9375);
-      } else {
-        return (7.5625 * (pos -= (2.625 / 2.75)) * pos + 0.984375);
-      }
-    },
-
-    bouncePast: function (pos) {
-      if (pos < (1 / 2.75)) {
-        return (7.5625 * pos * pos);
-      } else if (pos < (2 / 2.75)) {
-        return 2 - (7.5625 * (pos -= (1.5 / 2.75)) * pos + 0.75);
-      } else if (pos < (2.5 / 2.75)) {
-        return 2 - (7.5625 * (pos -= (2.25 / 2.75)) * pos + 0.9375);
-      } else {
-        return 2 - (7.5625 * (pos -= (2.625 / 2.75)) * pos + 0.984375);
-      }
-    },
-
-    easeFromTo: function (pos) {
-      if ((pos /= 0.5) < 1) {return 0.5 * Math.pow(pos,4);}
-      return -0.5 * ((pos -= 2) * Math.pow(pos,3) - 2);
-    },
-
-    easeFrom: function (pos) {
-      return Math.pow(pos,4);
-    },
-
-    easeTo: function (pos) {
-      return Math.pow(pos,0.25);
-    }
-  });
-
-}());
-
-// jshint maxlen:100
-/**
- * The Bezier magic in this file is adapted/copied almost wholesale from
- * [Scripty2](https://github.com/madrobby/scripty2/blob/master/src/effects/transitions/cubic-bezier.js),
- * which was adapted from Apple code (which probably came from
- * [here](http://opensource.apple.com/source/WebCore/WebCore-955.66/platform/graphics/UnitBezier.h)).
- * Special thanks to Apple and Thomas Fuchs for much of this code.
- */
-
-/**
- *  Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are met:
- *
- *  1. Redistributions of source code must retain the above copyright notice,
- *  this list of conditions and the following disclaimer.
- *
- *  2. Redistributions in binary form must reproduce the above copyright notice,
- *  this list of conditions and the following disclaimer in the documentation
- *  and/or other materials provided with the distribution.
- *
- *  3. Neither the name of the copyright holder(s) nor the names of any
- *  contributors may be used to endorse or promote products derived from
- *  this software without specific prior written permission.
- *
- *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- *  POSSIBILITY OF SUCH DAMAGE.
- */
-;(function () {
-  // port of webkit cubic bezier handling by http://www.netzgesta.de/dev/
-  function cubicBezierAtTime(t,p1x,p1y,p2x,p2y,duration) {
-    var ax = 0,bx = 0,cx = 0,ay = 0,by = 0,cy = 0;
-    function sampleCurveX(t) {
-      return ((ax * t + bx) * t + cx) * t;
-    }
-    function sampleCurveY(t) {
-      return ((ay * t + by) * t + cy) * t;
-    }
-    function sampleCurveDerivativeX(t) {
-      return (3.0 * ax * t + 2.0 * bx) * t + cx;
-    }
-    function solveEpsilon(duration) {
-      return 1.0 / (200.0 * duration);
-    }
-    function solve(x,epsilon) {
-      return sampleCurveY(solveCurveX(x, epsilon));
-    }
-    function fabs(n) {
-      if (n >= 0) {
-        return n;
-      } else {
-        return 0 - n;
-      }
-    }
-    function solveCurveX(x, epsilon) {
-      var t0,t1,t2,x2,d2,i;
-      for (t2 = x, i = 0; i < 8; i++) {
-        x2 = sampleCurveX(t2) - x;
-        if (fabs(x2) < epsilon) {
-          return t2;
-        }
-        d2 = sampleCurveDerivativeX(t2);
-        if (fabs(d2) < 1e-6) {
-          break;
-        }
-        t2 = t2 - x2 / d2;
-      }
-      t0 = 0.0;
-      t1 = 1.0;
-      t2 = x;
-      if (t2 < t0) {
-        return t0;
-      }
-      if (t2 > t1) {
-        return t1;
-      }
-      while (t0 < t1) {
-        x2 = sampleCurveX(t2);
-        if (fabs(x2 - x) < epsilon) {
-          return t2;
-        }
-        if (x > x2) {
-          t0 = t2;
-        }else {
-          t1 = t2;
-        }
-        t2 = (t1 - t0) * 0.5 + t0;
-      }
-      return t2; // Failure.
-    }
-    cx = 3.0 * p1x;
-    bx = 3.0 * (p2x - p1x) - cx;
-    ax = 1.0 - cx - bx;
-    cy = 3.0 * p1y;
-    by = 3.0 * (p2y - p1y) - cy;
-    ay = 1.0 - cy - by;
-    return solve(t, solveEpsilon(duration));
-  }
-  /**
-   *  getCubicBezierTransition(x1, y1, x2, y2) -> Function
-   *
-   *  Generates a transition easing function that is compatible
-   *  with WebKit's CSS transitions `-webkit-transition-timing-function`
-   *  CSS property.
-   *
-   *  The W3C has more information about CSS3 transition timing functions:
-   *  http://www.w3.org/TR/css3-transitions/#transition-timing-function_tag
-   *
-   *  @param {number} x1
-   *  @param {number} y1
-   *  @param {number} x2
-   *  @param {number} y2
-   *  @return {function}
-   *  @private
-   */
-  function getCubicBezierTransition (x1, y1, x2, y2) {
-    return function (pos) {
-      return cubicBezierAtTime(pos,x1,y1,x2,y2,1);
-    };
-  }
-  // End ported code
-
-  /**
-   * Create a Bezier easing function and attach it to `{{#crossLink
-   * "Tweenable/formula:property"}}Tweenable#formula{{/crossLink}}`.  This
-   * function gives you total control over the easing curve.  Matthew Lein's
-   * [Ceaser](http://matthewlein.com/ceaser/) is a useful tool for visualizing
-   * the curves you can make with this function.
-   * @method setBezierFunction
-   * @param {string} name The name of the easing curve.  Overwrites the old
-   * easing function on `{{#crossLink
-   * "Tweenable/formula:property"}}Tweenable#formula{{/crossLink}}` if it
-   * exists.
-   * @param {number} x1
-   * @param {number} y1
-   * @param {number} x2
-   * @param {number} y2
-   * @return {function} The easing function that was attached to
-   * Tweenable.prototype.formula.
-   */
-  Tweenable.setBezierFunction = function (name, x1, y1, x2, y2) {
-    var cubicBezierTransition = getCubicBezierTransition(x1, y1, x2, y2);
-    cubicBezierTransition.displayName = name;
-    cubicBezierTransition.x1 = x1;
-    cubicBezierTransition.y1 = y1;
-    cubicBezierTransition.x2 = x2;
-    cubicBezierTransition.y2 = y2;
-
-    return Tweenable.prototype.formula[name] = cubicBezierTransition;
-  };
-
-
-  /**
-   * `delete` an easing function from `{{#crossLink
-   * "Tweenable/formula:property"}}Tweenable#formula{{/crossLink}}`.  Be
-   * careful with this method, as it `delete`s whatever easing formula matches
-   * `name` (which means you can delete standard Shifty easing functions).
-   * @method unsetBezierFunction
-   * @param {string} name The name of the easing function to delete.
-   * @return {function}
-   */
-  Tweenable.unsetBezierFunction = function (name) {
-    delete Tweenable.prototype.formula[name];
-  };
-
-})();
-
-;(function () {
-
-  function getInterpolatedValues (
-    from, current, targetState, position, easing, delay) {
-    return Tweenable.tweenProps(
-      position, current, from, targetState, 1, delay, easing);
-  }
-
-  // Fake a Tweenable and patch some internals.  This approach allows us to
-  // skip uneccessary processing and object recreation, cutting down on garbage
-  // collection pauses.
-  var mockTweenable = new Tweenable();
-  mockTweenable._filterArgs = [];
-
-  /**
-   * Compute the midpoint of two Objects.  This method effectively calculates a
-   * specific frame of animation that `{{#crossLink
-   * "Tweenable/tween:method"}}{{/crossLink}}` does many times over the course
-   * of a full tween.
-   *
-   *     var interpolatedValues = Tweenable.interpolate({
-   *       width: '100px',
-   *       opacity: 0,
-   *       color: '#fff'
-   *     }, {
-   *       width: '200px',
-   *       opacity: 1,
-   *       color: '#000'
-   *     }, 0.5);
-   *
-   *     console.log(interpolatedValues);
-   *     // {opacity: 0.5, width: "150px", color: "rgb(127,127,127)"}
-   *
-   * @static
-   * @method interpolate
-   * @param {Object} from The starting values to tween from.
-   * @param {Object} targetState The ending values to tween to.
-   * @param {number} position The normalized position value (between `0.0` and
-   * `1.0`) to interpolate the values between `from` and `to` for.  `from`
-   * represents `0` and `to` represents `1`.
-   * @param {Object.<string|Function>|string|Function} easing The easing
-   * curve(s) to calculate the midpoint against.  You can reference any easing
-   * function attached to `Tweenable.prototype.formula`, or provide the easing
-   * function(s) directly.  If omitted, this defaults to "linear".
-   * @param {number=} opt_delay Optional delay to pad the beginning of the
-   * interpolated tween with.  This increases the range of `position` from (`0`
-   * through `1`) to (`0` through `1 + opt_delay`).  So, a delay of `0.5` would
-   * increase all valid values of `position` to numbers between `0` and `1.5`.
-   * @return {Object}
-   */
-  Tweenable.interpolate = function (
-    from, targetState, position, easing, opt_delay) {
-
-    var current = Tweenable.shallowCopy({}, from);
-    var delay = opt_delay || 0;
-    var easingObject = Tweenable.composeEasingObject(
-      from, easing || 'linear');
-
-    mockTweenable.set({});
-
-    // Alias and reuse the _filterArgs array instead of recreating it.
-    var filterArgs = mockTweenable._filterArgs;
-    filterArgs.length = 0;
-    filterArgs[0] = current;
-    filterArgs[1] = from;
-    filterArgs[2] = targetState;
-    filterArgs[3] = easingObject;
-
-    // Any defined value transformation must be applied
-    Tweenable.applyFilter(mockTweenable, 'tweenCreated');
-    Tweenable.applyFilter(mockTweenable, 'beforeTween');
-
-    var interpolatedValues = getInterpolatedValues(
-      from, current, targetState, position, easingObject, delay);
-
-    // Transform values back into their original format
-    Tweenable.applyFilter(mockTweenable, 'afterTween');
-
-    return interpolatedValues;
-  };
-
-}());
-
-/**
- * This module adds string interpolation support to Shifty.
- *
- * The Token extension allows Shifty to tween numbers inside of strings.  Among
- * other things, this allows you to animate CSS properties.  For example, you
- * can do this:
- *
- *     var tweenable = new Tweenable();
- *     tweenable.tween({
- *       from: { transform: 'translateX(45px)' },
- *       to: { transform: 'translateX(90xp)' }
- *     });
- *
- * `translateX(45)` will be tweened to `translateX(90)`.  To demonstrate:
- *
- *     var tweenable = new Tweenable();
- *     tweenable.tween({
- *       from: { transform: 'translateX(45px)' },
- *       to: { transform: 'translateX(90px)' },
- *       step: function (state) {
- *         console.log(state.transform);
- *       }
- *     });
- *
- * The above snippet will log something like this in the console:
- *
- *     translateX(60.3px)
- *     ...
- *     translateX(76.05px)
- *     ...
- *     translateX(90px)
- *
- * Another use for this is animating colors:
- *
- *     var tweenable = new Tweenable();
- *     tweenable.tween({
- *       from: { color: 'rgb(0,255,0)' },
- *       to: { color: 'rgb(255,0,255)' },
- *       step: function (state) {
- *         console.log(state.color);
- *       }
- *     });
- *
- * The above snippet will log something like this:
- *
- *     rgb(84,170,84)
- *     ...
- *     rgb(170,84,170)
- *     ...
- *     rgb(255,0,255)
- *
- * This extension also supports hexadecimal colors, in both long (`#ff00ff`)
- * and short (`#f0f`) forms.  Be aware that hexadecimal input values will be
- * converted into the equivalent RGB output values.  This is done to optimize
- * for performance.
- *
- *     var tweenable = new Tweenable();
- *     tweenable.tween({
- *       from: { color: '#0f0' },
- *       to: { color: '#f0f' },
- *       step: function (state) {
- *         console.log(state.color);
- *       }
- *     });
- *
- * This snippet will generate the same output as the one before it because
- * equivalent values were supplied (just in hexadecimal form rather than RGB):
- *
- *     rgb(84,170,84)
- *     ...
- *     rgb(170,84,170)
- *     ...
- *     rgb(255,0,255)
- *
- * ## Easing support
- *
- * Easing works somewhat differently in the Token extension.  This is because
- * some CSS properties have multiple values in them, and you might need to
- * tween each value along its own easing curve.  A basic example:
- *
- *     var tweenable = new Tweenable();
- *     tweenable.tween({
- *       from: { transform: 'translateX(0px) translateY(0px)' },
- *       to: { transform:   'translateX(100px) translateY(100px)' },
- *       easing: { transform: 'easeInQuad' },
- *       step: function (state) {
- *         console.log(state.transform);
- *       }
- *     });
- *
- * The above snippet will create values like this:
- *
- *     translateX(11.56px) translateY(11.56px)
- *     ...
- *     translateX(46.24px) translateY(46.24px)
- *     ...
- *     translateX(100px) translateY(100px)
- *
- * In this case, the values for `translateX` and `translateY` are always the
- * same for each step of the tween, because they have the same start and end
- * points and both use the same easing curve.  We can also tween `translateX`
- * and `translateY` along independent curves:
- *
- *     var tweenable = new Tweenable();
- *     tweenable.tween({
- *       from: { transform: 'translateX(0px) translateY(0px)' },
- *       to: { transform:   'translateX(100px) translateY(100px)' },
- *       easing: { transform: 'easeInQuad bounce' },
- *       step: function (state) {
- *         console.log(state.transform);
- *       }
- *     });
- *
- * The above snippet will create values like this:
- *
- *     translateX(10.89px) translateY(82.35px)
- *     ...
- *     translateX(44.89px) translateY(86.73px)
- *     ...
- *     translateX(100px) translateY(100px)
- *
- * `translateX` and `translateY` are not in sync anymore, because `easeInQuad`
- * was specified for `translateX` and `bounce` for `translateY`.  Mixing and
- * matching easing curves can make for some interesting motion in your
- * animations.
- *
- * The order of the space-separated easing curves correspond the token values
- * they apply to.  If there are more token values than easing curves listed,
- * the last easing curve listed is used.
- * @submodule Tweenable.token
- */
-
-// token function is defined above only so that dox-foundation sees it as
-// documentation and renders it.  It is never used, and is optimized away at
-// build time.
-
-;(function (Tweenable) {
-
-  /**
-   * @typedef {{
-   *   formatString: string
-   *   chunkNames: Array.<string>
-   * }}
-   * @private
-   */
-  var formatManifest;
-
-  // CONSTANTS
-
-  var R_NUMBER_COMPONENT = /(\d|\-|\.)/;
-  var R_FORMAT_CHUNKS = /([^\-0-9\.]+)/g;
-  var R_UNFORMATTED_VALUES = /[0-9.\-]+/g;
-  var R_RGB = new RegExp(
-    'rgb\\(' + R_UNFORMATTED_VALUES.source +
-    (/,\s*/.source) + R_UNFORMATTED_VALUES.source +
-    (/,\s*/.source) + R_UNFORMATTED_VALUES.source + '\\)', 'g');
-  var R_RGB_PREFIX = /^.*\(/;
-  var R_HEX = /#([0-9]|[a-f]){3,6}/gi;
-  var VALUE_PLACEHOLDER = 'VAL';
-
-  // HELPERS
-
-  /**
-   * @param {Array.number} rawValues
-   * @param {string} prefix
-   *
-   * @return {Array.<string>}
-   * @private
-   */
-  function getFormatChunksFrom (rawValues, prefix) {
-    var accumulator = [];
-
-    var rawValuesLength = rawValues.length;
-    var i;
-
-    for (i = 0; i < rawValuesLength; i++) {
-      accumulator.push('_' + prefix + '_' + i);
-    }
-
-    return accumulator;
-  }
-
-  /**
-   * @param {string} formattedString
-   *
-   * @return {string}
-   * @private
-   */
-  function getFormatStringFrom (formattedString) {
-    var chunks = formattedString.match(R_FORMAT_CHUNKS);
-
-    if (!chunks) {
-      // chunks will be null if there were no tokens to parse in
-      // formattedString (for example, if formattedString is '2').  Coerce
-      // chunks to be useful here.
-      chunks = ['', ''];
-
-      // If there is only one chunk, assume that the string is a number
-      // followed by a token...
-      // NOTE: This may be an unwise assumption.
-    } else if (chunks.length === 1 ||
-      // ...or if the string starts with a number component (".", "-", or a
-      // digit)...
-    formattedString.charAt(0).match(R_NUMBER_COMPONENT)) {
-      // ...prepend an empty string here to make sure that the formatted number
-      // is properly replaced by VALUE_PLACEHOLDER
-      chunks.unshift('');
-    }
-
-    return chunks.join(VALUE_PLACEHOLDER);
-  }
-
-  /**
-   * Convert all hex color values within a string to an rgb string.
-   *
-   * @param {Object} stateObject
-   *
-   * @return {Object} The modified obj
-   * @private
-   */
-  function sanitizeObjectForHexProps (stateObject) {
-    Tweenable.each(stateObject, function (prop) {
-      var currentProp = stateObject[prop];
-
-      if (typeof currentProp === 'string' && currentProp.match(R_HEX)) {
-        stateObject[prop] = sanitizeHexChunksToRGB(currentProp);
-      }
-    });
-  }
-
-  /**
-   * @param {string} str
-   *
-   * @return {string}
-   * @private
-   */
-  function  sanitizeHexChunksToRGB (str) {
-    return filterStringChunks(R_HEX, str, convertHexToRGB);
-  }
-
-  /**
-   * @param {string} hexString
-   *
-   * @return {string}
-   * @private
-   */
-  function convertHexToRGB (hexString) {
-    var rgbArr = hexToRGBArray(hexString);
-    return 'rgb(' + rgbArr[0] + ',' + rgbArr[1] + ',' + rgbArr[2] + ')';
-  }
-
-  var hexToRGBArray_returnArray = [];
-  /**
-   * Convert a hexadecimal string to an array with three items, one each for
-   * the red, blue, and green decimal values.
-   *
-   * @param {string} hex A hexadecimal string.
-   *
-   * @returns {Array.<number>} The converted Array of RGB values if `hex` is a
-   * valid string, or an Array of three 0's.
-   * @private
-   */
-  function hexToRGBArray (hex) {
-
-    hex = hex.replace(/#/, '');
-
-    // If the string is a shorthand three digit hex notation, normalize it to
-    // the standard six digit notation
-    if (hex.length === 3) {
-      hex = hex.split('');
-      hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
-    }
-
-    hexToRGBArray_returnArray[0] = hexToDec(hex.substr(0, 2));
-    hexToRGBArray_returnArray[1] = hexToDec(hex.substr(2, 2));
-    hexToRGBArray_returnArray[2] = hexToDec(hex.substr(4, 2));
-
-    return hexToRGBArray_returnArray;
-  }
-
-  /**
-   * Convert a base-16 number to base-10.
-   *
-   * @param {Number|String} hex The value to convert
-   *
-   * @returns {Number} The base-10 equivalent of `hex`.
-   * @private
-   */
-  function hexToDec (hex) {
-    return parseInt(hex, 16);
-  }
-
-  /**
-   * Runs a filter operation on all chunks of a string that match a RegExp
-   *
-   * @param {RegExp} pattern
-   * @param {string} unfilteredString
-   * @param {function(string)} filter
-   *
-   * @return {string}
-   * @private
-   */
-  function filterStringChunks (pattern, unfilteredString, filter) {
-    var pattenMatches = unfilteredString.match(pattern);
-    var filteredString = unfilteredString.replace(pattern, VALUE_PLACEHOLDER);
-
-    if (pattenMatches) {
-      var pattenMatchesLength = pattenMatches.length;
-      var currentChunk;
-
-      for (var i = 0; i < pattenMatchesLength; i++) {
-        currentChunk = pattenMatches.shift();
-        filteredString = filteredString.replace(
-          VALUE_PLACEHOLDER, filter(currentChunk));
-      }
-    }
-
-    return filteredString;
-  }
-
-  /**
-   * Check for floating point values within rgb strings and rounds them.
-   *
-   * @param {string} formattedString
-   *
-   * @return {string}
-   * @private
-   */
-  function sanitizeRGBChunks (formattedString) {
-    return filterStringChunks(R_RGB, formattedString, sanitizeRGBChunk);
-  }
-
-  /**
-   * @param {string} rgbChunk
-   *
-   * @return {string}
-   * @private
-   */
-  function sanitizeRGBChunk (rgbChunk) {
-    var numbers = rgbChunk.match(R_UNFORMATTED_VALUES);
-    var numbersLength = numbers.length;
-    var sanitizedString = rgbChunk.match(R_RGB_PREFIX)[0];
-
-    for (var i = 0; i < numbersLength; i++) {
-      sanitizedString += parseInt(numbers[i], 10) + ',';
-    }
-
-    sanitizedString = sanitizedString.slice(0, -1) + ')';
-
-    return sanitizedString;
-  }
-
-  /**
-   * @param {Object} stateObject
-   *
-   * @return {Object} An Object of formatManifests that correspond to
-   * the string properties of stateObject
-   * @private
-   */
-  function getFormatManifests (stateObject) {
-    var manifestAccumulator = {};
-
-    Tweenable.each(stateObject, function (prop) {
-      var currentProp = stateObject[prop];
-
-      if (typeof currentProp === 'string') {
-        var rawValues = getValuesFrom(currentProp);
-
-        manifestAccumulator[prop] = {
-          'formatString': getFormatStringFrom(currentProp)
-          ,'chunkNames': getFormatChunksFrom(rawValues, prop)
-        };
-      }
-    });
-
-    return manifestAccumulator;
-  }
-
-  /**
-   * @param {Object} stateObject
-   * @param {Object} formatManifests
-   * @private
-   */
-  function expandFormattedProperties (stateObject, formatManifests) {
-    Tweenable.each(formatManifests, function (prop) {
-      var currentProp = stateObject[prop];
-      var rawValues = getValuesFrom(currentProp);
-      var rawValuesLength = rawValues.length;
-
-      for (var i = 0; i < rawValuesLength; i++) {
-        stateObject[formatManifests[prop].chunkNames[i]] = +rawValues[i];
-      }
-
-      delete stateObject[prop];
-    });
-  }
-
-  /**
-   * @param {Object} stateObject
-   * @param {Object} formatManifests
-   * @private
-   */
-  function collapseFormattedProperties (stateObject, formatManifests) {
-    Tweenable.each(formatManifests, function (prop) {
-      var currentProp = stateObject[prop];
-      var formatChunks = extractPropertyChunks(
-        stateObject, formatManifests[prop].chunkNames);
-      var valuesList = getValuesList(
-        formatChunks, formatManifests[prop].chunkNames);
-      currentProp = getFormattedValues(
-        formatManifests[prop].formatString, valuesList);
-      stateObject[prop] = sanitizeRGBChunks(currentProp);
-    });
-  }
-
-  /**
-   * @param {Object} stateObject
-   * @param {Array.<string>} chunkNames
-   *
-   * @return {Object} The extracted value chunks.
-   * @private
-   */
-  function extractPropertyChunks (stateObject, chunkNames) {
-    var extractedValues = {};
-    var currentChunkName, chunkNamesLength = chunkNames.length;
-
-    for (var i = 0; i < chunkNamesLength; i++) {
-      currentChunkName = chunkNames[i];
-      extractedValues[currentChunkName] = stateObject[currentChunkName];
-      delete stateObject[currentChunkName];
-    }
-
-    return extractedValues;
-  }
-
-  var getValuesList_accumulator = [];
-  /**
-   * @param {Object} stateObject
-   * @param {Array.<string>} chunkNames
-   *
-   * @return {Array.<number>}
-   * @private
-   */
-  function getValuesList (stateObject, chunkNames) {
-    getValuesList_accumulator.length = 0;
-    var chunkNamesLength = chunkNames.length;
-
-    for (var i = 0; i < chunkNamesLength; i++) {
-      getValuesList_accumulator.push(stateObject[chunkNames[i]]);
-    }
-
-    return getValuesList_accumulator;
-  }
-
-  /**
-   * @param {string} formatString
-   * @param {Array.<number>} rawValues
-   *
-   * @return {string}
-   * @private
-   */
-  function getFormattedValues (formatString, rawValues) {
-    var formattedValueString = formatString;
-    var rawValuesLength = rawValues.length;
-
-    for (var i = 0; i < rawValuesLength; i++) {
-      formattedValueString = formattedValueString.replace(
-        VALUE_PLACEHOLDER, +rawValues[i].toFixed(4));
-    }
-
-    return formattedValueString;
-  }
-
-  /**
-   * Note: It's the duty of the caller to convert the Array elements of the
-   * return value into numbers.  This is a performance optimization.
-   *
-   * @param {string} formattedString
-   *
-   * @return {Array.<string>|null}
-   * @private
-   */
-  function getValuesFrom (formattedString) {
-    return formattedString.match(R_UNFORMATTED_VALUES);
-  }
-
-  /**
-   * @param {Object} easingObject
-   * @param {Object} tokenData
-   * @private
-   */
-  function expandEasingObject (easingObject, tokenData) {
-    Tweenable.each(tokenData, function (prop) {
-      var currentProp = tokenData[prop];
-      var chunkNames = currentProp.chunkNames;
-      var chunkLength = chunkNames.length;
-
-      var easing = easingObject[prop];
-      var i;
-
-      if (typeof easing === 'string') {
-        var easingChunks = easing.split(' ');
-        var lastEasingChunk = easingChunks[easingChunks.length - 1];
-
-        for (i = 0; i < chunkLength; i++) {
-          easingObject[chunkNames[i]] = easingChunks[i] || lastEasingChunk;
-        }
-
-      } else {
-        for (i = 0; i < chunkLength; i++) {
-          easingObject[chunkNames[i]] = easing;
-        }
-      }
-
-      delete easingObject[prop];
-    });
-  }
-
-  /**
-   * @param {Object} easingObject
-   * @param {Object} tokenData
-   * @private
-   */
-  function collapseEasingObject (easingObject, tokenData) {
-    Tweenable.each(tokenData, function (prop) {
-      var currentProp = tokenData[prop];
-      var chunkNames = currentProp.chunkNames;
-      var chunkLength = chunkNames.length;
-
-      var firstEasing = easingObject[chunkNames[0]];
-      var typeofEasings = typeof firstEasing;
-
-      if (typeofEasings === 'string') {
-        var composedEasingString = '';
-
-        for (var i = 0; i < chunkLength; i++) {
-          composedEasingString += ' ' + easingObject[chunkNames[i]];
-          delete easingObject[chunkNames[i]];
-        }
-
-        easingObject[prop] = composedEasingString.substr(1);
-      } else {
-        easingObject[prop] = firstEasing;
-      }
-    });
-  }
-
-  Tweenable.prototype.filter.token = {
-    'tweenCreated': function (currentState, fromState, toState, easingObject) {
-      sanitizeObjectForHexProps(currentState);
-      sanitizeObjectForHexProps(fromState);
-      sanitizeObjectForHexProps(toState);
-      this._tokenData = getFormatManifests(currentState);
-    },
-
-    'beforeTween': function (currentState, fromState, toState, easingObject) {
-      expandEasingObject(easingObject, this._tokenData);
-      expandFormattedProperties(currentState, this._tokenData);
-      expandFormattedProperties(fromState, this._tokenData);
-      expandFormattedProperties(toState, this._tokenData);
-    },
-
-    'afterTween': function (currentState, fromState, toState, easingObject) {
-      collapseFormattedProperties(currentState, this._tokenData);
-      collapseFormattedProperties(fromState, this._tokenData);
-      collapseFormattedProperties(toState, this._tokenData);
-      collapseEasingObject(easingObject, this._tokenData);
-    }
-  };
-
-} (Tweenable));
-
-}).call(null);
-
-},{}],2:[function(require,module,exports){
-// Circle shaped progress bar
-
-var Shape = require('./shape');
-var utils = require('./utils');
-
-var Circle = function Circle(container, options) {
-    // Use two arcs to form a circle
-    // See this answer http://stackoverflow.com/a/10477334/1446092
-    this._pathTemplate =
-        'M 50,50 m 0,-{radius}' +
-        ' a {radius},{radius} 0 1 1 0,{2radius}' +
-        ' a {radius},{radius} 0 1 1 0,-{2radius}';
-
-    this.containerAspectRatio = 1;
-
-    Shape.apply(this, arguments);
-};
-
-Circle.prototype = new Shape();
-Circle.prototype.constructor = Circle;
-
-Circle.prototype._pathString = function _pathString(opts) {
-    var widthOfWider = opts.strokeWidth;
-    if (opts.trailWidth && opts.trailWidth > opts.strokeWidth) {
-        widthOfWider = opts.trailWidth;
-    }
-
-    var r = 50 - widthOfWider / 2;
-
-    return utils.render(this._pathTemplate, {
-        radius: r,
-        '2radius': r * 2
-    });
-};
-
-Circle.prototype._trailString = function _trailString(opts) {
-    return this._pathString(opts);
-};
-
-module.exports = Circle;
-
-},{"./shape":7,"./utils":9}],3:[function(require,module,exports){
-// Line shaped progress bar
-
-var Shape = require('./shape');
-var utils = require('./utils');
-
-var Line = function Line(container, options) {
-    this._pathTemplate = 'M 0,{center} L 100,{center}';
-    Shape.apply(this, arguments);
-};
-
-Line.prototype = new Shape();
-Line.prototype.constructor = Line;
-
-Line.prototype._initializeSvg = function _initializeSvg(svg, opts) {
-    svg.setAttribute('viewBox', '0 0 100 ' + opts.strokeWidth);
-    svg.setAttribute('preserveAspectRatio', 'none');
-};
-
-Line.prototype._pathString = function _pathString(opts) {
-    return utils.render(this._pathTemplate, {
-        center: opts.strokeWidth / 2
-    });
-};
-
-Line.prototype._trailString = function _trailString(opts) {
-    return this._pathString(opts);
-};
-
-module.exports = Line;
-
-},{"./shape":7,"./utils":9}],4:[function(require,module,exports){
-module.exports = {
-    // Higher level API, different shaped progress bars
-    Line: require('./line'),
-    Circle: require('./circle'),
-    SemiCircle: require('./semicircle'),
-    Square: require('./square'),
-
-    // Lower level API to use any SVG path
-    Path: require('./path'),
-
-    // Base-class for creating new custom shapes
-    // to be in line with the API of built-in shapes
-    // Undocumented.
-    Shape: require('./shape'),
-
-    // Internal utils, undocumented.
-    utils: require('./utils')
-};
-
-},{"./circle":2,"./line":3,"./path":5,"./semicircle":6,"./shape":7,"./square":8,"./utils":9}],5:[function(require,module,exports){
-// Lower level API to animate any kind of svg path
-
-var Tweenable = require('shifty');
-var utils = require('./utils');
-
-var EASING_ALIASES = {
-    easeIn: 'easeInCubic',
-    easeOut: 'easeOutCubic',
-    easeInOut: 'easeInOutCubic'
-};
-
-var Path = function Path(path, opts) {
-    // Throw a better error if not initialized with `new` keyword
-    if (!(this instanceof Path)) {
-        throw new Error('Constructor was called without new keyword');
-    }
-
-    // Default parameters for animation
-    opts = utils.extend({
-        duration: 800,
-        easing: 'linear',
-        from: {},
-        to: {},
-        step: function() {}
-    }, opts);
-
-    var element;
-    if (utils.isString(path)) {
-        element = document.querySelector(path);
-    } else {
-        element = path;
-    }
-
-    // Reveal .path as public attribute
-    this.path = element;
-    this._opts = opts;
-    this._tweenable = null;
-
-    // Set up the starting positions
-    var length = this.path.getTotalLength();
-    this.path.style.strokeDasharray = length + ' ' + length;
-    this.set(0);
-};
-
-Path.prototype.value = function value() {
-    var offset = this._getComputedDashOffset();
-    var length = this.path.getTotalLength();
-
-    var progress = 1 - offset / length;
-    // Round number to prevent returning very small number like 1e-30, which
-    // is practically 0
-    return parseFloat(progress.toFixed(6), 10);
-};
-
-Path.prototype.set = function set(progress) {
-    this.stop();
-
-    this.path.style.strokeDashoffset = this._progressToOffset(progress);
-
-    var step = this._opts.step;
-    if (utils.isFunction(step)) {
-        var easing = this._easing(this._opts.easing);
-        var values = this._calculateTo(progress, easing);
-        var reference = this._opts.shape || this;
-        step(values, reference, this._opts.attachment);
-    }
-};
-
-Path.prototype.stop = function stop() {
-    this._stopTween();
-    this.path.style.strokeDashoffset = this._getComputedDashOffset();
-};
-
-// Method introduced here:
-// http://jakearchibald.com/2013/animated-line-drawing-svg/
-Path.prototype.animate = function animate(progress, opts, cb) {
-    opts = opts || {};
-
-    if (utils.isFunction(opts)) {
-        cb = opts;
-        opts = {};
-    }
-
-    var passedOpts = utils.extend({}, opts);
-
-    // Copy default opts to new object so defaults are not modified
-    var defaultOpts = utils.extend({}, this._opts);
-    opts = utils.extend(defaultOpts, opts);
-
-    var shiftyEasing = this._easing(opts.easing);
-    var values = this._resolveFromAndTo(progress, shiftyEasing, passedOpts);
-
-    this.stop();
-
-    // Trigger a layout so styles are calculated & the browser
-    // picks up the starting position before animating
-    this.path.getBoundingClientRect();
-
-    var offset = this._getComputedDashOffset();
-    var newOffset = this._progressToOffset(progress);
-
-    var self = this;
-    this._tweenable = new Tweenable();
-    this._tweenable.tween({
-        from: utils.extend({ offset: offset }, values.from),
-        to: utils.extend({ offset: newOffset }, values.to),
-        duration: opts.duration,
-        easing: shiftyEasing,
-        step: function(state) {
-            self.path.style.strokeDashoffset = state.offset;
-            var reference = opts.shape || self;
-            opts.step(state, reference, opts.attachment);
-        },
-        finish: function(state) {
-            if (utils.isFunction(cb)) {
-                cb();
-            }
-        }
-    });
-};
-
-Path.prototype._getComputedDashOffset = function _getComputedDashOffset() {
-    var computedStyle = window.getComputedStyle(this.path, null);
-    return parseFloat(computedStyle.getPropertyValue('stroke-dashoffset'), 10);
-};
-
-Path.prototype._progressToOffset = function _progressToOffset(progress) {
-    var length = this.path.getTotalLength();
-    return length - progress * length;
-};
-
-// Resolves from and to values for animation.
-Path.prototype._resolveFromAndTo = function _resolveFromAndTo(progress, easing, opts) {
-    if (opts.from && opts.to) {
-        return {
-            from: opts.from,
-            to: opts.to
-        };
-    }
-
-    return {
-        from: this._calculateFrom(easing),
-        to: this._calculateTo(progress, easing)
-    };
-};
-
-// Calculate `from` values from options passed at initialization
-Path.prototype._calculateFrom = function _calculateFrom(easing) {
-    return Tweenable.interpolate(this._opts.from, this._opts.to, this.value(), easing);
-};
-
-// Calculate `to` values from options passed at initialization
-Path.prototype._calculateTo = function _calculateTo(progress, easing) {
-    return Tweenable.interpolate(this._opts.from, this._opts.to, progress, easing);
-};
-
-Path.prototype._stopTween = function _stopTween() {
-    if (this._tweenable !== null) {
-        this._tweenable.stop();
-        this._tweenable = null;
-    }
-};
-
-Path.prototype._easing = function _easing(easing) {
-    if (EASING_ALIASES.hasOwnProperty(easing)) {
-        return EASING_ALIASES[easing];
-    }
-
-    return easing;
-};
-
-module.exports = Path;
-
-},{"./utils":9,"shifty":1}],6:[function(require,module,exports){
-// Semi-SemiCircle shaped progress bar
-
-var Shape = require('./shape');
-var Circle = require('./circle');
-var utils = require('./utils');
-
-var SemiCircle = function SemiCircle(container, options) {
-    // Use one arc to form a SemiCircle
-    // See this answer http://stackoverflow.com/a/10477334/1446092
-    this._pathTemplate =
-        'M 50,50 m -{radius},0' +
-        ' a {radius},{radius} 0 1 1 {2radius},0';
-
-    this.containerAspectRatio = 2;
-
-    Shape.apply(this, arguments);
-};
-
-SemiCircle.prototype = new Shape();
-SemiCircle.prototype.constructor = SemiCircle;
-
-SemiCircle.prototype._initializeSvg = function _initializeSvg(svg, opts) {
-    svg.setAttribute('viewBox', '0 0 100 50');
-};
-
-SemiCircle.prototype._initializeTextContainer = function _initializeTextContainer(
-    opts,
-    container,
-    textContainer
-) {
-    if (opts.text.style) {
-        // Reset top style
-        textContainer.style.top = 'auto';
-        textContainer.style.bottom = '0';
-
-        if (opts.text.alignToBottom) {
-            utils.setStyle(textContainer, 'transform', 'translate(-50%, 0)');
-        } else {
-            utils.setStyle(textContainer, 'transform', 'translate(-50%, 50%)');
-        }
-    }
-};
-
-// Share functionality with Circle, just have different path
-SemiCircle.prototype._pathString = Circle.prototype._pathString;
-SemiCircle.prototype._trailString = Circle.prototype._trailString;
-
-module.exports = SemiCircle;
-
-},{"./circle":2,"./shape":7,"./utils":9}],7:[function(require,module,exports){
-// Base object for different progress bar shapes
-
-var Path = require('./path');
-var utils = require('./utils');
-
-var DESTROYED_ERROR = 'Object is destroyed';
-
-var Shape = function Shape(container, opts) {
-    // Throw a better error if progress bars are not initialized with `new`
-    // keyword
-    if (!(this instanceof Shape)) {
-        throw new Error('Constructor was called without new keyword');
-    }
-
-    // Prevent calling constructor without parameters so inheritance
-    // works correctly. To understand, this is how Shape is inherited:
-    //
-    //   Line.prototype = new Shape();
-    //
-    // We just want to set the prototype for Line.
-    if (arguments.length === 0) {
-        return;
-    }
-
-    // Default parameters for progress bar creation
-    this._opts = utils.extend({
-        color: '#555',
-        strokeWidth: 1.0,
-        trailColor: null,
-        trailWidth: null,
-        fill: null,
-        text: {
-            style: {
-                color: null,
-                position: 'absolute',
-                left: '50%',
-                top: '50%',
-                padding: 0,
-                margin: 0,
-                transform: {
-                    prefix: true,
-                    value: 'translate(-50%, -50%)'
-                }
-            },
-            autoStyleContainer: true,
-            alignToBottom: true,
-            value: null,
-            className: 'progressbar-text'
-        },
-        svgStyle: {
-            display: 'block',
-            width: '100%'
-        },
-        warnings: false
-    }, opts, true);  // Use recursive extend
-
-    // If user specifies e.g. svgStyle or text style, the whole object
-    // should replace the defaults to make working with styles easier
-    if (utils.isObject(opts) && opts.svgStyle !== undefined) {
-        this._opts.svgStyle = opts.svgStyle;
-    }
-    if (utils.isObject(opts) && utils.isObject(opts.text) && opts.text.style !== undefined) {
-        this._opts.text.style = opts.text.style;
-    }
-
-    var svgView = this._createSvgView(this._opts);
-
-    var element;
-    if (utils.isString(container)) {
-        element = document.querySelector(container);
-    } else {
-        element = container;
-    }
-
-    if (!element) {
-        throw new Error('Container does not exist: ' + container);
-    }
-
-    this._container = element;
-    this._container.appendChild(svgView.svg);
-    if (this._opts.warnings) {
-        this._warnContainerAspectRatio(this._container);
-    }
-
-    if (this._opts.svgStyle) {
-        utils.setStyles(svgView.svg, this._opts.svgStyle);
-    }
-
-    // Expose public attributes before Path initialization
-    this.svg = svgView.svg;
-    this.path = svgView.path;
-    this.trail = svgView.trail;
-    this.text = null;
-
-    var newOpts = utils.extend({
-        attachment: undefined,
-        shape: this
-    }, this._opts);
-    this._progressPath = new Path(svgView.path, newOpts);
-
-    if (utils.isObject(this._opts.text) && this._opts.text.value !== null) {
-        this.setText(this._opts.text.value);
-    }
-};
-
-Shape.prototype.animate = function animate(progress, opts, cb) {
-    if (this._progressPath === null) {
-        throw new Error(DESTROYED_ERROR);
-    }
-
-    this._progressPath.animate(progress, opts, cb);
-};
-
-Shape.prototype.stop = function stop() {
-    if (this._progressPath === null) {
-        throw new Error(DESTROYED_ERROR);
-    }
-
-    // Don't crash if stop is called inside step function
-    if (this._progressPath === undefined) {
-        return;
-    }
-
-    this._progressPath.stop();
-};
-
-Shape.prototype.destroy = function destroy() {
-    if (this._progressPath === null) {
-        throw new Error(DESTROYED_ERROR);
-    }
-
-    this.stop();
-    this.svg.parentNode.removeChild(this.svg);
-    this.svg = null;
-    this.path = null;
-    this.trail = null;
-    this._progressPath = null;
-
-    if (this.text !== null) {
-        this.text.parentNode.removeChild(this.text);
-        this.text = null;
-    }
-};
-
-Shape.prototype.set = function set(progress) {
-    if (this._progressPath === null) {
-        throw new Error(DESTROYED_ERROR);
-    }
-
-    this._progressPath.set(progress);
-};
-
-Shape.prototype.value = function value() {
-    if (this._progressPath === null) {
-        throw new Error(DESTROYED_ERROR);
-    }
-
-    if (this._progressPath === undefined) {
-        return 0;
-    }
-
-    return this._progressPath.value();
-};
-
-Shape.prototype.setText = function setText(newText) {
-    if (this._progressPath === null) {
-        throw new Error(DESTROYED_ERROR);
-    }
-
-    if (this.text === null) {
-        // Create new text node
-        this.text = this._createTextContainer(this._opts, this._container);
-        this._container.appendChild(this.text);
-    }
-
-    // Remove previous text and add new
-    if (utils.isObject(newText)) {
-        utils.removeChildren(this.text);
-        this.text.appendChild(newText);
-    } else {
-        this.text.innerHTML = newText;
-    }
-};
-
-Shape.prototype._createSvgView = function _createSvgView(opts) {
-    var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
-    this._initializeSvg(svg, opts);
-
-    var trailPath = null;
-    // Each option listed in the if condition are 'triggers' for creating
-    // the trail path
-    if (opts.trailColor || opts.trailWidth) {
-        trailPath = this._createTrail(opts);
-        svg.appendChild(trailPath);
-    }
-
-    var path = this._createPath(opts);
-    svg.appendChild(path);
-
-    return {
-        svg: svg,
-        path: path,
-        trail: trailPath
-    };
-};
-
-Shape.prototype._initializeSvg = function _initializeSvg(svg, opts) {
-    svg.setAttribute('viewBox', '0 0 100 100');
-};
-
-Shape.prototype._createPath = function _createPath(opts) {
-    var pathString = this._pathString(opts);
-    return this._createPathElement(pathString, opts);
-};
-
-Shape.prototype._createTrail = function _createTrail(opts) {
-    // Create path string with original passed options
-    var pathString = this._trailString(opts);
-
-    // Prevent modifying original
-    var newOpts = utils.extend({}, opts);
-
-    // Defaults for parameters which modify trail path
-    if (!newOpts.trailColor) {
-        newOpts.trailColor = '#eee';
-    }
-    if (!newOpts.trailWidth) {
-        newOpts.trailWidth = newOpts.strokeWidth;
-    }
-
-    newOpts.color = newOpts.trailColor;
-    newOpts.strokeWidth = newOpts.trailWidth;
-
-    // When trail path is set, fill must be set for it instead of the
-    // actual path to prevent trail stroke from clipping
-    newOpts.fill = null;
-
-    return this._createPathElement(pathString, newOpts);
-};
-
-Shape.prototype._createPathElement = function _createPathElement(pathString, opts) {
-    var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
-    path.setAttribute('d', pathString);
-    path.setAttribute('stroke', opts.color);
-    path.setAttribute('stroke-width', opts.strokeWidth);
-
-    if (opts.fill) {
-        path.setAttribute('fill', opts.fill);
-    } else {
-        path.setAttribute('fill-opacity', '0');
-    }
-
-    return path;
-};
-
-Shape.prototype._createTextContainer = function _createTextContainer(opts, container) {
-    var textContainer = document.createElement('div');
-    textContainer.className = opts.text.className;
-
-    var textStyle = opts.text.style;
-    if (textStyle) {
-        if (opts.text.autoStyleContainer) {
-            container.style.position = 'relative';
-        }
-
-        utils.setStyles(textContainer, textStyle);
-        // Default text color to progress bar's color
-        if (!textStyle.color) {
-            textContainer.style.color = opts.color;
-        }
-    }
-
-    this._initializeTextContainer(opts, container, textContainer);
-    return textContainer;
-};
-
-// Give custom shapes possibility to modify text element
-Shape.prototype._initializeTextContainer = function(opts, container, element) {
-    // By default, no-op
-    // Custom shapes should respect API options, such as text.style
-};
-
-Shape.prototype._pathString = function _pathString(opts) {
-    throw new Error('Override this function for each progress bar');
-};
-
-Shape.prototype._trailString = function _trailString(opts) {
-    throw new Error('Override this function for each progress bar');
-};
-
-Shape.prototype._warnContainerAspectRatio = function _warnContainerAspectRatio(container) {
-    if (!this.containerAspectRatio) {
-        return;
-    }
-
-    var computedStyle = window.getComputedStyle(container, null);
-    var width = parseFloat(computedStyle.getPropertyValue('width'), 10);
-    var height = parseFloat(computedStyle.getPropertyValue('height'), 10);
-    if (!utils.floatEquals(this.containerAspectRatio, width / height)) {
-        console.warn(
-            'Incorrect aspect ratio of container',
-            '#' + container.id,
-            'detected:',
-            computedStyle.getPropertyValue('width') + '(width)',
-            '/',
-            computedStyle.getPropertyValue('height') + '(height)',
-            '=',
-            width / height
-        );
-
-        console.warn(
-            'Aspect ratio of should be',
-            this.containerAspectRatio
-        );
-    }
-};
-
-module.exports = Shape;
-
-},{"./path":5,"./utils":9}],8:[function(require,module,exports){
-// Square shaped progress bar
-// Note: Square is not core part of API anymore. It's left here
-//       for reference. square is not included to the progressbar
-//       build anymore
-
-var Shape = require('./shape');
-var utils = require('./utils');
-
-var Square = function Square(container, options) {
-    this._pathTemplate =
-        'M 0,{halfOfStrokeWidth}' +
-        ' L {width},{halfOfStrokeWidth}' +
-        ' L {width},{width}' +
-        ' L {halfOfStrokeWidth},{width}' +
-        ' L {halfOfStrokeWidth},{strokeWidth}';
-
-    this._trailTemplate =
-        'M {startMargin},{halfOfStrokeWidth}' +
-        ' L {width},{halfOfStrokeWidth}' +
-        ' L {width},{width}' +
-        ' L {halfOfStrokeWidth},{width}' +
-        ' L {halfOfStrokeWidth},{halfOfStrokeWidth}';
-
-    Shape.apply(this, arguments);
-};
-
-Square.prototype = new Shape();
-Square.prototype.constructor = Square;
-
-Square.prototype._pathString = function _pathString(opts) {
-    var w = 100 - opts.strokeWidth / 2;
-
-    return utils.render(this._pathTemplate, {
-        width: w,
-        strokeWidth: opts.strokeWidth,
-        halfOfStrokeWidth: opts.strokeWidth / 2
-    });
-};
-
-Square.prototype._trailString = function _trailString(opts) {
-    var w = 100 - opts.strokeWidth / 2;
-
-    return utils.render(this._trailTemplate, {
-        width: w,
-        strokeWidth: opts.strokeWidth,
-        halfOfStrokeWidth: opts.strokeWidth / 2,
-        startMargin: opts.strokeWidth / 2 - opts.trailWidth / 2
-    });
-};
-
-module.exports = Square;
-
-},{"./shape":7,"./utils":9}],9:[function(require,module,exports){
-// Utility functions
-
-var PREFIXES = 'Webkit Moz O ms'.split(' ');
-var FLOAT_COMPARISON_EPSILON = 0.001;
-
-// Copy all attributes from source object to destination object.
-// destination object is mutated.
-function extend(destination, source, recursive) {
-    destination = destination || {};
-    source = source || {};
-    recursive = recursive || false;
-
-    for (var attrName in source) {
-        if (source.hasOwnProperty(attrName)) {
-            var destVal = destination[attrName];
-            var sourceVal = source[attrName];
-            if (recursive && isObject(destVal) && isObject(sourceVal)) {
-                destination[attrName] = extend(destVal, sourceVal, recursive);
-            } else {
-                destination[attrName] = sourceVal;
-            }
-        }
-    }
-
-    return destination;
-}
-
-// Renders templates with given variables. Variables must be surrounded with
-// braces without any spaces, e.g. {variable}
-// All instances of variable placeholders will be replaced with given content
-// Example:
-// render('Hello, {message}!', {message: 'world'})
-function render(template, vars) {
-    var rendered = template;
-
-    for (var key in vars) {
-        if (vars.hasOwnProperty(key)) {
-            var val = vars[key];
-            var regExpString = '\\{' + key + '\\}';
-            var regExp = new RegExp(regExpString, 'g');
-
-            rendered = rendered.replace(regExp, val);
-        }
-    }
-
-    return rendered;
-}
-
-function setStyle(element, style, value) {
-    var elStyle = element.style;  // cache for performance
-
-    for (var i = 0; i < PREFIXES.length; ++i) {
-        var prefix = PREFIXES[i];
-        elStyle[prefix + capitalize(style)] = value;
-    }
-
-    elStyle[style] = value;
-}
-
-function setStyles(element, styles) {
-    forEachObject(styles, function(styleValue, styleName) {
-        // Allow disabling some individual styles by setting them
-        // to null or undefined
-        if (styleValue === null || styleValue === undefined) {
-            return;
-        }
-
-        // If style's value is {prefix: true, value: '50%'},
-        // Set also browser prefixed styles
-        if (isObject(styleValue) && styleValue.prefix === true) {
-            setStyle(element, styleName, styleValue.value);
-        } else {
-            element.style[styleName] = styleValue;
-        }
-    });
-}
-
-function capitalize(text) {
-    return text.charAt(0).toUpperCase() + text.slice(1);
-}
-
-function isString(obj) {
-    return typeof obj === 'string' || obj instanceof String;
-}
-
-function isFunction(obj) {
-    return typeof obj === 'function';
-}
-
-function isArray(obj) {
-    return Object.prototype.toString.call(obj) === '[object Array]';
-}
-
-// Returns true if `obj` is object as in {a: 1, b: 2}, not if it's function or
-// array
-function isObject(obj) {
-    if (isArray(obj)) {
-        return false;
-    }
-
-    var type = typeof obj;
-    return type === 'object' && !!obj;
-}
-
-function forEachObject(object, callback) {
-    for (var key in object) {
-        if (object.hasOwnProperty(key)) {
-            var val = object[key];
-            callback(val, key);
-        }
-    }
-}
-
-function floatEquals(a, b) {
-    return Math.abs(a - b) < FLOAT_COMPARISON_EPSILON;
-}
-
-// https://coderwall.com/p/nygghw/don-t-use-innerhtml-to-empty-dom-elements
-function removeChildren(el) {
-    while (el.firstChild) {
-        el.removeChild(el.firstChild);
-    }
-}
-
-module.exports = {
-    extend: extend,
-    render: render,
-    setStyle: setStyle,
-    setStyles: setStyles,
-    capitalize: capitalize,
-    isString: isString,
-    isFunction: isFunction,
-    isObject: isObject,
-    forEachObject: forEachObject,
-    floatEquals: floatEquals,
-    removeChildren: removeChildren
-};
-
-},{}]},{},[4])(4)
-});

+ 12 - 24
static/src/xml/widgets/chart_sale_by_store.xml

@@ -2,30 +2,18 @@
 <template xml:space="preserve">
     <t t-name="ChartSaleByStore">
         <t t-call="WidgetReportingBaseTemplate"> 
-            <!-- <h2  class="widget-title">
-                <div class="row">
-                    <div class="col-xs-6">
-                        <i class="fa fa-bar-chart" aria-hidden="true"></i>
-                        <span>Ventas por Sucursal</span> 
-                    </div>
-                    <div class="col-xs-6"> 
-                        <div class="col-xs-6 col-xs-offset-10"> -->
-                            <div class="btn-group btn-group-xs">
-                                <a type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
-                                <span class="caret"></span>
-                                <span class="sr-only">Toggle Dropdown</span>
-                                </a>
-                                <ul class="dropdown-menu dropdown-menu-left">
-                                    <li><a class="days">Hoy</a></li>
-                                    <li><a class="week">Esta semana</a></li>
-                                    <li role="separator" class="divider"></li>
-                                    <li><a class="month">Meses</a></li>
-                                </ul>
-                            </div>
-<!--                         </div>
-                    </div>
-                </div>
-            </h2> -->
+            <div class="btn-group btn-group-xs">
+                <a type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
+                <span class="caret"></span>
+                <span class="sr-only">Toggle Dropdown</span>
+                </a>
+                <ul class="dropdown-menu dropdown-menu-left">
+                    <li><a class="days">Hoy</a></li>
+                    <li><a class="week">Semana Actual</a></li>
+                    <li role="separator" class="divider"></li>
+                    <li><a class="month">Mes Actual</a></li>
+                </ul>
+            </div>
             <div class="widget-content">
                 <div class="chart-container">
                     <h3 class="text-center">Ventas por Sucursal</h3>

+ 4 - 3
templates.xml

@@ -11,11 +11,12 @@
 
                 <!-- Dashboard Widget Base -->
                 <script type="text/javascript" src="/eiru_reporting_dashboard/static/src/js/widget_base.js" />
+
                 <!-- LIB -->
                 <script type="text/javascript" src="/eiru_reporting_dashboard/static/src/lib/jquery.timeago.es.js" />
-                <script type="text/javascript" src="/eiru_reporting_dashboard/static/src/lib/moment-timezone.js" />
-                <script type="text/javascript" src="/eiru_reporting_dashboard/static/src/lib/timezones.js" />
-                <script type="text/javascript" src="/eiru_reporting_dashboard/static/src/lib/loading-bar.js" />
+                <!-- <script type="text/javascript" src="/eiru_reporting_dashboard/static/src/lib/moment-timezone.js" />
+                <script type="text/javascript" src="/eiru_reporting_dashboard/static/src/lib/timezones.js" /> -->
+                <script type="text/javascript" src="/eiru_reporting_dashboard/static/src/lib/loading-bar.js"/>
                 
                 <!-- user -->
                 <script type="text/javascript" src="/eiru_reporting_dashboard/static/src/js/widgets/user.js" />