<commit_before>angular.module('os.administrative.container.list', ['os.administrative.models'])
  .controller('ContainerListCtrl', function($scope, $state, Container, Util, DeleteUtil, ListPagerOpts, CheckList) {

    var pagerOpts;

    function init() {
      pagerOpts = $scope.pagerOpts = new ListPagerOpts({listSizeGetter: getContainersCount});
      $scope.containerFilterOpts = {
        maxResults: pagerOpts.recordsPerPage + 1,
        includeStats: true,
        topLevelContainers: true
      };

      $scope.ctx = {
        exportDetail: { objectType: 'storageContainer' }
      }

      loadContainers($scope.containerFilterOpts);
      Util.filter($scope, 'containerFilterOpts', loadContainers);
    }

    function loadContainers(filterOpts) {
      Container.list(filterOpts).then(
        function(containers) {
          angular.forEach(containers,
            function(container) {
              if (container.capacity) {
                container.utilisation = Math.round(container.storedSpecimens / container.capacity * 100);
              }
            }
          );

          $scope.containerList = containers;
          $scope.ctx.checkList = new CheckList(containers);
          pagerOpts.refreshOpts(containers);
        }
      );
    }

    function getContainerIds(containers) {
      return containers.map(function(container) { return container.id; });
    }

    function getContainersCount() {
      return Container.getCount($scope.containerFilterOpts);
    }

    $scope.showContainerDetail = function(container) {
      $state.go('container-detail.locations', {containerId: container.id});
    };

    $scope.deleteContainers = function() {
      var containers = $scope.ctx.checkList.getSelectedItems();

      var opts = {
        confirmDelete:  'container.delete_containers',
        successMessage: 'container.containers_deleted',
        onBulkDeletion: loadContainers
      }

      DeleteUtil.bulkDelete({bulkDelete: Container.bulkDelete}, getContainerIds(containers), opts);
    }

    init();
  });
<commit_msg>    OPSMN-3773: After bulk delete containers on list page utilisation bar not getting calculated.<commit_after>angular.module('os.administrative.container.list', ['os.administrative.models'])
  .controller('ContainerListCtrl', function($scope, $state, Container, Util, DeleteUtil, ListPagerOpts, CheckList) {

    var pagerOpts;

    function init() {
      pagerOpts = $scope.pagerOpts = new ListPagerOpts({listSizeGetter: getContainersCount});
      $scope.containerFilterOpts = {
        maxResults: pagerOpts.recordsPerPage + 1,
        includeStats: true,
        topLevelContainers: true
      };

      $scope.ctx = {
        exportDetail: { objectType: 'storageContainer' }
      }

      loadContainers($scope.containerFilterOpts);
      Util.filter($scope, 'containerFilterOpts', loadContainers);
    }

    function loadContainers(filterOpts) {
      Container.list(filterOpts).then(
        function(containers) {
          angular.forEach(containers,
            function(container) {
              if (container.capacity) {
                container.utilisation = Math.round(container.storedSpecimens / container.capacity * 100);
              }
            }
          );

          $scope.containerList = containers;
          $scope.ctx.checkList = new CheckList(containers);
          pagerOpts.refreshOpts(containers);
        }
      );
    }

    function getContainerIds(containers) {
      return containers.map(function(container) { return container.id; });
    }

    function getContainersCount() {
      return Container.getCount($scope.containerFilterOpts);
    }

    $scope.showContainerDetail = function(container) {
      $state.go('container-detail.locations', {containerId: container.id});
    };

    $scope.deleteContainers = function() {
      var containers = $scope.ctx.checkList.getSelectedItems();

      var opts = {
        confirmDelete:  'container.delete_containers',
        successMessage: 'container.containers_deleted',
        onBulkDeletion: function() {
          loadContainers($scope.containerFilterOpts);
        }
      }

      DeleteUtil.bulkDelete({bulkDelete: Container.bulkDelete}, getContainerIds(containers), opts);
    }

    init();
  });
<|endoftext|>


<commit_before>
(function(){
    // Simple bar chart
    // ----------------

    var BarChart = Datawrapper.Visualizations.BarChart = function() {

    };

    _.extend(BarChart.prototype, Datawrapper.Visualizations.RaphaelChart.prototype, {

        render: function(el) {
            el = $(el);

            this.setRoot(el);

            var me = this, row = 0,
            sortBars = me.get('sort-values', false),
            reverse = me.get('reverse-order'),
            useNegativeColor = me.get('negative-color', false);

            if (!_.isUndefined(me.get('selected-row'))) {
                row = me.get('selected-row', 0);
                row = row > me.chart.numRows() ? 0 : row;
            }

            var filterUI = me.getFilterUI(row);
            if (filterUI) $('#header').append(filterUI);

            var c = me.initCanvas({
                h: Math.max(
                    me.getSize()[1] - me.theme.padding.top - me.theme.padding.bottom - me.theme.vpadding,
                    18 * 1.35 * me.chart.dataSeries().length + 5
                )
            });

            var
            chart_width = c.w - c.lpad - c.rpad,
            series_gap = 0.05, // pull from theme
            row_gap = 0.01,
            labelsInsideBars = me.get('labels-inside-bars', false);

            if (me.chart.numRows() > 1) me.chart.filterRow(row);

            me.init();
            me.initDimensions(0);

            $('.tooltip').hide();

            c.lastBarY = 0;

            _.each(me.chart.dataSeries(sortBars, reverse), function(series, s) {
                _.each(series.data, function(val, r) {
                    var d = me.barDimensions(series, s, r),
                        lpos = me.labelPosition(series, s, r),
                        fill = me.getSeriesColor(series, r, useNegativeColor),
                        stroke = d3.cie.lch(d3.rgb(fill)).darker(0.6).toString();

                    if (labelsInsideBars) d.x -= 10;

                    // draw bar
                    me.registerSeriesElement(c.paper.rect(d.x, d.y, d.width, d.height).attr({
                        'stroke': stroke,
                        'fill': fill
                    }).data('strokeCol', stroke), series);

                    if (lpos.show_val) {
                        me.registerSeriesLabel(me.label(lpos.val_x, lpos.top, me.chart.formatValue(series.data[r], true),{
                            w: 40,
                            align: lpos.val_align,
                            cl: 'value' + lpos.lblClass
                        }), series);
                    }

                    if (lpos.show_lbl) {
                        me.registerSeriesLabel(me.label(lpos.lbl_x , lpos.top, series.name,{
                            w: 160,
                            align: lpos.lbl_align,
                            cl: 'series' + lpos.lblClass
                        }), series);
                    }

                    c.lastBarY = Math.max(c.lastBarY, d.y + d.height);
                });
            });

            if (me.__domain[0] < 0) {
                var x = c.lpad + c.zero ;
                if (labelsInsideBars) x -= 10;
                // add y-axis
                me.__yaxis = me.path('M' + [x, c.tpad] + 'V' + c.lastBarY, 'axis')
                    .attr(me.theme.yAxis);
            }

            // enable mouse events
            el.mousemove(_.bind(me.onMouseMove, me));

        },

        update: function(row) {
            var me = this;
            // re-filter dataset
            me.chart.filterRow(row);

            // update scales
            me.initDimensions(0);

            // update bar heights and labels
            _.each(me.chart.dataSeries(me.get('sort-values', false)), function(series, s) {
                _.each(me.__seriesElements[series.name], function(rect) {
                    var dim = me.barDimensions(series, s, 0);
                    rect.animate(dim, me.theme.duration, me.theme.easing);
                });

                _.each(me.__seriesLabels[series.name], function(lbl) {
		    var pos = me.labelPosition(series, s, 0), lpos;
                    if (lbl.hasClass('value')) {
                        // update value
                        $('span', lbl).html(me.chart.formatValue(series.data[0]));
                        lpos = { halign: pos.val_align, left: pos.val_x, top: pos.top };
                    } else if (lbl.hasClass('series')) {
                        // update series label position
                        lpos = { halign: pos.lbl_align, left: pos.lbl_x, top: pos.top };
                    }
                    if (lpos) {
                        lbl.animate({
                            align: lpos.halign,
                            x: lpos.left,
                            y: lpos.top
                        }, me.theme.duration, me.theme.easing);
                    }
                });
            });
            if (me.__domain[0] < 0) {
                var c = me.__canvas,
                    x = c.lpad + c.zero - (me.get('labels-inside-bars', false) ? 10 : 0),
                    p = 'M' + [x, c.tpad] + 'V' + c.lastBarY;
                // add y-axis
                if (me.__yaxis) {
                    me.__yaxis.animate({ path: p, opacity: 1 }, me.theme.duration, me.theme.easing);
                } else {
                    me.__yaxis = me.path(p, 'axis').attr(me.theme.yAxis);
                }
            } else if (me.__yaxis) {
                me.__yaxis.animate({ opacity: 0 }, me.theme.duration * 0.5, me.theme.easing);
            }
        },

        initDimensions: function(r) {
            //
            var me = this, c = me.__canvas,
                dMin = 0, dMax = 0, w = c.w - c.lpad - c.rpad - 30;
            _.each(me.chart.dataSeries(), function(series) {
                dMin = Math.min(dMin, series._min());
                dMax = Math.max(dMax, series._max());
            });
            me.__domain = [dMin, dMax];
            me.__scales = {
                y: d3.scale.linear().domain([dMin, dMax])
            };
            /* how maxw works:
             *
             * maxw[0] .. max series name label width      \
             * maxw[1] .. max formatted value label width   } positive
             * largestVal[0] .. max absolute value               /
             * maxw[2] .. max series name label width      \
             * maxw[3] .. max formatted value label width   } negative
             * largestVal[1] .. max absolute value               /
             */
            var maxw = [0, 0, 0, 0], ratio, largestVal = [0, 0];
            _.each(me.chart.dataSeries(), function(series, s) {
                var neg = series.data[r] < 0;
                largestVal[neg ? 1 : 0] = Math.max(largestVal[neg ? 1 : 0], Math.abs(series.data[r]));
            });
            _.each(me.chart.dataSeries(), function(series, s) {
                var val = series.data[r],
                    neg = val < 0,
                    t = neg ? 2 : 0,
                    bw;
                bw = Math.abs(val) / (largestVal[0] + largestVal[1]) * w;
                maxw[t] = Math.max(maxw[t], me.labelWidth(series.name, 'series') + 20);
                maxw[t+1] = Math.max(maxw[t+1], me.labelWidth(me.chart.formatValue(series.data[r], true), 'value') + 20 + bw);
            });

            c.left = 0;
            c.right = 0;
            c.zero = largestVal[1] / (largestVal[0] + largestVal[1]) * w;

            if (!me.get('labels-inside-bars', false) && w > 300) {

                var maxNegBar = c.zero;
                //console.log('c.left', );
                c.left = Math.max(maxw[0], maxw[3]) - c.zero;
                c.right = Math.max(maxw[1], maxw[2]) - (w - c.zero); // Math.max((maxw[2] + maxw[1]) - (w - c.zero), 0);

                w -= c.left + c.right;

                c.zero = c.left + largestVal[1] / (largestVal[0] + largestVal[1]) * w;
            } else {
                c.zero += 15;
            }

            c.maxSeriesLabelWidth = [maxw[0], maxw[2]];
            c.maxValueLabelWidth = [maxw[1], maxw[3]];

            me.__scales.y.rangeRound([c.lpad, w]);
        },

        barDimensions: function(series, s, r) {
            var me = this, w, h, x, y, i, cw, n = me.chart.dataSeries().length,
                sc = me.__scales, c = me.__canvas, bw, pad = 0.35, vspace = 0.1,
                val = series.data[r];
            //
            cw = c.h - c.bpad - c.tpad;
            //
            bw = Math.max(18, Math.min(50, cw / (n + (n-1) * pad)));
            w = sc.y(val) - sc.y(0);
            h = bw;
            if (w > 0) {
                x = c.lpad + c.zero;
            } else {
                x = c.lpad + c.zero + w;
                w *= -1;
            }
            y = Math.round(c.tpad + s * (bw + bw * pad));
            return { width: w, height: h, x: x, y: y };
        },

        labelPosition: function(series, s, r) {
            var me = this,
                d = me.barDimensions(series, s, r),
                c = me.__canvas,
                val = series.data[r],
                lbl_x = val >= 0 ?
                    c.zero - 10
                    : c.zero + 10,
                lbl_align = val >= 0 ? 'right' : 'left',
                val_x = val >= 0 ?
                    d.x + d.width + 10
                    : d.x - 10,
                val_align = val >= 0 ? 'left' : 'right',
                show_lbl = true,
                show_val = true,
                lblClass = me.chart.hasHighlight() && me.chart.isHighlighted(series) ? ' highlighted' : '';

            if (me.get('labels-inside-bars', false)) {
                lbl_x = val >= 0 ? d.x + 10 : d.x + d.width - 10;
                val_x = val >= 0 ? d.x + d.width - 10 : d.x + 10;
                lbl_align = val >= 0 ? 'left' : 'right';
                val_align = val >= 0 ? 'right' : 'left';

                // check if the label is bigger than the bar
                var slblw = me.labelWidth(series.name, 'series')+10,
                    vlblw = me.labelWidth(me.chart.formatValue(val, true), 'value')+20;
                if (slblw + vlblw > d.width) {
                    show_val = false;
                    if (slblw > d.width) show_lbl = false;
                }
                if (me.invertLabel(me.getSeriesColor(series, r, me.get('negative-color', false)))) lblClass += ' inverted';
            }

            return { lblClass: lblClass, val_align: val_align, show_lbl: show_lbl,
                show_val: show_val, lbl_align: lbl_align, lbl_x: lbl_x, val_x: val_x,
                top: d.y + d.height * 0.5 };
        },

        getDataRowByPoint: function(x, y) {
            return 0;
        },

        showTooltip: function() {

        },

        hideTooltip: function() {

        },

        hoverSeries: function(series) {
            var me = this;
            _.each(me.chart.dataSeries(), function(s) {
                _.each(me.__seriesLabels[s.name], function(lbl) {
                    if (series !== undefined && s.name == series.name) {
                        lbl.addClass('hover');
                    } else {
                        lbl.removeClass('hover');
                    }
                    _.each(me.__seriesElements[s.name], function(el) {
                        var fill = me.getSeriesColor(s, 0, me.get('negative-color', false)), stroke;
                        if (series !== undefined && s.name == series.name) fill = d3.cie.lch(d3.rgb(fill)).darker(0.6).toString();
                        stroke = d3.cie.lch(d3.rgb(fill)).darker(0.6).toString();
                        if (el.attrs.fill != fill || el.attrs.stroke != stroke)
                            el.animate({ fill: fill, stroke: stroke }, 50);
                    });
                });
            });
        },

        unhoverSeries: function() {
            this.hoverSeries();
        }
    });

    var Slice = function(paper, cx, cy, or, ir, startAngle, endAngle, label) {
        var me = this;
        me.cx = cx;
        me.cy = cy;
        me.or = or;
        me.ir = ir;
        me.startAngle = startAngle;
        me.endAngle = endAngle;
        me.path = paper.path(me.arcPath());
        me.label = label;
        me.updateLabelPos();
    };

}).call(this);
<commit_msg>Bar chart labels weren't updating on data series change. This is fixed.<commit_after>
(function(){
    // Simple bar chart
    // ----------------

    var BarChart = Datawrapper.Visualizations.BarChart = function() {

    };

    _.extend(BarChart.prototype, Datawrapper.Visualizations.RaphaelChart.prototype, {

        render: function(el) {
            el = $(el);

            this.setRoot(el);

            var me = this, row = 0,
            sortBars = me.get('sort-values', false),
            reverse = me.get('reverse-order'),
            useNegativeColor = me.get('negative-color', false);

            if (!_.isUndefined(me.get('selected-row'))) {
                row = me.get('selected-row', 0);
                row = row > me.chart.numRows() ? 0 : row;
            }

            var filterUI = me.getFilterUI(row);
            if (filterUI) $('#header').append(filterUI);

            var c = me.initCanvas({
                h: Math.max(
                    me.getSize()[1] - me.theme.padding.top - me.theme.padding.bottom - me.theme.vpadding,
                    18 * 1.35 * me.chart.dataSeries().length + 5
                )
            });

            var
            chart_width = c.w - c.lpad - c.rpad,
            series_gap = 0.05, // pull from theme
            row_gap = 0.01,
            labelsInsideBars = me.get('labels-inside-bars', false);

            if (me.chart.numRows() > 1) me.chart.filterRow(row);

            me.init();
            me.initDimensions(0);

            $('.tooltip').hide();

            c.lastBarY = 0;

            _.each(me.chart.dataSeries(sortBars, reverse), function(series, s) {
                _.each(series.data, function(val, r) {
                    var d = me.barDimensions(series, s, r),
                        lpos = me.labelPosition(series, s, r),
                        fill = me.getSeriesColor(series, r, useNegativeColor),
                        stroke = d3.cie.lch(d3.rgb(fill)).darker(0.6).toString();

                    if (labelsInsideBars) d.x -= 10;

                    // draw bar
                    me.registerSeriesElement(c.paper.rect(d.x, d.y, d.width, d.height).attr({
                        'stroke': stroke,
                        'fill': fill
                    }).data('strokeCol', stroke), series);

                    if (lpos.show_val) {
                        me.registerSeriesLabel(me.label(lpos.val_x, lpos.top, me.chart.formatValue(series.data[r], true),{
                            w: 40,
                            align: lpos.val_align,
                            cl: 'value' + lpos.lblClass
                        }), series);
                    }

                    if (lpos.show_lbl) {
                        me.registerSeriesLabel(me.label(lpos.lbl_x , lpos.top, series.name,{
                            w: 160,
                            align: lpos.lbl_align,
                            cl: 'series' + lpos.lblClass
                        }), series);
                    }

                    c.lastBarY = Math.max(c.lastBarY, d.y + d.height);
                });
            });

            if (me.__domain[0] < 0) {
                var x = c.lpad + c.zero ;
                if (labelsInsideBars) x -= 10;
                // add y-axis
                me.__yaxis = me.path('M' + [x, c.tpad] + 'V' + c.lastBarY, 'axis')
                    .attr(me.theme.yAxis);
            }

            // enable mouse events
            el.mousemove(_.bind(me.onMouseMove, me));

        },

        update: function(row) {
            var me = this;
            // re-filter dataset
            me.chart.filterRow(row);

            // update scales
            me.initDimensions(0);

            // update bar heights and labels
            _.each(me.chart.dataSeries(me.get('sort-values', false)), function(series, s) {
                _.each(me.__seriesElements[series.name], function(rect) {
                    var dim = me.barDimensions(series, s, 0);
                    rect.animate(dim, me.theme.duration, me.theme.easing);
                });

                _.each(me.__seriesLabels[series.name], function(lbl) {
		    var pos = me.labelPosition(series, s, 0), lpos;
                    if (lbl.hasClass('value')) {
                        // update value
                        $('span', lbl.el).html(me.chart.formatValue(series.data[0]));
                        lpos = { halign: pos.val_align, left: pos.val_x, top: pos.top };
                    } else if (lbl.hasClass('series')) {
                        // update series label position
                        lpos = { halign: pos.lbl_align, left: pos.lbl_x, top: pos.top };
                    }
                    if (lpos) {
                        lbl.animate({
                            align: lpos.halign,
                            x: lpos.left,
                            y: lpos.top
                        }, me.theme.duration, me.theme.easing);
                    }
                });
            });
            if (me.__domain[0] < 0) {
                var c = me.__canvas,
                    x = c.lpad + c.zero - (me.get('labels-inside-bars', false) ? 10 : 0),
                    p = 'M' + [x, c.tpad] + 'V' + c.lastBarY;
                // add y-axis
                if (me.__yaxis) {
                    me.__yaxis.animate({ path: p, opacity: 1 }, me.theme.duration, me.theme.easing);
                } else {
                    me.__yaxis = me.path(p, 'axis').attr(me.theme.yAxis);
                }
            } else if (me.__yaxis) {
                me.__yaxis.animate({ opacity: 0 }, me.theme.duration * 0.5, me.theme.easing);
            }
        },

        initDimensions: function(r) {
            //
            var me = this, c = me.__canvas,
                dMin = 0, dMax = 0, w = c.w - c.lpad - c.rpad - 30;
            _.each(me.chart.dataSeries(), function(series) {
                dMin = Math.min(dMin, series._min());
                dMax = Math.max(dMax, series._max());
            });
            me.__domain = [dMin, dMax];
            me.__scales = {
                y: d3.scale.linear().domain([dMin, dMax])
            };
            /* how maxw works:
             *
             * maxw[0] .. max series name label width      \
             * maxw[1] .. max formatted value label width   } positive
             * largestVal[0] .. max absolute value               /
             * maxw[2] .. max series name label width      \
             * maxw[3] .. max formatted value label width   } negative
             * largestVal[1] .. max absolute value               /
             */
            var maxw = [0, 0, 0, 0], ratio, largestVal = [0, 0];
            _.each(me.chart.dataSeries(), function(series, s) {
                var neg = series.data[r] < 0;
                largestVal[neg ? 1 : 0] = Math.max(largestVal[neg ? 1 : 0], Math.abs(series.data[r]));
            });
            _.each(me.chart.dataSeries(), function(series, s) {
                var val = series.data[r],
                    neg = val < 0,
                    t = neg ? 2 : 0,
                    bw;
                bw = Math.abs(val) / (largestVal[0] + largestVal[1]) * w;
                maxw[t] = Math.max(maxw[t], me.labelWidth(series.name, 'series') + 20);
                maxw[t+1] = Math.max(maxw[t+1], me.labelWidth(me.chart.formatValue(series.data[r], true), 'value') + 20 + bw);
            });

            c.left = 0;
            c.right = 0;
            c.zero = largestVal[1] / (largestVal[0] + largestVal[1]) * w;

            if (!me.get('labels-inside-bars', false) && w > 300) {

                var maxNegBar = c.zero;
                //console.log('c.left', );
                c.left = Math.max(maxw[0], maxw[3]) - c.zero;
                c.right = Math.max(maxw[1], maxw[2]) - (w - c.zero); // Math.max((maxw[2] + maxw[1]) - (w - c.zero), 0);

                w -= c.left + c.right;

                c.zero = c.left + largestVal[1] / (largestVal[0] + largestVal[1]) * w;
            } else {
                c.zero += 15;
            }

            c.maxSeriesLabelWidth = [maxw[0], maxw[2]];
            c.maxValueLabelWidth = [maxw[1], maxw[3]];

            me.__scales.y.rangeRound([c.lpad, w]);
        },

        barDimensions: function(series, s, r) {
            var me = this, w, h, x, y, i, cw, n = me.chart.dataSeries().length,
                sc = me.__scales, c = me.__canvas, bw, pad = 0.35, vspace = 0.1,
                val = series.data[r];
            //
            cw = c.h - c.bpad - c.tpad;
            //
            bw = Math.max(18, Math.min(50, cw / (n + (n-1) * pad)));
            w = sc.y(val) - sc.y(0);
            h = bw;
            if (w > 0) {
                x = c.lpad + c.zero;
            } else {
                x = c.lpad + c.zero + w;
                w *= -1;
            }
            y = Math.round(c.tpad + s * (bw + bw * pad));
            return { width: w, height: h, x: x, y: y };
        },

        labelPosition: function(series, s, r) {
            var me = this,
                d = me.barDimensions(series, s, r),
                c = me.__canvas,
                val = series.data[r],
                lbl_x = val >= 0 ?
                    c.zero - 10
                    : c.zero + 10,
                lbl_align = val >= 0 ? 'right' : 'left',
                val_x = val >= 0 ?
                    d.x + d.width + 10
                    : d.x - 10,
                val_align = val >= 0 ? 'left' : 'right',
                show_lbl = true,
                show_val = true,
                lblClass = me.chart.hasHighlight() && me.chart.isHighlighted(series) ? ' highlighted' : '';

            if (me.get('labels-inside-bars', false)) {
                lbl_x = val >= 0 ? d.x + 10 : d.x + d.width - 10;
                val_x = val >= 0 ? d.x + d.width - 10 : d.x + 10;
                lbl_align = val >= 0 ? 'left' : 'right';
                val_align = val >= 0 ? 'right' : 'left';

                // check if the label is bigger than the bar
                var slblw = me.labelWidth(series.name, 'series')+10,
                    vlblw = me.labelWidth(me.chart.formatValue(val, true), 'value')+20;
                if (slblw + vlblw > d.width) {
                    show_val = false;
                    if (slblw > d.width) show_lbl = false;
                }
                if (me.invertLabel(me.getSeriesColor(series, r, me.get('negative-color', false)))) lblClass += ' inverted';
            }

            return { lblClass: lblClass, val_align: val_align, show_lbl: show_lbl,
                show_val: show_val, lbl_align: lbl_align, lbl_x: lbl_x, val_x: val_x,
                top: d.y + d.height * 0.5 };
        },

        getDataRowByPoint: function(x, y) {
            return 0;
        },

        showTooltip: function() {

        },

        hideTooltip: function() {

        },

        hoverSeries: function(series) {
            var me = this;
            _.each(me.chart.dataSeries(), function(s) {
                _.each(me.__seriesLabels[s.name], function(lbl) {
                    if (series !== undefined && s.name == series.name) {
                        lbl.addClass('hover');
                    } else {
                        lbl.removeClass('hover');
                    }
                    _.each(me.__seriesElements[s.name], function(el) {
                        var fill = me.getSeriesColor(s, 0, me.get('negative-color', false)), stroke;
                        if (series !== undefined && s.name == series.name) fill = d3.cie.lch(d3.rgb(fill)).darker(0.6).toString();
                        stroke = d3.cie.lch(d3.rgb(fill)).darker(0.6).toString();
                        if (el.attrs.fill != fill || el.attrs.stroke != stroke)
                            el.animate({ fill: fill, stroke: stroke }, 50);
                    });
                });
            });
        },

        unhoverSeries: function() {
            this.hoverSeries();
        }
    });

    var Slice = function(paper, cx, cy, or, ir, startAngle, endAngle, label) {
        var me = this;
        me.cx = cx;
        me.cy = cy;
        me.or = or;
        me.ir = ir;
        me.startAngle = startAngle;
        me.endAngle = endAngle;
        me.path = paper.path(me.arcPath());
        me.label = label;
        me.updateLabelPos();
    };

}).call(this);
<|endoftext|>


<commit_before>if (window.location.href.indexOf("/comments/") > -1) {
    var submittedURL = document.getElementById('siteTable').getElementsByClassName('title')[1].attributes.href.nodeValue;
    var submittedTitle = document.getElementById('siteTable').getElementsByClassName('title')[0].getElementsByTagName('a')[0].textContent;
    var subreddit = document.getElementsByClassName('redditname')[0].innerText;

    var buttons = document.getElementById('siteTable').getElementsByClassName('flat-list buttons')[0];
    var xpostButton = document.createElement('li');
    var xpostButtonLink = document.createElement('a');

    xpostButtonLink.setAttribute('href', "http://www.example.com");
    xpostButtonLink.appendChild(document.createTextNode('xpost'));

    xpostButton.appendChild(xpostButtonLink);
    xpostButton.setAttribute('id', 'xpostButton');
    xpostButton.setAttribute('title', 'submit this link to a different subreddit');

    buttons.appendChild(xpostButton);

    console.log(submittedURL);
    console.log(submittedTitle);
    console.log(subreddit);
}
<commit_msg>First shippable version<commit_after>function generateURL(submittedURL, submittedTitle, subreddit) {
    var base = "http://www.reddit.com/submit?resubmit=true&selftext=false";
    var formattedTitle = "&title=" + encodeURIComponent(submittedTitle) + "%20[x-post%20from%20/r/" + subreddit + "]";
    var formattedURL = "&url=" + encodeURIComponent(submittedURL);

    return base + formattedTitle + formattedURL;
}

if (window.location.href.indexOf("/comments/") > -1) {
    var submittedURL = document.getElementById('siteTable').getElementsByClassName('title')[1].attributes.href.nodeValue;
    var submittedTitle = document.getElementById('siteTable').getElementsByClassName('title')[0].getElementsByTagName('a')[0].textContent;
    var subreddit = document.getElementsByClassName('redditname')[0].innerText;

    var buttons = document.getElementById('siteTable').getElementsByClassName('flat-list buttons')[0];
    var xpostButton = document.createElement('li');
    var xpostButtonLink = document.createElement('a');

    var finalURL = generateURL(submittedURL, submittedTitle, subreddit);

    xpostButtonLink.setAttribute('href', finalURL);
    xpostButtonLink.appendChild(document.createTextNode('xpost'));

    xpostButton.appendChild(xpostButtonLink);
    xpostButton.setAttribute('id', 'xpostButton');
    xpostButton.setAttribute('title', 'submit this link to a different subreddit');

    buttons.appendChild(xpostButton);

    console.log(submittedURL);
    console.log(submittedTitle);
    console.log(subreddit);
    console.log(finalURL);
}
<|endoftext|>


<commit_before>const { authenticate } = require('@feathersjs/authentication');
const reqlib = require('app-root-path').require;

const { Forbidden } = reqlib('src/errors');
const { SCHOOL_FEATURES } = require('../../school/model');
const globalHooks = require('../../../hooks');
const { isSuperheroUser } = require('../../../helper/userHelpers');
const { isValid } = require('../../../helper/compare').ObjectId;
const { populateCurrentSchool } = require('../../../hooks/index');

const isBBBCreateRequest = (context) => context.data && context.data.url && context.data.url === 'BBB_URL';

const isValidCourseTool = (context) => context.data && context.data.courseId && isValid(context.data.courseId);

const setupBBB = (context) => {
	// ignore if no bbb request or no valid courseId given
	if (!isBBBCreateRequest(context) || !isValidCourseTool(context)) {
		return context;
	}
	// update url
	context.data.url = `/videoconference/course/${context.data.courseId}`;
	return context;
};

const protectSecrets = (context) => {
	if (Array.isArray(context.result.data)) {
		let i;
		for (i = 0; i < context.result.data.length; i += 1) {
			context.result.data[i].secret = undefined;
		}
	} else {
		context.result.secret = undefined;
	}
	return context;
};

const addSecret = (context) => {
	if (context.data.originTool) {
		return context.app
			.service('/ltiTools/')
			.get(context.data.originTool)
			.then((tool) => {
				context.data.secret = tool.secret;
				return context;
			});
	}

	return context;
};

const isBBBTool = (tool) => tool.name && tool.name === 'Video-Konferenz mit BigBlueButton';

const filterFindBBB = (context) => {
	let hasVideoconferenceItems = false;
	if (context.result && context.result.data && Array.isArray(context.result.data)) {
		hasVideoconferenceItems = context.result.data.some((tool) => isBBBTool(tool));
	}
	if (hasVideoconferenceItems) {
		// if school feature disabled, remove bbb tools from results data
		const { features } = context.params.school;
		if (!features.includes(SCHOOL_FEATURES.VIDEOCONFERENCE)) {
			context.result.data = context.result.data.filter((tool) => !isBBBTool(tool));
		}
	}
};

const filterGetBBB = (context) => {
	if (context.data && isBBBTool(context.data)) {
		const { features } = context.params.school;
		if (!features.includes(SCHOOL_FEATURES.VIDEOCONFERENCE)) {
			throw new Forbidden('school feature disabled');
		}
	}
};

const restrictToUsersOwnTools = async (context) => {
	const currentUserId = context.params.account.userId;
	const isSuperhero = await isSuperheroUser(context.app, currentUserId);
	if (isSuperhero) return context;
	const coursesOfUser = await context.app.service('courses').find({
		query: {
			$or: [{ teacherIds: { $in: [currentUserId] } }, { substitutionIds: { $in: [currentUserId] } }],
		},
	});
	if (
		coursesOfUser.data.some((course) => course.ltiToolIds.map((id) => id.toString()).includes(context.id.toString()))
	) {
		return context;
	}
	throw new Forbidden('tool is not part of your courses');
};

exports.before = {
	all: [authenticate('jwt')],
	find: [globalHooks.hasPermission('TOOL_VIEW'), globalHooks.ifNotLocal(populateCurrentSchool)],
	get: [globalHooks.hasPermission('TOOL_VIEW'), globalHooks.ifNotLocal(populateCurrentSchool)],
	create: [globalHooks.hasPermission('TOOL_CREATE'), addSecret, setupBBB],
	update: [globalHooks.hasPermission('TOOL_EDIT')],
	patch: [globalHooks.hasPermission('TOOL_EDIT'), globalHooks.ifNotLocal(restrictToUsersOwnTools)],
	remove: [globalHooks.hasPermission('TOOL_CREATE'), globalHooks.ifNotLocal(restrictToUsersOwnTools)],
};

exports.after = {
	all: [],
	find: [globalHooks.ifNotLocal(protectSecrets), filterFindBBB],
	get: [globalHooks.ifNotLocal(protectSecrets), filterGetBBB],
	create: [],
	update: [],
	patch: [globalHooks.ifNotLocal(protectSecrets)],
	remove: [],
};
<commit_msg>fix adding tools for schools without features<commit_after>const { authenticate } = require('@feathersjs/authentication');
const reqlib = require('app-root-path').require;

const { Forbidden } = reqlib('src/errors');
const { SCHOOL_FEATURES } = require('../../school/model');
const globalHooks = require('../../../hooks');
const { isSuperheroUser } = require('../../../helper/userHelpers');
const { isValid } = require('../../../helper/compare').ObjectId;
const { populateCurrentSchool } = require('../../../hooks/index');

const isBBBCreateRequest = (context) => context.data && context.data.url && context.data.url === 'BBB_URL';

const isValidCourseTool = (context) => context.data && context.data.courseId && isValid(context.data.courseId);

const setupBBB = (context) => {
	// ignore if no bbb request or no valid courseId given
	if (!isBBBCreateRequest(context) || !isValidCourseTool(context)) {
		return context;
	}
	// update url
	context.data.url = `/videoconference/course/${context.data.courseId}`;
	return context;
};

const protectSecrets = (context) => {
	if (Array.isArray(context.result.data)) {
		let i;
		for (i = 0; i < context.result.data.length; i += 1) {
			context.result.data[i].secret = undefined;
		}
	} else {
		context.result.secret = undefined;
	}
	return context;
};

const addSecret = (context) => {
	if (context.data.originTool) {
		return context.app
			.service('/ltiTools/')
			.get(context.data.originTool)
			.then((tool) => {
				context.data.secret = tool.secret;
				return context;
			});
	}

	return context;
};

const isBBBTool = (tool) => tool.name && tool.name === 'Video-Konferenz mit BigBlueButton';

const filterFindBBB = (context) => {
	let hasVideoconferenceItems = false;
	if (context.result && context.result.data && Array.isArray(context.result.data)) {
		hasVideoconferenceItems = context.result.data.some((tool) => isBBBTool(tool));
	}
	if (hasVideoconferenceItems) {
		// if school feature disabled, remove bbb tools from results data
		const { features = [] } = context.params.school;
		if (!features.includes(SCHOOL_FEATURES.VIDEOCONFERENCE)) {
			context.result.data = context.result.data.filter((tool) => !isBBBTool(tool));
		}
	}
};

const filterGetBBB = (context) => {
	if (context.data && isBBBTool(context.data)) {
		const { features } = context.params.school;
		if (!features.includes(SCHOOL_FEATURES.VIDEOCONFERENCE)) {
			throw new Forbidden('school feature disabled');
		}
	}
};

const restrictToUsersOwnTools = async (context) => {
	const currentUserId = context.params.account.userId;
	const isSuperhero = await isSuperheroUser(context.app, currentUserId);
	if (isSuperhero) return context;
	const coursesOfUser = await context.app.service('courses').find({
		query: {
			$or: [{ teacherIds: { $in: [currentUserId] } }, { substitutionIds: { $in: [currentUserId] } }],
		},
	});
	if (
		coursesOfUser.data.some((course) => course.ltiToolIds.map((id) => id.toString()).includes(context.id.toString()))
	) {
		return context;
	}
	throw new Forbidden('tool is not part of your courses');
};

exports.before = {
	all: [authenticate('jwt')],
	find: [globalHooks.hasPermission('TOOL_VIEW'), globalHooks.ifNotLocal(populateCurrentSchool)],
	get: [globalHooks.hasPermission('TOOL_VIEW'), globalHooks.ifNotLocal(populateCurrentSchool)],
	create: [globalHooks.hasPermission('TOOL_CREATE'), addSecret, setupBBB],
	update: [globalHooks.hasPermission('TOOL_EDIT')],
	patch: [globalHooks.hasPermission('TOOL_EDIT'), globalHooks.ifNotLocal(restrictToUsersOwnTools)],
	remove: [globalHooks.hasPermission('TOOL_CREATE'), globalHooks.ifNotLocal(restrictToUsersOwnTools)],
};

exports.after = {
	all: [],
	find: [globalHooks.ifNotLocal(protectSecrets), filterFindBBB],
	get: [globalHooks.ifNotLocal(protectSecrets), filterGetBBB],
	create: [],
	update: [],
	patch: [globalHooks.ifNotLocal(protectSecrets)],
	remove: [],
};
<|endoftext|>


<commit_before>orderController = function()
{
    var self = this;
    var items = [];
    var monay = 0;
    var orderOn = "Оформить заказ";
    var orderOff = "Заказать пиццу";
    var url, urlGet, urlRemove;
    var discount = 0;
    var chain_id = 0;
    var nameIn = '';
    var phoneIn = '';
    var network = '';
    var network_id = 0;

    this.init = function()
    {
        items = []
        self.getItems();
        $("#phone_order").mask("+38(999) 999-9999");
        self.checkOrder();
        self.setOnForIngridient();

        $('.show-list-edit').click(function(){
            if ($(this).hasClass('active')) {
                $(this).removeClass('active');
                $('.wrap-popup-menu').removeClass('open');
            } else {
                $(this).addClass('active');
                $('.wrap-popup-menu').addClass('open');
            }

            return false;
        });
    }

    this.checkOrder = function()
    {
        var orderLink = $('#basket_box .order_link');
        if (items.length > 0) {
            orderLink.html(orderOn);
            orderLink.attr('href', '#order_from');
        }

        return false;
    }

    this.addItemToBasket = function (id)
    {
        self.setDiscount();
        self.setChainId();
        var objItem = $('#item_'+id);
        var item = {
            id: id,
            weight: objItem.data('weight'),
            size: objItem.data('size'),
            price: objItem.data('price'),
            title: objItem.data('title').replace(/"/g, ""),
            ingredients: objItem.find('div.feature_in > p').html(),
            image: objItem.find('img').first().attr('src'),
            discount: discount,
            chain_id: chain_id
        };

        $.ajax({
            type: "POST",
            dataType: "json",
            url: url,
            data: {"item": item}
        }).success(function(data){
            if( data.error !== undefined ){
                alert(data.error_text);
            } else {
                self.getItems();
            }
        });

        return false;
    }

    this.getItems = function()
    {
        var ar = [];

        $.ajax({
            type: "POST",
            dataType: "json",
            url: urlGet
        }).success(function(data){
            if( data.error !== undefined ){
                alert(data.error_text);
            } else {
                discount = data.discount;
                items = data.items;
                $.each(data.items, function(k, val){
                    ar[k] = self.createItemHtml(val);
                });
                $('.body-order').html(ar.join(''));
                $('#cost').html(data.prices);
                $('#money').html(data.prices);
                $('#items_count').html(data.items.length);
                if (data.prices > 0) {
                    $('#cost_new').html(data.prices);
                }
                self.checkOrder();
            }
        });
    }

    this.createItemHtml = function(item)
    {
        var html = '
'+
            '
'+
                '
'+
                    ''+
                    '
'+
                        '
'+item.title+'
'+
                        '
'+item.ingredients+'
'+
                        '
<span class="diametr"'+item.size+'
'+
                    '
'+
                '
'+
            '
'+
            '
'+
                '№'+item.id+''+
            '
'+
            '
'+
                '
'+
//                    ''+
                    '1 шт'+
//                    ''+
                '
'+
            '
'+
            '
'+item.price+' грн
'+
            '
Удалить
'+
        '
';

        return html;
    }

    this.setUrl = function(uri)
    {
        url = uri;

        return false;
    }

    this.setUrlGetItems = function(uri)
    {
        urlGet = uri;

        return false;
    }

    this.setUrlRemoveItem = function(uri)
    {
        urlRemove = uri;

        return false;
    }

    this.removeItem = function(id)
    {
        $.ajax({
            type: "POST",
            dataType: "json",
            url: urlRemove,
            data: {"item_id": id}
        }).success(function(data){
                if( data.error !== undefined ){
                    alert(data.error_text);
                } else {
                    self.getItems();
                }
            });

        return false;
    }

    this.submitOrder = function()
    {
        var name = $('#name_order').val().trim();
        var phone = $('#phone_order').val().trim();

        if (name == '' || name.length < 3) {
            alert('Введите корректное имя');

            return false;
        }

        if (phone == '' || phone.length < 7) {
            alert('Введите корректный телефон');

            return false;
        }

        if (items.length < 1) {
            alert('Корзина пустая');

            return false;
        }

        self.sendOrderToPartners();

        return false;
    }

    this.sendOrderToPartners = function()
    {
        var itemsSend = [];
        $.each(items, function(k, val){
            itemsSend[itemsSend.length] = { id: val.id, qnt: 1};
        });

        var args = {
            name: $('#name_order').val().trim(),
            phone: $('#phone_order').val().trim(),
            i: itemsSend
        };

        var userData = {
            name: nameIn,
            phone: phoneIn,
            network: network,
            network_id: network_id
        };

        $.ajax({
            type: "POST",
            dataType: "json",
            url: $('#senditemsajax').val(),
            data: {data: args, user: userData}
        }).success(function(data){
                console.log(data);
                if( data.error !== undefined ){
                    alert(data.error_text);
                } else {
                    alert('Спасибо! С Вами скоро свяжутся.');
                    $('#wrapper').show();
                    $('#popup-order-overlay').hide();
                    $('#popup-order-wrap').hide();
                    self.getItems();
//                    window.location.reload();
                }
            });

        return false;
    }

    this.getUserData = function(netw, data)
    {
        $.ajax({
            type: "POST",
            dataType: "json",
            url: $('#usersocialca').val(),
            data: { data: data, network: netw }
        }).success(function(data){
                console.log(data);
                if( data.error !== undefined ){
//                    alert(data.error_text);
                } else {
                    if (data.data.img) {
                        $('#login_box').hide();
                        $('#data_box').show();
                        $('#data_box').find('img').first().attr('src',data.data.img);
                    }
                    if (data.data.name) {
                        nameIn = data.data.name;
                        $('#name_order').val(nameIn);
                        $('#data_box').find('div.name-user').first().html(data.data.name);
                    }
                    if (data.data.phone) {
                        phoneIn = data.data.phone;
                        $('#phone_order').val(phoneIn);
                    }
                    if (data.data.id) {
                        network_id = data.data.id;
                    }
                    network = netw;
//                    alert('Спасибо! С Вами скоро свяжутся.');
//                    window.location.reload();
                }
            });

        return false;
    }

    this.hellLogin = function()
    {
        hello( 'facebook' ).login();

        return false;
    }

    this.showIngredient = function(ele)
    {
        $(ele).find('.feature_in').show();
    }

    this.hideIngredient = function(ele)
    {
        $(ele).find('.feature_in').hide();
    }

    this.setOnForIngridient = function() {
        $('#gallery-pizza').on('mouseover','.box .img-holder',function(){
            self.showIngredient(this);
        });
        $('#gallery-pizza').on('mouseout','.box .img-holder',function(){
            self.hideIngredient(this);
        });
        $('#gallery-pizza').on('click','.order_link',function(){
            self.addItemToBasket($(this).data('id'));

            order.getItems();

            $('#popup-order-overlay').show();
            $('#popup-order-wrap').show();

            setTimeout( self.show_popup_order , 10 );

            $("html, body").animate({ scrollTop: 0 }, "slow");

            return false;
        });
    }

    this.show_popup_order =  function()
    {
        $('#popup-order-wrap').addClass('move');
        $('#wrapper').hide();
    }

    this.setDiscount = function()
    {
        discount = menu.getDiscount();

        return false;
    }

    this.setChainId = function()
    {
        chain_id = menu.getChainId();

        return false;
    }
}

var order = new orderController();
$(document).ready(function(){
    order.init();
});<commit_msg>Fix double quotes<commit_after>orderController = function()
{
    var self = this;
    var items = [];
    var monay = 0;
    var orderOn = "Оформить заказ";
    var orderOff = "Заказать пиццу";
    var url, urlGet, urlRemove;
    var discount = 0;
    var chain_id = 0;
    var nameIn = '';
    var phoneIn = '';
    var network = '';
    var network_id = 0;

    this.init = function()
    {
        items = []
        self.getItems();
        $("#phone_order").mask("+38(999) 999-9999");
        self.checkOrder();
        self.setOnForIngridient();

        $('.show-list-edit').click(function(){
            if ($(this).hasClass('active')) {
                $(this).removeClass('active');
                $('.wrap-popup-menu').removeClass('open');
            } else {
                $(this).addClass('active');
                $('.wrap-popup-menu').addClass('open');
            }

            return false;
        });
    }

    this.checkOrder = function()
    {
        var orderLink = $('#basket_box .order_link');
        if (items.length > 0) {
            orderLink.html(orderOn);
            orderLink.attr('href', '#order_from');
        }

        return false;
    }

    this.addItemToBasket = function (id)
    {
        console.log(objItem.data('title'));
        console.log(objItem.data('title').replace(/"/g, ""));
        self.setDiscount();
        self.setChainId();
        var objItem = $('#item_'+id);
        var item = {
            id: id,
            weight: objItem.data('weight'),
            size: objItem.data('size'),
            price: objItem.data('price'),
            title: objItem.data('title').replace(/"/g, ""),
            ingredients: objItem.find('div.feature_in > p').html(),
            image: objItem.find('img').first().attr('src'),
            discount: discount,
            chain_id: chain_id
        };

        $.ajax({
            type: "POST",
            dataType: "json",
            url: url,
            data: {"item": item}
        }).success(function(data){
            if( data.error !== undefined ){
                alert(data.error_text);
            } else {
                self.getItems();
            }
        });

        return false;
    }

    this.getItems = function()
    {
        var ar = [];

        $.ajax({
            type: "POST",
            dataType: "json",
            url: urlGet
        }).success(function(data){
            if( data.error !== undefined ){
                alert(data.error_text);
            } else {
                discount = data.discount;
                items = data.items;
                $.each(data.items, function(k, val){
                    ar[k] = self.createItemHtml(val);
                });
                $('.body-order').html(ar.join(''));
                $('#cost').html(data.prices);
                $('#money').html(data.prices);
                $('#items_count').html(data.items.length);
                if (data.prices > 0) {
                    $('#cost_new').html(data.prices);
                }
                self.checkOrder();
            }
        });
    }

    this.createItemHtml = function(item)
    {
        var html = '
'+
            '
'+
                '
'+
                    ''+
                    '
'+
                        '
'+item.title+'
'+
                        '
'+item.ingredients+'
'+
                        '
<span class="diametr"'+item.size+'
'+
                    '
'+
                '
'+
            '
'+
            '
'+
                '№'+item.id+''+
            '
'+
            '
'+
                '
'+
//                    ''+
                    '1 шт'+
//                    ''+
                '
'+
            '
'+
            '
'+item.price+' грн
'+
            '
Удалить
'+
        '
';

        return html;
    }

    this.setUrl = function(uri)
    {
        url = uri;

        return false;
    }

    this.setUrlGetItems = function(uri)
    {
        urlGet = uri;

        return false;
    }

    this.setUrlRemoveItem = function(uri)
    {
        urlRemove = uri;

        return false;
    }

    this.removeItem = function(id)
    {
        $.ajax({
            type: "POST",
            dataType: "json",
            url: urlRemove,
            data: {"item_id": id}
        }).success(function(data){
                if( data.error !== undefined ){
                    alert(data.error_text);
                } else {
                    self.getItems();
                }
            });

        return false;
    }

    this.submitOrder = function()
    {
        var name = $('#name_order').val().trim();
        var phone = $('#phone_order').val().trim();

        if (name == '' || name.length < 3) {
            alert('Введите корректное имя');

            return false;
        }

        if (phone == '' || phone.length < 7) {
            alert('Введите корректный телефон');

            return false;
        }

        if (items.length < 1) {
            alert('Корзина пустая');

            return false;
        }

        self.sendOrderToPartners();

        return false;
    }

    this.sendOrderToPartners = function()
    {
        var itemsSend = [];
        $.each(items, function(k, val){
            itemsSend[itemsSend.length] = { id: val.id, qnt: 1};
        });

        var args = {
            name: $('#name_order').val().trim(),
            phone: $('#phone_order').val().trim(),
            i: itemsSend
        };

        var userData = {
            name: nameIn,
            phone: phoneIn,
            network: network,
            network_id: network_id
        };

        $.ajax({
            type: "POST",
            dataType: "json",
            url: $('#senditemsajax').val(),
            data: {data: args, user: userData}
        }).success(function(data){
                console.log(data);
                if( data.error !== undefined ){
                    alert(data.error_text);
                } else {
                    alert('Спасибо! С Вами скоро свяжутся.');
                    $('#wrapper').show();
                    $('#popup-order-overlay').hide();
                    $('#popup-order-wrap').hide();
                    self.getItems();
//                    window.location.reload();
                }
            });

        return false;
    }

    this.getUserData = function(netw, data)
    {
        $.ajax({
            type: "POST",
            dataType: "json",
            url: $('#usersocialca').val(),
            data: { data: data, network: netw }
        }).success(function(data){
                console.log(data);
                if( data.error !== undefined ){
//                    alert(data.error_text);
                } else {
                    if (data.data.img) {
                        $('#login_box').hide();
                        $('#data_box').show();
                        $('#data_box').find('img').first().attr('src',data.data.img);
                    }
                    if (data.data.name) {
                        nameIn = data.data.name;
                        $('#name_order').val(nameIn);
                        $('#data_box').find('div.name-user').first().html(data.data.name);
                    }
                    if (data.data.phone) {
                        phoneIn = data.data.phone;
                        $('#phone_order').val(phoneIn);
                    }
                    if (data.data.id) {
                        network_id = data.data.id;
                    }
                    network = netw;
//                    alert('Спасибо! С Вами скоро свяжутся.');
//                    window.location.reload();
                }
            });

        return false;
    }

    this.hellLogin = function()
    {
        hello( 'facebook' ).login();

        return false;
    }

    this.showIngredient = function(ele)
    {
        $(ele).find('.feature_in').show();
    }

    this.hideIngredient = function(ele)
    {
        $(ele).find('.feature_in').hide();
    }

    this.setOnForIngridient = function() {
        $('#gallery-pizza').on('mouseover','.box .img-holder',function(){
            self.showIngredient(this);
        });
        $('#gallery-pizza').on('mouseout','.box .img-holder',function(){
            self.hideIngredient(this);
        });
        $('#gallery-pizza').on('click','.order_link',function(){
            self.addItemToBasket($(this).data('id'));

            order.getItems();

            $('#popup-order-overlay').show();
            $('#popup-order-wrap').show();

            setTimeout( self.show_popup_order , 10 );

            $("html, body").animate({ scrollTop: 0 }, "slow");

            return false;
        });
    }

    this.show_popup_order =  function()
    {
        $('#popup-order-wrap').addClass('move');
        $('#wrapper').hide();
    }

    this.setDiscount = function()
    {
        discount = menu.getDiscount();

        return false;
    }

    this.setChainId = function()
    {
        chain_id = menu.getChainId();

        return false;
    }
}

var order = new orderController();
$(document).ready(function(){
    order.init();
});<|endoftext|>


<commit_before>import {createElement} from 'react'

import composeClasses from './utils/compose-classes'
import type {styledType} from './types'

const injectStyled = (styled: styledType) => (InnerComponent: ReactClass<any>) => {
  styled.mountSheets()

  const {sheets} = styled
  const {staticSheet, dynamicSheet} = sheets

  const classNames = new Set([
    ...Object.keys(staticSheet.classes),
    ...Object.keys(dynamicSheet.classes)
  ])

  const classes = [...classNames]
    .reduce((acc, name) => ({
      ...acc,
      [name]: composeClasses(staticSheet.classes[name], dynamicSheet.classes[name]),
    }), {})

  return (...props: any) => createElement(InnerComponent, {sheets, classes, ...props})
}

export default injectStyled
<commit_msg>Avoid set and remove sheets prop in injectStyled<commit_after>import {createElement} from 'react'

import composeClasses from './utils/compose-classes'
import type {styledType} from './types'

const injectStyled = (styled: styledType) => (InnerComponent: ReactClass<any>) => {
  styled.mountSheets()

  const {sheets} = styled
  const {staticSheet, dynamicSheet} = sheets

  const classNames = Object.keys({...staticSheet.classes, ...dynamicSheet.classes})

  const classes = [...classNames]
    .reduce((acc, name) => ({
      ...acc,
      [name]: composeClasses(staticSheet.classes[name], dynamicSheet.classes[name]),
    }), {})

  return (props: Object) => createElement(InnerComponent, {classes, ...props})
}

export default injectStyled
<|endoftext|>


<commit_before>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
(function(scope) {

  // imports

  var log = window.logFlags || 0;
  var events = scope.api.instance.events;

  var expressions = function() {
    PolymerExpressions.call(this);
  }

  expressions.prototype = Object.create(PolymerExpressions.prototype);

  //var syntax = new PolymerExpressions();
  expressions.prototype.resolveEventHandler = function(model, path, node) {
    var ctlr = this.eventController;

    var owner = findController(node);
    if (owner !== ctlr) {
      console.warn('not in tree', ctlr, owner);
      // TODO(sorvell): context is wrong... sigh, fix it.
      ctlr = owner;
    }
    if (ctlr) {
      var fn = path.getValueFrom(ctlr);
      if (fn) {
        return fn.bind(ctlr);
      }
    }
  }

  function findController(node) {
    while (node.parentNode) {
      node = node.parentNode;
    }
    return node.host;
  };

  // element api supporting mdv

  var mdv = {
    //syntax: syntax,
    instanceTemplate: function(template) {
      if (!this.syntax) {
        this.syntax = new expressions();
        this.syntax.eventController = this;
        //console.log(this.syntax.eventController)
      }
      return template.createInstance(this, this.syntax);
    },
    bind: function(name, observable, oneTime) {
      // note: binding is a prepare signal. This allows us to be sure that any
      // property changes that occur as a result of binding will be observed.
      if (!this._elementPrepared) {
        this.prepareElement();
      }
      var property = this.propertyForAttribute(name);
      if (!property) {
        // TODO(sjmiles): this mixin method must use the special form
        // of `super` installed by `mixinMethod` in declaration/prototype.js
        return this.mixinSuper(arguments);
      } else {
        // clean out the closets
        this.unbind(name);
        // use n-way Polymer binding
        var observer = this.bindProperty(property, observable);
        // stick path on observer so it's available via this.bindings
        observer.path = observable.path_;
        // reflect bound property to attribute when binding
        // to ensure binding is not left on attribute if property
        // does not update due to not changing.
        this.reflectPropertyToAttribute(property);
        return this.bindings[name] = observer;
      }
    },
    asyncUnbindAll: function() {
      if (!this._unbound) {
        log.unbind && console.log('[%s] asyncUnbindAll', this.localName);
        this._unbindAllJob = this.job(this._unbindAllJob, this.unbindAll, 0);
      }
    },
    unbindAll: function() {
      if (!this._unbound) {
        this.unbindAllProperties();
        this.super();
        // unbind shadowRoot
        var root = this.shadowRoot;
        while (root) {
          unbindNodeTree(root);
          root = root.olderShadowRoot;
        }
        this._unbound = true;
      }
    },
    cancelUnbindAll: function(preventCascade) {
      if (this._unbound) {
        log.unbind && console.warn('[%s] already unbound, cannot cancel unbindAll', this.localName);
        return;
      }
      log.unbind && console.log('[%s] cancelUnbindAll', this.localName);
      if (this._unbindAllJob) {
        this._unbindAllJob = this._unbindAllJob.stop();
      }
      // cancel unbinding our shadow tree iff we're not in the process of
      // cascading our tree (as we do, for example, when the element is inserted).
      if (!preventCascade) {
        forNodeTree(this.shadowRoot, function(n) {
          if (n.cancelUnbindAll) {
            n.cancelUnbindAll();
          }
        });
      }
    }
  };

  function unbindNodeTree(node) {
    forNodeTree(node, _nodeUnbindAll);
  }

  function _nodeUnbindAll(node) {
    node.unbindAll();
  }

  function forNodeTree(node, callback) {
    if (node) {
      callback(node);
      for (var child = node.firstChild; child; child = child.nextSibling) {
        forNodeTree(child, callback);
      }
    }
  }

  var mustachePattern = /\{\{([^{}]*)}}/;

  // exports

  scope.bindPattern = mustachePattern;
  scope.api.instance.mdv = mdv;

})(Polymer);
<commit_msg>Events again use the dom tree to find controller.<commit_after>/*
 * Copyright 2013 The Polymer Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */
(function(scope) {

  // imports

  var log = window.logFlags || 0;
  var events = scope.api.instance.events;

  var syntax = new PolymerExpressions();
  syntax.resolveEventHandler = function(model, path, node) {
    var ctlr = findEventController(node);
    if (ctlr) {
      var fn = path.getValueFrom(ctlr);
      if (fn) {
        return fn.bind(ctlr);
      }
    }
  }

  // An event controller is the host element for the shadowRoot in which
  // the node exists, or the first ancestor with a 'lightDomController'
  // property.
  function findEventController(node) {
    while (node.parentNode) {
      if (node.lightDomController) {
        return node;
      }
      node = node.parentNode;
    }
    return node.host;
  };

  // element api supporting mdv

  var mdv = {
    syntax: syntax,
    instanceTemplate: function(template) {
      return template.createInstance(this, this.syntax);
    },
    bind: function(name, observable, oneTime) {
      // note: binding is a prepare signal. This allows us to be sure that any
      // property changes that occur as a result of binding will be observed.
      if (!this._elementPrepared) {
        this.prepareElement();
      }
      var property = this.propertyForAttribute(name);
      if (!property) {
        // TODO(sjmiles): this mixin method must use the special form
        // of `super` installed by `mixinMethod` in declaration/prototype.js
        return this.mixinSuper(arguments);
      } else {
        // clean out the closets
        this.unbind(name);
        // use n-way Polymer binding
        var observer = this.bindProperty(property, observable);
        // stick path on observer so it's available via this.bindings
        observer.path = observable.path_;
        // reflect bound property to attribute when binding
        // to ensure binding is not left on attribute if property
        // does not update due to not changing.
        this.reflectPropertyToAttribute(property);
        return this.bindings[name] = observer;
      }
    },
    asyncUnbindAll: function() {
      if (!this._unbound) {
        log.unbind && console.log('[%s] asyncUnbindAll', this.localName);
        this._unbindAllJob = this.job(this._unbindAllJob, this.unbindAll, 0);
      }
    },
    unbindAll: function() {
      if (!this._unbound) {
        this.unbindAllProperties();
        this.super();
        // unbind shadowRoot
        var root = this.shadowRoot;
        while (root) {
          unbindNodeTree(root);
          root = root.olderShadowRoot;
        }
        this._unbound = true;
      }
    },
    cancelUnbindAll: function(preventCascade) {
      if (this._unbound) {
        log.unbind && console.warn('[%s] already unbound, cannot cancel unbindAll', this.localName);
        return;
      }
      log.unbind && console.log('[%s] cancelUnbindAll', this.localName);
      if (this._unbindAllJob) {
        this._unbindAllJob = this._unbindAllJob.stop();
      }
      // cancel unbinding our shadow tree iff we're not in the process of
      // cascading our tree (as we do, for example, when the element is inserted).
      if (!preventCascade) {
        forNodeTree(this.shadowRoot, function(n) {
          if (n.cancelUnbindAll) {
            n.cancelUnbindAll();
          }
        });
      }
    }
  };

  function unbindNodeTree(node) {
    forNodeTree(node, _nodeUnbindAll);
  }

  function _nodeUnbindAll(node) {
    node.unbindAll();
  }

  function forNodeTree(node, callback) {
    if (node) {
      callback(node);
      for (var child = node.firstChild; child; child = child.nextSibling) {
        forNodeTree(child, callback);
      }
    }
  }

  var mustachePattern = /\{\{([^{}]*)}}/;

  // exports

  scope.bindPattern = mustachePattern;
  scope.api.instance.mdv = mdv;

})(Polymer);
<|endoftext|>


<commit_before>var helper    = require('./specHelper');
var net       = require('net');

describe('The net module', function() {
  // TODO: This still appears to be racy on CI
  it('should handle pause and resume on a socket', function() {
    helper.testComplete(false);
    waitsFor(helper.testComplete, "The net pause/resume test", 10000);
    var N = 200;
    var recv = '', chars_recved = 0;

    var server = net.createServer(function(connection) {
      console.log( "server got connection" );
      function write(j) {
        console.log( "write(" + j + ")" );
        if (j >= N) {
          connection.end();
          return;
        }
        console.log( "server writing a C to connection" );
        connection.write('C');
        setTimeout(function() {
          write(j + 1);
        }, 10);
      }
      write(0);
    });

    server.on('listening', function() {
      var client = net.createConnection(8800);
      client.setEncoding('ascii');
      client.on('data', function(d) {
        console.log( "client got: " + d.toString() );
        recv += d;
      });

      setTimeout(function() {
        client.pause();
        chars_recved = recv.length;
        console.log( "pause client at: " + chars_recved );
        expect(chars_recved).toBeGreaterThan(1);
        setTimeout(function() {
          expect(recv.length).toBe(chars_recved);
          client.resume();

          setTimeout(function() {
            client.pause();
            chars_recved = recv.length;

            setTimeout(function() {
              expect(recv.length).toBe(chars_recved);
              client.resume();

            }, 1000);

          }, 1000);

        }, 1000);

      }, 1000);

      client.on('end', function() {
        server.close();
        client.end();
        helper.testComplete(true);
      });
    });
    server.listen(8800);
  });
});
<commit_msg>Remove debug, leave sleep.<commit_after>var helper    = require('./specHelper');
var net       = require('net');

describe('The net module', function() {
  // TODO: This still appears to be racy on CI
  it('should handle pause and resume on a socket', function() {
    helper.testComplete(false);
    waitsFor(helper.testComplete, "The net pause/resume test", 10000);
    var N = 200;
    var recv = '', chars_recved = 0;

    var server = net.createServer(function(connection) {
      function write(j) {
        console.log( "write(" + j + ")" );
        if (j >= N) {
          connection.end();
          return;
        }
        console.log( "server writing a C to connection" );
        connection.write('C');
        setTimeout(function() {
          write(j + 1);
        }, 10);
      }
      write(0);
    });

    server.on('listening', function() {
      var client = net.createConnection(8800);
      client.setEncoding('ascii');
      client.on('data', function(d) {
        recv += d;
      });

      setTimeout(function() {
        client.pause();
        chars_recved = recv.length;
        expect(chars_recved).toBeGreaterThan(1);
        setTimeout(function() {
          expect(recv.length).toBe(chars_recved);
          client.resume();

          setTimeout(function() {
            client.pause();
            chars_recved = recv.length;

            setTimeout(function() {
              expect(recv.length).toBe(chars_recved);
              client.resume();

            }, 1000);

          }, 1000);

        }, 1000);

      }, 1000);

      client.on('end', function() {
        server.close();
        client.end();
        helper.testComplete(true);
      });
    });
    server.listen(8800);
  });
});
<|endoftext|>


<commit_before>test(
  'InsertionTest',

  [
    'ephox.boss.mutant.Insertion',
    'ephox.boss.mutant.Locator',
    'ephox.boss.mutant.Logger',
    'ephox.boss.mutant.Tracks',
    'ephox.perhaps.Option'
  ],

  function (Insertion, Locator, Logger, Tracks, Option) {
    var check = function (expected, input, anchorId, itemId) {
      var family = Tracks.track(input, Option.none());
      var anchor = Locator.byId(family, anchorId).getOrDie();
      var item = Locator.byId(family, itemId).getOrDie();
      Insertion.before(anchor, item);
      assert.eq(expected, Logger.basic(family));
    };

    check('A(B,C(D(F,E)))', {
      id: 'A',
      children: [
        { id: 'B', children: [ ] },
        { id: 'C', children: [
          { id: 'D', children: [
            { id: 'E', children: [] }
          ]},
          { id: 'F', children: [] }
        ]}
      ]
    }, 'E', 'F');

  }
);
<commit_msg>insert before<commit_after>test(
  'InsertionTest',

  [
    'ephox.boss.mutant.Insertion',
    'ephox.boss.mutant.Locator',
    'ephox.boss.mutant.Logger',
    'ephox.boss.mutant.Tracks',
    'ephox.perhaps.Option'
  ],

  function (Insertion, Locator, Logger, Tracks, Option) {
    var check = function (expected, input, anchorId, itemId) {
      var family = Tracks.track(input, Option.none());
      var anchor = Locator.byId(family, anchorId).getOrDie();
      var item = Locator.byId(family, itemId).getOrDie();
      Insertion.before(anchor, item);
      assert.eq(expected, Logger.basic(family));
    };

    check('A(B,C(D(F,E)))', {
      id: 'A',
      children: [
        { id: 'B', children: [ ] },
        { id: 'C', children: [
          { id: 'D', children: [
            { id: 'E', children: [] }
          ]},
          { id: 'F', children: [] }
        ]}
      ]
    }, 'E', 'F');

    check('A(F,B,C(D(E)))', {
      id: 'A',
      children: [
        { id: 'B', children: [ ] },
        { id: 'C', children: [
          { id: 'D', children: [
            { id: 'E', children: [] }
          ]},
          { id: 'F', children: [] }
        ]}
      ]
    }, 'B', 'F');

    check('A(B,C(E,D,F))', {
      id: 'A',
      children: [
        { id: 'B', children: [ ] },
        { id: 'C', children: [
          { id: 'D', children: [
            { id: 'E', children: [] }
          ]},
          { id: 'F', children: [] }
        ]}
      ]
    }, 'D', 'E');

  }
);
<|endoftext|>


<commit_before>/*
 * JavaScript DOM tools library
 * 2013-12-20
 *
 * By mysegfault <maxime.alexandre@mobile-spot.com>, https://github.com/mysegfault/js-dom-tools
 *
 * MIT Licence
 */

define([], function() {

	function loadAsyncScript(src, id, callback) {
		if (typeof src !== 'string') {
			console.error('src parameter is invalid: [' + src + ']');
			return;
		}
		var tag = document.createElement('script');
		tag.src = src;
		tag.async = true;
		if (typeof id === 'string') {
			tag.id = id;
		}

		if (typeof callback === 'function') {
			tag.addEventListener("load", function load(event) {
				tag.removeEventListener("load", load, false);
				callback(event);
			}, false);
		}

		document.body.appendChild(tag);
	}

	function loadAsyncCss(src, callback) {
		if (typeof src !== 'string') {
			console.error('src parameter is invalid: [' + src + ']');
			return;
		}
		var tag = document.createElement('link');
		tag.rel = 'stylesheet';
		tag.href = src;
		tag.async = true;

		if (typeof callback === 'function') {
			tag.addEventListener("load", function load(event) {
				tag.removeEventListener("load", load, false);
				callback(event);
			}, false);
		}

		document.head.appendChild(tag);
	}

	function findParentNodeWithNodeName(element, nodeName) {
		if (typeof element === 'undefined') {
			return null;
		}
		if (typeof nodeName !== 'string') {
			console.error('className parameter is not valid: ' + nodeName);
			return null;
		}

		if (element.nodeName.toLowerCase() === 'body') {
			return null;
		}

		if (element.nodeName.toLowerCase() === nodeName.toLowerCase()) {
			return element;
		}
		else {
			return findParentNodeWithNodeName(element.parentNode, nodeName);
		}
	}

	function findParentNodeWithClassName(element, className) {

		if (typeof element === 'undefined') {
			return null;
		}
		if (typeof className !== 'string') {
			console.error('className parameter is not valid: ' + className);
			return null;
		}

		if (element.nodeName.toLowerCase() === 'body') {
			return null;
		}

		if (element.classList.contains(className) === true) {
			return element;
		}
		else {
			return findParentNodeWithClassName(element.parentNode, className);
		}
	}

	function findParentNodeWithAttribute(element, attributeName) {

		if (typeof element === 'undefined') {
			return null;
		}
		if (typeof attributeName !== 'string') {
			console.error('attributeName parameter is not valid: ' + attributeName);
			return null;
		}
		if (typeof element.getAttribute !== 'function') {
			return null;
		}

		if (element.getAttribute(attributeName) !== null) {
			return element;
		}
		else {
			return findParentNodeWithAttribute(element.parentNode, attributeName);
		}
	}

	function objectTotalLength(object) {

		if ('length' in object) {
			return object.length;
		}
		if (typeof object !== 'object') {
			return 0;
		}

		var totalLength = 0;
		for (var i in object) {
			totalLength += objectTotalLength(object[i]);
		}
		return totalLength;
	}

	function getOffsetSum(elem) {
		var top = 0, left = 0;

		while (elem) {
			top = top + parseInt(elem.offsetTop);
			left = left + parseInt(elem.offsetLeft);
			elem = elem.offsetParent;
		}

		return {top: top, left: left};
	}

	function isEmpty(data) {
		if (data === null || typeof data === 'undefined') {
			return true;
		}
		if (typeof data.length === 'number' && data.length === 0) {
			return true;
		}
		if (typeof data === 'string' && data.trim() === '') {
			return true;
		}
		return false;
	}

	function getItemHeight(element) {
		if (typeof element === 'undefined' || element === null) {
			console.error('getItemHeight: item is invalid', element);
			return 0;
		}
		var cs = window.getComputedStyle(element, null);
		if (isEmpty(cs) === true) {
			console.error('Could not get getComputedStyle of ', element);
			return 0;
		}
		if (cs.height === 'auto') {
			return 0;
		}
		var height = parseInt(cs.height.replace('px', ''));
		if (isNaN(height) === true) {
			console.error('getItemHeight: item height is invalid', element);
			height = 0;
		}
		return height;
	}

	function getItemWidth(element) {
		if (typeof element === 'undefined' || element === null) {
			console.error('getItemHeight: item is invalid', element);
			return 0;
		}
		var cs = window.getComputedStyle(element, null);
		if (isEmpty(cs) === true) {
			console.error('Could not get getComputedStyle of ', element);
			return 0;
		}
		if (cs.width === 'auto') {
			return 0;
		}
		var width = parseInt(cs.width.replace('px', ''));
		if (isNaN(width) === true) {
			console.error('getItemWidth: item width is invalid', element);
			width = 0;
		}
		return width;
	}

	return {
		loadAsyncScript: loadAsyncScript,
		loadAsyncCss: loadAsyncCss,
		findParentNodeWithNodeName: findParentNodeWithNodeName,
		findParentNodeWithClassName: findParentNodeWithClassName,
		findParentNodeWithAttribute: findParentNodeWithAttribute,
		objectTotalLength: objectTotalLength,
		getOffsetSum: getOffsetSum,
		isEmpty: isEmpty,
		getItemHeight: getItemHeight,
		getItemWidth: getItemWidth
	};
});
<commit_msg>Add defensive code / checking variable types<commit_after>/*
 * JavaScript DOM tools library
 * 2013-12-20
 *
 * By mysegfault <maxime.alexandre@mobile-spot.com>, https://github.com/mysegfault/js-dom-tools
 *
 * MIT Licence
 */

define([], function() {

	function loadAsyncScript(src, id, callback) {
		if (typeof src !== 'string') {
			console.error('src parameter is invalid: [' + src + ']');
			return;
		}
		var tag = document.createElement('script');
		tag.src = src;
		tag.async = true;
		if (typeof id === 'string') {
			tag.id = id;
		}

		if (typeof callback === 'function') {
			tag.addEventListener("load", function load(event) {
				tag.removeEventListener("load", load, false);
				callback(event);
			}, false);
		}

		document.body.appendChild(tag);
	}

	function loadAsyncCss(src, callback) {
		if (typeof src !== 'string') {
			console.error('src parameter is invalid: [' + src + ']');
			return;
		}
		var tag = document.createElement('link');
		tag.rel = 'stylesheet';
		tag.href = src;
		tag.async = true;

		if (typeof callback === 'function') {
			tag.addEventListener("load", function load(event) {
				tag.removeEventListener("load", load, false);
				callback(event);
			}, false);
		}

		document.head.appendChild(tag);
	}

	function findParentNodeWithNodeName(element, nodeName) {
		if (element === null || typeof element !== 'object') {
			return null;
		}
		if (typeof nodeName !== 'string') {
			console.error('className parameter is not valid: ' + nodeName);
			return null;
		}

		if (element.nodeName.toLowerCase() === 'body') {
			return null;
		}

		if (element.nodeName.toLowerCase() === nodeName.toLowerCase()) {
			return element;
		}
		else {
			return findParentNodeWithNodeName(element.parentNode, nodeName);
		}
	}

	function findParentNodeWithClassName(element, className) {

		if (element === null || typeof element !== 'object') {
			return null;
		}
		if (typeof className !== 'string') {
			console.error('className parameter is not valid: ' + className);
			return null;
		}

		if (element.nodeName.toLowerCase() === 'body') {
			return null;
		}

		if (element.classList.contains(className) === true) {
			return element;
		}
		else {
			return findParentNodeWithClassName(element.parentNode, className);
		}
	}

	function findParentNodeWithAttribute(element, attributeName) {

		if (element === null || typeof element !== 'object') {
			return null;
		}
		if (typeof attributeName !== 'string') {
			console.error('attributeName parameter is not valid: ' + attributeName);
			return null;
		}
		if (typeof element.getAttribute !== 'function') {
			return null;
		}

		if (element.getAttribute(attributeName) !== null) {
			return element;
		}
		else {
			return findParentNodeWithAttribute(element.parentNode, attributeName);
		}
	}

	function objectTotalLength(object) {

		if (typeof object !== 'object') {
			console.error('objectTotalLength: object is not an object. ', object);
			return 0;
		}

		if ('length' in object) {
			return object.length;
		}
		if (typeof object !== 'object') {
			return 0;
		}

		var totalLength = 0;
		for (var i in object) {
			totalLength += objectTotalLength(object[i]);
		}
		return totalLength;
	}

	function getOffsetSum(elem) {
		var top = 0, left = 0;

		while (elem) {
			top = top + parseInt(elem.offsetTop);
			left = left + parseInt(elem.offsetLeft);
			elem = elem.offsetParent;
		}

		return {top: top, left: left};
	}

	function isEmpty(data) {
		if (data === null || typeof data === 'undefined') {
			return true;
		}
		if (typeof data.length === 'number' && data.length === 0) {
			return true;
		}
		if (typeof data === 'string' && data.trim() === '') {
			return true;
		}
		return false;
	}

	function getItemHeight(element) {
		if (typeof element === 'undefined' || element === null) {
			console.error('getItemHeight: item is invalid', element);
			return 0;
		}
		var cs = window.getComputedStyle(element, null);
		if (isEmpty(cs) === true) {
			console.error('Could not get getComputedStyle of ', element);
			return 0;
		}
		if (cs.height === 'auto') {
			return 0;
		}
		var height = parseInt(cs.height.replace('px', ''));
		if (isNaN(height) === true) {
			console.error('getItemHeight: item height is invalid', element);
			height = 0;
		}
		return height;
	}

	function getItemWidth(element) {
		if (typeof element === 'undefined' || element === null) {
			console.error('getItemHeight: item is invalid', element);
			return 0;
		}
		var cs = window.getComputedStyle(element, null);
		if (isEmpty(cs) === true) {
			console.error('Could not get getComputedStyle of ', element);
			return 0;
		}
		if (cs.width === 'auto') {
			return 0;
		}
		var width = parseInt(cs.width.replace('px', ''));
		if (isNaN(width) === true) {
			console.error('getItemWidth: item width is invalid', element);
			width = 0;
		}
		return width;
	}

	return {
		loadAsyncScript: loadAsyncScript,
		loadAsyncCss: loadAsyncCss,
		findParentNodeWithNodeName: findParentNodeWithNodeName,
		findParentNodeWithClassName: findParentNodeWithClassName,
		findParentNodeWithAttribute: findParentNodeWithAttribute,
		objectTotalLength: objectTotalLength,
		getOffsetSum: getOffsetSum,
		isEmpty: isEmpty,
		getItemHeight: getItemHeight,
		getItemWidth: getItemWidth
	};
});
<|endoftext|>