<commit_before>if (jQuery && saveAs) {
    (function($) {
        $.fn.wordExport = function(fileName) {
            var static = {
                mhtml: {
                    top: "Mime-Version: 1.0\nContent-Base: " + location.href + "\nContent-Type: Multipart/related; boundary=\"NEXT.ITEM-BOUNDARY\";type=\"text/html\"\n\n--NEXT.ITEM-BOUNDARY\nContent-Type: text/html; charset=\"utf-8\"\nContent-Location: " + location.href + "\n\n<!DOCTYPE html>\n\n_html_",
                    head: "\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n\n\n",
                    body: "_body_"
                }
            };
            var options = {
                maxWidth: 624
            };
            // Clone selected element before manipulating it
            var markup = $(this).clone();

            // Remove hidden elements from the output
            markup.each(function() {
                var self = $(this);
                if (self.is(':hidden'))
                    self.remove();
            });

            // Embed all images using Data URLs
            var images = Array();
            var img = markup.find('img');
            for (var i = 0; i < img.length; i++) {
                // Calculate dimensions of output image
                var w = Math.min(img[i].width, options.maxWidth);
                var h = img[i].height * (w / img[i].width);
                // Create canvas for converting image to data URL
                $('<canvas>').attr("id", "jQuery-Word-export_img_" + i).width(w).height(h).insertAfter(img[i]);
                var canvas = document.getElementById("jQuery-Word-export_img_" + i);
                canvas.width = w;
                canvas.height = h;
                // Draw image to canvas
                var context = canvas.getContext('2d');
                context.drawImage(img[i], 0, 0, w, h);
                // Get data URL encoding of image
                var uri = canvas.toDataURL();
                $(img[i]).attr("src", img[i].src);
                img[i].width = w;
                img[i].height = h;
                // Save encoded image to array
                images[i] = {
                    type: uri.substring(uri.indexOf(":") + 1, uri.indexOf(";")),
                    encoding: uri.substring(uri.indexOf(";") + 1, uri.indexOf(",")),
                    location: $(img[i]).attr("src"),
                    data: uri.substring(uri.indexOf(",") + 1)
                };
                // Remove canvas now that we no longer need it
                canvas.parentNode.removeChild(canvas);
            }

            // Prepare bottom of mhtml file with image data
            var mhtmlBottom = "";
            for (var i = 0; i < images.length; i++) {
                mhtmlBottom += "--NEXT.ITEM-BOUNDARY\n";
                mhtmlBottom += "Content-Location: " + images[i].contentLocation + "\n";
                mhtmlBottom += "Content-Type: " + images[i].contentType + "\n";
                mhtmlBottom += "Content-Transfer-Encoding: " + images[i].contentEncoding + "\n\n";
                mhtmlBottom += images[i].contentData + "\n\n";
            }

            //TODO: load css from included stylesheet
            var styles = "";

            // Aggregate parts of the file together
            var fileContent = static.mhtml.top.replace("_html_", static.mhtml.head.replace("_styles_", styles) + static.mhtml.body.replace("_body_", markup.html())) + mhtmlBottom;
            mhtmlBottom += "--NEXT.ITEM-BOUNDARY--";

            // Create a Blob with the file contents
            var blob = new Blob([content], {
                type: "application/msword;charset=utf-8"
            });
            saveAs(blob, fileName + ".doc");
        };
    })(jQuery);
} else {
    if (!jQuery) {
        console.error("jQuery Word Export: missing dependency (jQuery)");
    }
    if (!saveAs) {
        console.error("jQuery Word Export: missing dependency (FileSaver.js)");
    };
}
<commit_msg>Update jquery.wordexport.js<commit_after>if (typeof jQuery !== "undefined" && typeof saveAs !== "undefined") {
    (function($) {
        $.fn.wordExport = function(fileName) {
            fileName = typeof fileName !== 'undefined' ? fileName : "jQuery-Word-Export";
            var static = {
                mhtml: {
                    top: "Mime-Version: 1.0\nContent-Base: " + location.href + "\nContent-Type: Multipart/related; boundary=\"NEXT.ITEM-BOUNDARY\";type=\"text/html\"\n\n--NEXT.ITEM-BOUNDARY\nContent-Type: text/html; charset=\"utf-8\"\nContent-Location: " + location.href + "\n\n<!DOCTYPE html>\n\n_html_",
                    head: "\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n\n\n",
                    body: "_body_"
                }
            };
            var options = {
                maxWidth: 624
            };
            // Clone selected element before manipulating it
            var markup = $(this).clone();

            // Remove hidden elements from the output
            markup.each(function() {
                var self = $(this);
                if (self.is(':hidden'))
                    self.remove();
            });

            // Embed all images using Data URLs
            var images = Array();
            var img = markup.find('img');
            for (var i = 0; i < img.length; i++) {
                // Calculate dimensions of output image
                var w = Math.min(img[i].width, options.maxWidth);
                var h = img[i].height * (w / img[i].width);
                // Create canvas for converting image to data URL
                $('<canvas>').attr("id", "jQuery-Word-export_img_" + i).width(w).height(h).insertAfter(img[i]);
                var canvas = document.getElementById("jQuery-Word-export_img_" + i);
                canvas.width = w;
                canvas.height = h;
                // Draw image to canvas
                var context = canvas.getContext('2d');
                context.drawImage(img[i], 0, 0, w, h);
                // Get data URL encoding of image
                var uri = canvas.toDataURL();
                $(img[i]).attr("src", img[i].src);
                img[i].width = w;
                img[i].height = h;
                // Save encoded image to array
                images[i] = {
                    type: uri.substring(uri.indexOf(":") + 1, uri.indexOf(";")),
                    encoding: uri.substring(uri.indexOf(";") + 1, uri.indexOf(",")),
                    location: $(img[i]).attr("src"),
                    data: uri.substring(uri.indexOf(",") + 1)
                };
                // Remove canvas now that we no longer need it
                canvas.parentNode.removeChild(canvas);
            }

            // Prepare bottom of mhtml file with image data
            var mhtmlBottom = "\n";
            for (var i = 0; i < images.length; i++) {
                mhtmlBottom += "--NEXT.ITEM-BOUNDARY\n";
                mhtmlBottom += "Content-Location: " + images[i].contentLocation + "\n";
                mhtmlBottom += "Content-Type: " + images[i].contentType + "\n";
                mhtmlBottom += "Content-Transfer-Encoding: " + images[i].contentEncoding + "\n\n";
                mhtmlBottom += images[i].contentData + "\n\n";
            }
            mhtmlBottom += "--NEXT.ITEM-BOUNDARY--";

            //TODO: load css from included stylesheet
            var styles = "";

            // Aggregate parts of the file together
            var fileContent = static.mhtml.top.replace("_html_", static.mhtml.head.replace("_styles_", styles) + static.mhtml.body.replace("_body_", markup.html())) + mhtmlBottom;

            // Create a Blob with the file contents
            var blob = new Blob([fileContent], {
                type: "application/msword;charset=utf-8"
            });
            saveAs(blob, fileName + ".doc");
        };
    })(jQuery);
} else {
    if (typeof jQuery === "undefined") {
        console.error("jQuery Word Export: missing dependency (jQuery)");
    }
    if (typeof saveAs === "undefined") {
        console.error("jQuery Word Export: missing dependency (FileSaver.js)");
    };
}
<|endoftext|>


<commit_before>paper.install(window);

var paperFunctions = {

    setupCanvasWithPaper : function(canvas) {

		// Create an empty project and a view for the canvas:
		paper.setup(canvas);

		var rect = new Rectangle(new Point(0, 0), new Point(paper.view.size.width, paper.view.size.height));
		var rectPath = new Path.Rectangle(rect);
		rectPath.fillColor = 'yellow';

        //draw vertical lines
        var i;
        var line;
        for (i = 0; i < paper.view.size.width; i=i+25) {
            segments = [new Point(i, 0), new Point(i, paper.view.size.height)];
            var path = new Path(segments);
            path.strokeColor = strokeStyle(i);
        }

        //Horizontal lines
        for (i = 0; i < paper.view.size.height; i=i+25) {
            segments = [new Point(0, i), new Point(paper.view.size.width, i)];
            var path = new Path(segments);
            path.strokeColor = strokeStyle(i);
        }

        function strokeStyle(coord){
            if (coord % 100) return 'grey';
            else return 'black';
        };

		//Tool stuff
		var tool = new Tool();

		//Path stuff
		var path;

		tool.onMouseDown = function(event) {
            //Don't draw while zooming
            if (hammer.pinch) return;
            fingerDown = true;
			path = new Path();
			path.strokeColor = 'blue';
			console.log("MouseDown coords: " + event.point);
			path.add(event.point);
		}

		tool.onMouseDrag = function(event) {
            if (hammer.pinch) return;
			console.log("MouseDrag coords: " + event.point);
			path.add(event.point);
		}

		tool.onMouseUp = function(event) {
			console.log("MouseUp coords: " + event.point);
			path.simplify(5);
            //Assist with scaling from hammer
            hammer.pinch = false;
            hammer.prevScale = hammer.curScale;
            //Assist with panning from hammer
            hammer.prevCenterPoint = hammer.curCenterPoint;

		}

		paper.view.draw();

    }
}
<commit_msg>Increased strokeWidth for better visual exp<commit_after>paper.install(window);

var paperFunctions = {

    setupCanvasWithPaper : function(canvas) {

		// Create an empty project and a view for the canvas:
		paper.setup(canvas);

		var rect = new Rectangle(new Point(0, 0), new Point(paper.view.size.width, paper.view.size.height));
		var rectPath = new Path.Rectangle(rect);
		rectPath.fillColor = 'yellow';

        //draw vertical lines
        var i;
        var line;
        for (i = 0; i < paper.view.size.width; i=i+25) {
            segments = [new Point(i, 0), new Point(i, paper.view.size.height)];
            var path = new Path(segments);
            path.strokeColor = strokeStyle(i);
        }

        //Horizontal lines
        for (i = 0; i < paper.view.size.height; i=i+25) {
            segments = [new Point(0, i), new Point(paper.view.size.width, i)];
            var path = new Path(segments);
            path.strokeColor = strokeStyle(i);
        }

        function strokeStyle(coord){
            if (coord % 100) return 'grey';
            else return 'black';
        };

		//Tool stuff
		var tool = new Tool();

		//Path stuff
		var path;

		tool.onMouseDown = function(event) {
            //Don't draw while zooming
            if (hammer.pinch) return;
            fingerDown = true;
			path = new Path();
			path.strokeColor = 'blue';
            path.strokeWidth = 3;
			path.add(event.point);
		}

		tool.onMouseDrag = function(event) {
            if (hammer.pinch) return;
			path.add(event.point);
		}

		tool.onMouseUp = function(event) {
			path.simplify(5);
            //Assist with scaling from hammer
            hammer.pinch = false;
            hammer.prevScale = hammer.curScale;
            //Assist with panning from hammer
            hammer.prevCenterPoint = hammer.curCenterPoint;

		}

		paper.view.draw();

    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/**
 * @author mig <michel.gutierrez@gmail.com>
 * @version 0.1
 * @module jaingee
 * @overview Javascript UI/Layout application framework.
 */

(function($) {

	'use strict';

	angular.module('com.jocly.jaingee.layout', [])

	/**
	 * jngLayout service
	 */
	.service('jngLayout', [ '$rootScope', '$window', '$document', function($rootScope, $window, $document) {
		var self = this;

		/**
		 * Walk through DOM descendants to invoke callback on jngLayout-managed element
		 */
	    function WalkDescendants(element,callback) {
			if(element.attr("jng-layout"))
				callback(element);
			else
				angular.forEach(element.children(),function(child) {
					WalkDescendants(angular.element(child),callback);
				});
	    }

	    /**
	     * Request relayout on descendants
	     */
	    function Layout() {
        	WalkDescendants(angular.element($document[0].body),function(element) {
        		if(element.scope().hasOwnProperty("jngRequestLayout"))
        			element.scope().jngRequestLayout();
        		else
        			console.log(element.attr("id"),"has no jngRequestLayout",element.scope())
        	});
	    }

		var w = angular.element($window);

		$rootScope.jngLayout={
	        getWindowDimensions : function () {
	            return { 'h': $window.innerHeight, 'w': $window.innerWidth };
	        },
	        layout: Layout,
	        anim: 400,
		}

		this.watchWindowDimensions = function(callback) {
        	$rootScope.$watch($rootScope.jngLayout.getWindowDimensions, function(newDim, oldDim) {
        		callback(newDim,oldDim);
        	},true);
        }

        this.watchWindowDimensions(function () {
        	Layout();
        });

        this.layout=Layout;

		$rootScope.$on("$viewContentLoaded",function() {
			Layout();
		});

        w.bind('resize', function () {
        	if(!$rootScope.$$phase)
        		$rootScope.$apply();
        });

	} ])

	/**
	 * jngLayout directive
	 *
	 * an element using the jngLayout directive (having a jng-layout attribute), organised its children size and position vertically or horizontally
	 */
	.directive('jngLayout',
			[ '$rootScope','$timeout','jngLayout', function factory($rootScope,$timeout,jngLayout) {
		return {
			priority: 10,
			scope: true,
	    	link: function(scope,element,attrs) {
				var jqElement=$(element[0]);
			    var requestedLayout=false;
			    var requestLayoutCount;
			    var requestLayoutDelay=10;
			    var elementDimension;

				/**
			     * Evaluate children size description
			     */
				function GetSizeDesc(jngSize) {
					var m=/^([0-9]+)$/.exec(jngSize);
					if(m)
						return {
							weight: parseInt(m[1]),
						}
					m=/^([0-9]+)px$/.exec(jngSize);
					if(m)
						return {
							pixels: parseInt(m[1]),
						}
					return scope.$eval(jngSize);
				}

				/**
				 * Go through DOM descendants to invoke callback on jngLayout-managed elements
				 */
			    function WalkDescendants(element,callback) {
					angular.forEach(element.children(),function(child) {
						var childElem=angular.element(child);
						if(callback(childElem))
							WalkDescendants(childElem,callback);
					});
			    }

			    /**
			     * Request a new layout. The action is not performed immediately to perform only one relayout if several are requested within a short period of time.
			     */
			    function RequestLayout(element) {
		    		function DecrementRequestCount() {
		    			requestLayoutCount--;
			    		$timeout(function() {
			    			if(requestLayoutCount==0) {
			    				requestedLayout=false;
			    				DoLayout(element);
			    			} else
			    				DecrementRequestCount();
			    		},0);
		    		}
			    	requestLayoutCount=requestLayoutDelay;
			    	if(requestedLayout==false) {
			    		requestedLayout=true;
			    		DecrementRequestCount();
			    	}
			    }

			    /**
			     * Perform a new layout calculation on the current element.
			     */
			    function DoLayout(element) {

			    	//console.log("DoLayout",element.attr("id"));

			    	var children=[];

			    	/**
			    	 * Order jngLayout children indexes to get lower priority children first.
			    	 */
				    function ChildrenIndexesByPriority() {
				    	var children1=[];
			    		for(var i=0;i<children.length;i++)
			    			if(children[i].sizeDesc.keep)
			    				children1.push(i);
			    		children1.sort(function(i1,i2) {
			    			var child1=children[i1];
			    			var child2=children[i2];
			    			var fit1=(child1.sizeDesc.pixels!==undefined && child1.sizeDesc.pixels<=elementSize) ||
			    				(child1.sizeDesc.pixels===undefined && child1.sizeDesc.min<=elementSize);
			    			var fit2=(child2.sizeDesc.pixels!==undefined && child2.sizeDesc.pixels<=elementSize) ||
		    					(child2.sizeDesc.pixels===undefined && child2.sizeDesc.min<=elementSize);
			    			if(fit1 && !fit2)
			    				return 1;
			    			else if(fit2 && !fit1)
			    				return -1;
			    			else
			    				return child1.sizeDesc.priority-child2.sizeDesc.priority;
			    		});
			    		return children1;
				    }

					var dimension;
					if(scope.hasOwnProperty("jngSize") && scope.jngSize.width>=0) {
						dimension={
							width: scope.jngSize.width,
							height: scope.jngSize.height,
						}
					} else {
						dimension={
								width: element[0].clientWidth,
								height: element[0].clientHeight,
							};
						var m=/^(.*)px$/.exec(element.css("width"));
						if(m)
							dimension.width=parseInt(m[1]);
						m=/^(.*)px$/.exec(element.css("height"));
						if(m)
							dimension.height=parseInt(m[1]);
					}

					var padding={
						top: parseInt(jqElement.css("padding-top")),
						bottom: parseInt(jqElement.css("padding-bottom")),
						left: parseInt(jqElement.css("padding-left")),
						right: parseInt(jqElement.css("padding-right")),
					}

					dimension.width-=padding.left+padding.right;
					dimension.height-=padding.top+padding.bottom;

					switch(element.css("position")) {
					case "relative":
					case "absolute":
						break;
					default:
						element.css("position","relative");
					}

					// dealing with horizontal/vertical directions with the same algorithm, so css properties indirections are required
					var dirs={
						"vertical": {
							"pos": "top",
							"size": "height",
							"keep": "width",
							"anchor": "left",
						},
						"horizontal": {
							"pos": "left",
							"size": "width",
							"keep": "height",
							"anchor": "top",
						},
					}

					// interpret jng-layout attribute value: 'horizontal' and 'vertical' is expected as direct attribute value or evaluated expression
					var dir; // hold direction (horizontal or vertical) css properties
					var m=/^(horizontal|vertical)$/.exec(attrs.jngLayout);
					if(m)
						dir=dirs[m[1]];
					else
						dir=dirs[scope.$eval(attrs.jngLayout)];

					// collect to-be-resized/moved children elements data
			    	var totalWeight=0, 	// total defined weight
			    		weightMin=0,	// minimum size requested by weight-based children
			    		fixedSize=0;   	// total requested fixed size

			    	angular.forEach(element.children(), function(child) {
						var $child=angular.element(child);
						if(!$child.hasClass("ng-scope"))
							return;
						var childScope=$child.scope();
						if(childScope && childScope.hasOwnProperty("jngSize")) {
							var sd=angular.extend({
				    			priority: 0,
				    			min: 0,
				    			max: Infinity,
				    			keep: true,
				    		},GetSizeDesc(childScope.jngSizeExpr));
							children.push({
								element: $child,
								sizeExpr: childScope.jngSizeExpr,
								sizeDesc: sd,
								size: childScope.jngSize,
							});
				    		if($child.hasClass("ng-leave")) {
				    			sd.keep=false;
				    			return;
				    		}
				    		if($child.attr("ng-show")!==undefined && !scope.$eval($child.attr("ng-show"))) {
				    			sd.keep=false;
				    			return;
				    		}
				    		if(sd.pixels!==undefined)
				    			fixedSize+=sd.pixels;
				    		else if(sd.weight!==undefined) {
				    			totalWeight+=sd.weight;
				    			weightMin+=sd.min;
				    		} else {
				    			console.warn("Element id",$child.attr("id"),"has neither 'pixels' not 'weight' spec",sd);
				    			sd.keep=false;
				    		}
						}
					});

			    	var elementSize=dimension[dir.size]; // container size in the current direction (horizontal/vertical)

			    	// hide children that won't fit in the container
			    	while(fixedSize+weightMin>elementSize) {
			    		var children1=ChildrenIndexesByPriority();
			    		if(children1.length==0) {
			    			//console.warn("Impossible to place any child");
			    			break;
			    		}
			    		var child1=children[children1[0]];
			    		var sd1=child1.sizeDesc;
			    		sd1.keep=false;
			    		if(sd1.pixels!==undefined)
			    			fixedSize-=sd1.pixels;
			    		else {
			    			totalWeight-=sd1.weight;
			    			weightMin-=sd1.min;
			    		}
			    		//console.log("removed element",child1.element.attr("id"),"from layout");
			    	}

			    	// hide weight-based children that cannot realize minimum size
					angular.forEach(ChildrenIndexesByPriority(), function(childIndex) {
						var child=children[childIndex];
						var sd=child.sizeDesc;
						if(sd.keep && sd.pixels===undefined) {
							if((elementSize-fixedSize)*sd.weight/totalWeight<sd.min) {
								sd.keep=false;
								totalWeight-=sd.weight;
							}
						}
					});

					// handle weight-based children that have specified a maximum size
					angular.forEach(children, function(child) {
						var sd=child.sizeDesc;
						if(sd.keep && sd.pixels===undefined) {
							var value=(elementSize-fixedSize)*sd.weight/totalWeight;
							if(value>sd.max) {
								totalWeight-=sd.weight;
								delete sd.weight;
								sd.pixels=sd.max;
								fixedSize+=sd.pixels;
							}
						}
					});

			    	var spare=elementSize-fixedSize; // unrequested size to be distributed over weight-based children

			    	// update children size
					var current=0; // current position
					angular.forEach(children, function(child) {
						var sd=child.sizeDesc;
						var sv=child.size;
						sv[dir.pos]=(current+padding[dir.pos]);
						sv[dir.keep]=dimension[dir.keep];
						sv[dir.anchor]=padding[dir.anchor];

						var value=0;
						if(!sd.keep) {
							value=0;
						} else if(sd.pixels!==undefined)
							value=sd.pixels;
						else {
							value=Math.round(Math.max(Math.min(spare*sd.weight/totalWeight,sd.max),sd.min));
							spare-=value;
							totalWeight-=sd.weight;
						}
						sv[dir.size]=value;

						child.element.scope().setSize(sv);

						current+=value;
					});

					// perform relayout on children
					scope._jngDoLayout=scope.jngDoLayout;
					scope.jngDoLayout=function() {}
			    	WalkDescendants(element,function(elementBelow) {
			    		if(elementBelow.attr("ng-show")===undefined || scope.$eval(elementBelow.attr("ng-show")))
			    			if(typeof elementBelow.scope().jngDoLayout=="function") {
				    			elementBelow.scope().jngDoLayout();
				    			return false;
			    			}
			    		return true;
			    	});
					scope.jngDoLayout=scope._jngDoLayout;
			    }

				// define delayed layout request as a scope function
				scope.jngRequestLayout=function() {
					RequestLayout(element);
				}

				// define immediate layout as a scope function
				scope.jngDoLayout=function() {
						DoLayout(element);
				}

				RequestLayout(element);
			},
		};
	}])

	/**
	 * Directive to specify that the element has scrollable content.
	 */
	.directive('jngScrollable',
			[ function factory() {
		return {
			link: function(scope,element,attrs) {
				element.addClass("jng-scrollable");
			},
		};
	}])

	/**
	 * Directive jngSize (attribute 'jng-size') to create a scope so that the element size is immediately accessible.
	 */
	.directive('jngSize',
			[ '$rootScope', function factory($rootScope) {
		return {
			scope: true,
			priority: 20,
			link: function(scope,element,attrs) {
				scope.jngSize={
					width: 0,
					height: 0,
					top: 0,
					left: 0,
				};
				scope.jngSize0=angular.extend({},scope.jngSize);
				scope.jngSizeExpr=attrs.jngSize;
				scope.$watch('jngSize',function(newSize) {
					scope.setCSS(newSize)
				});
				scope.setCSS=function(size) {
					angular.extend(scope.jngSize0,size);
					var css={
						position: "absolute",
						top: size.top+"px",
						left: size.left+"px",
						width: size.width+"px",
						height: size.height+"px",
					};
					$(element[0]).stop().animate(css,$rootScope.jngLayout.anim)
				}
				scope.setSize=function(newSize) {
					var size0=scope.jngSize0;
					if(newSize.left!=size0.left || newSize.top!=size0.top || newSize.width!=size0.width || newSize.height!=size0.height) {
						angular.extend(scope.jngSize,newSize);
						scope.setCSS(scope.jngSize);
					}
				};
				element.css("position","absolute");
				if(!/^[0-9]+(?:px)?$/.exec(attrs.jngSize))
					scope.$watch(attrs.jngSize,function() {
						if(scope.$parent && scope.$parent.jngRequestLayout)
							scope.$parent.jngRequestLayout();
					},true);
				if(element.attr("ng-show")!==undefined)
					scope.$watch(element.attr("ng-show"),function() {
						if(scope.$parent && scope.$parent.jngRequestLayout)
							scope.$parent.jngRequestLayout();
					});
			},
		};
	}])

})(jQuery);
<commit_msg>Fixed elementBelow not having scope. Added jng-resized handler.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/**
 * @author mig <michel.gutierrez@gmail.com>
 * @version 0.1
 * @module jaingee
 * @overview Javascript UI/Layout application framework.
 */

(function($) {

	'use strict';

	angular.module('com.jocly.jaingee.layout', [])

	/**
	 * jngLayout service
	 */
	.service('jngLayout', [ '$rootScope', '$window', '$document', function($rootScope, $window, $document) {
		var self = this;

		/**
		 * Walk through DOM descendants to invoke callback on jngLayout-managed element
		 */
	    function WalkDescendants(element,callback) {
			if(element.attr("jng-layout"))
				callback(element);
			else
				angular.forEach(element.children(),function(child) {
					WalkDescendants(angular.element(child),callback);
				});
	    }

	    /**
	     * Request relayout on descendants
	     */
	    function Layout() {
        	WalkDescendants(angular.element($document[0].body),function(element) {
        		if(element.scope().hasOwnProperty("jngRequestLayout"))
        			element.scope().jngRequestLayout();
        		else
        			console.log(element.attr("id"),"has no jngRequestLayout",element.scope())
        	});
	    }

		var w = angular.element($window);

		$rootScope.jngLayout={
	        getWindowDimensions : function () {
	            return { 'h': $window.innerHeight, 'w': $window.innerWidth };
	        },
	        layout: Layout,
	        anim: 400,
		}

		this.watchWindowDimensions = function(callback) {
        	$rootScope.$watch($rootScope.jngLayout.getWindowDimensions, function(newDim, oldDim) {
        		callback(newDim,oldDim);
        	},true);
        }

        this.watchWindowDimensions(function () {
        	Layout();
        });

        this.layout=Layout;

		$rootScope.$on("$viewContentLoaded",function() {
			Layout();
		});

        w.bind('resize', function () {
        	if(!$rootScope.$$phase)
        		$rootScope.$apply();
        });

	} ])

	/**
	 * jngLayout directive
	 *
	 * an element using the jngLayout directive (having a jng-layout attribute), organised its children size and position vertically or horizontally
	 */
	.directive('jngLayout',
			[ '$rootScope','$timeout','jngLayout', function factory($rootScope,$timeout,jngLayout) {
		return {
			priority: 10,
			scope: true,
	    	link: function(scope,element,attrs) {
				var jqElement=$(element[0]);
			    var requestedLayout=false;
			    var requestLayoutCount;
			    var requestLayoutDelay=10;
			    var elementDimension;

				/**
			     * Evaluate children size description
			     */
				function GetSizeDesc(jngSize) {
					var m=/^fit$/.exec(jngSize)
					if(m)
						return {
							fit:true,
						}
					m=/^([0-9]+)$/.exec(jngSize);
					if(m)
						return {
							weight: parseInt(m[1]),
						}
					m=/^([0-9]+)px$/.exec(jngSize);
					if(m)
						return {
							pixels: parseInt(m[1]),
						}
					return scope.$eval(jngSize);
				}

				/**
				 * Go through DOM descendants to invoke callback on jngLayout-managed elements
				 */
			    function WalkDescendants(element,callback) {
					angular.forEach(element.children(),function(child) {
						var childElem=angular.element(child);
						if(callback(childElem))
							WalkDescendants(childElem,callback);
					});
			    }

			    /**
			     * Request a new layout. The action is not performed immediately to perform only one relayout if several are requested within a short period of time.
			     */
			    function RequestLayout(element) {
		    		function DecrementRequestCount() {
		    			requestLayoutCount--;
			    		$timeout(function() {
			    			if(requestLayoutCount==0) {
			    				requestedLayout=false;
			    				DoLayout(element);
			    			} else
			    				DecrementRequestCount();
			    		},0);
		    		}
			    	requestLayoutCount=requestLayoutDelay;
			    	if(requestedLayout==false) {
			    		requestedLayout=true;
			    		DecrementRequestCount();
			    	}
			    }

			    /**
			     * Perform a new layout calculation on the current element.
			     */
			    function DoLayout(element) {

			    	//console.log("DoLayout",element.attr("id"));

			    	var children=[];

			    	/**
			    	 * Order jngLayout children indexes to get lower priority children first.
			    	 */
				    function ChildrenIndexesByPriority() {
				    	var children1=[];
			    		for(var i=0;i<children.length;i++)
			    			if(children[i].sizeDesc.keep)
			    				children1.push(i);
			    		children1.sort(function(i1,i2) {
			    			var child1=children[i1];
			    			var child2=children[i2];
			    			var fit1=(child1.sizeDesc.pixels!==undefined && child1.sizeDesc.pixels<=elementSize) ||
			    				(child1.sizeDesc.pixels===undefined && child1.sizeDesc.min<=elementSize);
			    			var fit2=(child2.sizeDesc.pixels!==undefined && child2.sizeDesc.pixels<=elementSize) ||
		    					(child2.sizeDesc.pixels===undefined && child2.sizeDesc.min<=elementSize);
			    			if(fit1 && !fit2)
			    				return 1;
			    			else if(fit2 && !fit1)
			    				return -1;
			    			else
			    				return child1.sizeDesc.priority-child2.sizeDesc.priority;
			    		});
			    		return children1;
				    }

					var dimension;
					if(scope.hasOwnProperty("jngSize") && scope.jngSize.width>=0) {
						dimension={
							width: scope.jngSize.width,
							height: scope.jngSize.height,
						}
					} else {
						dimension={
								width: element[0].clientWidth,
								height: element[0].clientHeight,
							};
						var m=/^(.*)px$/.exec(element.css("width"));
						if(m)
							dimension.width=parseInt(m[1]);
						m=/^(.*)px$/.exec(element.css("height"));
						if(m)
							dimension.height=parseInt(m[1]);
					}

					var padding={
						top: parseInt(jqElement.css("padding-top")),
						bottom: parseInt(jqElement.css("padding-bottom")),
						left: parseInt(jqElement.css("padding-left")),
						right: parseInt(jqElement.css("padding-right")),
					}

					dimension.width-=padding.left+padding.right;
					dimension.height-=padding.top+padding.bottom;

					//console.log("container size",dimension);

					switch(element.css("position")) {
					case "relative":
					case "absolute":
						break;
					default:
						element.css("position","relative");
					}

					// dealing with horizontal/vertical directions with the same algorithm, so css properties indirections are required
					var dirs={
						"vertical": {
							"pos": "top",
							"size": "height",
							"keep": "width",
							"anchor": "left",
						},
						"horizontal": {
							"pos": "left",
							"size": "width",
							"keep": "height",
							"anchor": "top",
						},
					}

					// interpret jng-layout attribute value: 'horizontal' and 'vertical' is expected as direct attribute value or evaluated expression
					var dir; // hold direction (horizontal or vertical) css properties
					var m=/^(horizontal|vertical)$/.exec(attrs.jngLayout);
					if(m)
						dir=dirs[m[1]];
					else
						dir=dirs[scope.$eval(attrs.jngLayout)];

					// collect to-be-resized/moved children elements data
			    	var totalWeight=0, 	// total defined weight
			    		weightMin=0,	// minimum size requested by weight-based children
			    		fixedSize=0;   	// total requested fixed size

			    	angular.forEach(element.children(), function(child) {
						var $child=angular.element(child);
						if(!$child.hasClass("ng-scope"))
							return;
						var childScope=$child.scope();
						if(childScope && childScope.hasOwnProperty("jngSize")) {
							var sd=angular.extend({
				    			priority: 0,
				    			min: 0,
				    			max: Infinity,
				    			keep: true,
				    		},GetSizeDesc(childScope.jngSizeExpr));
							children.push({
								element: $child,
								sizeExpr: childScope.jngSizeExpr,
								sizeDesc: sd,
								size: childScope.jngSize,
							});
				    		if($child.hasClass("ng-leave")) {
				    			sd.keep=false;
				    			return;
				    		}
				    		if($child.attr("ng-show")!==undefined && !scope.$eval($child.attr("ng-show"))) {
				    			sd.keep=false;
				    			return;
				    		}
							if(sd.fit) {
								var css={
								};
								css[dir.keep]=dimension[dir.keep]+"px";
								css[dir.size]='';
								$($child[0]).css(css);
								sd.pixels=$($child[0])[dir.size]();
							}
							if(sd.pixels!==undefined)
				    			fixedSize+=sd.pixels;
				    		else if(sd.weight!==undefined) {
				    			totalWeight+=sd.weight;
				    			weightMin+=sd.min;
				    		} else {
				    			console.warn("Element id",$child.attr("id"),"has neither 'pixels' not 'weight' spec",sd);
				    			sd.keep=false;
				    		}
						}
					});

			    	var elementSize=dimension[dir.size]; // container size in the current direction (horizontal/vertical)

			    	// hide children that won't fit in the container
			    	while(fixedSize+weightMin>elementSize) {
			    		var children1=ChildrenIndexesByPriority();
			    		if(children1.length==0) {
			    			//console.warn("Impossible to place any child");
			    			break;
			    		}
			    		var child1=children[children1[0]];
			    		var sd1=child1.sizeDesc;
			    		sd1.keep=false;
			    		if(sd1.pixels!==undefined)
			    			fixedSize-=sd1.pixels;
			    		else {
			    			totalWeight-=sd1.weight;
			    			weightMin-=sd1.min;
			    		}
			    		//console.log("removed element",child1.element.attr("id"),"from layout");
			    	}

			    	// hide weight-based children that cannot realize minimum size
					angular.forEach(ChildrenIndexesByPriority(), function(childIndex) {
						var child=children[childIndex];
						var sd=child.sizeDesc;
						if(sd.keep && sd.pixels===undefined) {
							if((elementSize-fixedSize)*sd.weight/totalWeight<sd.min) {
								sd.keep=false;
								totalWeight-=sd.weight;
							}
						}
					});

					// handle weight-based children that have specified a maximum size
					angular.forEach(children, function(child) {
						var sd=child.sizeDesc;
						if(sd.keep && sd.pixels===undefined) {
							var value=(elementSize-fixedSize)*sd.weight/totalWeight;
							if(value>sd.max) {
								totalWeight-=sd.weight;
								delete sd.weight;
								sd.pixels=sd.max;
								fixedSize+=sd.pixels;
							}
						}
					});

			    	var spare=elementSize-fixedSize; // unrequested size to be distributed over weight-based children

			    	// update children size
					var current=0; // current position
					angular.forEach(children, function(child) {
						var sd=child.sizeDesc;
						var sv=child.size;
						sv[dir.pos]=(current+padding[dir.pos]);
						sv[dir.keep]=dimension[dir.keep];
						sv[dir.anchor]=padding[dir.anchor];

						var value=0;
						if(!sd.keep) {
							value=0;
						} else if(sd.pixels!==undefined)
							value=sd.pixels;
						else {
							value=Math.round(Math.max(Math.min(spare*sd.weight/totalWeight,sd.max),sd.min));
							spare-=value;
							totalWeight-=sd.weight;
						}
						sv[dir.size]=value;

						//console.log("placed",child.element.attr("id"),sv);

						child.element.scope().setSize(sv);

						current+=value;
					});

					// perform relayout on children
					scope._jngDoLayout=scope.jngDoLayout;
					scope.jngDoLayout=function() {}
			    	WalkDescendants(element,function(elementBelow) {
			    		if(elementBelow.attr("ng-show")===undefined || scope.$eval(elementBelow.attr("ng-show"))) {
			    			var belowScope=elementBelow.scope();
			    			if(belowScope && typeof belowScope.jngDoLayout=="function") {
				    			belowScope.jngDoLayout();
				    			return false;
			    			}
			    		return true;
			    	});
					scope.jngDoLayout=scope._jngDoLayout;
			    }

				// define delayed layout request as a scope function
				scope.jngRequestLayout=function() {
					RequestLayout(element);
				}

				// define immediate layout as a scope function
				scope.jngDoLayout=function() {
						DoLayout(element);
				}

				RequestLayout(element);
			},
		};
	}])

	/**
	 * Directive to specify that the element has scrollable content.
	 */
	.directive('jngScrollable',
			[ function factory() {
		return {
			link: function(scope,element,attrs) {
				element.addClass("jng-scrollable");
			},
		};
	}])

	/**
	 * Directive jngSize (attribute 'jng-size') to create a scope so that the element size is immediately accessible.
	 */
	.directive('jngSize',
			[ '$rootScope', function factory($rootScope) {
		return {
			scope: true,
			priority: 20,
			link: function(scope,element,attrs) {
				scope.jngSize={
					width: 0,
					height: 0,
					top: 0,
					left: 0,
				};
				scope.jngSize0=angular.extend({},scope.jngSize);
				scope.jngSizeExpr=attrs.jngSize;
				scope.$watch('jngSize',function(newSize) {
					scope.setCSS(newSize)
				});
				scope.setCSS=function(size) {
					angular.extend(scope.jngSize0,size);
					var css={
						position: "absolute",
						top: size.top+"px",
						left: size.left+"px",
						width: size.width+"px",
						height: size.height+"px",
					};
					if(size.width==0 || size.height==0)
						css.opacity=0;
					else
						css.opacity=1;
					$(element[0]).stop().animate(css,$rootScope.jngLayout.anim,function() {
			    		var resizedHandler=attrs.jngResized;
			    		if(resizedHandler)
			    			scope.$eval(resizedHandler);
					});
				}
				scope.setSize=function(newSize) {
					var size0=scope.jngSize0;
					if(newSize.left!=size0.left || newSize.top!=size0.top || newSize.width!=size0.width || newSize.height!=size0.height) {
						angular.extend(scope.jngSize,newSize);
						scope.setCSS(scope.jngSize);
					}
				};
				element.css("position","absolute");
				if(!/^[0-9]+(?:px)?$/.exec(attrs.jngSize))
					scope.$watch(attrs.jngSize,function() {
						if(scope.$parent && scope.$parent.jngRequestLayout)
							scope.$parent.jngRequestLayout();
					},true);
				if(element.attr("ng-show")!==undefined)
					scope.$watch(element.attr("ng-show"),function() {
						if(scope.$parent && scope.$parent.jngRequestLayout)
							scope.$parent.jngRequestLayout();
					});
			},
		};
	}])

})(jQuery);
<|endoftext|>


<commit_before>define(['js/data/Entity'], function(Entity) {
    return Entity.inherit('sprd.entity.Appearance', {
    })
});<commit_msg>added schema for Appearance<commit_after>define(['js/data/Entity', 'sprd/model/PrintType'], function(Entity, PrintType) {
    return Entity.inherit('sprd.entity.Appearance', {
        schema: {
            name: String,
            printTypes: [PrintType]
        }
    })
});<|endoftext|>


<commit_before>var events = require('events'),
    stream = require('stream'),
    Stream = stream.Stream,
    util   = require('util'),
    _      = require('underscore'),
    CSV    = require('./csv');

/**
 * RecordStream
 * @abstract
 */
var RecordStream = function() {
  this.sendable = false;
  this.receivable = false;
  this.on('error', function() {
    this.sendable = false;
    this.recievable = false;
  });
  this.on('end', function() {
    this.recievable = false;
  });
};

util.inherits(RecordStream, events.EventEmitter);

/*--- Output Record Stream methods (Sendable) ---*/

/**
 * Output record into stream.
 */
RecordStream.prototype.send = function(record) {
  // abstract
};

/**
 * End sending records into stream.
 */
RecordStream.prototype.end = function() {
  this.sendable = false;
};

/**
 * Destroy record stream;
 */
RecordStream.prototype.destroy = function() {
  this.reciebable = false;
  this.sendable = false;
};

/**
 * Destroy record stream after all record submission in the queue;
 * @abstract
 */
RecordStream.prototype.destroySoon = function() {
  //
};

/*--- Input Record Stream methods (Receivable) ---*/

/*
 * Pause record fetch
 */
RecordStream.prototype.pause = function() {
  // abstract
};

/**
 * Resume record fetch and query execution
 * @abstract
 */
RecordStream.prototype.resume = function() {
  // abstract
};

/**
 * Streaming pipe for record manipulation
 * Originally from Node.js's Stream#pipe
 * https://github.com/joyent/node/blob/master/lib/stream.js
 */
RecordStream.prototype.pipe = function (dest, options) {
  var source = this;

  var onRecord = function(record) {
    if (dest.send && false === dest.send(record)) { source.pause(); }
  };

  source.on('record', onRecord);

  var onDrain = function() { source.resume(); };

  dest.on('drain', onDrain);

  var didOnEnd = false;
  var onEnd = function() {
    if (didOnEnd) { return; }
    didOnEnd = true;
    dest.end();
  };

  var onClose = function() {
    if (didOnEnd) { return; }
    didOnEnd = true;
    if (typeof dest.destroy === 'function') { dest.destroy(); }
  };

  // If the 'end' option is not supplied, dest.end() will be called when
  // source gets the 'end' or 'close' events.  Only dest.end() once.
  if (!options || options.end !== false) {
    source.on('end', onEnd);
    source.on('close', onClose);
  }

  // don't leave dangling pipes when there are errors.
  var onError = function(err) {
    cleanup();
    if (this.listeners('error').length === 0) {
      throw err; // Unhandled stream error in pipe.
    }
  };

  source.on('error', onError);
  dest.on('error', onError);

  // remove all the event listeners that were added.
  var cleanup = function() {
    source.removeListener('record', onRecord);
    dest.removeListener('drain', onDrain);

    source.removeListener('end', onEnd);
    source.removeListener('close', onClose);

    source.removeListener('error', onError);
    dest.removeListener('error', onError);

    source.removeListener('end', cleanup);
    source.removeListener('close', cleanup);

    dest.removeListener('end', cleanup);
    dest.removeListener('close', cleanup);
  };

  source.on('end', cleanup);
  source.on('close', cleanup);

  dest.on('end', cleanup);
  dest.on('close', cleanup);

  dest.emit('pipe', source);

  // Allow for unix-like usage: A.pipe(B).pipe(C)
  return dest;
};

/**
 * Create Stream instance for serializing/deserialize records
 */
RecordStream.prototype.stream = function(type) {
  type = type || 'csv';
  var recStream;
  if (type === "csv") {
    recStream = new RecordStream.CSVStream();
  }
  if (!recStream) {
    throw new Error("No stream type defined for '"+type+"'.");
  }
  if (this.receivable) {
    this.pipe(recStream);
  } else if (this.sendable) {
    recStream.pipe(this);
  }
  return recStream.stream(); // get Node.js stream instance
};
/* --------------------------------------------------- */

/**
 * Map record and pass to downstream
 */
RecordStream.map = function(fn) {
  var rstream = new RecordStream();
  rstream.receivable = true;
  rstream.send = function(record) {
    var rec = fn(record) || record; // if not returned record, use same record
    this.emit('record', rec);
  };
  return rstream;
};

/**
 * Create mapping stream using given record template
 */
RecordStream.recordMapStream = function(record, noeval) {
  return RecordStream.map(function(rec) {
    var mapped = { Id: rec.Id };
    for (var prop in record) {
      mapped[prop] = noeval ? record[prop] : evalMapping(record[prop], rec);
    }
    return mapped;
  });

  function evalMapping(value, mapping) {
    if (_.isString(value)) {
      var m = /^\$\{(\w+)\}$/.exec(value);
      if (m) { return mapping[m[1]]; }
      return value.replace(/\$\{(\w+)\}/g, function($0, prop) {
        var v = mapping[prop];
        return _.isNull(v) || _.isUndefined(v) ? "" : String(v);
      });
    } else {
      return value;
    }
  }
};

/**
 * Filter record to pass to downstream
 */
RecordStream.filter = function(fn) {
  var rstream = new RecordStream();
  rstream.receivable = true;
  rstream.send = function(record) {
    if (fn(record)) {
      this.emit('record', record);
    }
  };
  return rstream;
};

/* --------------------------------------------------- */

/**
 * CSVStream (extends RecordStream implements Receivable, Sendable)
 */
var CSVStream = function(headers) {
  var self = this;
  this.sendable = true;
  this.receivable = true;
  this.headers = headers;
  this.wroteHeaders = false;
  this._stream = new Stream();
  this._buffer = [];
  this._stream.on('data', function(data) { self._handleData(data); });
  this._stream.on('end', function(data) { self._handleEnd(data); });
};

util.inherits(CSVStream, RecordStream);

/**
 *
 */
CSVStream.prototype.send = function(record) {
  if (!this.wroteHeaders) {
    if (!this.headers) {
      this.headers = CSV.extractHeaders([ record ]);
    }
    this._stream.emit("data", CSV.arrayToCSV(this.headers) + "\n");
    this.wroteHeaders = true;
  }
  this._stream.emit("data", CSV.recordToCSV(record, this.headers) + "\n");
};

/**
 *
 */
CSVStream.prototype.end = function(record) {
  if (record) { this.send(record); }
  this.readable = false;
  this.sendable = false;
  this._stream.emit("end");
};

/**
 *
 */
CSVStream.prototype._handleData = function(data, enc) {
  this._buffer.push([ data, enc ]);
};

/**
 *
 */
CSVStream.prototype._handleEnd = function(data, enc) {
  var self = this;
  if (data) {
    this._buffer.push([ data, enc ]);
  }
  data = this._buffer.map(function(d) {
    return d[0].toString(d[1] || 'utf-8');
  }).join('');
  var records = CSV.parseCSV(data);
  records.forEach(function(record) {
    self.emit('record', record);
  });
  this.emit('end');
};

/**
 * Get delegating Node.js stream
 * @override
 */
CSVStream.prototype.stream = function(record) {
  return this._stream;
};

RecordStream.CSVStream = CSVStream;

/* --------------------------------------------------- */

module.exports = RecordStream;
<commit_msg>add RecordStream#filter and RecordStream#map for much simple chaining<commit_after>var events = require('events'),
    stream = require('stream'),
    Stream = stream.Stream,
    util   = require('util'),
    _      = require('underscore'),
    CSV    = require('./csv');

/**
 * RecordStream
 * @abstract
 */
var RecordStream = function() {
  this.sendable = false;
  this.receivable = false;
  this.on('error', function() {
    this.sendable = false;
    this.recievable = false;
  });
  this.on('end', function() {
    this.recievable = false;
  });
};

util.inherits(RecordStream, events.EventEmitter);

/*--- Output Record Stream methods (Sendable) ---*/

/**
 * Output record into stream.
 */
RecordStream.prototype.send = function(record) {
  // abstract
};

/**
 * End sending records into stream.
 */
RecordStream.prototype.end = function() {
  this.sendable = false;
};

/**
 * Destroy record stream;
 */
RecordStream.prototype.destroy = function() {
  this.reciebable = false;
  this.sendable = false;
};

/**
 * Destroy record stream after all record submission in the queue;
 * @abstract
 */
RecordStream.prototype.destroySoon = function() {
  //
};

/*--- Input Record Stream methods (Receivable) ---*/

/*
 * Pause record fetch
 */
RecordStream.prototype.pause = function() {
  // abstract
};

/**
 * Resume record fetch and query execution
 * @abstract
 */
RecordStream.prototype.resume = function() {
  // abstract
};

/**
 * Streaming pipe for record manipulation
 * Originally from Node.js's Stream#pipe
 * https://github.com/joyent/node/blob/master/lib/stream.js
 */
RecordStream.prototype.pipe = function (dest, options) {
  var source = this;

  var onRecord = function(record) {
    if (dest.send && false === dest.send(record)) { source.pause(); }
  };

  source.on('record', onRecord);

  var onDrain = function() { source.resume(); };

  dest.on('drain', onDrain);

  var didOnEnd = false;
  var onEnd = function() {
    if (didOnEnd) { return; }
    didOnEnd = true;
    dest.end();
  };

  var onClose = function() {
    if (didOnEnd) { return; }
    didOnEnd = true;
    if (typeof dest.destroy === 'function') { dest.destroy(); }
  };

  // If the 'end' option is not supplied, dest.end() will be called when
  // source gets the 'end' or 'close' events.  Only dest.end() once.
  if (!options || options.end !== false) {
    source.on('end', onEnd);
    source.on('close', onClose);
  }

  // don't leave dangling pipes when there are errors.
  var onError = function(err) {
    cleanup();
    if (this.listeners('error').length === 0) {
      throw err; // Unhandled stream error in pipe.
    }
  };

  source.on('error', onError);
  dest.on('error', onError);

  // remove all the event listeners that were added.
  var cleanup = function() {
    source.removeListener('record', onRecord);
    dest.removeListener('drain', onDrain);

    source.removeListener('end', onEnd);
    source.removeListener('close', onClose);

    source.removeListener('error', onError);
    dest.removeListener('error', onError);

    source.removeListener('end', cleanup);
    source.removeListener('close', cleanup);

    dest.removeListener('end', cleanup);
    dest.removeListener('close', cleanup);
  };

  source.on('end', cleanup);
  source.on('close', cleanup);

  dest.on('end', cleanup);
  dest.on('close', cleanup);

  dest.emit('pipe', source);

  // Allow for unix-like usage: A.pipe(B).pipe(C)
  return dest;
};

/**
 * Mapping incoming record from upstream, and pass to downstream
 */
RecordStream.prototype.map = function(fn) {
  return this.pipe(RecordStream.map(fn));
};

/**
 * Filtering incoming record from upstream, and pass to downstream
 */
RecordStream.prototype.filter = function(fn) {
  return this.pipe(RecordStream.filter(fn));
};

/**
 * Create Stream instance for serializing/deserialize records
 */
RecordStream.prototype.stream = function(type) {
  type = type || 'csv';
  var recStream;
  if (type === "csv") {
    recStream = new RecordStream.CSVStream();
  }
  if (!recStream) {
    throw new Error("No stream type defined for '"+type+"'.");
  }
  if (this.receivable) {
    this.pipe(recStream);
  } else if (this.sendable) {
    recStream.pipe(this);
  }
  return recStream.stream(); // get Node.js stream instance
};

/* --------------------------------------------------- */

/**
 * Create a record stream which maps records and pass them to downstream
 */
RecordStream.map = function(fn) {
  var rstream = new RecordStream();
  rstream.receivable = true;
  rstream.send = function(record) {
    var rec = fn(record) || record; // if not returned record, use same record
    this.emit('record', rec);
  };
  return rstream;
};

/**
 * Create mapping stream using given record template
 */
RecordStream.recordMapStream = function(record, noeval) {
  return RecordStream.map(function(rec) {
    var mapped = { Id: rec.Id };
    for (var prop in record) {
      mapped[prop] = noeval ? record[prop] : evalMapping(record[prop], rec);
    }
    return mapped;
  });

  function evalMapping(value, mapping) {
    if (_.isString(value)) {
      var m = /^\$\{(\w+)\}$/.exec(value);
      if (m) { return mapping[m[1]]; }
      return value.replace(/\$\{(\w+)\}/g, function($0, prop) {
        var v = mapping[prop];
        return _.isNull(v) || _.isUndefined(v) ? "" : String(v);
      });
    } else {
      return value;
    }
  }
};

/**
 * Create a record stream which filters records and pass them to downstream
 */
RecordStream.filter = function(fn) {
  var rstream = new RecordStream();
  rstream.receivable = true;
  rstream.send = function(record) {
    if (fn(record)) {
      this.emit('record', record);
    }
  };
  return rstream;
};

/* --------------------------------------------------- */

/**
 * CSVStream (extends RecordStream implements Receivable, Sendable)
 */
var CSVStream = function(headers) {
  var self = this;
  this.sendable = true;
  this.receivable = true;
  this.headers = headers;
  this.wroteHeaders = false;
  this._stream = new Stream();
  this._buffer = [];
  this._stream.on('data', function(data) { self._handleData(data); });
  this._stream.on('end', function(data) { self._handleEnd(data); });
};

util.inherits(CSVStream, RecordStream);

/**
 *
 */
CSVStream.prototype.send = function(record) {
  if (!this.wroteHeaders) {
    if (!this.headers) {
      this.headers = CSV.extractHeaders([ record ]);
    }
    this._stream.emit("data", CSV.arrayToCSV(this.headers) + "\n");
    this.wroteHeaders = true;
  }
  this._stream.emit("data", CSV.recordToCSV(record, this.headers) + "\n");
};

/**
 *
 */
CSVStream.prototype.end = function(record) {
  if (record) { this.send(record); }
  this.readable = false;
  this.sendable = false;
  this._stream.emit("end");
};

/**
 *
 */
CSVStream.prototype._handleData = function(data, enc) {
  this._buffer.push([ data, enc ]);
};

/**
 *
 */
CSVStream.prototype._handleEnd = function(data, enc) {
  var self = this;
  if (data) {
    this._buffer.push([ data, enc ]);
  }
  data = this._buffer.map(function(d) {
    return d[0].toString(d[1] || 'utf-8');
  }).join('');
  var records = CSV.parseCSV(data);
  records.forEach(function(record) {
    self.emit('record', record);
  });
  this.emit('end');
};

/**
 * Get delegating Node.js stream
 * @override
 */
CSVStream.prototype.stream = function(record) {
  return this._stream;
};

RecordStream.CSVStream = CSVStream;

/* --------------------------------------------------- */

module.exports = RecordStream;
<|endoftext|>


<commit_before>function Shortener(backendId, useAcct, login, apiKey) {
  if(!backendId) {
    backendId = 'bitly';
  }
  this.useAcct = useAcct;
  if(useAcct) {
    this.login = login;
    this.apiKey = apiKey;
  }
  this.shortenerInfo = SHORTENERS_BACKEND[backendId];
}
Shortener.prototype = {
  shorten: function(longUrl, callback) {
    var _this = this;
    this.shortenerInfo.backend.shorten(longUrl, this.useAcct, this.login, this.apiKey,
        function(errorCode, msg) {
      var cbMsg = null;
      var success = true;
      if(errorCode == 0 && msg) {
        cbMsg = _this.shortenerInfo.baseUrl + msg;
      } else if(errorCode != 0 && msg) {
        cbMsg = 'Error ' + errorCode + ': ' + msg;
        success = false;
      } else {
        cbMsg = 'Unknown Error';
        success = false;
      }
      callback(success, cbMsg);
    });
  }
}

BitLyShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var url = "http://api.bit.ly/shorten";
    var params = {
      version: '2.0.1',
      format: 'json',
      longUrl: longUrl
    }
    if(useAcct) {
      params['login'] = login;
      params['apiKey'] = apiKey;
      params['history'] = 1;
    } else {
      params['login'] = 'chromedbird';
      params['apiKey'] = 'R_aa77c64a8258cf704e7fa361555a4d81';
    }

    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      dataType: 'json',
      success: function(data, status) {
        var ecAPI = data.errorCode;
        if(ecAPI == 0) {
          var ecURL = data.results[longUrl].errorCode;
          if(!ecURL || ecURL==0) {
            callback(0, data.results[longUrl].userHash);
          } else {
            callback(ecURL, data.results[longUrl].errorMessage);
          }
        } else {
          callback(ecAPI, data.errorMessage);
        }
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

TrimShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var url = "http://api.tr.im/v1/trim_url.json";
    var params = {
      url: longUrl
    }
    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      dataType: 'json',
      success: function(data, status) {
        if(data.status.result != 'OK') {
          callback(data.status.code, data.status.message);
          return;
        }
        callback(0, data.trimpath);
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

MigremeShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var url = "http://migre.me/api.xml";
    var params = {
      url: longUrl
    }
    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      dataType: 'xml',
      success: function(data, status) {
        var errorId = $('error', data).text();
        if(errorId != 0) {
          callback(errorId, $('errormessage', data).text());
          return;
        }
        callback(0, $('id', data).text());
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

IsGdShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var url = "http://is.gd/api.php";
    var params = {
      longurl: longUrl
    }
    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      dataType: 'text',
      success: function(data, status) {
        if(data.match(/^ERROR/i)) {
          callback(-1, data);
          return;
        }
        callback(0, data);
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

MiudinShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var url = "http://miud.in/api-create.php";
    var params = {
      url: longUrl
    }
    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      dataType: 'text',
      success: function(data, status) {
        callback(0, data);
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

UdanaxShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var url = "http://udanax.org/shorturl.jsp";
    var params = {
      mode: 'api',
      longurl: longUrl
    };
    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      jsonp: 'jsoncallback',
      dataType: 'jsonp',
      success: function(data, status) {
        callback(0, data.shorturl);
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

URLinlShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var url = "http://urli.nl/api.php";
    var params = {
      format: 'json',
      action: 'shorturl',
      url: longUrl
    };
    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      dataType: 'json',
      success: function(data, status) {
        if(data && data.status && data.status == 'success') {
          callback(0, data.url.keyword);
        } else {
          callback(data.statusCode, data.message);
        }
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

URLcortaShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var url = "http://urlcorta.es/api/text/";
    var params = {
      url: longUrl
    }
    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      dataType: 'text',
      success: function(data, status) {
        callback(0, data);
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

GooglShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var authFunc = function(f){function k(){for(var c=0,b=0;b<arguments.length;b++)c=c+arguments[b]&4294967295;return c}function m(c){c=c=String(c>0?c:c+4294967296);var b;b=c;for(var d=0,i=false,j=b.length-1;j>=0;--j){var g=Number(b.charAt(j));if(i){g*=2;d+=Math.floor(g/10)+g%10}else d+=g;i=!i}b=b=d%10;d=0;if(b!=0){d=10-b;if(c.length%2==1){if(d%2==1)d+=9;d/=2}}b=String(d);b+=c;return b}function n(c){for(var b=5381,d=0;d<c.length;d++)b=k(b<<5,b,c.charCodeAt(d));return b}function o(c){for(var b=0,d=0;d<c.length;d++)b=k(c.charCodeAt(d),b<<6,b<<16,-b);return b}f={byteArray_:f,charCodeAt:function(c){return this.byteArray_[c]}};f.length=f.byteArray_.length;var e=n(f.byteArray_);e=e>>2&1073741823;e=e>>4&67108800|e&63;e=e>>4&4193280|e&1023;e=e>>4&245760|e&16383;var l="7";f=o(f.byteArray_);var h=(e>>2&15)<<4|f&15;h|=(e>>6&15)<<12|(f>>8&15)<<8;h|=(e>>10&15)<<20|(f>>16&15)<<16;h|=(e>>14&15)<<28|(f>>24&15)<<24;l+=m(h);return l};
    var url = 'http://goo.gl/api/url';
    var params = {
      user: 'toolbar@google.com',
      url: longUrl,
      auth_token: authFunc(longUrl)
    };
    $.ajax({
      url: url,
      type: 'post',
      data: params,
      dataType: 'json',
      success: function(data, status) {
        callback(0, data.short_url);
      },
      error: function (request, status, error) {
        var errMsg;
        try {
          var rspObj = JSON.parse(request.responseText);
          errMsg = rspObj.error_message;
        } catch(e) {
          errMsg = chrome.i18n.getMessage("ajaxFailed");
        }
        callback(-1, errMsg);
      }
    });
  }
}

KCYShortener = {
	shorten : function(longUrl, useAcct, login, apiKey, callback) {
		var url = 'http://kcy.me/api/';
		var params = {
			url: longUrl,
			u: login,
			key: apiKey
		};
		$.ajax({
			type: 'GET',
			url: url,
			data: params,
			dataType: 'text',
	      	success: function(data, status) {
	        	callback(0, data);
	      	},
	      	error: function (request, status, error) {
	        	callback(-1, chrome.i18n.getMessage("ajaxFailed"));
	      	}

		});
	}
}

SHORTENERS_BACKEND = {
  bitly: {
    desc: 'bit.ly',
    baseUrl: 'http://bit.ly/',
    backend: BitLyShortener
  },
  jmp: {
    desc: 'j.mp',
    baseUrl: 'http://j.mp/',
    backend: BitLyShortener
  },
  trim: {
    desc: 'tr.im',
    baseUrl: 'http://tr.im/',
    backend: TrimShortener
  },
  isgd: {
    desc: 'is.gd',
    baseUrl: '',
    backend: IsGdShortener
  },
  migreme: {
    desc: 'migre.me',
    baseUrl: 'http://migre.me/',
    backend: MigremeShortener
  },
  miudin: {
    desc: 'miud.in',
    baseUrl: '',
    backend: MiudinShortener
  },
  udanax: {
    desc: 'udanax.org',
    baseUrl: 'http://udanax.org/',
    backend: UdanaxShortener
  },
  urlinl: {
    desc: 'URLi.nl',
    baseUrl: 'http://urli.nl/',
    backend: URLinlShortener
  },
  urlcorta: {
    desc: 'URLcorta.es',
    baseUrl: '',
    backend: URLcortaShortener
  },
  googl: {
    desc: 'goo.gl',
    baseUrl: '',
    backend: GooglShortener
  },
  karmacracy: {
	desc: 'karmacracy.com',
	baseUrl: '',
	backend: KCYShortener
  }
}
<commit_msg>Style fix<commit_after>function Shortener(backendId, useAcct, login, apiKey) {
  if(!backendId) {
    backendId = 'bitly';
  }
  this.useAcct = useAcct;
  if(useAcct) {
    this.login = login;
    this.apiKey = apiKey;
  }
  this.shortenerInfo = SHORTENERS_BACKEND[backendId];
}
Shortener.prototype = {
  shorten: function(longUrl, callback) {
    var _this = this;
    this.shortenerInfo.backend.shorten(longUrl, this.useAcct, this.login, this.apiKey,
        function(errorCode, msg) {
      var cbMsg = null;
      var success = true;
      if(errorCode == 0 && msg) {
        cbMsg = _this.shortenerInfo.baseUrl + msg;
      } else if(errorCode != 0 && msg) {
        cbMsg = 'Error ' + errorCode + ': ' + msg;
        success = false;
      } else {
        cbMsg = 'Unknown Error';
        success = false;
      }
      callback(success, cbMsg);
    });
  }
}

BitLyShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var url = "http://api.bit.ly/shorten";
    var params = {
      version: '2.0.1',
      format: 'json',
      longUrl: longUrl
    }
    if(useAcct) {
      params['login'] = login;
      params['apiKey'] = apiKey;
      params['history'] = 1;
    } else {
      params['login'] = 'chromedbird';
      params['apiKey'] = 'R_aa77c64a8258cf704e7fa361555a4d81';
    }

    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      dataType: 'json',
      success: function(data, status) {
        var ecAPI = data.errorCode;
        if(ecAPI == 0) {
          var ecURL = data.results[longUrl].errorCode;
          if(!ecURL || ecURL==0) {
            callback(0, data.results[longUrl].userHash);
          } else {
            callback(ecURL, data.results[longUrl].errorMessage);
          }
        } else {
          callback(ecAPI, data.errorMessage);
        }
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

TrimShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var url = "http://api.tr.im/v1/trim_url.json";
    var params = {
      url: longUrl
    }
    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      dataType: 'json',
      success: function(data, status) {
        if(data.status.result != 'OK') {
          callback(data.status.code, data.status.message);
          return;
        }
        callback(0, data.trimpath);
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

MigremeShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var url = "http://migre.me/api.xml";
    var params = {
      url: longUrl
    }
    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      dataType: 'xml',
      success: function(data, status) {
        var errorId = $('error', data).text();
        if(errorId != 0) {
          callback(errorId, $('errormessage', data).text());
          return;
        }
        callback(0, $('id', data).text());
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

IsGdShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var url = "http://is.gd/api.php";
    var params = {
      longurl: longUrl
    }
    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      dataType: 'text',
      success: function(data, status) {
        if(data.match(/^ERROR/i)) {
          callback(-1, data);
          return;
        }
        callback(0, data);
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

MiudinShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var url = "http://miud.in/api-create.php";
    var params = {
      url: longUrl
    }
    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      dataType: 'text',
      success: function(data, status) {
        callback(0, data);
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

UdanaxShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var url = "http://udanax.org/shorturl.jsp";
    var params = {
      mode: 'api',
      longurl: longUrl
    };
    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      jsonp: 'jsoncallback',
      dataType: 'jsonp',
      success: function(data, status) {
        callback(0, data.shorturl);
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

URLinlShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var url = "http://urli.nl/api.php";
    var params = {
      format: 'json',
      action: 'shorturl',
      url: longUrl
    };
    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      dataType: 'json',
      success: function(data, status) {
        if(data && data.status && data.status == 'success') {
          callback(0, data.url.keyword);
        } else {
          callback(data.statusCode, data.message);
        }
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

URLcortaShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var url = "http://urlcorta.es/api/text/";
    var params = {
      url: longUrl
    }
    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      dataType: 'text',
      success: function(data, status) {
        callback(0, data);
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

GooglShortener = {
  shorten: function(longUrl, useAcct, login, apiKey, callback) {
    var authFunc = function(f){function k(){for(var c=0,b=0;b<arguments.length;b++)c=c+arguments[b]&4294967295;return c}function m(c){c=c=String(c>0?c:c+4294967296);var b;b=c;for(var d=0,i=false,j=b.length-1;j>=0;--j){var g=Number(b.charAt(j));if(i){g*=2;d+=Math.floor(g/10)+g%10}else d+=g;i=!i}b=b=d%10;d=0;if(b!=0){d=10-b;if(c.length%2==1){if(d%2==1)d+=9;d/=2}}b=String(d);b+=c;return b}function n(c){for(var b=5381,d=0;d<c.length;d++)b=k(b<<5,b,c.charCodeAt(d));return b}function o(c){for(var b=0,d=0;d<c.length;d++)b=k(c.charCodeAt(d),b<<6,b<<16,-b);return b}f={byteArray_:f,charCodeAt:function(c){return this.byteArray_[c]}};f.length=f.byteArray_.length;var e=n(f.byteArray_);e=e>>2&1073741823;e=e>>4&67108800|e&63;e=e>>4&4193280|e&1023;e=e>>4&245760|e&16383;var l="7";f=o(f.byteArray_);var h=(e>>2&15)<<4|f&15;h|=(e>>6&15)<<12|(f>>8&15)<<8;h|=(e>>10&15)<<20|(f>>16&15)<<16;h|=(e>>14&15)<<28|(f>>24&15)<<24;l+=m(h);return l};
    var url = 'http://goo.gl/api/url';
    var params = {
      user: 'toolbar@google.com',
      url: longUrl,
      auth_token: authFunc(longUrl)
    };
    $.ajax({
      url: url,
      type: 'post',
      data: params,
      dataType: 'json',
      success: function(data, status) {
        callback(0, data.short_url);
      },
      error: function (request, status, error) {
        var errMsg;
        try {
          var rspObj = JSON.parse(request.responseText);
          errMsg = rspObj.error_message;
        } catch(e) {
          errMsg = chrome.i18n.getMessage("ajaxFailed");
        }
        callback(-1, errMsg);
      }
    });
  }
}

KCYShortener = {
  shorten : function(longUrl, useAcct, login, apiKey, callback) {
    var url = 'http://kcy.me/api/';
    var params = {
      url: longUrl,
      u: login,
      key: apiKey
    };
    $.ajax({
      type: 'GET',
      url: url,
      data: params,
      dataType: 'text',
      success: function(data, status) {
        callback(0, data);
      },
      error: function (request, status, error) {
        callback(-1, chrome.i18n.getMessage("ajaxFailed"));
      }
    });
  }
}

SHORTENERS_BACKEND = {
  bitly: {
    desc: 'bit.ly',
    baseUrl: 'http://bit.ly/',
    backend: BitLyShortener
  },
  jmp: {
    desc: 'j.mp',
    baseUrl: 'http://j.mp/',
    backend: BitLyShortener
  },
  trim: {
    desc: 'tr.im',
    baseUrl: 'http://tr.im/',
    backend: TrimShortener
  },
  isgd: {
    desc: 'is.gd',
    baseUrl: '',
    backend: IsGdShortener
  },
  migreme: {
    desc: 'migre.me',
    baseUrl: 'http://migre.me/',
    backend: MigremeShortener
  },
  miudin: {
    desc: 'miud.in',
    baseUrl: '',
    backend: MiudinShortener
  },
  udanax: {
    desc: 'udanax.org',
    baseUrl: 'http://udanax.org/',
    backend: UdanaxShortener
  },
  urlinl: {
    desc: 'URLi.nl',
    baseUrl: 'http://urli.nl/',
    backend: URLinlShortener
  },
  urlcorta: {
    desc: 'URLcorta.es',
    baseUrl: '',
    backend: URLcortaShortener
  },
  googl: {
    desc: 'goo.gl',
    baseUrl: '',
    backend: GooglShortener
  },
  karmacracy: {
    desc: 'karmacracy.com',
    baseUrl: '',
    backend: KCYShortener
  }
}
<|endoftext|>


<commit_before>
/*
 * Used by UPC, ISBN/EAN
 *
 */
function weight3CheckDigit(data) {
  var checksum = 0,
    nData;

  for (var i = 0; i < data.length; i++) {

    if ( typeof data[i] !== 'string' ) {
      return -1;
    }

    nData = parseInt(data[i]);
    // If i is odd (pos is even), add the digit
    // If i is even (pos is odd), add the digit x 3
    checksum += (i & 1) ? nData : 3 * nData;
  }

  return (10 - checksum % 10) % 10;
}

/*
 * Used by code128
 */
function linearMod103(data) {
  if (data.length < 2) {
    return null;
  }

  var checksum = 0,
    aryData = data.split('');

  // first two are x1, then it continues form there.
  checksum += parseInt(data.shift());

  for (var i = 0; i < aryData.length; i++) {
    checksum += (i + 1) * parseInt(aryData[i]);
  }

  return checksum % 103;
}

module.exports.weight3CheckDigit = weight3CheckDigit;
module.exports.linearMod103 = linearMod103;
<commit_msg>Shoving it to an exp branch instead<commit_after><|endoftext|>


<commit_before>import Helper from '@ember/component/helper';
import {inject as service} from '@ember/service';

export default class ParseAuditLogEvent extends Helper {
    @service store;

    compute([ev]) {
        const action = getAction(ev);
        const actionIcon = getActionIcon(ev);
        const getActor = () => this.store.findRecord('user', ev.actor_id, {reload: false});
        const getResource = () => this.store.findRecord(ev.resource_type, ev.resource_id, {reload: false});

        return {
            get actor() {
                return getActor();
            },
            get resource() {
                return getResource();
            },
            actionIcon,
            action,
            original: ev
        };
    }
}

function getActionIcon(ev) {
    switch (ev.event) {
    case 'added':
        return 'add-stroke';
    case 'edited':
        return 'content';
    case 'deleted':
        return 'cross-circle';
    }
}

function getAction(ev) {
    return `${ev.event} ${ev.resource_type}`;
}
<commit_msg>Added fallback icon to audit log<commit_after>import Helper from '@ember/component/helper';
import {inject as service} from '@ember/service';

export default class ParseAuditLogEvent extends Helper {
    @service store;

    compute([ev]) {
        const action = getAction(ev);
        const actionIcon = getActionIcon(ev);
        const getActor = () => this.store.findRecord('user', ev.actor_id, {reload: false});
        const getResource = () => this.store.findRecord(ev.resource_type, ev.resource_id, {reload: false});

        return {
            get actor() {
                return getActor();
            },
            get resource() {
                return getResource();
            },
            actionIcon,
            action,
            original: ev
        };
    }
}

function getActionIcon(ev) {
    switch (ev.event) {
    case 'added':
        return 'add-stroke';
    case 'edited':
        return 'content';
    case 'deleted':
        return 'cross-circle';
    }

    return 'info';
}

function getAction(ev) {
    return `${ev.event} ${ev.resource_type}`;
}
<|endoftext|>


<commit_before>// Give a sort spec, which can be in any of these forms:
//   {"key1": 1, "key2": -1}
//   [["key1", "asc"], ["key2", "desc"]]
//   ["key1", ["key2", "desc"]]
//
// (.. with the first form being dependent on the key enumeration
// behavior of your javascript VM, which usually does what you mean in
// this case if the key names don't look like integers ..)
//
// return a function that takes two objects, and returns -1 if the
// first object comes first in order, 1 if the second object comes
// first, or 0 if neither object comes before the other.

// XXX sort does not yet support subkeys ('a.b') .. fix that!

LocalCollection._compileSort = function (spec) {
  var keys = [];
  var asc = [];

  if (spec instanceof Array) {
    for (var i = 0; i < spec.length; i++) {
      if (typeof spec[i] === "string") {
        keys.push(spec[i]);
        asc.push(true);
      } else {
        keys.push(spec[i][0]);
        asc.push(spec[i][1] !== "desc");
      }
    }
  } else if (typeof spec === "object") {
    for (key in spec) {
      keys.push(key);
      asc.push(!(spec[key] < 0));
    }
  } else {
    throw Error("Bad sort specification: ", JSON.stringify(spec));
  }

  if (keys.length === 0)
    return function () {return 0;};

  // eval() does not return a value in IE8, nor does the spec say it
  // should. Assign to a local to get the value, instead.
  var _func;
  var code = "_func = (function(c){return function(a,b){var x;";
  for (var i = 0; i < keys.length; i++) {
    if (i !== 0)
      code += "if(x!==0)return x;";
    code += "x=" + (asc[i] ? "" : "-") +
      "c(a[" + JSON.stringify(keys[i]) + "],b[" +
      JSON.stringify(keys[i]) + "]);";
  }
  code += "return x;};})";

  eval(code);
  return _func(LocalCollection._f._cmp);
};
<commit_msg>Added sorting functionality for 'a.b'<commit_after>// Give a sort spec, which can be in any of these forms:
//   {"key1": 1, "key2": -1}
//   [["key1", "asc"], ["key2", "desc"]]
//   ["key1", ["key2", "desc"]]
//
// (.. with the first form being dependent on the key enumeration
// behavior of your javascript VM, which usually does what you mean in
// this case if the key names don't look like integers ..)
//
// return a function that takes two objects, and returns -1 if the
// first object comes first in order, 1 if the second object comes
// first, or 0 if neither object comes before the other.

// XXX sort does not yet support subkeys ('a.b') .. fix that!

LocalCollection._compileSort = function (spec) {
  var keys = [];
  var asc = [];

  if (spec instanceof Array) {
    for (var i = 0; i < spec.length; i++) {
      if (typeof spec[i] === "string") {
        keys.push(spec[i]);
        asc.push(true);
      } else {
        keys.push(spec[i][0]);
        asc.push(spec[i][1] !== "desc");
      }
    }
  } else if (typeof spec === "object") {
    for (key in spec) {
      keys.push(key);
      asc.push(!(spec[key] < 0));
    }
  } else {
    throw Error("Bad sort specification: ", JSON.stringify(spec));
  }

  if (keys.length === 0)
    return function () {return 0;};

  // eval() does not return a value in IE8, nor does the spec say it
  // should. Assign to a local to get the value, instead.
  var _func;
  var code = "_func = (function(c){return function(a,b){var x;";
  for (var i = 0; i < keys.length; i++) {
      var splittedKeys = keys[i].split(".");
      var keyString = "";
      for(o = 0;o<splittedKeys.length;o++){
        keyString  = keyString + "["+ JSON.stringify(splittedKeys[o]) +"]";
      }
      if (i !== 0){
        code += "if(x!==0)return x;";
      }
      code += "x=" + (asc[i] ? "" : "-") +
        "c(a" + keyString +",b"+keyString+");";
  }
  code += "return x;};})";
  eval(code);
  return _func(LocalCollection._f._cmp);
};
<|endoftext|>


<commit_before>// Give a sort spec, which can be in any of these forms:
//   {"key1": 1, "key2": -1}
//   [["key1", "asc"], ["key2", "desc"]]
//   ["key1", ["key2", "desc"]]
//
// (.. with the first form being dependent on the key enumeration
// behavior of your javascript VM, which usually does what you mean in
// this case if the key names don't look like integers ..)
//
// return a function that takes two objects, and returns -1 if the
// first object comes first in order, 1 if the second object comes
// first, or 0 if neither object comes before the other.

Sorter = function (spec) {
  var self = this;
  self._sortFunction = null;

  var sortSpecParts = [];

  if (spec instanceof Array) {
    for (var i = 0; i < spec.length; i++) {
      if (typeof spec[i] === "string") {
        sortSpecParts.push({
          lookup: makeLookupFunction(spec[i]),
          ascending: true
        });
      } else {
        sortSpecParts.push({
          lookup: makeLookupFunction(spec[i][0]),
          ascending: spec[i][1] !== "desc"
        });
      }
    }
  } else if (typeof spec === "object") {
    for (var key in spec) {
      sortSpecParts.push({
        lookup: makeLookupFunction(key),
        ascending: spec[key] >= 0
      });
    }
  } else {
    throw Error("Bad sort specification: ", JSON.stringify(spec));
  }

  // If there are no sorting rules specified, leave _sortFunction as null.  This
  // will allow us to have a special case where we sort on distances if query
  // involved the $near operator.
  if (sortSpecParts.length === 0)
    return;

  // reduceValue takes in all the possible values for the sort key along various
  // branches, and returns the min or max value (according to the bool
  // findMin). Each value can itself be an array, and we look at its values
  // too. (ie, we do a single level of flattening on branchValues, then find the
  // min/max.)
  var reduceValue = function (branchValues, findMin) {
    // Expand any leaf arrays that we find, and ignore those arrays themselves.
    branchValues = expandArraysInBranches(branchValues, true);
    var reduced = undefined;
    var first = true;
    // Iterate over all the values found in all the branches, and if a value is
    // an array itself, iterate over the values in the array separately.
    _.each(branchValues, function (branchValue) {
      if (first) {
        reduced = branchValue.value;
        first = false;
      } else {
        // Compare the value we found to the value we found so far, saving it
        // if it's less (for an ascending sort) or more (for a descending
        // sort).
        var cmp = LocalCollection._f._cmp(reduced, branchValue.value);
        if ((findMin && cmp > 0) || (!findMin && cmp < 0))
          reduced = branchValue.value;
      }
    });
    return reduced;
  };

  self._sortFunction = function (a, b) {
    for (var i = 0; i < sortSpecParts.length; ++i) {
      var specPart = sortSpecParts[i];
      var aValue = reduceValue(specPart.lookup(a), specPart.ascending);
      var bValue = reduceValue(specPart.lookup(b), specPart.ascending);
      var compare = LocalCollection._f._cmp(aValue, bValue);
      if (compare !== 0)
        return specPart.ascending ? compare : -compare;
    };
    return 0;
  };
};

Sorter.prototype.getComparator = function (options) {
  var self = this;
  // If there was a sort specification, use it.
  // XXX do we not use distance as a secondary sort key?
  if (self._sortFunction)
    return self._sortFunction;

  // If there was no sort specification and we have no distances, everything is
  // equal.
  if (!options || !options.distances) {
    return function (a, b) {
      return 0;
    };
  }

  return function (a, b) {
    return options.distances.get(a._id) - options.distances.get(b._id);
  };
};

MinimongoTest.Sorter = Sorter;
<commit_msg>add comment about sort vs query<commit_after>// Give a sort spec, which can be in any of these forms:
//   {"key1": 1, "key2": -1}
//   [["key1", "asc"], ["key2", "desc"]]
//   ["key1", ["key2", "desc"]]
//
// (.. with the first form being dependent on the key enumeration
// behavior of your javascript VM, which usually does what you mean in
// this case if the key names don't look like integers ..)
//
// return a function that takes two objects, and returns -1 if the
// first object comes first in order, 1 if the second object comes
// first, or 0 if neither object comes before the other.

Sorter = function (spec) {
  var self = this;
  self._sortFunction = null;

  var sortSpecParts = [];

  if (spec instanceof Array) {
    for (var i = 0; i < spec.length; i++) {
      if (typeof spec[i] === "string") {
        sortSpecParts.push({
          lookup: makeLookupFunction(spec[i]),
          ascending: true
        });
      } else {
        sortSpecParts.push({
          lookup: makeLookupFunction(spec[i][0]),
          ascending: spec[i][1] !== "desc"
        });
      }
    }
  } else if (typeof spec === "object") {
    for (var key in spec) {
      sortSpecParts.push({
        lookup: makeLookupFunction(key),
        ascending: spec[key] >= 0
      });
    }
  } else {
    throw Error("Bad sort specification: ", JSON.stringify(spec));
  }

  // If there are no sorting rules specified, leave _sortFunction as null.  This
  // will allow us to have a special case where we sort on distances if query
  // involved the $near operator.
  if (sortSpecParts.length === 0)
    return;

  // reduceValue takes in all the possible values for the sort key along various
  // branches, and returns the min or max value (according to the bool
  // findMin). Each value can itself be an array, and we look at its values
  // too. (ie, we do a single level of flattening on branchValues, then find the
  // min/max.)
  //
  // XXX This is actually wrong! In fact, the whole attempt to compile sort
  // functions independently of selectors is wrong. In MongoDB, if you have
  // documents {_id: 'x', a: [1, 10]} and {_id: 'y', a: [5, 15]},
  // then C.find({}, {sort: {a: 1}}) puts x before y (1 comes before 5).
  // But C.find({a: {$gt: 3}}, {sort: {a: 1}}) puts y before x (1 does not match
  // the selector, and 5 comes before 10).
  var reduceValue = function (branchValues, findMin) {
    // Expand any leaf arrays that we find, and ignore those arrays themselves.
    branchValues = expandArraysInBranches(branchValues, true);
    var reduced = undefined;
    var first = true;
    // Iterate over all the values found in all the branches, and if a value is
    // an array itself, iterate over the values in the array separately.
    _.each(branchValues, function (branchValue) {
      if (first) {
        reduced = branchValue.value;
        first = false;
      } else {
        // Compare the value we found to the value we found so far, saving it
        // if it's less (for an ascending sort) or more (for a descending
        // sort).
        var cmp = LocalCollection._f._cmp(reduced, branchValue.value);
        if ((findMin && cmp > 0) || (!findMin && cmp < 0))
          reduced = branchValue.value;
      }
    });
    return reduced;
  };

  self._sortFunction = function (a, b) {
    for (var i = 0; i < sortSpecParts.length; ++i) {
      var specPart = sortSpecParts[i];
      var aValue = reduceValue(specPart.lookup(a), specPart.ascending);
      var bValue = reduceValue(specPart.lookup(b), specPart.ascending);
      var compare = LocalCollection._f._cmp(aValue, bValue);
      if (compare !== 0)
        return specPart.ascending ? compare : -compare;
    };
    return 0;
  };
};

Sorter.prototype.getComparator = function (options) {
  var self = this;
  // If there was a sort specification, use it.
  // XXX do we not use distance as a secondary sort key?
  if (self._sortFunction)
    return self._sortFunction;

  // If there was no sort specification and we have no distances, everything is
  // equal.
  if (!options || !options.distances) {
    return function (a, b) {
      return 0;
    };
  }

  return function (a, b) {
    return options.distances.get(a._id) - options.distances.get(b._id);
  };
};

MinimongoTest.Sorter = Sorter;
<|endoftext|>


<commit_before>describe('Angular Rest Support', function() {
  var $httpBackend;
  var arsHelper;
  var dataBuilder = jsonApiDataBuilder();

  beforeEach(function() {
    module('ars');
    inject(function(_$httpBackend_, _arsHelper_) {
      $httpBackend = _$httpBackend_;
      arsHelper = _arsHelper_;
    });

    // Mock Data
    $httpBackend.whenGET('/authors').respond(200, dataBuilder.allAuthors);
  });

  describe('When calling a GET end-point', function() {
    var getRequest;

    beforeEach(function() {
      getRequest = arsHelper
        .get('/authors')
        .request();
    });

    it('Should make a GET request', function() {
      $httpBackend.expectGET('/authors');
      $httpBackend.flush();
    });

    it('Should return the correct data', function() {
      var returnedData;
      getRequest
        .then(function(success) {
          returnedData = success.data;
        });
      $httpBackend.flush();
      expect(returnedData).toEqual(dataBuilder.allAuthors);
    });
  });
});
<commit_msg>docs(tests): minor comment change<commit_after>describe('Angular Rest Support', function() {
  var $httpBackend;
  var arsHelper;
  var dataBuilder = jsonApiDataBuilder();

  beforeEach(function() {
    module('ars');
    inject(function(_$httpBackend_, _arsHelper_) {
      $httpBackend = _$httpBackend_;
      arsHelper = _arsHelper_;
    });

    // Mock the Data
    $httpBackend.whenGET('/authors').respond(200, dataBuilder.allAuthors);
  });

  describe('When calling a GET end-point', function() {
    var getRequest;

    beforeEach(function() {
      getRequest = arsHelper
        .get('/authors')
        .request();
    });

    it('Should make a GET request', function() {
      $httpBackend.expectGET('/authors');
      $httpBackend.flush();
    });

    it('Should return the correct data', function() {
      var returnedData;
      getRequest
        .then(function(success) {
          returnedData = success.data;
        });
      $httpBackend.flush();
      expect(returnedData).toEqual(dataBuilder.allAuthors);
    });
  });
});
<|endoftext|>


<commit_before>import WeElement from './we-element'
import options from './options'

const getType = function(obj) {
  return Object.prototype.toString.call(obj).slice(8, -1)
}

export function define(name, ctor) {
  if (options.mapping[name]) {
    return
  }
  if (ctor.is === 'WeElement') {
    customElements.define(name, ctor)
    options.mapping[name] = ctor
    if (ctor.use) {
      ctor.updatePath = getPath(ctor.use)
    }
  } else {
    let depPaths
    let config = {}
    const len = arguments.length
    if (len === 3) {
      if (typeof arguments[1] === 'function') {
        ctor = arguments[1]
        config = arguments[2]
      } else {
        depPaths = arguments[1]
        ctor = arguments[2]
      }
    } else if (len === 4) {
      depPaths = arguments[1]
      ctor = arguments[2]
      config = arguments[3]
    }
    if (typeof config === 'string') {
      config = { css: config }
    }

    class Ele extends WeElement {
      static use = depPaths

      static css = config.css

      static propTypes = config.propTypes

      static defaultProps = config.defaultProps

      render() {
        return ctor.call(this, this)
      }

      install() {
        config.install && config.install.apply(this, arguments)
      }

      installed() {
        config.installed && config.installed.apply(this, arguments)
      }

      uninstall() {
        config.uninstall && config.uninstall.apply(this, arguments)
      }

      beforeUpdate() {
        config.beforeUpdate && config.beforeUpdate.apply(this, arguments)
      }

      updated() {
        config.updated && config.updated.apply(this, arguments)
      }

      beforeRender() {
        config.beforeRender && config.beforeRender.apply(this, arguments)
      }

      rendered() {
        config.rendered && config.rendered.apply(this, arguments)
      }

      receiveProps() {
        if (config.receiveProps) {
          return config.receiveProps.apply(this, arguments)
        }
      }
    }

    if (config.use) {
      Ele.prototype.use = function() {
        return typeof config.use === 'function'
          ? config.use.apply(this, arguments)
          : config.use
      }
    }

    if (config.useSelf) {
      Ele.prototype.useSelf = function() {
        return typeof config.useSelf === 'function'
          ? config.useSelf.apply(this, arguments)
          : config.useSelf
      }
    }

    if (Ele.use) {
      Ele.updatePath = getPath(Ele.use)
    }

    customElements.define(name, Ele)
    options.mapping[name] = Ele
  }
}

export function getPath(obj) {
  if (getType(obj) === '[object Array]') {
    const result = {}
    obj.forEach(item => {
      if (typeof item === 'string') {
        result[item] = true
      } else {
        const tempPath = item[Object.keys(item)[0]]
        if (typeof tempPath === 'string') {
          result[tempPath] = true
        } else {
          if (typeof tempPath[0] === 'string') {
            result[tempPath[0]] = true
          } else {
            tempPath[0].forEach(path => (result[path] = true))
          }
        }
      }
    })
    return result
  } else {
    return getUpdatePath(obj)
  }
}

export function getUpdatePath(data) {
  const result = {}
  dataToPath(data, result)
  return result
}

function dataToPath(data, result) {
  Object.keys(data).forEach(key => {
    result[key] = true
    const type = getType(data[key])
    if (type === 'Object') {
      _objToPath(data[key], key, result)
    } else if (type === 'Array') {
      _arrayToPath(data[key], key, result)
    }
  })
}

function _objToPath(data, path, result) {
  Object.keys(data).forEach(key => {
    result[path + '.' + key] = true
    delete result[path]
    const type = getType(data[key])
    if (type === 'Object') {
      _objToPath(data[key], path + '.' + key, result)
    } else if (type === 'Array') {
      _arrayToPath(data[key], path + '.' + key, result)
    }
  })
}

function _arrayToPath(data, path, result) {
  data.forEach((item, index) => {
    result[path + '[' + index + ']'] = true
    delete result[path]
    const type = getType(item)
    if (type === 'Object') {
      _objToPath(item, path + '[' + index + ']', result)
    } else if (type === 'Array') {
      _arrayToPath(item, path + '[' + index + ']', result)
    }
  })
}
<commit_msg>fix: fix type comparison<commit_after>import WeElement from './we-element'
import options from './options'

const getType = function(obj) {
  return Object.prototype.toString.call(obj).slice(8, -1)
}

export function define(name, ctor) {
  if (options.mapping[name]) {
    return
  }
  if (ctor.is === 'WeElement') {
    customElements.define(name, ctor)
    options.mapping[name] = ctor
    if (ctor.use) {
      ctor.updatePath = getPath(ctor.use)
    }
  } else {
    let depPaths
    let config = {}
    const len = arguments.length
    if (len === 3) {
      if (typeof arguments[1] === 'function') {
        ctor = arguments[1]
        config = arguments[2]
      } else {
        depPaths = arguments[1]
        ctor = arguments[2]
      }
    } else if (len === 4) {
      depPaths = arguments[1]
      ctor = arguments[2]
      config = arguments[3]
    }
    if (typeof config === 'string') {
      config = { css: config }
    }

    class Ele extends WeElement {
      static use = depPaths

      static css = config.css

      static propTypes = config.propTypes

      static defaultProps = config.defaultProps

      render() {
        return ctor.call(this, this)
      }

      install() {
        config.install && config.install.apply(this, arguments)
      }

      installed() {
        config.installed && config.installed.apply(this, arguments)
      }

      uninstall() {
        config.uninstall && config.uninstall.apply(this, arguments)
      }

      beforeUpdate() {
        config.beforeUpdate && config.beforeUpdate.apply(this, arguments)
      }

      updated() {
        config.updated && config.updated.apply(this, arguments)
      }

      beforeRender() {
        config.beforeRender && config.beforeRender.apply(this, arguments)
      }

      rendered() {
        config.rendered && config.rendered.apply(this, arguments)
      }

      receiveProps() {
        if (config.receiveProps) {
          return config.receiveProps.apply(this, arguments)
        }
      }
    }

    if (config.use) {
      Ele.prototype.use = function() {
        return typeof config.use === 'function'
          ? config.use.apply(this, arguments)
          : config.use
      }
    }

    if (config.useSelf) {
      Ele.prototype.useSelf = function() {
        return typeof config.useSelf === 'function'
          ? config.useSelf.apply(this, arguments)
          : config.useSelf
      }
    }

    if (Ele.use) {
      Ele.updatePath = getPath(Ele.use)
    }

    customElements.define(name, Ele)
    options.mapping[name] = Ele
  }
}

export function getPath(obj) {
  if (getType(obj) === 'Array') {
    const result = {}
    obj.forEach(item => {
      if (typeof item === 'string') {
        result[item] = true
      } else {
        const tempPath = item[Object.keys(item)[0]]
        if (typeof tempPath === 'string') {
          result[tempPath] = true
        } else {
          if (typeof tempPath[0] === 'string') {
            result[tempPath[0]] = true
          } else {
            tempPath[0].forEach(path => (result[path] = true))
          }
        }
      }
    })
    return result
  } else {
    return getUpdatePath(obj)
  }
}

export function getUpdatePath(data) {
  const result = {}
  dataToPath(data, result)
  return result
}

function dataToPath(data, result) {
  Object.keys(data).forEach(key => {
    result[key] = true
    const type = getType(data[key])
    if (type === 'Object') {
      _objToPath(data[key], key, result)
    } else if (type === 'Array') {
      _arrayToPath(data[key], key, result)
    }
  })
}

function _objToPath(data, path, result) {
  Object.keys(data).forEach(key => {
    result[path + '.' + key] = true
    delete result[path]
    const type = getType(data[key])
    if (type === 'Object') {
      _objToPath(data[key], path + '.' + key, result)
    } else if (type === 'Array') {
      _arrayToPath(data[key], path + '.' + key, result)
    }
  })
}

function _arrayToPath(data, path, result) {
  data.forEach((item, index) => {
    result[path + '[' + index + ']'] = true
    delete result[path]
    const type = getType(item)
    if (type === 'Object') {
      _objToPath(item, path + '[' + index + ']', result)
    } else if (type === 'Array') {
      _arrayToPath(item, path + '[' + index + ']', result)
    }
  })
}
<|endoftext|>