<commit_before>(function() {
    angular.module('usMap', [])
    .factory('allStates', function() {
        return [
            "AK","AL","AR","AZ","CA","CO","CT","DC","DE","FL",
            "GA","GU","HI","IA","ID","IL","IN","KS","KY","LA",
            "MA","MD","ME","MH","MI","MN","MO","MS","MT","NC",
            "ND","NE","NH","NJ","NM","NV","NY","OH","OK","OR",
            "PA","PR","PW","RI","SC","SD","TN","TX","UT","VA",
            "VI","VT","WA","WI","WV","WY"
        ];
    });
})();

(function(currentScriptPath) {
    angular.module('usMap')
    .directive('usMap', ['allStates', function(allStates) {
        return {
            restrict: 'E',
            scope: {},
            transclude: true,
            templateUrl: currentScriptPath.replace('us-map.js', 'us-map.svg'),
            controllerAs: 'ctrl',
            controller: function() {
                var ctrl = this;

                ctrl.setColor = function(state, color) {
                    ctrl.states[state].attr('fill', color);
                };

                ctrl.getStateElement = function(state) {
                    return ctrl.states[state];
                };
            },
            link: function(scope, elem, attr, ctrl, transcludeFn) {
                scope.ctrl.states = {};
                var svg = elem.find('svg')[0];

                allStates.forEach(function(state) {
                    var st = svg.getElementById(state);
                    var stElem = angular.element(st);
                    scope.ctrl.states[state] = stElem;
                });

                // manually append the transcluded templates
                transcludeFn(function(clone) {
                    elem.append(clone);
                });
            }
        };
    }])
})(
    /*
     * quick hack to get current script path
     * (http://stackoverflow.com/questions/21103724/angular-directive-templateurl-relative-to-js-file)
     */
    (function() {
        var scripts = document.getElementsByTagName("script");
        var currentScriptPath = scripts[scripts.length - 1].src;
        return currentScriptPath;
    })()
);

(function() {
    angular.module('usMap')
    .directive('mapData', function() {
        return {
            restrict: 'E',
            scope: {
                state: '@',
                color: '@',
                hoverData: '@',
                hoverColor: '@', //defaults to #69707a
                hoverBgColor: '@', //defaults to #f5f7fa
                hoverPadding: '@', //defaults to 5px
                hoverTitle: '@', //not used yet
            },
            require: '^^usMap',
            link: function(scope, elem, attr, ctrl) {
                if(!scope.hoverColor) {
                    scope.hoverColor = '#69707a';
                }

                if(!scope.hoverBgColor) {
                    scope.hoverBgColor = '#f5f7fa';
                }

                if(!scope.hoverPadding) {
                    scope.hoverPadding = '5px';
                }

                if(scope.state) {
                    var preElem = elem.find('pre');
                    var stElem = ctrl.getStateElement(scope.state);

                    //hack to get the grandfather scope
                    scope.data = scope.$parent.$eval(scope.hoverData);

                    preElem.css('position', 'absolute');
                    preElem.css('color', scope.hoverColor);
                    preElem.css('background-color', scope.hoverBgColor);
                    preElem.css('padding', scope.hoverPadding);

                    stElem.on('mouseenter', function() {
                        preElem.css('display', 'block');
                    });

                    stElem.on('mousemove', function(e) {
                        preElem.css('left', e.pageX+'px');
                        preElem.css('top', e.pageY+'px');
                    });

                    stElem.on('mouseout', function() {
                        preElem.css('display', 'none');
                    });

                    if(scope.color) {
                        ctrl.setColor(scope.state, scope.color);
                    }
                }
            },
            template: '
{{data}}
'
        };
    });
})();
<commit_msg>set display to none initially<commit_after>(function() {
    angular.module('usMap', [])
    .factory('allStates', function() {
        return [
            "AK","AL","AR","AZ","CA","CO","CT","DC","DE","FL",
            "GA","GU","HI","IA","ID","IL","IN","KS","KY","LA",
            "MA","MD","ME","MH","MI","MN","MO","MS","MT","NC",
            "ND","NE","NH","NJ","NM","NV","NY","OH","OK","OR",
            "PA","PR","PW","RI","SC","SD","TN","TX","UT","VA",
            "VI","VT","WA","WI","WV","WY"
        ];
    });
})();

(function(currentScriptPath) {
    angular.module('usMap')
    .directive('usMap', ['allStates', function(allStates) {
        return {
            restrict: 'E',
            scope: {},
            transclude: true,
            templateUrl: currentScriptPath.replace('us-map.js', 'us-map.svg'),
            controllerAs: 'ctrl',
            controller: function() {
                var ctrl = this;

                ctrl.setColor = function(state, color) {
                    ctrl.states[state].attr('fill', color);
                };

                ctrl.getStateElement = function(state) {
                    return ctrl.states[state];
                };
            },
            link: function(scope, elem, attr, ctrl, transcludeFn) {
                scope.ctrl.states = {};
                var svg = elem.find('svg')[0];

                allStates.forEach(function(state) {
                    var st = svg.getElementById(state);
                    var stElem = angular.element(st);
                    scope.ctrl.states[state] = stElem;
                });

                // manually append the transcluded templates
                transcludeFn(function(clone) {
                    elem.append(clone);
                });
            }
        };
    }])
})(
    /*
     * quick hack to get current script path
     * (http://stackoverflow.com/questions/21103724/angular-directive-templateurl-relative-to-js-file)
     */
    (function() {
        var scripts = document.getElementsByTagName("script");
        var currentScriptPath = scripts[scripts.length - 1].src;
        return currentScriptPath;
    })()
);

(function() {
    angular.module('usMap')
    .directive('mapData', function() {
        return {
            restrict: 'E',
            scope: {
                state: '@',
                color: '@',
                hoverData: '@',
                hoverColor: '@', //defaults to #69707a
                hoverBgColor: '@', //defaults to #f5f7fa
                hoverPadding: '@', //defaults to 5px
                hoverTitle: '@', //not used yet
            },
            require: '^^usMap',
            link: function(scope, elem, attr, ctrl) {
                if(!scope.hoverColor) {
                    scope.hoverColor = '#69707a';
                }

                if(!scope.hoverBgColor) {
                    scope.hoverBgColor = '#f5f7fa';
                }

                if(!scope.hoverPadding) {
                    scope.hoverPadding = '5px';
                }

                if(scope.state) {
                    var preElem = elem.find('pre');
                    var stElem = ctrl.getStateElement(scope.state);

                    //hack to get the grandfather scope
                    scope.data = scope.$parent.$eval(scope.hoverData);

                    preElem.css('position', 'absolute');
                    preElem.css('color', scope.hoverColor);
                    preElem.css('background-color', scope.hoverBgColor);
                    preElem.css('padding', scope.hoverPadding);
                    preElem.css('display', 'none');

                    stElem.on('mouseenter', function() {
                        preElem.css('display', 'block');
                    });

                    stElem.on('mousemove', function(e) {
                        preElem.css('left', e.pageX+'px');
                        preElem.css('top', e.pageY+'px');
                    });

                    stElem.on('mouseout', function() {
                        preElem.css('display', 'none');
                    });

                    if(scope.color) {
                        ctrl.setColor(scope.state, scope.color);
                    }
                }
            },
            template: '
{{data}}
'
        };
    });
})();
<|endoftext|>


<commit_before>import constant from "./constant";
import {interpolate} from 'd3-interpolate';
import {map} from "d3-collection";

function index(d) {
  return d.index;
}

function find(nodeById, nodeId) {
  var node = nodeById.get(nodeId);
  if (!node) throw new Error("missing: " + nodeId);
  return node;
}

export default function(vectors) {
  var id = index,
      strength = defaultStrength,
      strengths,
      magnitude = constant(30),
      magnitudes,
      xComponents,
      yComponents,
      angle = defaultAngle,
      angles,
      cone = defaultCone(),
      nodes,
      totalVectors,
      totalVectorsConnectingNode,
      iterations = 1;

  vectors = vectors || []

  function defaultStrength(vector) {
    return 1 / Math.min(totalVectorsConnectingNode[vector.source.index], totalVectorsConnectingNode[vector.target.index]);
  }

  function defaultAngle(vector, vectorNumber) {
    return cone(vectorNumber / totalVectorsConnectingNode[vector.source.index])
  }

  function defaultCone() {
    return coneDegrees(0,360)
  }

  function coneDegrees(angle1, angle2, orientation) {
    orientation = orientation || 0
    angle1 = angle1+orientation % 360
    angle2 = angle2+orientation % 360
    if (angle2 <= angle1) { angle2 += 360 }
    return d3.interpolateNumber(angle1, angle2)
  }

  function force(alpha) {
    for (var iteration = 0; iteration < iterations; ++iteration) {
      for (var i = 0, source, target; i < totalVectors; ++i) {
        source = vectors[i].source, target = vectors[i].target;

        target.vx += (source.x + source.vx + xComponents[i] - target.x) * strengths[i] * alpha
        target.vy += (source.y + source.vy + yComponents[i] - target.y) * strengths[i] * alpha
      }
    }
  }

  function initialize() {
    if (!nodes) return;

    var i,
        totalNodes = nodes.length,
        nodeById = map(nodes, id),
        vector;

    totalVectors = vectors.length
    totalVectorsConnectingNode = new Array(totalNodes)
    // convert IDs in `vectors` to object references, and count the number of vectors connecting to each node
    for (i = 0; i < totalVectors; ++i) {
      vector = vectors[i], vector.index = i;
      if (typeof vector.source !== "object") vector.source = find(nodeById, vector.source);
      if (typeof vector.target !== "object") vector.target = find(nodeById, vector.target);
      totalVectorsConnectingNode[vector.source.index] = (totalVectorsConnectingNode[vector.source.index] || 0) + 1;
      totalVectorsConnectingNode[vector.target.index] = (totalVectorsConnectingNode[vector.target.index] || 0) + 1;
    }

    strengths = new Array(totalVectors), initializeStrength();
    magnitudes = new Array(totalVectors), initializeMagnitudes();
    angles = new Array(totalVectors)
    xComponents = new Array(totalVectors), yComponents = new Array(totalVectors), initializeComponents();
  }

  function initializeStrength() {
    if (!nodes) return;

    for (var i = 0; i < totalVectors; ++i) {
      strengths[i] = +strength(vectors[i], i, vectors);
    }
  }

  function initializeMagnitudes() {
    if (!nodes) return;

    for (var i = 0; i < totalVectors; ++i) {
      magnitudes[i] = +magnitude(vectors[i], i, vectors);
    }
  }

  function initializeAngles() {
    if (!nodes) return;

    var timesNodeHasBeenSource = {}

    for (var i = 0, source, radians; i < totalVectors; ++i) {
      source = vectors[i].source
      timesNodeHasBeenSource[source.index] = (totalVectorsConnectingNode[source.index] || 0) + 1

      radians = +angle(vectors[i], timesNodeHasBeenSource[source.index])*Math.PI/180;
      angles[i] = radians;
    }
  }

  function initializeComponents() {
    if (!nodes) return;

    initializeAngles()
    for (var i = 0, n = totalVectors; i < n; ++i) {
      xComponents[i] = Math.round(magnitudes[i] * Math.cos(angles[i]))
      yComponents[i] = Math.round(magnitudes[i] * Math.sin(angles[i]))
    }

  }

  force.initialize = function(_) {
    nodes = _;
    initialize();
  };

  force.vectors = function(_) {
    return arguments.length ? (vectors = _, initialize(), force) : vectors;
  };

  force.id = function(_) {
    return arguments.length ? (id = _, force) : id;
  };

  force.iterations = function(_) {
    return arguments.length ? (iterations = +_, force) : iterations;
  };

  force.strength = function(_) {
    return arguments.length ? (strength = typeof _ === "function" ? _ : constant(+_), initializeStrength(), force) : strength;
  };

  force.magnitude = function(_) {
    return arguments.length ? (magnitude = typeof _ === "function" ? _ : constant(+_), initializeMagnitudes(), force) : magnitude;
  };

  force.cone = function(_) {

    switch (arguments.length) {
      case 0:
        return cone
      case 1:
        if (Array.isArray(_)) {
          cone = coneDegrees.apply(null, _)
        } else{
          cone = typeof _ === "function" ? _ : constant(+_)
        }
        break
      case 2:
        cone = coneDegrees.apply(null, arguments)
        break

    }
    initializeComponents();
    return force;
  };

  return force;
}
<commit_msg>Semicolons?!<commit_after>import constant from "./constant"
import {interpolate} from 'd3-interpolate'
import {map} from "d3-collection"

function index(d) {
  return d.index
}

function find(nodeById, nodeId) {
  var node = nodeById.get(nodeId)
  if (!node) throw new Error("missing: " + nodeId)
  return node
}

export default function(vectors) {
  var id = index,
      strength = defaultStrength,
      strengths,
      magnitude = constant(30),
      magnitudes,
      xComponents,
      yComponents,
      angle = defaultAngle,
      angles,
      cone = defaultCone(),
      nodes,
      totalVectors,
      totalVectorsConnectingNode,
      iterations = 1

  vectors = vectors || []

  function defaultStrength(vector) {
    return 1 / Math.min(totalVectorsConnectingNode[vector.source.index], totalVectorsConnectingNode[vector.target.index])
  }

  function defaultAngle(vector, vectorNumber) {
    return cone(vectorNumber / totalVectorsConnectingNode[vector.source.index])
  }

  function defaultCone() {
    return coneDegrees(0,360)
  }

  function coneDegrees(angle1, angle2, orientation) {
    orientation = orientation || 0
    angle1 = angle1+orientation % 360
    angle2 = angle2+orientation % 360
    if (angle2 <= angle1) { angle2 += 360 }
    return d3.interpolateNumber(angle1, angle2)
  }

  function force(alpha) {
    for (var iteration = 0 iteration < iterations ++iteration) {
      for (var i = 0, source, target i < totalVectors ++i) {
        source = vectors[i].source, target = vectors[i].target

        target.vx += (source.x + source.vx + xComponents[i] - target.x) * strengths[i] * alpha
        target.vy += (source.y + source.vy + yComponents[i] - target.y) * strengths[i] * alpha
      }
    }
  }

  function initialize() {
    if (!nodes) return

    var i,
        totalNodes = nodes.length,
        nodeById = map(nodes, id),
        vector

    totalVectors = vectors.length
    totalVectorsConnectingNode = new Array(totalNodes)
    // convert IDs in `vectors` to object references, and count the number of vectors connecting to each node
    for (i = 0 i < totalVectors ++i) {
      vector = vectors[i], vector.index = i
      if (typeof vector.source !== "object") vector.source = find(nodeById, vector.source)
      if (typeof vector.target !== "object") vector.target = find(nodeById, vector.target)
      totalVectorsConnectingNode[vector.source.index] = (totalVectorsConnectingNode[vector.source.index] || 0) + 1
      totalVectorsConnectingNode[vector.target.index] = (totalVectorsConnectingNode[vector.target.index] || 0) + 1
    }

    strengths = new Array(totalVectors), initializeStrength()
    magnitudes = new Array(totalVectors), initializeMagnitudes()
    angles = new Array(totalVectors)
    xComponents = new Array(totalVectors), yComponents = new Array(totalVectors), initializeComponents()
  }

  function initializeStrength() {
    if (!nodes) return

    for (var i = 0 i < totalVectors ++i) {
      strengths[i] = +strength(vectors[i], i, vectors)
    }
  }

  function initializeMagnitudes() {
    if (!nodes) return

    for (var i = 0 i < totalVectors ++i) {
      magnitudes[i] = +magnitude(vectors[i], i, vectors)
    }
  }

  function initializeAngles() {
    if (!nodes) return

    var timesNodeHasBeenSource = {}

    for (var i = 0, source, radians i < totalVectors ++i) {
      source = vectors[i].source
      timesNodeHasBeenSource[source.index] = (totalVectorsConnectingNode[source.index] || 0) + 1

      radians = +angle(vectors[i], timesNodeHasBeenSource[source.index])*Math.PI/180
      angles[i] = radians
    }
  }

  function initializeComponents() {
    if (!nodes) return

    initializeAngles()
    for (var i = 0, n = totalVectors i < n ++i) {
      xComponents[i] = Math.round(magnitudes[i] * Math.cos(angles[i]))
      yComponents[i] = Math.round(magnitudes[i] * Math.sin(angles[i]))
    }

  }

  force.initialize = function(_) {
    nodes = _
    initialize()
  }

  force.vectors = function(_) {
    return arguments.length ? (vectors = _, initialize(), force) : vectors
  }

  force.id = function(_) {
    return arguments.length ? (id = _, force) : id
  }

  force.iterations = function(_) {
    return arguments.length ? (iterations = +_, force) : iterations
  }

  force.strength = function(_) {
    return arguments.length ? (strength = typeof _ === "function" ? _ : constant(+_), initializeStrength(), force) : strength
  }

  force.magnitude = function(_) {
    return arguments.length ? (magnitude = typeof _ === "function" ? _ : constant(+_), initializeMagnitudes(), force) : magnitude
  }

  force.cone = function(_) {

    switch (arguments.length) {
      case 0:
        return cone
      case 1:
        if (Array.isArray(_)) {
          cone = coneDegrees.apply(null, _)
        } else{
          cone = typeof _ === "function" ? _ : constant(+_)
        }
        break
      case 2:
        cone = coneDegrees.apply(null, arguments)
        break

    }
    initializeComponents()
    return force
  }

  return force
}
<|endoftext|>


<commit_before><commit_msg>use strict for tv-ui app<commit_after><|endoftext|>


<commit_before>"use strict";

jjtApingYoutube.service('apingYoutubeHelper', ['apingOutputObjects', 'apingTimeHelper', 'apingUtilityHelper', function (apingOutputObjects, apingTimeHelper, apingUtilityHelper) {

    this.getObjectByJsonData = function (_data, _type) {

        var requestResults = [];

        if (_data) {

            var _this = this;

            if (_data.items) {
                angular.forEach(_data.items, function (value, key) {
                    requestResults.push(_this.getItemByJsonData(value, _type));
                });
            }
        }

        return requestResults;
    };

    this.getItemByJsonData = function (_item, _type) {

        var returnObject = {};

        if (_item && _type) {
            switch (_type) {
                case "social":
                    returnObject = this.getSocialItemByJsonData(_item);
                    break;
            }
        }

        return returnObject;
    };

    this.getSocialItemByJsonData = function (_item) {
        var socialObject = apingOutputObjects.getNew("social", "youtube");

        $.extend(true, socialObject, {
            blog_name: _item.snippet.channelTitle || false,
            blog_id: _item.snippet.channelId || false,
            blog_link: "https://www.youtube.com/channel/" + _item.snippet.channelId,
            intern_type: _item.id.kind,
            date: _item.snippet.publishedAt,
            intern_id: _item.id.videoId || _item.snippet.resourceId.videoId,
            timestamp: apingTimeHelper.getTimestampFromDateString(_item.snippet.publishedAt, 1000, 7200),
        });

        if (_item.snippet.title !== "" && _item.snippet.description !== "") {
            socialObject.caption = _item.snippet.title;
            socialObject.text = _item.snippet.description;
        } else {
            if (_item.snippet.title !== "") {
                socialObject.caption = _item.snippet.title;
            } else {
                socialObject.caption = _item.snippet.description;
            }
        }

        if (_item.id.kind == "youtube#video") {
            socialObject.type = "video";
        } else if (_item.kind == "youtube#playlistItem" && _item.snippet.resourceId && _item.snippet.resourceId.kind == "youtube#video") {
            socialObject.type = "video";
        }

        socialObject.img_url = apingUtilityHelper.getYoutubeImageFromId(socialObject.intern_id);
        socialObject.post_url = "https://www.youtube.com/watch?v=" + socialObject.intern_id;

        return socialObject;
    }

}]);<commit_msg>added support for outputObject "video"<commit_after>"use strict";
jjtApingYoutube.service('apingYoutubeHelper', ['apingOutputObjects', 'apingTimeHelper', 'apingUtilityHelper', function (apingOutputObjects, apingTimeHelper, apingUtilityHelper) {
    this.getObjectByJsonData = function (_data, _type) {
        var requestResults = [];
        if (_data) {
            var _this = this;
            if (_data.items) {
                angular.forEach(_data.items, function (value, key) {
                    requestResults.push(_this.getItemByJsonData(value, _type));
                });
            }
        }
        return requestResults;
    };

    this.getItemByJsonData = function (_item, _type) {
        var returnObject = {};
        if (_item && _type) {
            switch (_type) {
                case "social":
                    returnObject = this.getSocialItemByJsonData(_item);
                    break;
                case "video":
                    returnObject = this.getVideoItemByJsonData(_item);
                    break;
            }
        }
        return returnObject;
    };

    this.getSocialItemByJsonData = function (_item) {
        var socialObject = apingOutputObjects.getNew("social", "youtube");
        $.extend(true, socialObject, {
            blog_name: _item.snippet.channelTitle || false,
            blog_id: _item.snippet.channelId || false,
            blog_link: "https://www.youtube.com/channel/" + _item.snippet.channelId,
            intern_type: _item.id.kind,
            date: _item.snippet.publishedAt,
            intern_id: _item.id.videoId || _item.snippet.resourceId.videoId,
            timestamp: apingTimeHelper.getTimestampFromDateString(_item.snippet.publishedAt, 1000, 7200),
        });
        if (_item.snippet.title !== "" && _item.snippet.description !== "") {
            socialObject.caption = _item.snippet.title;
            socialObject.text = _item.snippet.description;
        } else {
            if (_item.snippet.title !== "") {
                socialObject.caption = _item.snippet.title;
            } else {
                socialObject.caption = _item.snippet.description;
            }
        }
        if (_item.id.kind == "youtube#video") {
            socialObject.type = "video";
        } else if (_item.kind == "youtube#playlistItem" && _item.snippet.resourceId && _item.snippet.resourceId.kind == "youtube#video") {
            socialObject.type = "video";
        }
        socialObject.img_url = apingUtilityHelper.getYoutubeImageFromId(socialObject.intern_id);
        socialObject.post_url = "https://www.youtube.com/watch?v=" + socialObject.intern_id;
        return socialObject;
    };

    this.getVideoItemByJsonData = function (_item) {
        var socialObject = apingOutputObjects.getNew("video", "youtube");
        $.extend(true, socialObject, {
            blog_name: _item.snippet.channelTitle || false,
            blog_id: _item.snippet.channelId || false,
            blog_link: "https://www.youtube.com/channel/" + _item.snippet.channelId,
            intern_type: _item.id.kind,
            date: _item.snippet.publishedAt,
            intern_id: _item.id.videoId || _item.snippet.resourceId.videoId,
            timestamp: apingTimeHelper.getTimestampFromDateString(_item.snippet.publishedAt, 1000, 7200),
        });
        if (_item.snippet.title !== "" && _item.snippet.description !== "") {
            socialObject.caption = _item.snippet.title;
            socialObject.text = _item.snippet.description;
        } else {
            if (_item.snippet.title !== "") {
                socialObject.caption = _item.snippet.title;
            } else {
                socialObject.caption = _item.snippet.description;
            }
        }
        socialObject.img_url = apingUtilityHelper.getYoutubeImageFromId(socialObject.intern_id);
        socialObject.post_url = "https://www.youtube.com/watch?v=" + socialObject.intern_id;
        return socialObject;
    };
}]);<|endoftext|>


<commit_before>(function($) {
	"use strict";

	/**
	 * This namespace provides the models and collections for working with BC web applications and their items.
	 *
	 * @namespace BCAPI.Models.WebApp
	 * @memberOf BCAPI.Models
	 */
	BCAPI.Models.WebApp = {};

    /**
     * This class provides the model for interacting with web apps.
     *
     * ## Load webapps list
     *
     * ```javascript
     * var apps = new BCAPI.Models.WebApp.AppCollection();
     * apps.fetch({
     *		success: function(webAppItems) {
	 * 			// handle success
	 * 		},
	 * 		error: function(webAppItems, xhr) {
	 * 			// handle errors
	 * 		}
	 * });
     *
     * apps.each(function(webApp) {
	 * 		// display logic
	 * });
     * ```
     *
     * ## Create webapp
     *
     * ```javascript
     * var app = new BCAPI.Models.WebApp.App({
	 * 		"name": "Test app"
	 * });
     *
     * var response = app.save({
	 * 		success: function(webAppItem) {
	 * 			// handle success
	 * 		},
	 * 		error: function(webAppItem, xhr) {
	 * 			// handle errors
	 * 		}
	 * });
     * ```
     *
     * If you want to refresh collections which rely on Item model please refresh those collections.
     *
     * ## Remove app
     *
     * ```javascript
     * var app = new BCAPI.Models.WebApp.Item({name: "Test app"});
     * item.destroy({
	 * 	success: function(webAppItem, response) {
	 * 		// handle success here.
	 *  },
	 *  error: function(webAppItem, xhr, options) {
	 * 		// handle error scenario.
	 *  }
	 * });
     * ```
     *
     * ## Supported attributes
     *
     * ```javascript
     * var app = new BCAPI.Models.WebApp.Item({
	 *	templateId: -1,
     *  uploadFolder: "images",
     *  requiresApproval: true,
     *  allowFileUpload: true,
     *  customerCanAdd: false,
     *  customerCanDelete: false,
     *  customerCanEdit: false,
     *  anyoneCanEdit: false,
     *  requiresPayment: false,
     *  validDays: -1, // never expire
     *  roleId: 0,
     *  hasAddress: false,
     *  disableDetailPages: false,
     *  locationEnabled: false
     * });
     * ```
     *
     * @class
     */
	BCAPI.Models.WebApp.App = BCAPI.Models.Model.extend({
        idAttribute: 'name',

        /**
         * Set tot true if you want to save or delete an existing item before fetching it
         *
         * @type {boolean}
         * @memberOf WebApp
         */
        isNotNew: null,

        isNew: function() {
            return this.isNotNew ? false : !this.get('id');
        },

        endpoint: function() {
            return '/api/v2/admin/sites/current/webapps';
        },

        fetch: function() {
            this.isNotNew = true;
            return Backbone.Model.prototype.fetch.apply(this, arguments);
        },

        destroy: function() {
            this.isNotNew = true;
            return Backbone.Model.prototype.destroy.apply(this, arguments);
        }
    });

    /**
     * This class provides a collection that can be used to list all webapps from a site. For
     * more information about a webapp see {@link BCAPI.Models.WebApp.App}.
     *
     * @name AppCollection
     * @class
     * @constructor
     * @memberOf BCAPI.Models.WebApp
     * @example
     * // fetch all available webapps
     * var appCollection = new BCAPI.Models.WebApp.AppCollection();
     *
     * appCollection.fetch({fetchFields: false,
     *  success: function(webapps) {
     *  	webapps.each(function(webapp) {
     *  		// no custom fields are retrieved.
     *  	});
     *  }
     *
     * @example
     * // extract and fetch webap details from a fetched collection (by webapp id).
     * var webappId = 1,
     *		webapp = appCollection.get(webappId);
     *
     * webapp.fetch({
     * 	success: function(webapp) {
     * 		// webapp is now fully loaded.
     *  }
     * });
     *
     * @example
     * // extract and fetch webapp details from fetched collection (by webapp index)
     * var idx = 1,
     * 	    webapp = appCollection.at(idx);
     *
     * webapp.fetch({
     * 	success: function(webapp) {
     * 		// webapp is now fully loaded.
     *  }
     * });
     */
    BCAPI.Models.WebApp.AppCollection = BCAPI.Models.Collection.extend({
        model: BCAPI.Models.WebApp.App,
    	/**
    	 * We override this method in order to transform each returned item into a strong typed
    	 * {@link BCAPI.Models.WebApp.App} models.
    	 *
    	 * @method
    	 * @instance
    	 * @param {Object} response The JSON response received from Web apps api.
    	 * @returns A list of web app items.
    	 * @memberOf BCAPI.Models.WebApp.AppCollection
         */
        parse: function(response) {
        	var webapps = [],
        		self = this;

        	response = BCAPI.Models.Collection.prototype.parse.call(this, response);

        	_.each(response, function(webapp) {
        		webapps.push(self.model(webapp));
        	});

        	return webapps;
        }
    });
})(jQuery);<commit_msg>I fixed a bug in web app remove documentation.<commit_after>(function($) {
	"use strict";

	/**
	 * This namespace provides the models and collections for working with BC web applications and their items.
	 *
	 * @namespace BCAPI.Models.WebApp
	 * @memberOf BCAPI.Models
	 */
	BCAPI.Models.WebApp = {};

    /**
     * This class provides the model for interacting with web apps.
     *
     * ## Load webapps list
     *
     * ```javascript
     * var apps = new BCAPI.Models.WebApp.AppCollection();
     * apps.fetch({
     *		success: function(webAppItems) {
	 * 			// handle success
	 * 		},
	 * 		error: function(webAppItems, xhr) {
	 * 			// handle errors
	 * 		}
	 * });
     *
     * apps.each(function(webApp) {
	 * 		// display logic
	 * });
     * ```
     *
     * ## Create webapp
     *
     * ```javascript
     * var app = new BCAPI.Models.WebApp.App({
	 * 		"name": "Test app"
	 * });
     *
     * var response = app.save({
	 * 		success: function(webAppItem) {
	 * 			// handle success
	 * 		},
	 * 		error: function(webAppItem, xhr) {
	 * 			// handle errors
	 * 		}
	 * });
     * ```
     *
     * If you want to refresh collections which rely on Item model please refresh those collections.
     *
     * ## Remove app
     *
     * ```javascript
     * var app = new BCAPI.Models.WebApp.App({name: "Test app"});
     * item.destroy({
	 * 	success: function(webAppItem, response) {
	 * 		// handle success here.
	 *  },
	 *  error: function(webAppItem, xhr, options) {
	 * 		// handle error scenario.
	 *  }
	 * });
     * ```
     *
     * ## Supported attributes
     *
     * ```javascript
     * var app = new BCAPI.Models.WebApp.Item({
	 *	templateId: -1,
     *  uploadFolder: "images",
     *  requiresApproval: true,
     *  allowFileUpload: true,
     *  customerCanAdd: false,
     *  customerCanDelete: false,
     *  customerCanEdit: false,
     *  anyoneCanEdit: false,
     *  requiresPayment: false,
     *  validDays: -1, // never expire
     *  roleId: 0,
     *  hasAddress: false,
     *  disableDetailPages: false,
     *  locationEnabled: false
     * });
     * ```
     *
     * @class
     */
	BCAPI.Models.WebApp.App = BCAPI.Models.Model.extend({
        idAttribute: 'name',

        /**
         * Set tot true if you want to save or delete an existing item before fetching it
         *
         * @type {boolean}
         * @memberOf WebApp
         */
        isNotNew: null,

        isNew: function() {
            return this.isNotNew ? false : !this.get('id');
        },

        endpoint: function() {
            return '/api/v2/admin/sites/current/webapps';
        },

        fetch: function() {
            this.isNotNew = true;
            return Backbone.Model.prototype.fetch.apply(this, arguments);
        },

        destroy: function() {
            this.isNotNew = true;
            return Backbone.Model.prototype.destroy.apply(this, arguments);
        }
    });

    /**
     * This class provides a collection that can be used to list all webapps from a site. For
     * more information about a webapp see {@link BCAPI.Models.WebApp.App}.
     *
     * @name AppCollection
     * @class
     * @constructor
     * @memberOf BCAPI.Models.WebApp
     * @example
     * // fetch all available webapps
     * var appCollection = new BCAPI.Models.WebApp.AppCollection();
     *
     * appCollection.fetch({fetchFields: false,
     *  success: function(webapps) {
     *  	webapps.each(function(webapp) {
     *  		// no custom fields are retrieved.
     *  	});
     *  }
     *
     * @example
     * // extract and fetch webap details from a fetched collection (by webapp id).
     * var webappId = 1,
     *		webapp = appCollection.get(webappId);
     *
     * webapp.fetch({
     * 	success: function(webapp) {
     * 		// webapp is now fully loaded.
     *  }
     * });
     *
     * @example
     * // extract and fetch webapp details from fetched collection (by webapp index)
     * var idx = 1,
     * 	    webapp = appCollection.at(idx);
     *
     * webapp.fetch({
     * 	success: function(webapp) {
     * 		// webapp is now fully loaded.
     *  }
     * });
     */
    BCAPI.Models.WebApp.AppCollection = BCAPI.Models.Collection.extend({
        model: BCAPI.Models.WebApp.App,
    	/**
    	 * We override this method in order to transform each returned item into a strong typed
    	 * {@link BCAPI.Models.WebApp.App} models.
    	 *
    	 * @method
    	 * @instance
    	 * @param {Object} response The JSON response received from Web apps api.
    	 * @returns A list of web app items.
    	 * @memberOf BCAPI.Models.WebApp.AppCollection
         */
        parse: function(response) {
        	var webapps = [],
        		self = this;

        	response = BCAPI.Models.Collection.prototype.parse.call(this, response);

        	_.each(response, function(webapp) {
        		webapps.push(self.model(webapp));
        	});

        	return webapps;
        }
    });
})(jQuery);<|endoftext|>


<commit_before>var profile = (function(){
	var testResourceRe = /^dijit\/tests\//,

		copyOnly = function(filename, mid){
			var list = {
				"dijit/dijit.profile":1,
				"dijit/package.json":1,
				"dijit/themes/claro/compile":1
			};
			return (mid in list) || (/^dijit\/resources\//.test(mid) && !/\.css$/.test(filename)) || /(png|jpg|jpeg|gif|tiff)$/.test(filename);
		};

	return {
		resourceTags:{
			test: function(filename, mid){
				return testResourceRe.test(mid) || mid=="dijit/robot" || mid=="dijit/robotx";
			},

			copyOnly: function(filename, mid){
				return copyOnly(filename, mid);
			},

			amd: function(filename, mid){
				return !testResourceRe.test(mid) && !copyOnly(filename, mid) && /\.js$/.test(filename);
			},

			miniExclude: function(filename, mid){
				return /^dijit\/bench\//.test(mid) || /^dijit\/themes\/themeTest/.test(mid);
			}
		},

		trees:[
			[".", ".", /(\/\.)|(~$)/]
		]
	};
})();

<commit_msg>improved discovery to not pass base src path to exclude computation; removed unneeded trees config from all standard profiles; fixes #15484; !strict; thanks blowery<commit_after>var profile = (function(){
	var testResourceRe = /^dijit\/tests\//,

		copyOnly = function(filename, mid){
			var list = {
				"dijit/dijit.profile":1,
				"dijit/package.json":1,
				"dijit/themes/claro/compile":1
			};
			return (mid in list) || (/^dijit\/resources\//.test(mid) && !/\.css$/.test(filename)) || /(png|jpg|jpeg|gif|tiff)$/.test(filename);
		};

	return {
		resourceTags:{
			test: function(filename, mid){
				return testResourceRe.test(mid) || mid=="dijit/robot" || mid=="dijit/robotx";
			},

			copyOnly: function(filename, mid){
				return copyOnly(filename, mid);
			},

			amd: function(filename, mid){
				return !testResourceRe.test(mid) && !copyOnly(filename, mid) && /\.js$/.test(filename);
			},

			miniExclude: function(filename, mid){
				return /^dijit\/bench\//.test(mid) || /^dijit\/themes\/themeTest/.test(mid);
			}
		}
	};
})();

<|endoftext|>


<commit_before>define(
    [
        './widget-extensions',
        './router',
        './events',
        './htmlCanvas',
        'jquery'
    ],

    function (ext, router, events, htmlCanvas, jQuery) {

        /**
         * Base for all widgets. A widget can keep state in variables, contain logic and
         * render itself using `renderOn()`.
         *
         * @example
         *
         *      var titleWidget = function(spec) {
         *          var that = widget(spec);
         *
         *          var title = spec.title || 'Hello World';
         *
         *          that.renderContentOn = function(html) {
         *              html.h1(title)
         *          }
         *
         *          return that;
         *      };
         *
         *      var helloWorldWidget = titleWidget({title: 'Hello Widget!'});
         *
         *      $(document).ready(function() {
         *          helloWorldWidget.appendTo('BODY');
         *      });
         *
         * Widgets can also be rendered on a HTML canvas (since widget implements `appendToBrush()`). Eg.
         *
         *      html.div(helloWorldWidget)
         *
         * It is therefor easy to compose widgets from other widgets.
         *
         *
         * @param {Object} spec
         * @param {String} [spec.id] Unique id for widget. Also used for root element when attached/rendered to DOM.
         *                           If not provided an ID will automatically be generated and assigned.
         * @param {Object} [my]
         *
         * @returns {widget}
         */
        var widget = function (spec, my) {
            my = my || {};
            spec = spec || {};

			/** @typedef {{}} widget */
            var that = {};

            var id = spec.id || idGenerator.newId();

            /** When within an update transaction, do not update the widget */
            var inUpdateTransaction = false;

            /** Events for widget */
            my.events = events.eventCategory();

            //
            // Public
            //

            /**
             * Returns a unique id for the widget
             *
             * @returns {String}
             */
            that.getId = function () {
                return id;
            };

            that.id = that.getId; //TODO: deprecated

            /**
             * Performance tasks need for freeing/releasing/cleaning-up resources used by widget.
             *
             * Should always be executed before a widget is disposed. Especially
             * if the widget register events to avoid memory leaks.
             *
             * If overridden in a subclass, make sure to execute `my.disposeWidget()`.
             *
             */
            that.dispose = function() {
                my.disposeWidget();
            };

            /**
             * Renders the widget on a JQuery / DOM
             *
             * @example
             *    widget.appendTo('BODY');
             *
             * @param aJQuery
             */
            that.appendTo = function (aJQuery) {
                that.renderOn(htmlCanvas(aJQuery));
            };

            /**
             * Does the same as appendTo except it first clear the
             * elements matched by aJQuery
             *
             * @param aJQuery
             */
            that.replace = function (aJQuery) {
                var canvas = htmlCanvas(aJQuery);
                canvas.root.asJQuery().empty();
                that.renderOn(canvas);
            };

            /**
             * Answers a jQuery that match the root DOM element. By default
             * by selecting an element that have the same ID as the widget.
             *
             * See 'renderOn'
             *
             * @returns {*}
             */
            that.asJQuery = function () {
                return jQuery('#' + that.getId());
            };

            /**
             * Answers true if if widget have rendered content in DOM
             *
             * @returns {boolean}
             */
            that.isRendered = function () {
                return that.asJQuery().length > 0;
            };

            /**
             * Implementation for `appendToBrush()` to allow a widget to be
             * appended to a brush. See 'htmlCanvas'.
             *
             * Basically it allows us to do:
             *      html.div(widget);
             *
             * @param aTagBrush
             */
            that.appendToBrush = function (aTagBrush) {
                that.appendTo(aTagBrush.asJQuery());
            };

            // Expose events
            that.on = my.events.on;
            that.onceOn = my.events.onceOn;
            that.off = my.events.off;
            that.trigger = my.events.trigger;

			//
            // Protected
			//

            /**
             * Exposes the internal ID generator. Generates new unique IDs to be used
             * for sub-widgets, etc.
             *
             * @returns {String}
             */
            my.nextId = function () {
                return idGenerator.newId();
            };

            /**
             * Widget specific dispose.
             */
            my.disposeWidget = function() {
              my.events.dispose();
            };

            my.trigger = my.events.trigger;

            // Route / Controller extensions

			my.router = router.getRouter();

            my.linkTo = my.router.linkTo;
            my.linkToPath = my.router.linkToPath;
            my.linkToUrl = my.router.linkToUrl;

            my.redirectTo = my.router.redirectTo;
            my.redirectToPath = my.router.redirectToPath;
            my.redirectToUrl = my.router.redirectToUrl;

            my.getParameters = my.router.getParameters;
            my.getParameter = my.router.getParameter;
            my.setParameters = my.router.setParameters;

			//
            // Render
			//

            /**
             * Main entry point for rendering. For convenience 'renderOn' will  wrap the content
             * rendered by 'renderContentOn' in a root element (renderRootOn) that will be matched
             * by asJQuery.
             *
             * Usually concrete widgets override 'renderContentOn' to render it content. Widgets
             * can override 'renderOn' but must then make sure that it can be matched by 'asJQuery'.
             *
             * One way to do that is to make sure to have only one root element and setting the ID of
             * that element to the ID of the widget.
             *
             * @example
             *
             *      that.renderOn = function (html) {
             *          html.ul({id: that.getId()}
             *              html.li('BMW'),
             *              html.li('Toyota')
             *          );
             *      };
             *
             *
             * @param html
             */
            that.renderOn = function (html) {
                // Renders widget by wrapping `renderContentOn()` in a root element.
                my.renderRootOn(html).render(that.renderContentOn);
            };

            /**
             * Renders a wrapper element (by default a 'widgetjs-widget' tag) and
             * set the element ID to the ID of the widget so that it can be found by
             * 'asJQuery' eg. when we re-render using 'update'.
             *
             * @param html
             * @returns {htmlBrush}
             */
            my.renderRootOn = function (html) {
                return html.tag('widgetjs-widget').id(id);
            };

            /**
             * Overridden in concrete widgets to render widget to canvas/DOM.
             *
             * @example
             *
             *      that.renderContentOn = function (html) {
             *          html.ul(
             *              html.li('BMW'),
             *              html.li('Toyota')
             *          );
             *      };
             *
             * @param {htmlCanvas} html
             */
            that.renderContentOn = function (html) {};

            /**
             * Re-renders the widget and replace it in the DOM
             *
             * Content is first re-rendered on a document fragment. Update then replace the element matched
             * by 'asJQuery' with the new content.
             *
             */
            that.update = function () {
                if (inUpdateTransaction || !that.isRendered()) {
                    return;
                }

                // Re-render
                var html = htmlCanvas();
                that.renderOn(html);

                // Replace our self
                that.asJQuery().replaceWith(html.root.element);
            };

            /**
             * Evaluate `fn`, ensuring that an update will be
             * performed after evaluating the function. Nested calls
             * to `withUpdate` or `update` will result in updating the
             * widget only once.
             */
            that.withUpdate = function(fn) {
                if(inUpdateTransaction) {
                    fn();
                } else {
                    try {
                        inUpdateTransaction = true;
                        fn();
                    }
                    finally {
                        inUpdateTransaction = false;
                        that.update();
                    }
                }
            };

            // Third party protected extensions** added to `my`.
            // See widget-extensions.js
            for (var extProperty in ext) {
                if (ext.hasOwnProperty(extProperty)) {
                    my[extProperty] = ext[extProperty];
                }
            }

            return that;
        };

        /**
         * Creates unique ids used by widgets to identify their root div.
         */
        var idGenerator = (function () {
            var that = {};
            var id = 0;

            that.newId = function () {
                id += 1;
                return id.toString();
            };

            return that;
        })();

        return widget;
    }
);
<commit_msg>Adds support for automatic children registration in widget.js<commit_after>define(
    [
        './widget-extensions',
        './router',
        './events',
        './htmlCanvas',
        'jquery'
    ],

    function (ext, router, events, htmlCanvas, jQuery) {

        /**
         * Base for all widgets. A widget can keep state in variables, contain logic and
         * render itself using `renderOn()`.
         *
         * @example
         *
         *      var titleWidget = function(spec) {
         *          var that = widget(spec);
         *
         *          var title = spec.title || 'Hello World';
         *
         *          that.renderContentOn = function(html) {
         *              html.h1(title)
         *          }
         *
         *          return that;
         *      };
         *
         *      var helloWorldWidget = titleWidget({title: 'Hello Widget!'});
         *
         *      $(document).ready(function() {
         *          helloWorldWidget.appendTo('BODY');
         *      });
         *
         * Widgets can also be rendered on a HTML canvas (since widget implements `appendToBrush()`). Eg.
         *
         *      html.div(helloWorldWidget)
         *
         * It is therefor easy to compose widgets from other widgets.
         *
         *
         * @param {Object} spec
         * @param {String} [spec.id] Unique id for widget. Also used for root element when attached/rendered to DOM.
         *                           If not provided an ID will automatically be generated and assigned.
         * @param {Object} [my]
         *
         * @returns {widget}
         */
        var widget = function (spec, my) {
            my = my || {};
            spec = spec || {};

			/** @typedef {{}} widget */
            var that = {};

            var id = spec.id || idGenerator.newId();

            /** When within an update transaction, do not update the widget */
            var inUpdateTransaction = false;

            /** Events for widget */
            my.events = events.eventCategory();

            //
            // Public
            //

            /**
             * Returns a unique id for the widget
             *
             * @returns {String}
             */
            that.getId = function () {
                return id;
            };

            that.id = that.getId; //TODO: deprecated

            /**
             * Performance tasks need for freeing/releasing/cleaning-up resources used by widget.
             *
             * Should always be executed before a widget is disposed. Especially
             * if the widget register events to avoid memory leaks.
             *
             * If overridden in a subclass, make sure to execute `my.disposeWidget()`.
             *
             */
            that.dispose = function() {
                my.disposeWidget();
            };

            /**
             * Renders the widget on a JQuery / DOM
             *
             * @example
             *    widget.appendTo('BODY');
             *
             * @param aJQuery
             */
            that.appendTo = function (aJQuery) {
                that.renderOn(htmlCanvas(aJQuery));
            };

            /**
             * Does the same as appendTo except it first clear the
             * elements matched by aJQuery
             *
             * @param aJQuery
             */
            that.replace = function (aJQuery) {
                var canvas = htmlCanvas(aJQuery);
                canvas.root.asJQuery().empty();
                that.renderOn(canvas);
            };

            /**
             * Answers a jQuery that match the root DOM element. By default
             * by selecting an element that have the same ID as the widget.
             *
             * See 'renderOn'
             *
             * @returns {*}
             */
            that.asJQuery = function () {
                return jQuery('#' + that.getId());
            };

            /**
             * Answers true if if widget have rendered content in DOM
             *
             * @returns {boolean}
             */
            that.isRendered = function () {
                return that.asJQuery().length > 0;
            };

            /**
             * Implementation for `appendToBrush()` to allow a widget to be
             * appended to a brush. See 'htmlCanvas'.
             *
             * Basically it allows us to do:
             *      html.div(widget);
             *
             * @param aTagBrush
             */
            that.appendToBrush = function (aTagBrush) {
                that.appendTo(aTagBrush.asJQuery());
            };

            // Expose events
            that.on = my.events.on;
            that.onceOn = my.events.onceOn;
            that.off = my.events.off;
            that.trigger = my.events.trigger;

			//
            // Protected
			//

            /**
             * Exposes the internal ID generator. Generates new unique IDs to be used
             * for sub-widgets, etc.
             *
             * @returns {String}
             */
            my.nextId = function () {
                return idGenerator.newId();
            };

            /**
             * Widget specific dispose.
             */
            my.disposeWidget = function() {
              my.events.dispose();
            };

            my.trigger = my.events.trigger;

            // Route / Controller extensions

			my.router = router.getRouter();

            my.linkTo = my.router.linkTo;
            my.linkToPath = my.router.linkToPath;
            my.linkToUrl = my.router.linkToUrl;

            my.redirectTo = my.router.redirectTo;
            my.redirectToPath = my.router.redirectToPath;
            my.redirectToUrl = my.router.redirectToUrl;

            my.getParameters = my.router.getParameters;
            my.getParameter = my.router.getParameter;
            my.setParameters = my.router.setParameters;

			//
            // Render
			//

            /**
             * Main entry point for rendering. For convenience 'renderOn' will  wrap the content
             * rendered by 'renderContentOn' in a root element (renderRootOn) that will be matched
             * by asJQuery.
             *
             * Usually concrete widgets override 'renderContentOn' to render it content. Widgets
             * can override 'renderOn' but must then make sure that it can be matched by 'asJQuery'.
             *
             * One way to do that is to make sure to have only one root element and setting the ID of
             * that element to the ID of the widget.
             *
             * @example
             *
             *      that.renderOn = function (html) {
             *          html.ul({id: that.getId()}
             *              html.li('BMW'),
             *              html.li('Toyota')
             *          );
             *      };
             *
             *
             * @param html
             */
            that.renderOn = function (html) {
                // Renders widget by wrapping `renderContentOn()` in a root element.
				my.withRenderingRegistration(function() {
					my.renderRootOn(html).render(that.renderContentOn);
				});
            };

			my.withRenderingRegistration = function(fn) {
				var parent = currentWidget;
				if(parent) {
					parent.registerChild(that);
				}
				currentWidget = that;
				try {
					that.clearChildren();
					fn();
				} finally {
					currentWidget = parent;
				}
			};

			that.registerChild = function(widget) {
				my.children.push(widget);
			};

			that.clearChildren = function() {
				my.children = [];
			};

            /**
             * Renders a wrapper element (by default a 'widgetjs-widget' tag) and
             * set the element ID to the ID of the widget so that it can be found by
             * 'asJQuery' eg. when we re-render using 'update'.
             *
             * @param html
             * @returns {htmlBrush}
             */
            my.renderRootOn = function (html) {
                return html.tag('widgetjs-widget').id(id);
            };

            /**
             * Overridden in concrete widgets to render widget to canvas/DOM.
             *
             * @example
             *
             *      that.renderContentOn = function (html) {
             *          html.ul(
             *              html.li('BMW'),
             *              html.li('Toyota')
             *          );
             *      };
             *
             * @param {htmlCanvas} html
             */
            that.renderContentOn = function (html) {};

            /**
             * Re-renders the widget and replace it in the DOM
             *
             * Content is first re-rendered on a document fragment. Update then replace the element matched
             * by 'asJQuery' with the new content.
             *
             */
            that.update = function () {
                if (inUpdateTransaction || !that.isRendered()) {
                    return;
                }

                // Re-render
                var html = htmlCanvas();
                that.renderOn(html);

                // Replace our self
                that.asJQuery().replaceWith(html.root.element);
            };

            /**
             * Evaluate `fn`, ensuring that an update will be
             * performed after evaluating the function. Nested calls
             * to `withUpdate` or `update` will result in updating the
             * widget only once.
             */
            that.withUpdate = function(fn) {
                if(inUpdateTransaction) {
                    fn();
                } else {
                    try {
                        inUpdateTransaction = true;
                        fn();
                    }
                    finally {
                        inUpdateTransaction = false;
                        that.update();
                    }
                }
            };

            // Third party protected extensions** added to `my`.
            // See widget-extensions.js
            for (var extProperty in ext) {
                if (ext.hasOwnProperty(extProperty)) {
                    my[extProperty] = ext[extProperty];
                }
            }

            return that;
        };

		var currentWidget;

        /**
         * Creates unique ids used by widgets to identify their root div.
         */
        var idGenerator = (function () {
            var that = {};
            var id = 0;

            that.newId = function () {
                id += 1;
                return id.toString();
            };

            return that;
        })();

        return widget;
    }
);
<|endoftext|>


<commit_before>import _ from 'lodash';
import React, { Component } from 'react';
import { Text, View, Alert, TextInput, Linking, ListView } from 'react-native';
import SubmitButton from 'react-native-submit-button';
import Toast from 'react-native-simple-toast';
import { TextButton, RaisedTextButton } from 'react-native-material-buttons';
import { Button, Icon } from 'react-native-elements';
import firebase from 'firebase';
import Bglistitem from './Bglistitem.js';

class BgList extends Component {

    constructor(props) {
        super(props);
        let ds = new ListView.DataSource({
            rowHasChanged: (row1, row2) => row1 !== row2
        });
        this.state = {
            dataSource: ds
        };
        const { currentUser } = firebase.auth();
        this.itemsRef = firebase.database().ref(`/users/${currentUser.uid}/Bglst`);

    }
    getitems(itemsRef) {
        itemsRef.on('value', snap => {
            let items = [];
            //  //console.log(snap.val());
            snap.forEach((bg) => {
                //  //console.log(bg);
                items.push({
                    bgVal: bg.val().BG.bgVal,
                    carbsAm: bg.val().BG.carbsAm,
                    desc: bg.val().BG.desc,
                    imgsrc: bg.val().BG.imgsrc,
                    insUn: bg.val().BG.insUn,
                    _key: bg.key
                })
            });
            // //console.log('items');
            //console.log(items);
            this.setState({ dataSource: this.state.dataSource.cloneWithRows(items) });
        });
    }

    componentDidMount() {
        this.getitems(this.itemsRef);
    }
    componentWillMount() {
        this.getitems(this.itemsRef);
    }

    renderBG(self) {
        //console.log("self.state.bglst");
        //console.log(self.state.bglst);
        // return <Bglistitem BG={BG} />
        if (self.state.bglst) {
            return (

                self.state.bglst.map(bg => {
                    //console.log(bg);
                    <Bglistitem BG={bg} />
                }
                ));
        }
    }

    renderItem(item) {
       // console.log('item');
       // console.log(item);
        return (
            <View>
                <Bglistitem BG={item} />
            </View>

        );
    }

    render() {
        return (
            <View>
                <ListView
                    dataSource={this.state.dataSource}
                    renderRow={this.renderItem.bind(this)}
                    style={styles.listview} />
            </View>

        );

    }

}
export default BgList;

const styles = {

    viewStyle:
    {
        backgroundColor: '#ccffd1',
        justifyContent: 'center',
        alignItems: 'center',
        height: 70,
        elevation: 5,
        position: 'relative'
    },
    textStyle:
    {
        fontSize: 40
    },

    buttonStyle:
    {

        alignItems: 'left',
    },

};
<commit_msg>scrolling fixed<commit_after>import _ from 'lodash';
import React, { Component } from 'react';
import { Text, View, Alert, TextInput, Linking, ListView } from 'react-native';
import SubmitButton from 'react-native-submit-button';
import Toast from 'react-native-simple-toast';
import { TextButton, RaisedTextButton } from 'react-native-material-buttons';
import { Button, Icon } from 'react-native-elements';
import firebase from 'firebase';
import Bglistitem from './Bglistitem.js';

class BgList extends Component {

    constructor(props) {
        super(props);
        let ds = new ListView.DataSource({
            rowHasChanged: (row1, row2) => row1 !== row2
        });
        this.state = {
            dataSource: ds
        };
        const { currentUser } = firebase.auth();
        this.itemsRef = firebase.database().ref(`/users/${currentUser.uid}/Bglst`);

    }
    getitems(itemsRef) {
        itemsRef.on('value', snap => {
            let items = [];
            //  //console.log(snap.val());
            snap.forEach((bg) => {
                //  //console.log(bg);
                items.push({
                    bgVal: bg.val().BG.bgVal,
                    carbsAm: bg.val().BG.carbsAm,
                    desc: bg.val().BG.desc,
                    imgsrc: bg.val().BG.imgsrc,
                    insUn: bg.val().BG.insUn,
                    _key: bg.key
                })
            });
            // //console.log('items');
            //console.log(items);
            this.setState({ dataSource: this.state.dataSource.cloneWithRows(items) });
        });
    }

    componentDidMount() {
        this.getitems(this.itemsRef);
    }
    componentWillMount() {
        this.getitems(this.itemsRef);
    }

    renderBG(self) {
        //console.log("self.state.bglst");
        //console.log(self.state.bglst);
        // return <Bglistitem BG={BG} />
        if (self.state.bglst) {
            return (

                self.state.bglst.map(bg => {
                    //console.log(bg);
                    <Bglistitem BG={bg} />
                }
                ));
        }
    }

    renderItem(item) {
        // console.log('item');
        // console.log(item);
        return (
            <View>
                <Bglistitem BG={item} />
            </View>

        );
    }

    render() {
        return (
            <View style={styles.viewStyle}>
                <ListView
                    enableEmptySections
                    scrollEnabled={true}
                    dataSource={this.state.dataSource}
                    renderRow={this.renderItem.bind(this)}
                    style={styles.listview} />
            </View>

        );

    }

}
export default BgList;

const styles = {

    viewStyle:
    {

        justifyContent: 'center',
        alignItems: 'center',
        elevation: 1

    },
    listview:
    {
        height: 630
    },
    textStyle:
    {
        fontSize: 40
    },

    buttonStyle:
    {

        alignItems: 'left',
    },

};
<|endoftext|>


<commit_before>/* Require hooks for server-side */

const sass = require("node-sass");

const postcssConfig = require("../../postcss.config");

module.exports = () => {
  // CSS modules
  require("@dr.pogodin/css-modules-require-hook")({
    // Must use the same pattern with your webpack config
    generateScopedName: __DEV__ ? "[path][name]__[local]" : "[hash:base64]",
    extensions: [".css", ".scss", ".sass"],
    prepend: [...postcssConfig.plugins],
    preprocessCss: (data, filename) =>
      sass.renderSync({ data, file: filename }).css,
    devMode: __DEV__,
  });

  // Images
  require("asset-require-hook")({
    // Must use the same option with webpack's configuration
    extensions: ["gif", "jpg", "jpeg", "png", "webp", "svg"],
    publicPath: "/assets/",
    limit: 8 * 1024, // Sync with the default setting of "asset" type
  });

  // Fonts
  require("asset-require-hook")({
    // Must use the same option with webpack's configuration
    extensions: ["woff", "woff2", "ttf", "otf", "eot"],
    publicPath: "/assets/",
  });
};
<commit_msg>Refactor: adjust comment<commit_after>/* Require hooks for server-side */

const sass = require("node-sass");

const postcssConfig = require("../../postcss.config");

module.exports = () => {
  // CSS modules
  require("@dr.pogodin/css-modules-require-hook")({
    // Must use the same pattern with your webpack config
    generateScopedName: __DEV__ ? "[path][name]__[local]" : "[hash:base64]",
    extensions: [".css", ".scss", ".sass"],
    prepend: [...postcssConfig.plugins],
    preprocessCss: (data, filename) =>
      sass.renderSync({ data, file: filename }).css,
    devMode: __DEV__,
  });

  // Images
  require("asset-require-hook")({
    // Must use the same option with webpack's configuration
    extensions: ["gif", "jpg", "jpeg", "png", "webp", "svg"],
    publicPath: "/assets/",
    limit: 8 * 1024, // Sync with wepack's asset modules
  });

  // Fonts
  require("asset-require-hook")({
    // Must use the same option with webpack's configuration
    extensions: ["woff", "woff2", "ttf", "otf", "eot"],
    publicPath: "/assets/",
  });
};
<|endoftext|>


<commit_before>import Debug from 'debug';
import intree from './intree';
import taskcluster from 'taskcluster-client';
import slugid from 'slugid';
import yaml from 'js-yaml';
import _ from 'lodash';

let debug = Debug('taskcluster-github');
let worker = module.exports = {};

const INSPECTOR_URL = 'https://tools.taskcluster.net/task-graph-inspector/#';

/**
 * If a .taskcluster.yml exists, attempt to turn it into a taskcluster
 * graph config, and submit it to the scheduler.
 **/
worker.webHookHandler = async function(message, context) {
  // We must attempt to convert the sanitized fields back to normal here.
  // Further discussion of how to deal with this cleanly is in
  // https://github.com/taskcluster/taskcluster-github/issues/52
  let organization = message.payload.organization.replace(/%/g, '.');
  let repository = message.payload.repository.replace(/%/g, '.');

  debug('handling webhook: ', message);
  let repoconf = undefined;

  // Try to fetch a .taskcluster.yml file for every request
  try {
    let tcyml = await context.github.repos.getContent({
      user: organization,
      repo: repository,
      path: '.taskcluster.yml',
      ref: message.payload.details['event.head.sha'],
    });
    repoconf = new Buffer(tcyml.content, 'base64').toString();
  } catch (e) {
    if (e.code === 404) {
      debug(`${organization}/${repository} has no '.taskcluster.yml'. Skipping.`);
      return;
    }
    if (_.endsWith(e.message, '\n\n') && e.message.length > 10000) {
      // We kept getting full html 500/400 pages from github in the logs.
      // I consider this to be a hard-to-fix bug in octokat, so let's make
      // the logs usable for now and try to fix this later. It's a relatively
      // rare occurence.
      debug('Detected an extremeley long error. Truncating!');
      e.message = _.join(_.take(e.message, 100).concat('...'), '');
      e.stack = e.stack.split('\n\n')[1] || e.stack;
    }
    throw e;
  }

  // Check if this is meant to be built by tc-github at all.
  // This is a bit of a hack, but is needed for bug 1274077 for now
  let c = yaml.safeLoad(repoconf);
  c.tasks = (c.tasks || []).filter((task) => _.has(task, 'extra.github'));
  if (c.tasks.length === 0) {
    debug('Skipping tasks because no task with "extra.github" exists!');
    debug(`Repository: ${organization}/${repository}`);
    return;
  }

  // Decide if a user has permissions to run tasks.
  let login = message.payload.details['event.head.user.login'];
  let isCollaborator = false;

  if (login === organization) {
    isCollaborator = true;
  }

  if (!isCollaborator) {
    // If the user is in the org, we consider them
    // qualified to trigger any job in that org.
    try {
      github.orgs.checkMembership({
        org: organization,
        user: login,
      });
      isCollaborator = true;
    } catch (e) {
      if (e.code == 404) {
        // Only a 404 error means the user isn't a member
        // anything else should just throw like normal
      } else {
        throw e;
      }
    }
  }

  if (!isCollaborator) {
    // GithubAPI's collaborator check returns an error if a user isn't
    // listed as a collaborator.
    try {
      await context.github.repos.checkCollaborator({
        user: organization,
        repo: repository,
        collabuser: login,
      });
      // No error, the user is a collaborator
      isCollaborator = true;
    } catch (e) {
      if (e.code == 404) {
        // Only a 404 error means the user isn't a collaborator
        // anything else should just throw like normal
      } else {
        throw e;
      }
    }
  }

  // If all of the collaborator checks fail, we should post to the commit
  // and ignore the request
  if (!isCollaborator) {
    let msg = `@${login} does not have permission to trigger tasks.`;
    debug(`${login} does not have permissions for ${organization}/${repository}. Skipping.`);
    await context.github.repos.createCommitComment({
      user: organization,
      repo: repository,
      sha: message.payload.details['event.head.sha'],
      body: 'TaskCluster: ' + msg,
    });
  }

  // Now we can try processing the config and kicking off a task.
  try {
    let graphConfig = intree({
      config: repoconf,
      payload: message.payload,
      validator: context.validator,
      schema: 'http://schemas.taskcluster.net/github/v1/taskcluster-github-config.json#',
    });
    if (graphConfig.tasks.length) {
      let graph = await context.scheduler.createTaskGraph(slugid.nice(), graphConfig);
      // On pushes, leave a comment on the commit
      if (message.payload.details['event.type'] == 'push') {
        await context.github.repos.createCommitComment({
          user: organization,
          repo: repository,
          sha: message.payload.details['event.head.sha'],
          body: 'TaskCluster: ' + INSPECTOR_URL + graph.status.taskGraphId + '/',
        });
      }
    } else {
      debug('intree config compiled with zero tasks. Skipping');
    }
  } catch (e) {
    let errorMessage = e.message;
    let errorBody = e.errors || e.body.error;
    // Let's prettify any objects
    if (typeof errorBody == 'object') {
      errorBody = JSON.stringify(errorBody, null, 4);
    }
    // Warn the user know that there was a problem processing their
    // config file with a comment.
    await context.github.repos.createCommitComment({
      user: organization,
      repo: repository,
      sha: message.payload.details['event.head.sha'],
      body: 'Submitting the task to TaskCluster failed. ' + errorMessage
      + 'Details:\n\n```js\n' +  errorBody + '\n```',
    });
    throw e;
  }
};

/**
 * Post updates to GitHub, when the status of a task changes.
 * TaskCluster States: http://docs.taskcluster.net/queue/exchanges/
 * GitHub Statuses: https://developer.github.com/v3/repos/statuses/
 **/
worker.graphStateChangeHandler = async function(message, context) {
  let statusMapping = {
    running:  'pending',
    blocked:  'failure',
    finished: 'success',
  };
  debug('handling state change for message: ', message);
  let route = message.routes[0].split('.');
  try {
    await context.github.repos.createStatus({
      user: route[0],
      repo: route[1],
      sha: route[2],
      state:        StatusMapping[message.payload.status.state],
      target_url:   INSPECTOR_URL + message.payload.status.taskGraphId + '/',
      description:  'TaskGraph: ' + message.payload.status.state,
      context:      'Taskcluster',
    });
  } catch (e) {
    debug(`Failed to update status: ${route[0]}/${route[1]}@${route[2]}`);
    throw e;
  }
};

<commit_msg>Wow we need some more test coverage in this service<commit_after>import Debug from 'debug';
import intree from './intree';
import taskcluster from 'taskcluster-client';
import slugid from 'slugid';
import yaml from 'js-yaml';
import _ from 'lodash';

let debug = Debug('taskcluster-github');
let worker = module.exports = {};

const INSPECTOR_URL = 'https://tools.taskcluster.net/task-graph-inspector/#';

/**
 * If a .taskcluster.yml exists, attempt to turn it into a taskcluster
 * graph config, and submit it to the scheduler.
 **/
worker.webHookHandler = async function(message, context) {
  // We must attempt to convert the sanitized fields back to normal here.
  // Further discussion of how to deal with this cleanly is in
  // https://github.com/taskcluster/taskcluster-github/issues/52
  let organization = message.payload.organization.replace(/%/g, '.');
  let repository = message.payload.repository.replace(/%/g, '.');

  debug('handling webhook: ', message);
  let repoconf = undefined;

  // Try to fetch a .taskcluster.yml file for every request
  try {
    let tcyml = await context.github.repos.getContent({
      user: organization,
      repo: repository,
      path: '.taskcluster.yml',
      ref: message.payload.details['event.head.sha'],
    });
    repoconf = new Buffer(tcyml.content, 'base64').toString();
  } catch (e) {
    if (e.code === 404) {
      debug(`${organization}/${repository} has no '.taskcluster.yml'. Skipping.`);
      return;
    }
    if (_.endsWith(e.message, '\n\n') && e.message.length > 10000) {
      // We kept getting full html 500/400 pages from github in the logs.
      // I consider this to be a hard-to-fix bug in octokat, so let's make
      // the logs usable for now and try to fix this later. It's a relatively
      // rare occurence.
      debug('Detected an extremeley long error. Truncating!');
      e.message = _.join(_.take(e.message, 100).concat('...'), '');
      e.stack = e.stack.split('\n\n')[1] || e.stack;
    }
    throw e;
  }

  // Check if this is meant to be built by tc-github at all.
  // This is a bit of a hack, but is needed for bug 1274077 for now
  let c = yaml.safeLoad(repoconf);
  c.tasks = (c.tasks || []).filter((task) => _.has(task, 'extra.github'));
  if (c.tasks.length === 0) {
    debug('Skipping tasks because no task with "extra.github" exists!');
    debug(`Repository: ${organization}/${repository}`);
    return;
  }

  // Decide if a user has permissions to run tasks.
  let login = message.payload.details['event.head.user.login'];
  let isCollaborator = false;

  if (login === organization) {
    isCollaborator = true;
  }

  if (!isCollaborator) {
    // If the user is in the org, we consider them
    // qualified to trigger any job in that org.
    try {
      context.github.orgs.checkMembership({
        org: organization,
        user: login,
      });
      isCollaborator = true;
    } catch (e) {
      if (e.code == 404) {
        // Only a 404 error means the user isn't a member
        // anything else should just throw like normal
      } else {
        throw e;
      }
    }
  }

  if (!isCollaborator) {
    // GithubAPI's collaborator check returns an error if a user isn't
    // listed as a collaborator.
    try {
      await context.github.repos.checkCollaborator({
        user: organization,
        repo: repository,
        collabuser: login,
      });
      // No error, the user is a collaborator
      isCollaborator = true;
    } catch (e) {
      if (e.code == 404) {
        // Only a 404 error means the user isn't a collaborator
        // anything else should just throw like normal
      } else {
        throw e;
      }
    }
  }

  // If all of the collaborator checks fail, we should post to the commit
  // and ignore the request
  if (!isCollaborator) {
    let msg = `@${login} does not have permission to trigger tasks.`;
    debug(`${login} does not have permissions for ${organization}/${repository}. Skipping.`);
    await context.github.repos.createCommitComment({
      user: organization,
      repo: repository,
      sha: message.payload.details['event.head.sha'],
      body: 'TaskCluster: ' + msg,
    });
  }

  // Now we can try processing the config and kicking off a task.
  try {
    let graphConfig = intree({
      config: repoconf,
      payload: message.payload,
      validator: context.validator,
      schema: 'http://schemas.taskcluster.net/github/v1/taskcluster-github-config.json#',
    });
    if (graphConfig.tasks.length) {
      let graph = await context.scheduler.createTaskGraph(slugid.nice(), graphConfig);
      // On pushes, leave a comment on the commit
      if (message.payload.details['event.type'] == 'push') {
        await context.github.repos.createCommitComment({
          user: organization,
          repo: repository,
          sha: message.payload.details['event.head.sha'],
          body: 'TaskCluster: ' + INSPECTOR_URL + graph.status.taskGraphId + '/',
        });
      }
    } else {
      debug('intree config compiled with zero tasks. Skipping');
    }
  } catch (e) {
    let errorMessage = e.message;
    let errorBody = e.errors || e.body.error;
    // Let's prettify any objects
    if (typeof errorBody == 'object') {
      errorBody = JSON.stringify(errorBody, null, 4);
    }
    // Warn the user know that there was a problem processing their
    // config file with a comment.
    await context.github.repos.createCommitComment({
      user: organization,
      repo: repository,
      sha: message.payload.details['event.head.sha'],
      body: 'Submitting the task to TaskCluster failed. ' + errorMessage
      + 'Details:\n\n```js\n' +  errorBody + '\n```',
    });
    throw e;
  }
};

/**
 * Post updates to GitHub, when the status of a task changes.
 * TaskCluster States: http://docs.taskcluster.net/queue/exchanges/
 * GitHub Statuses: https://developer.github.com/v3/repos/statuses/
 **/
worker.graphStateChangeHandler = async function(message, context) {
  let statusMapping = {
    running:  'pending',
    blocked:  'failure',
    finished: 'success',
  };
  debug('handling state change for message: ', message);
  let route = message.routes[0].split('.');
  try {
    await context.github.repos.createStatus({
      user: route[0],
      repo: route[1],
      sha: route[2],
      state:        statusMapping[message.payload.status.state],
      target_url:   INSPECTOR_URL + message.payload.status.taskGraphId + '/',
      description:  'TaskGraph: ' + message.payload.status.state,
      context:      'Taskcluster',
    });
  } catch (e) {
    debug(`Failed to update status: ${route[0]}/${route[1]}@${route[2]}`);
    throw e;
  }
};

<|endoftext|>