text:
;(function() {

	/**
	 *
	 * Helper class to consume unused mouse events by components that are DOM elements and
	 * are used by all of the different rendering modes.
	 *
	 */
	jsPlumb.DOMElementComponent = jsPlumbUtil.extend(jsPlumb.jsPlumbUIComponent, function(params) {
		// when render mode is canvas, these functions may be called by the canvas mouse handler.
		// this component is safe to pipe this stuff to /dev/null.
		this.mousemove =
		this.dblclick  =
		this.click =
		this.mousedown =
		this.mouseup = function(e) { };
	});

	jsPlumb.Segments = {

        /*
         * Class: AbstractSegment
         * A Connector is made up of 1..N Segments, each of which has a Type, such as 'Straight', 'Arc',
         * 'Bezier'. This is new from 1.4.2, and gives us a lot more flexibility when drawing connections: things such
         * as rounded corners for flowchart connectors, for example, or a straight line stub for Bezier connections, are
         * much easier to do now.
         *
         * A Segment is responsible for providing coordinates for painting it, and also must be able to report its length.
         *
         */
        AbstractSegment : function(params) {
            this.params = params;

            /**
            * Function: findClosestPointOnPath
            * Finds the closest point on this segment to the given [x, y],
            * returning both the x and y of the point plus its distance from
            * the supplied point, and its location along the length of the
            * path inscribed by the segment.  This implementation returns
            * Infinity for distance and null values for everything else;
            * subclasses are expected to override.
            */
            this.findClosestPointOnPath = function(x, y) {
                return {
                    d:Infinity,
                    x:null,
                    y:null,
                    l:null
                };
            };

            this.getBounds = function() {
                return {
                    minX:Math.min(params.x1, params.x2),
                    minY:Math.min(params.y1, params.y2),
                    maxX:Math.max(params.x1, params.x2),
                    maxY:Math.max(params.y1, params.y2)
                };
            };
        },
        Straight : function(params) {
            var _super = jsPlumb.Segments.AbstractSegment.apply(this, arguments),
                length, m, m2, x1, x2, y1, y2,
                _recalc = function() {
                    length = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
                    m = jsPlumbGeom.gradient({x:x1, y:y1}, {x:x2, y:y2});
                    m2 = -1 / m;
                };

            this.type = "Straight";

            this.getLength = function() { return length; };
            this.getGradient = function() { return m; };

            this.getCoordinates = function() {
                return { x1:x1,y1:y1,x2:x2,y2:y2 };
            };
            this.setCoordinates = function(coords) {
                x1 = coords.x1; y1 = coords.y1; x2 = coords.x2; y2 = coords.y2;
                _recalc();
            };
            this.setCoordinates({x1:params.x1, y1:params.y1, x2:params.x2, y2:params.y2});

            this.getBounds = function() {
                return {
                    minX:Math.min(x1, x2),
                    minY:Math.min(y1, y2),
                    maxX:Math.max(x1, x2),
                    maxY:Math.max(y1, y2)
                };
            };

            /**
             * returns the point on the segment's path that is 'location' along the length of the path, where 'location' is a decimal from
             * 0 to 1 inclusive. for the straight line segment this is simple maths.
             */
             this.pointOnPath = function(location, absolute) {
                if (location === 0 && !absolute)
                    return { x:x1, y:y1 };
                else if (location == 1 && !absolute)
                    return { x:x2, y:y2 };
                else {
                    var l = absolute ? location > 0 ? location : length + location : location * length;
                    return jsPlumbGeom.pointOnLine({x:x1, y:y1}, {x:x2, y:y2}, l);
                }
            };

            /**
             * returns the gradient of the segment at the given point - which for us is constant.
             */
            this.gradientAtPoint = function(_) {
                return m;
            };

            /**
             * returns the point on the segment's path that is 'distance' along the length of the path from 'location', where
             * 'location' is a decimal from 0 to 1 inclusive, and 'distance' is a number of pixels.
             * this hands off to jsPlumbUtil to do the maths, supplying two points and the distance.
             */
            this.pointAlongPathFrom = function(location, distance, absolute) {
                var p = this.pointOnPath(location, absolute),
                    farAwayPoint = distance <= 0 ? {x:x1, y:y1} : {x:x2, y:y2 };

                /*
                location == 1 ? {
                                        x:x1 + ((x2 - x1) * 10),
                                        y:y1 + ((y1 - y2) * 10)
                                    } :
                */

                if (distance <= 0 && Math.abs(distance) > 1) distance *= -1;

                return jsPlumbGeom.pointOnLine(p, farAwayPoint, distance);
            };

            // is c between a and b?
            var within = function(a,b,c) {
                return c >= Math.min(a,b) && c <= Math.max(a,b);
            };
            // find which of a and b is closest to c
            var closest = function(a,b,c) {
                return Math.abs(c - a) < Math.abs(c - b) ? a : b;
            };

            /**
                Function: findClosestPointOnPath
                Finds the closest point on this segment to [x,y]. See
                notes on this method in AbstractSegment.
            */
            this.findClosestPointOnPath = function(x, y) {
                var out = {
                    d:Infinity,
                    x:null,
                    y:null,
                    l:null,
                    x1:x1,
                    x2:x2,
                    y1:y1,
                    y2:y2
                };

                if (m === 0) {
                    out.y = y1;
                    out.x = within(x1, x2, x) ? x : closest(x1, x2, x);
                }
                else if (m == Infinity || m == -Infinity) {
                    out.x = x1;
                    out.y = within(y1, y2, y) ? y : closest(y1, y2, y);
                }
                else {
                    // closest point lies on normal from given point to this line.
                    var b = y1 - (m * x1),
                        b2 = y - (m2 * x),
                    // y1 = m.x1 + b and y1 = m2.x1 + b2
                    // so m.x1 + b = m2.x1 + b2
                    // x1(m - m2) = b2 - b
                    // x1 = (b2 - b) / (m - m2)
                        _x1 = (b2 -b) / (m - m2),
                        _y1 = (m * _x1) + b;

                    out.x = within(x1,x2,_x1) ? _x1 : closest(x1,x2,_x1);//_x1;
                    out.y = within(y1,y2,_y1) ? _y1 : closest(y1,y2,_y1);//_y1;
                }

                var fractionInSegment = jsPlumbGeom.lineLength([ out.x, out.y ], [ x1, y1 ]);
                out.d = jsPlumbGeom.lineLength([x,y], [out.x, out.y]);
                out.l = fractionInSegment / length;
                return out;
            };
        },

        /*
            Arc Segment. You need to supply:

            r   -   radius
            cx  -   center x for the arc
            cy  -   center y for the arc
            ac  -   whether the arc is anticlockwise or not. default is clockwise.

            and then either:

            startAngle  -   startAngle for the arc.
            endAngle    -   endAngle for the arc.

            or:

            x1          -   x for start point
            y1          -   y for start point
            x2          -   x for end point
            y2          -   y for end point

        */
        Arc : function(params) {
            var _super = jsPlumb.Segments.AbstractSegment.apply(this, arguments),
                _calcAngle = function(_x, _y) {
                    return jsPlumbGeom.theta([params.cx, params.cy], [_x, _y]);
                },
                _calcAngleForLocation = function(segment, location) {
                    if (segment.anticlockwise) {
                        var sa = segment.startAngle < segment.endAngle ? segment.startAngle + TWO_PI : segment.startAngle,
                            s = Math.abs(sa - segment.endAngle);
                        return sa - (s * location);
                    }
                    else {
                        var ea = segment.endAngle < segment.startAngle ? segment.endAngle + TWO_PI : segment.endAngle,
                            ss = Math.abs (ea - segment.startAngle);

                        return segment.startAngle + (ss * location);
                    }
                },
                TWO_PI = 2 * Math.PI;

            this.radius = params.r;
            this.anticlockwise = params.ac;
            this.type = "Arc";

            if (params.startAngle && params.endAngle) {
                this.startAngle = params.startAngle;
                this.endAngle = params.endAngle;
                this.x1 = params.cx + (this.radius * Math.cos(params.startAngle));
                this.y1 = params.cy + (this.radius * Math.sin(params.startAngle));
                this.x2 = params.cx + (this.radius * Math.cos(params.endAngle));
                this.y2 = params.cy + (this.radius * Math.sin(params.endAngle));
            }
            else {
                this.startAngle = _calcAngle(params.x1, params.y1);
                this.endAngle = _calcAngle(params.x2, params.y2);
                this.x1 = params.x1;
                this.y1 = params.y1;
                this.x2 = params.x2;
                this.y2 = params.y2;
            }

            if (this.endAngle < 0) this.endAngle += TWO_PI;
            if (this.startAngle < 0) this.startAngle += TWO_PI;

            // segment is used by vml
            this.segment = jsPlumbGeom.quadrant([this.x1, this.y1], [this.x2, this.y2]);

            // we now have startAngle and endAngle as positive numbers, meaning the
            // absolute difference (|d|) between them is the sweep (s) of this arc, unless the
            // arc is 'anticlockwise' in which case 's' is given by 2PI - |d|.

            var ea = this.endAngle < this.startAngle ? this.endAngle + TWO_PI : this.endAngle;
            this.sweep = Math.abs (ea - this.startAngle);
            if (this.anticlockwise) this.sweep = TWO_PI - this.sweep;
            var circumference = 2 * Math.PI * this.radius,
                frac = this.sweep / TWO_PI,
                length = circumference * frac;

            this.getLength = function() {
                return length;
            };

            this.getBounds = function() {
                return {
                    minX:params.cx - params.r,
                    maxX:params.cx + params.r,
                    minY:params.cy - params.r,
                    maxY:params.cy + params.r
                };
            };

            var VERY_SMALL_VALUE = 0.0000000001,
                gentleRound = function(n) {
                    var f = Math.floor(n), r = Math.ceil(n);
                    if (n - f < VERY_SMALL_VALUE)
                        return f;
                    else if (r - n < VERY_SMALL_VALUE)
                        return r;
                    return n;
                };

            /**
             * returns the point on the segment's path that is 'location' along the length of the path, where 'location' is a decimal from
             * 0 to 1 inclusive.
             */
            this.pointOnPath = function(location, absolute) {

                if (location === 0) {
                    return { x:this.x1, y:this.y1, theta:this.startAngle };
                }
                else if (location == 1) {
                    return { x:this.x2, y:this.y2, theta:this.endAngle };
                }

                if (absolute) {
                    location = location / length;
                }

                var angle = _calcAngleForLocation(this, location),
                    _x = params.cx + (params.r * Math.cos(angle)),
                    _y  = params.cy + (params.r * Math.sin(angle));

                return { x:gentleRound(_x), y:gentleRound(_y), theta:angle };
            };

            /**
             * returns the gradient of the segment at the given point.
             */
            this.gradientAtPoint = function(location, absolute) {
                var p = this.pointOnPath(location, absolute);
                var m = jsPlumbGeom.normal( [ params.cx, params.cy ], [p.x, p.y ] );
                if (!this.anticlockwise && (m == Infinity || m == -Infinity)) m *= -1;
                return m;
            };

            this.pointAlongPathFrom = function(location, distance, absolute) {
                var p = this.pointOnPath(location, absolute),
                    arcSpan = distance / circumference * 2 * Math.PI,
                    dir = this.anticlockwise ? -1 : 1,
                    startAngle = p.theta + (dir * arcSpan),
                    startX = params.cx + (this.radius * Math.cos(startAngle)),
                    startY = params.cy + (this.radius * Math.sin(startAngle));

                return {x:startX, y:startY};
            };
        },

        Bezier : function(params) {
            var _super = jsPlumb.Segments.AbstractSegment.apply(this, arguments),
                curve = [
                    { x:params.x1, y:params.y1},
                    { x:params.cp1x, y:params.cp1y },
                    { x:params.cp2x, y:params.cp2y },
                    { x:params.x2, y:params.y2 }
                ],
                // although this is not a strictly rigorous determination of bounds
                // of a bezier curve, it works for the types of curves that this segment
                // type produces.
                bounds = {
                    minX:Math.min(params.x1, params.x2, params.cp1x, params.cp2x),
                    minY:Math.min(params.y1, params.y2, params.cp1y, params.cp2y),
                    maxX:Math.max(params.x1, params.x2, params.cp1x, params.cp2x),
                    maxY:Math.max(params.y1, params.y2, params.cp1y, params.cp2y)
                };

            this.type = "Bezier";

            var _translateLocation = function(_curve, location, absolute) {
                if (absolute)
                    location = jsBezier.locationAlongCurveFrom(_curve, location > 0 ? 0 : 1, location);

                return location;
            };

            /**
             * returns the point on the segment's path that is 'location' along the length of the path, where 'location' is a decimal from
             * 0 to 1 inclusive.
             */
            this.pointOnPath = function(location, absolute) {
                location = _translateLocation(curve, location, absolute);
                return jsBezier.pointOnCurve(curve, location);
            };

            /**
             * returns the gradient of the segment at the given point.
             */
            this.gradientAtPoint = function(location, absolute) {
                location = _translateLocation(curve, location, absolute);
                return jsBezier.gradientAtPoint(curve, location);
            };

            this.pointAlongPathFrom = function(location, distance, absolute) {
                location = _translateLocation(curve, location, absolute);
                return jsBezier.pointAlongCurveFrom(curve, location, distance);
            };

            this.getLength = function() {
                return jsBezier.getLength(curve);
            };

            this.getBounds = function() {
                return bounds;
            };
        }
    };

    /*
        Class: AbstractComponent
        Superclass for AbstractConnector and AbstractEndpoint.
    */
    var AbstractComponent = function() {
        this.resetBounds = function() {
            this.bounds = { minX:Infinity, minY:Infinity, maxX:-Infinity, maxY:-Infinity };
        };
        this.resetBounds();
    };

	/*
	 * Class: AbstractConnector
	 * Superclass for all Connectors; here is where Segments are managed.  This is exposed on jsPlumb just so it
	 * can be accessed from other files. You should not try to instantiate one of these directly.
	 *
	 * When this class is asked for a pointOnPath, or gradient etc, it must first figure out which segment to dispatch
	 * that request to. This is done by keeping track of the total connector length as segments are added, and also
	 * their cumulative ratios to the total length.  Then when the right segment is found it is a simple case of dispatching
	 * the request to it (and adjusting 'location' so that it is relative to the beginning of that segment.)
	 */
	jsPlumb.Connectors.AbstractConnector = function(params) {

        AbstractComponent.apply(this, arguments);

		var //self = this,
            segments = [],
            editing = false,
			totalLength = 0,
			segmentProportions = [],
			segmentProportionalLengths = [],
            stub = params.stub || 0,
            sourceStub = jsPlumbUtil.isArray(stub) ? stub[0] : stub,
            targetStub = jsPlumbUtil.isArray(stub) ? stub[1] : stub,
            gap = params.gap || 0,
            sourceGap = jsPlumbUtil.isArray(gap) ? gap[0] : gap,
            targetGap = jsPlumbUtil.isArray(gap) ? gap[1] : gap,
            userProvidedSegments = null,
            edited = false,
            paintInfo = null;

        // subclasses should override.
        this.isEditable = function() { return false; };
        this.setEdited = function(ed) { edited = ed; };

        // to be overridden by subclasses.
        this.getPath = function() { };
        this.setPath = function(path) { };

        /**
        * Function: findSegmentForPoint
        * Returns the segment that is closest to the given [x,y],
        * null if nothing found.  This function returns a JS
        * object with:
        *
        *   d   -   distance from segment
        *   l   -   proportional location in segment
        *   x   -   x point on the segment
        *   y   -   y point on the segment
        *   s   -   the segment itself.
        */
        this.findSegmentForPoint = function(x, y) {
            var out = { d:Infinity, s:null, x:null, y:null, l:null };
            for (var i = 0; i < segments.length; i++) {
                var _s = segments[i].findClosestPointOnPath(x, y);
                if (_s.d < out.d) {
                    out.d = _s.d;
                    out.l = _s.l;
                    out.x = _s.x;
                    out.y = _s.y;
                    out.s = segments[i];
                    out.x1 = _s.x1;
                    out.x2 = _s.x2;
                    out.y1 = _s.y1;
                    out.y2 = _s.y2;
                    out.index = i;
                }
            }

            return out;
        };

		var _updateSegmentProportions = function() {
                var curLoc = 0;
                for (var i = 0; i < segments.length; i++) {
                    var sl = segments[i].getLength();
                    segmentProportionalLengths[i] = sl / totalLength;
                    segmentProportions[i] = [curLoc, (curLoc += (sl / totalLength)) ];
                }
            },

            /**
             * returns [segment, proportion of travel in segment, segment index] for the segment
             * that contains the point which is 'location' distance along the entire path, where
             * 'location' is a decimal between 0 and 1 inclusive. in this connector type, paths
             * are made up of a list of segments, each of which contributes some fraction to
             * the total length.
             * From 1.3.10 this also supports the 'absolute' property, which lets us specify a location
             * as the absolute distance in pixels, rather than a proportion of the total path.
             */
            _findSegmentForLocation = function(location, absolute) {
                if (absolute) {
                    location = location > 0 ? location / totalLength : (totalLength + location) / totalLength;
                }

                var idx = segmentProportions.length - 1, inSegmentProportion = 1;
                //if (location < 1) {
                    for (var i = 0; i < segmentProportions.length; i++) {
                        if (segmentProportions[i][1] >= location) {
                            idx = i;
                            // todo is this correct for all connector path types?
                            inSegmentProportion = location == 1 ? 1 : location === 0 ? 0 : (location - segmentProportions[i][0]) / segmentProportionalLengths[i];
                            break;
                        }
                    }
                //}
                return { segment:segments[idx], proportion:inSegmentProportion, index:idx };
            },
            _addSegment = function(conn, type, params) {
                if (params.x1 == params.x2 && params.y1 == params.y2) return;
                var s = new jsPlumb.Segments[type](params);
                segments.push(s);
                totalLength += s.getLength();
                conn.updateBounds(s);
            },
            _clearSegments = function() {
                totalLength = 0;
                segments.splice(0, segments.length);
                segmentProportions.splice(0, segmentProportions.length);
                segmentProportionalLengths.splice(0, segmentProportionalLengths.length);
            };

        this.setSegments = function(_segs) {
            userProvidedSegments = [];
            totalLength = 0;
            for (var i = 0; i < _segs.length; i++) {
                userProvidedSegments.push(_segs[i]);
                totalLength += _segs[i].getLength();
            }
        };

        var _prepareCompute = function(params) {
            this.lineWidth = params.lineWidth;
            var segment = jsPlumbGeom.quadrant(params.sourcePos, params.targetPos),
                swapX = params.targetPos[0] < params.sourcePos[0],
                swapY = params.targetPos[1] < params.sourcePos[1],
                lw = params.lineWidth || 1,
                so = params.sourceEndpoint.anchor.getOrientation(params.sourceEndpoint),
                to = params.targetEndpoint.anchor.getOrientation(params.targetEndpoint),
                x = swapX ? params.targetPos[0] : params.sourcePos[0],
                y = swapY ? params.targetPos[1] : params.sourcePos[1],
                w = Math.abs(params.targetPos[0] - params.sourcePos[0]),
                h = Math.abs(params.targetPos[1] - params.sourcePos[1]);

            // if either anchor does not have an orientation set, we derive one from their relative
            // positions.  we fix the axis to be the one in which the two elements are further apart, and
            // point each anchor at the other element.  this is also used when dragging a new connection.
            if (so[0] === 0 && so[1] === 0 || to[0] === 0 && to[1] === 0) {
                var index = w > h ? 0 : 1, oIndex = [1,0][index];
                so = []; to = [];
                so[index] = params.sourcePos[index] > params.targetPos[index] ? -1 : 1;
                to[index] = params.sourcePos[index] > params.targetPos[index] ? 1 : -1;
                so[oIndex] = 0; to[oIndex] = 0;
            }

            var sx = swapX ? w + (sourceGap * so[0])  : sourceGap * so[0],
                sy = swapY ? h + (sourceGap * so[1])  : sourceGap * so[1],
                tx = swapX ? targetGap * to[0] : w + (targetGap * to[0]),
                ty = swapY ? targetGap * to[1] : h + (targetGap * to[1]),
                oProduct = ((so[0] * to[0]) + (so[1] * to[1]));

            var result = {
                sx:sx, sy:sy, tx:tx, ty:ty, lw:lw,
                xSpan:Math.abs(tx - sx),
                ySpan:Math.abs(ty - sy),
                mx:(sx + tx) / 2,
                my:(sy + ty) / 2,
                so:so, to:to, x:x, y:y, w:w, h:h,
                segment : segment,
                startStubX : sx + (so[0] * sourceStub),
                startStubY : sy + (so[1] * sourceStub),
                endStubX : tx + (to[0] * targetStub),
                endStubY : ty + (to[1] * targetStub),
                isXGreaterThanStubTimes2 : Math.abs(sx - tx) > (sourceStub + targetStub),
                isYGreaterThanStubTimes2 : Math.abs(sy - ty) > (sourceStub + targetStub),
                opposite:oProduct == -1,
                perpendicular:oProduct === 0,
                orthogonal:oProduct == 1,
                sourceAxis : so[0] === 0 ? "y" : "x",
                points:[x, y, w, h, sx, sy, tx, ty ]
            };
            result.anchorOrientation = result.opposite ? "opposite" : result.orthogonal ? "orthogonal" : "perpendicular";
            return result;
        };

		this.getSegments = function() { return segments; };

        this.updateBounds = function(segment) {
            var segBounds = segment.getBounds();
            this.bounds.minX = Math.min(this.bounds.minX, segBounds.minX);
            this.bounds.maxX = Math.max(this.bounds.maxX, segBounds.maxX);
            this.bounds.minY = Math.min(this.bounds.minY, segBounds.minY);
            this.bounds.maxY = Math.max(this.bounds.maxY, segBounds.maxY);
        };

        var dumpSegmentsToConsole = function() {
            console.log("SEGMENTS:");
            for (var i = 0; i < segments.length; i++) {
                console.log(segments[i].type, segments[i].getLength(), segmentProportions[i]);
            }
        };

		this.pointOnPath = function(location, absolute) {
            var seg = _findSegmentForLocation(location, absolute);
            return seg.segment && seg.segment.pointOnPath(seg.proportion, absolute) || [0,0];
        };

        this.gradientAtPoint = function(location) {
            var seg = _findSegmentForLocation(location, absolute);
            return seg.segment && seg.segment.gradientAtPoint(seg.proportion, absolute) || 0;
        };

        this.pointAlongPathFrom = function(location, distance, absolute) {
            var seg = _findSegmentForLocation(location, absolute);
            // TODO what happens if this crosses to the next segment?
            return seg.segment && seg.segment.pointAlongPathFrom(seg.proportion, distance, false) || [0,0];
        };

		this.compute = function(params)  {
            if (!edited)
                paintInfo = _prepareCompute.call(this, params);

            _clearSegments();
            this._compute(paintInfo, params);
            this.x = paintInfo.points[0];
            this.y = paintInfo.points[1];
            this.w = paintInfo.points[2];
            this.h = paintInfo.points[3];
            this.segment = paintInfo.segment;
            _updateSegmentProportions();
		};

		return {
			addSegment:_addSegment,
            prepareCompute:_prepareCompute,
            sourceStub:sourceStub,
            targetStub:targetStub,
            maxStub:Math.max(sourceStub, targetStub),
            sourceGap:sourceGap,
            targetGap:targetGap,
            maxGap:Math.max(sourceGap, targetGap)
		};
	};
    jsPlumbUtil.extend(jsPlumb.Connectors.AbstractConnector, AbstractComponent);

    /**
     * Class: Connectors.Straight
     * The Straight connector draws a simple straight line between the two anchor points.  It does not have any constructor parameters.
     */
    var Straight = jsPlumb.Connectors.Straight = function() {
    	this.type = "Straight";
		var _super =  jsPlumb.Connectors.AbstractConnector.apply(this, arguments);

        this._compute = function(paintInfo, _) {
            _super.addSegment(this, "Straight", {x1:paintInfo.sx, y1:paintInfo.sy, x2:paintInfo.startStubX, y2:paintInfo.startStubY});
            _super.addSegment(this, "Straight", {x1:paintInfo.startStubX, y1:paintInfo.startStubY, x2:paintInfo.endStubX, y2:paintInfo.endStubY});
            _super.addSegment(this, "Straight", {x1:paintInfo.endStubX, y1:paintInfo.endStubY, x2:paintInfo.tx, y2:paintInfo.ty});
        };
    };
    jsPlumbUtil.extend(jsPlumb.Connectors.Straight, jsPlumb.Connectors.AbstractConnector);
    jsPlumb.registerConnectorType(Straight, "Straight");

    /**
     * Class:Connectors.Bezier
     * This Connector draws a Bezier curve with two control points.  You can provide a 'curviness' value which gets applied to jsPlumb's
     * internal voodoo machine and ends up generating locations for the two control points.  See the constructor documentation below.
     */
    /**
     * Function:Constructor
     *
     * Parameters:
     * 	curviness - How 'curvy' you want the curve to be! This is a directive for the placement of control points, not endpoints of the curve, so your curve does not
     * actually touch the given point, but it has the tendency to lean towards it.  The larger this value, the greater the curve is pulled from a straight line.
     * Optional; defaults to 150.
     * stub - optional value for a distance to travel from the connector's endpoint before beginning the Bezier curve. defaults to 0.
     *
     */
    var Bezier = function(params) {
        params = params || {};

    	var _super =  jsPlumb.Connectors.AbstractConnector.apply(this, arguments),
            stub = params.stub || 50,
            majorAnchor = params.curviness || 150,
            minorAnchor = 10;

        this.type = "Bezier";
        this.getCurviness = function() { return majorAnchor; };

        this._findControlPoint = function(point, sourceAnchorPosition, targetAnchorPosition, sourceEndpoint, targetEndpoint) {
        	// determine if the two anchors are perpendicular to each other in their orientation.  we swap the control
        	// points around if so (code could be tightened up)
        	var soo = sourceEndpoint.anchor.getOrientation(sourceEndpoint),
        		too = targetEndpoint.anchor.getOrientation(targetEndpoint),
        		perpendicular = soo[0] != too[0] || soo[1] == too[1],
            	p = [];

            if (!perpendicular) {
                if (soo[0] === 0) // X
                    p.push(sourceAnchorPosition[0] < targetAnchorPosition[0] ? point[0] + minorAnchor : point[0] - minorAnchor);
                else p.push(point[0] - (majorAnchor * soo[0]));

                if (soo[1] === 0) // Y
                	p.push(sourceAnchorPosition[1] < targetAnchorPosition[1] ? point[1] + minorAnchor : point[1] - minorAnchor);
                else p.push(point[1] + (majorAnchor * too[1]));
            }
             else {
                if (too[0] === 0) // X
                	p.push(targetAnchorPosition[0] < sourceAnchorPosition[0] ? point[0] + minorAnchor : point[0] - minorAnchor);
                else p.push(point[0] + (majorAnchor * too[0]));

                if (too[1] === 0) // Y
                	p.push(targetAnchorPosition[1] < sourceAnchorPosition[1] ? point[1] + minorAnchor : point[1] - minorAnchor);
                else p.push(point[1] + (majorAnchor * soo[1]));
             }

            return p;
        };

        this._compute = function(paintInfo, p) {
			var sp = p.sourcePos,
				tp = p.targetPos,
                _w = Math.abs(sp[0] - tp[0]),
                _h = Math.abs(sp[1] - tp[1]),
                _sx = sp[0] < tp[0] ? _w : 0,
                _sy = sp[1] < tp[1] ? _h : 0,
                _tx = sp[0] < tp[0] ? 0 : _w,
                _ty = sp[1] < tp[1] ? 0 : _h,
                _CP = this._findControlPoint([_sx, _sy], sp, tp, p.sourceEndpoint, p.targetEndpoint),
                _CP2 = this._findControlPoint([_tx, _ty], tp, sp, p.targetEndpoint, p.sourceEndpoint);

			_super.addSegment(this, "Bezier", {
				x1:_sx, y1:_sy, x2:_tx, y2:_ty,
				cp1x:_CP[0], cp1y:_CP[1], cp2x:_CP2[0], cp2y:_CP2[1]
			});
        };
    };
    jsPlumbUtil.extend(Bezier, jsPlumb.Connectors.AbstractConnector);
    jsPlumb.registerConnectorType(Bezier, "Bezier");

 // ********************************* END OF CONNECTOR TYPES *******************************************************************

 // ********************************* ENDPOINT TYPES *******************************************************************

    jsPlumb.Endpoints.AbstractEndpoint = function(params) {
        AbstractComponent.apply(this, arguments);
        var compute = this.compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
            var out = this._compute.apply(this, arguments);
            this.x = out[0];
            this.y = out[1];
            this.w = out[2];
            this.h = out[3];
            this.bounds.minX = this.x;
            this.bounds.minY = this.y;
            this.bounds.maxX = this.x + this.w;
            this.bounds.maxY = this.y + this.h;
            return out;
        };
        return {
            compute:compute,
            cssClass:params.cssClass
        };
    };
    jsPlumbUtil.extend(jsPlumb.Endpoints.AbstractEndpoint, AbstractComponent);

    /**
     * Class: Endpoints.Dot
     * A round endpoint, with default radius 10 pixels.
     */

	/**
	 * Function: Constructor
	 *
	 * Parameters:
	 *
	 * 	radius	-	radius of the endpoint.  defaults to 10 pixels.
	 */
	jsPlumb.Endpoints.Dot = function(params) {
		this.type = "Dot";
		var _super = jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
		params = params || {};
		this.radius = params.radius || 10;
		this.defaultOffset = 0.5 * this.radius;
		this.defaultInnerRadius = this.radius / 3;

		this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
			this.radius = endpointStyle.radius || this.radius;
			var	x = anchorPoint[0] - this.radius,
				y = anchorPoint[1] - this.radius,
                w = this.radius * 2,
                h = this.radius * 2;

            if (endpointStyle.strokeStyle) {
                var lw = endpointStyle.lineWidth || 1;
                x -= lw;
                y -= lw;
                w += (lw * 2);
                h += (lw * 2);
            }
			return [ x, y, w, h, this.radius ];
		};
	};
    jsPlumbUtil.extend(jsPlumb.Endpoints.Dot, jsPlumb.Endpoints.AbstractEndpoint);

	/**
	 * Class: Endpoints.Rectangle
	 * A Rectangular Endpoint, with default size 20x20.
	 */
	/**
	 * Function: Constructor
	 *
	 * Parameters:
	 *
	 * 	width	- width of the endpoint. defaults to 20 pixels.
	 * 	height	- height of the endpoint. defaults to 20 pixels.
	 */
	jsPlumb.Endpoints.Rectangle = function(params) {
		this.type = "Rectangle";
		var _super = jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
		params = params || {};
		this.width = params.width || 20;
		this.height = params.height || 20;

		this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
			var width = endpointStyle.width || this.width,
				height = endpointStyle.height || this.height,
				x = anchorPoint[0] - (width/2),
				y = anchorPoint[1] - (height/2);

			return [ x, y, width, height];
		};
	};
    jsPlumbUtil.extend(jsPlumb.Endpoints.Rectangle, jsPlumb.Endpoints.AbstractEndpoint);

    var DOMElementEndpoint = function(params) {
        jsPlumb.DOMElementComponent.apply(this, arguments);
        this._jsPlumb.displayElements = [  ];
    };
    jsPlumbUtil.extend(DOMElementEndpoint, jsPlumb.DOMElementComponent, {
       // jsPlumb.Endpoints.AbstractEndpoint
        getDisplayElements : function() {
            return this._jsPlumb.displayElements;
        },
        appendDisplayElement : function(el) {
            this._jsPlumb.displayElements.push(el);
        }
    });

	/**
	 * Class: Endpoints.Image
	 * Draws an image as the Endpoint.
	 */
	/**
	 * Function: Constructor
	 *
	 * Parameters:
	 *
	 * 	src	-	location of the image to use.

    TODO: multiple references to self. not sure quite how to get rid of them entirely. perhaps self = null in the cleanup
    function will suffice

    TODO this class still leaks memory.

	 */
	jsPlumb.Endpoints.Image = function(params) {

		this.type = "Image";
		DOMElementEndpoint.apply(this, arguments);
        jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);

		var _onload = params.onload,
            src = params.src || params.url,
            parent = params.parent,
            clazz = params.cssClass ? " " + params.cssClass : "";

        this._jsPlumb.img = new Image();
        this._jsPlumb.ready = false;
        this._jsPlumb.initialized = false;
        this._jsPlumb.deleted = false;
        this._jsPlumb.widthToUse = params.width;
        this._jsPlumb.heightToUse = params.height;
        this._jsPlumb.endpoint = params.endpoint;

		this._jsPlumb.img.onload = function() {
            // check we weren't actually discarded before use (in fact mostly happens in tests)
            if (this._jsPlumb != null) {
    			this._jsPlumb.ready = true;
    			this._jsPlumb.widthToUse = this._jsPlumb.widthToUse || this._jsPlumb.img.width;
    			this._jsPlumb.heightToUse = this._jsPlumb.heightToUse || this._jsPlumb.img.height;
                if (_onload) {
                    _onload(this);
                }
            }
		}.bind(this);

        /*
            Function: setImage
            Sets the Image to use in this Endpoint.

            Parameters:
            img         -   may be a URL or an Image object
            onload      -   optional; a callback to execute once the image has loaded.
        */
        this._jsPlumb.endpoint.setImage = function(_img, onload) {
            var s = _img.constructor == String ? _img : _img.src;
            _onload = onload;
            this._jsPlumb.img.src = s;

            if (this.canvas != null)
                this.canvas.setAttribute("src", this._jsPlumb.img.src);
        }.bind(this);

        this._jsPlumb.endpoint.setImage(src, _onload);
        /*
            var s = src.constructor == String ? src : src.src;
            //_onload = onload;
            this._jsPlumb.img.src = src;

            if (this.canvas != null)
                this.canvas.setAttribute("src", this._jsPlumb.img.src);
       // }.bind(this);

        //this._jsPlumb.endpoint.setImage(src, _onload);*/

		this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
			this.anchorPoint = anchorPoint;
			if (this._jsPlumb.ready) return [anchorPoint[0] - this._jsPlumb.widthToUse / 2, anchorPoint[1] - this._jsPlumb.heightToUse / 2,
									this._jsPlumb.widthToUse, this._jsPlumb.heightToUse];
			else return [0,0,0,0];
		};

		this.canvas = document.createElement("img");
		this.canvas.style.margin = 0;
		this.canvas.style.padding = 0;
		this.canvas.style.outline = 0;
		this.canvas.style.position = "absolute";
		this.canvas.className = this._jsPlumb.instance.endpointClass + clazz;
		if (this._jsPlumb.widthToUse) this.canvas.setAttribute("width", this._jsPlumb.widthToUse);
		if (this._jsPlumb.heightToUse) this.canvas.setAttribute("height", this._jsPlumb.heightToUse);
		this._jsPlumb.instance.appendElement(this.canvas, parent);
		this.attachListeners(this.canvas, this);

		this.actuallyPaint = function(d, style, anchor) {
			if (!this._jsPlumb.deleted) {
				if (!this._jsPlumb.initialized) {
					this.canvas.setAttribute("src", this._jsPlumb.img.src);
					this.appendDisplayElement(this.canvas);
					this._jsPlumb.initialized = true;
				}
				var x = this.anchorPoint[0] - (this._jsPlumb.widthToUse / 2),
					y = this.anchorPoint[1] - (this._jsPlumb.heightToUse / 2);
				jsPlumbUtil.sizeElement(this.canvas, x, y, this._jsPlumb.widthToUse, this._jsPlumb.heightToUse);
			}
		};

		this.paint = function(style, anchor) {
            if (this._jsPlumb != null) {  // may have been deleted
    			if (this._jsPlumb.ready) {
        			this.actuallyPaint(style, anchor);
    			}
    			else {
    				window.setTimeout(function() {
    					this.paint(style, anchor);
    				}.bind(this), 200);
    			}
            }
		};
	};
    jsPlumbUtil.extend(jsPlumb.Endpoints.Image, [ DOMElementEndpoint, jsPlumb.Endpoints.AbstractEndpoint ], {
        cleanup : function() {
            this._jsPlumb.deleted = true;
            jsPlumbUtil.removeElement(this.canvas);
            this.canvas = null;
        }
    });

	/*
	 * Class: Endpoints.Blank
	 * An Endpoint that paints nothing (visible) on the screen.  Supports cssClass and hoverClass parameters like all Endpoints.
	 */
	jsPlumb.Endpoints.Blank = function(params) {
		var _super = jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
		this.type = "Blank";
		DOMElementEndpoint.apply(this, arguments);
		this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
			return [anchorPoint[0], anchorPoint[1],10,0];
		};

		this.canvas = document.createElement("div");
		this.canvas.style.display = "block";
		this.canvas.style.width = "1px";
		this.canvas.style.height = "1px";
		this.canvas.style.background = "transparent";
		this.canvas.style.position = "absolute";
		this.canvas.className = this._jsPlumb.endpointClass;
		jsPlumb.appendElement(this.canvas, params.parent);

		this.paint = function(style, anchor) {
			jsPlumbUtil.sizeElement(this.canvas, this.x, this.y, this.w, this.h);
		};
	};
    jsPlumbUtil.extend(jsPlumb.Endpoints.Blank, [jsPlumb.Endpoints.AbstractEndpoint, DOMElementEndpoint], {
        cleanup:function() {
            if (this.canvas && this.canvas.parentNode) {
                this.canvas.parentNode.removeChild(this.canvas);
            }
        }
    });

	/*
	 * Class: Endpoints.Triangle
	 * A triangular Endpoint.
	 */
	/*
	 * Function: Constructor
	 *
	 * Parameters:
	 *
	 * 	width	-	width of the triangle's base.  defaults to 55 pixels.
	 * 	height	-	height of the triangle from base to apex.  defaults to 55 pixels.
	 */
	jsPlumb.Endpoints.Triangle = function(params) {
		this.type = "Triangle";
        var _super = jsPlumb.Endpoints.AbstractEndpoint.apply(this, arguments);
		params = params || {  };
		params.width = params.width || 55;
		params.height = params.height || 55;
		this.width = params.width;
		this.height = params.height;
		this._compute = function(anchorPoint, orientation, endpointStyle, connectorPaintStyle) {
			var width = endpointStyle.width || self.width,
			height = endpointStyle.height || self.height,
			x = anchorPoint[0] - (width/2),
			y = anchorPoint[1] - (height/2);
			return [ x, y, width, height ];
		};
	};
// ********************************* END OF ENDPOINT TYPES *******************************************************************

// ********************************* OVERLAY DEFINITIONS ***********************************************************************

	var AbstractOverlay = jsPlumb.Overlays.AbstractOverlay = function(params) {
		this.visible = true;
        this.isAppendedAtTopLevel = true;
		this.component = params.component;
		this.loc = params.location == null ? 0.5 : params.location;
        this.endpointLoc = params.endpointLocation == null ? [ 0.5, 0.5] : params.endpointLocation;
	};
    AbstractOverlay.prototype = {
        cleanup:function() {
           this.component = null;
           this.canvas = null;
           this.endpointLoc = null;
        },
        setVisible : function(val) {
            this.visible = val;
            // TODO this is only actually necessary for canvas. so, the Canvas overlay should
            // override setVisible and call this.
            //this.component.repaint();
        },
        isVisible : function() { return this.visible; },
        hide : function() { this.setVisible(false); },
        show : function() { this.setVisible(true); },
        incrementLocation : function(amount) {
            this.loc += amount;
            this.component.repaint();
        },
        setLocation : function(l) {
            this.loc = l;
            this.component.repaint();
        },
        getLocation : function() {
            return this.loc;
        }
    };

	/*
	 * Class: Overlays.Arrow
	 *
	 * An arrow overlay, defined by four points: the head, the two sides of the tail, and a 'foldback' point at some distance along the length
	 * of the arrow that lines from each tail point converge into.  The foldback point is defined using a decimal that indicates some fraction
	 * of the length of the arrow and has a default value of 0.623.  A foldback point value of 1 would mean that the arrow had a straight line
	 * across the tail.
	 */
	/*
	 * Function: Constructor
	 *
	 * Parameters:
	 *
	 * 	length - distance in pixels from head to tail baseline. default 20.
	 * 	width - width in pixels of the tail baseline. default 20.
	 * 	fillStyle - style to use when filling the arrow.  defaults to "black".
	 * 	strokeStyle - style to use when stroking the arrow. defaults to null, which means the arrow is not stroked.
	 * 	lineWidth - line width to use when stroking the arrow. defaults to 1, but only used if strokeStyle is not null.
	 * 	foldback - distance (as a decimal from 0 to 1 inclusive) along the length of the arrow marking the point the tail points should fold back to.  defaults to 0.623.
	 * 	location - distance (as a decimal from 0 to 1 inclusive) marking where the arrow should sit on the connector. defaults to 0.5.
	 * 	direction - indicates the direction the arrow points in. valid values are -1 and 1; 1 is default.
	 */
	jsPlumb.Overlays.Arrow = function(params) {
		this.type = "Arrow";
		AbstractOverlay.apply(this, arguments);
        this.isAppendedAtTopLevel = false;
		params = params || {};
		var _ju = jsPlumbUtil, _jg = jsPlumbGeom;

    	this.length = params.length || 20;
    	this.width = params.width || 20;
    	this.id = params.id;
    	var direction = (params.direction || 1) < 0 ? -1 : 1,
    	    paintStyle = params.paintStyle || { lineWidth:1 },
    	    // how far along the arrow the lines folding back in come to. default is 62.3%.
    	    foldback = params.foldback || 0.623;

    	this.computeMaxSize = function() { return self.width * 1.5; };
    	//this.cleanup = function() { };  // nothing to clean up for Arrows
    	this.draw = function(component, currentConnectionPaintStyle) {

            var hxy, mid, txy, tail, cxy;
            if (component.pointAlongPathFrom) {

                if (_ju.isString(this.loc) || this.loc > 1 || this.loc < 0) {
                    var l = parseInt(this.loc, 10),
                        fromLoc = this.loc < 0 ? 1 : 0;
                    hxy = component.pointAlongPathFrom(fromLoc, l, false);
                    mid = component.pointAlongPathFrom(fromLoc, l - (direction * this.length / 2), false);
                    txy = _jg.pointOnLine(hxy, mid, this.length);
                }
                else if (this.loc == 1) {
					hxy = component.pointOnPath(this.loc);
                    mid = component.pointAlongPathFrom(this.loc, -(this.length));
					txy = _jg.pointOnLine(hxy, mid, this.length);

					if (direction == -1) {
						var _ = txy;
						txy = hxy;
						hxy = _;
					}
                }
                else if (this.loc === 0) {
					txy = component.pointOnPath(this.loc);
					mid = component.pointAlongPathFrom(this.loc, this.length);
					hxy = _jg.pointOnLine(txy, mid, this.length);
					if (direction == -1) {
						var __ = txy;
						txy = hxy;
						hxy = __;
					}
                }
                else {
    			    hxy = component.pointAlongPathFrom(this.loc, direction * this.length / 2);
                    mid = component.pointOnPath(this.loc);
                    txy = _jg.pointOnLine(hxy, mid, this.length);
                }

                tail = _jg.perpendicularLineTo(hxy, txy, this.width);
                cxy = _jg.pointOnLine(hxy, txy, foldback * this.length);

    			var d = { hxy:hxy, tail:tail, cxy:cxy },
    			    strokeStyle = paintStyle.strokeStyle || currentConnectionPaintStyle.strokeStyle,
    			    fillStyle = paintStyle.fillStyle || currentConnectionPaintStyle.strokeStyle,
    			    lineWidth = paintStyle.lineWidth || currentConnectionPaintStyle.lineWidth,
                    info = {
                        component:component,
                        d:d,
                        lineWidth:lineWidth,
                        strokeStyle:strokeStyle,
                        fillStyle:fillStyle,
                        minX:Math.min(hxy.x, tail[0].x, tail[1].x),
                        maxX:Math.max(hxy.x, tail[0].x, tail[1].x),
                        minY:Math.min(hxy.y, tail[0].y, tail[1].y),
                        maxY:Math.max(hxy.y, tail[0].y, tail[1].y)
                    };

                return info;
            }
            else return {component:component, minX:0,maxX:0,minY:0,maxY:0};
    	};
    };
    jsPlumbUtil.extend(jsPlumb.Overlays.Arrow, AbstractOverlay);

    /*
     * Class: Overlays.PlainArrow
	 *
	 * A basic arrow.  This is in fact just one instance of the more generic case in which the tail folds back on itself to some
	 * point along the length of the arrow: in this case, that foldback point is the full length of the arrow.  so it just does
	 * a 'call' to Arrow with foldback set appropriately.
	 */
    /*
     * Function: Constructor
     * See <Overlays.Arrow> for allowed parameters for this overlay.
     */
    jsPlumb.Overlays.PlainArrow = function(params) {
    	params = params || {};
    	var p = jsPlumb.extend(params, {foldback:1});
    	jsPlumb.Overlays.Arrow.call(this, p);
    	this.type = "PlainArrow";
    };
    jsPlumbUtil.extend(jsPlumb.Overlays.PlainArrow, jsPlumb.Overlays.Arrow);

    /*
     * Class: Overlays.Diamond
     *
	 * A diamond. Like PlainArrow, this is a concrete case of the more generic case of the tail points converging on some point...it just
	 * happens that in this case, that point is greater than the length of the the arrow.
	 *
	 *      this could probably do with some help with positioning...due to the way it reuses the Arrow paint code, what Arrow thinks is the
	 *      center is actually 1/4 of the way along for this guy.  but we don't have any knowledge of pixels at this point, so we're kind of
	 *      stuck when it comes to helping out the Arrow class. possibly we could pass in a 'transpose' parameter or something. the value
	 *      would be -l/4 in this case - move along one quarter of the total length.
	 */
    /*
     * Function: Constructor
     * See <Overlays.Arrow> for allowed parameters for this overlay.
     */
    jsPlumb.Overlays.Diamond = function(params) {
    	params = params || {};
    	var l = params.length || 40,
    	    p = jsPlumb.extend(params, {length:l/2, foldback:2});
    	jsPlumb.Overlays.Arrow.call(this, p);
    	this.type = "Diamond";
    };
    jsPlumbUtil.extend(jsPlumb.Overlays.Diamond, jsPlumb.Overlays.Arrow);

    var _getDimensions = function(component) {
        if (component._jsPlumb.cachedDimensions == null)
            component._jsPlumb.cachedDimensions = component.getDimensions();
        return component._jsPlumb.cachedDimensions;
    };

	// abstract superclass for overlays that add an element to the DOM.
    var AbstractDOMOverlay = function(params) {
		jsPlumb.DOMElementComponent.apply(this, arguments);
    	AbstractOverlay.apply(this, arguments);

		var jpcl = jsPlumb.CurrentLibrary;
		this.id = params.id;
        this._jsPlumb.div = null;
        this._jsPlumb.initialised = false;
        this._jsPlumb.component = params.component;
        this._jsPlumb.cachedDimensions = null;
        this._jsPlumb.create = params.create;

		this.getElement = function() {
			if (this._jsPlumb.div == null) {
                var div = this._jsPlumb.div = jpcl.getDOMElement(this._jsPlumb.create(this._jsPlumb.component));
                div.style.position   =   "absolute";
                var clazz = params._jsPlumb.overlayClass + " " +
                    (this.cssClass ? this.cssClass :
                    params.cssClass ? params.cssClass : "");
                div.className = clazz;
                this._jsPlumb.instance.appendElement(div, this._jsPlumb.component.parent);
                this._jsPlumb.instance.getId(div);
                this.attachListeners(div, this);
                this.canvas = div;
			}
    		return this._jsPlumb.div;
    	};

		this.draw = function(component, currentConnectionPaintStyle, absolutePosition) {
	    	var td = _getDimensions(this);
	    	if (td != null && td.length == 2) {
				var cxy = { x:0,y:0 };

                // absolutePosition would have been set by a call to connection.setAbsoluteOverlayPosition.
                if (absolutePosition) {
                    cxy = { x:absolutePosition[0], y:absolutePosition[1] };
                }
                else if (component.pointOnPath) {
                    var loc = this.loc, absolute = false;
                    if (jsPlumbUtil.isString(this.loc) || this.loc < 0 || this.loc > 1) {
                        loc = parseInt(this.loc, 10);
                        absolute = true;
                    }
                    cxy = component.pointOnPath(loc, absolute);  // a connection
                }
                else {
                    var locToUse = this.loc.constructor == Array ? this.loc : this.endpointLoc;
                    cxy = { x:locToUse[0] * component.w,
                            y:locToUse[1] * component.h };
                }

				var minx = cxy.x - (td[0] / 2),
				    miny = cxy.y - (td[1] / 2);

                return {
                    component:component,
                    d:{ minx:minx, miny:miny, td:td, cxy:cxy },
                    minX:minx,
                    maxX:minx + td[0],
                    minY:miny,
                    maxY:miny + td[1]
                };
        	}
	    	else return {minX:0,maxX:0,minY:0,maxY:0};
	    };
	};
    jsPlumbUtil.extend(AbstractDOMOverlay, [jsPlumb.DOMElementComponent, AbstractOverlay], {
        getDimensions : function() {
            return jsPlumb.CurrentLibrary.getSize(jsPlumb.CurrentLibrary.getElementObject(this.getElement()));
        },
        setVisible : function(state) {
            this._jsPlumb.div.style.display = state ? "block" : "none";
        },
        /*
         * Function: clearCachedDimensions
         * Clears the cached dimensions for the label. As a performance enhancement, label dimensions are
         * cached from 1.3.12 onwards. The cache is cleared when you change the label text, of course, but
         * there are other reasons why the text dimensions might change - if you make a change through CSS, for
         * example, you might change the font size.  in that case you should explicitly call this method.
         */
        clearCachedDimensions : function() {
            this._jsPlumb.cachedDimensions = null;
        },
        cleanup : function() {
            if (this._jsPlumb.div != null)
                jsPlumb.CurrentLibrary.removeElement(this._jsPlumb.div);
        },
        computeMaxSize : function() {
            var td = _getDimensions(this);
            return Math.max(td[0], td[1]);
        },
        reattachListeners : function(connector) {
            if (this._jsPlumb.div) {
                this.reattachListenersForElement(this._jsPlumb.div, this, connector);
            }
        },
        paint : function(p, containerExtents) {
            if (!this._jsPlumb.initialised) {
                this.getElement();
                p.component.appendDisplayElement(this._jsPlumb.div);
                this.attachListeners(this._jsPlumb.div, p.component);
                this._jsPlumb.initialised = true;
            }
            this._jsPlumb.div.style.left = (p.component.x + p.d.minx) + "px";
            this._jsPlumb.div.style.top = (p.component.y + p.d.miny) + "px";
        }
    });

	/*
     * Class: Overlays.Custom
     * A Custom overlay. You supply a 'create' function which returns some DOM element, and jsPlumb positions it.
     * The 'create' function is passed a Connection or Endpoint.
     */
    /*
     * Function: Constructor
     *
     * Parameters:
     * 	create - function for jsPlumb to call that returns a DOM element.
     * 	location - distance (as a decimal from 0 to 1 inclusive) marking where the label should sit on the connector. defaults to 0.5.
     * 	id - optional id to use for later retrieval of this overlay.
     *
     */
    jsPlumb.Overlays.Custom = function(params) {
    	this.type = "Custom";
    	AbstractDOMOverlay.apply(this, arguments);
    };
    jsPlumbUtil.extend(jsPlumb.Overlays.Custom, AbstractDOMOverlay);

    jsPlumb.Overlays.GuideLines = function() {
        var self = this;
        self.length = 50;
        self.lineWidth = 5;
        this.type = "GuideLines";
        AbstractOverlay.apply(this, arguments);
        jsPlumb.jsPlumbUIComponent.apply(this, arguments);
        this.draw = function(connector, currentConnectionPaintStyle) {

            var head = connector.pointAlongPathFrom(self.loc, self.length / 2),
                mid = connector.pointOnPath(self.loc),
                tail = jsPlumbGeom.pointOnLine(head, mid, self.length),
                tailLine = jsPlumbGeom.perpendicularLineTo(head, tail, 40),
                headLine = jsPlumbGeom.perpendicularLineTo(tail, head, 20);

            return {
                connector:connector,
                head:head,
                tail:tail,
                headLine:headLine,
                tailLine:tailLine,
                minX:Math.min(head.x, tail.x, headLine[0].x, headLine[1].x),
                minY:Math.min(head.y, tail.y, headLine[0].y, headLine[1].y),
                maxX:Math.max(head.x, tail.x, headLine[0].x, headLine[1].x),
                maxY:Math.max(head.y, tail.y, headLine[0].y, headLine[1].y)
            };
        };

       // this.cleanup = function() { };  // nothing to clean up for GuideLines
    };

    /*
     * Class: Overlays.Label

     */
    /*
     * Function: Constructor
     *
     * Parameters:
     * 	cssClass - optional css class string to append to css class. This string is appended "as-is", so you can of course have multiple classes
     *             defined.  This parameter is preferred to using labelStyle, borderWidth and borderStyle.
     * 	label - the label to paint.  May be a string or a function that returns a string.  Nothing will be painted if your label is null or your
     *         label function returns null.  empty strings _will_ be painted.
     * 	location - distance (as a decimal from 0 to 1 inclusive) marking where the label should sit on the connector. defaults to 0.5.
     * 	id - optional id to use for later retrieval of this overlay.
     *
     *
     */
    jsPlumb.Overlays.Label =  function(params) {
		this.labelStyle = params.labelStyle;

        var labelWidth = null, labelHeight =  null, labelText = null, labelPadding = null;
		this.cssClass = this.labelStyle != null ? this.labelStyle.cssClass : null;
		var p = jsPlumb.extend({
            create : function() {
                return document.createElement("div");
            }}, params);
    	jsPlumb.Overlays.Custom.call(this, p);
		this.type = "Label";
        this.label = params.label || "";
        this.labelText = null;
        if (this.labelStyle) {
            var el = this.getElement();
            this.labelStyle.font = this.labelStyle.font || "12px sans-serif";
            el.style.font = this.labelStyle.font;
            el.style.color = this.labelStyle.color || "black";
            if (this.labelStyle.fillStyle) el.style.background = this.labelStyle.fillStyle;
            if (this.labelStyle.borderWidth > 0) {
                var dStyle = this.labelStyle.borderStyle ? this.labelStyle.borderStyle : "black";
                el.style.border = this.labelStyle.borderWidth  + "px solid " + dStyle;
            }
            if (this.labelStyle.padding) el.style.padding = this.labelStyle.padding;
        }

    };
    jsPlumbUtil.extend(jsPlumb.Overlays.Label, jsPlumb.Overlays.Custom, {
        cleanup:function() {
            this.div = null;
            this.label = null;
            this.labelText = null;
            this.cssClass = null;
            this.labelStyle = null;
        },
        getLabel : function() {
            return this.label;
        },
        /*
         * Function: setLabel
         * sets the label's, um, label.  you would think i'd call this function
         * 'setText', but you can pass either a Function or a String to this, so
         * it makes more sense as 'setLabel'. This uses innerHTML on the label div, so keep
         * that in mind if you need escaped HTML.
         */
        setLabel : function(l) {
            this.label = l;
            this.labelText = null;
            this.clearCachedDimensions();
            this.update();
            this.component.repaint();
        },
        getDimensions : function() {
            this.update();
            return AbstractDOMOverlay.prototype.getDimensions.apply(this, arguments);
        },
        update : function() {
            if (typeof this.label == "function") {
                var lt = this.label(this);
                this.getElement().innerHTML = lt.replace(/\r\n/g, "<br/>");
            }
            else {
                if (this.labelText == null) {
                    this.labelText = this.label;
                    this.getElement().innerHTML = this.labelText.replace(/\r\n/g, "<br/>");
                }
            }
        }
    });

 // ********************************* END OF OVERLAY DEFINITIONS ***********************************************************************

})();


text:
{% extends './train_base.html' %}

{% block head %}
<link rel="stylesheet" href="/static/css/codemirror.css"/>
<script src="/static/js/codemirror.js"></script>
<script src="/static/js/uikit/components/htmleditor.js"></script>
{% endblock %}

{% block jump-title  %}
{% if ! __id %}
课程创建成功
{% else %}
课程修改成功
{% endif %}
{% endblock %}

{% block production_readyscript %}
{% include './component/build/train_course.js' %}
{% if ! __id %}
ReactDOM.render(
 	React.createElement(NewCoursePage, {}), document.getElementById('vm')
 	);
{% else %}
ReactDOM.render(
 	React.createElement(EditCoursePage, {cid:'{{__id}}'}), document.getElementById('vm')
 	);
{% endif %}
{% endblock %}

{% block developmode_readyscript %}
{% include './component/src/train_course.jsx' %}
{% if ! __id %}
ReactDOM.render(
	<NewCoursePage  />,
		document.getElementById('vm')
	);
{% else %}
ReactDOM.render(
	<EditCoursePage cid='{{__id}}' />,
		document.getElementById('vm')
	);
{% endif %}
{% endblock %}

redpajama_set_name: RedPajamaGithub


text:
![LOGO](misc/logo.png)

[![Documentation](https://img.shields.io/badge/documentation-shtools.github.io%2FSHTOOLS%2F-yellow.svg)](https://shtools.github.io/SHTOOLS/)
[![DOI](https://zenodo.org/badge/doi/10.5281/zenodo.592762.svg)](https://doi.org/10.5281/zenodo.592762)
[![Paper](https://img.shields.io/badge/paper-10.1029/2018GC007529-orange.svg)](https://doi.org/10.1029/2018GC007529)
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/SHTOOLS/SHTOOLS/master?filepath=examples%2Fnotebooks%2F)
[![Chat on matrix](https://img.shields.io/badge/chat-on_[matrix]-4bb596.svg)](https://matrix.to/#/#pyshtools:matrix.org?via=matrix.org&via=gitter.im)
[![Chat at gitter](https://badges.gitter.im/SHTOOLS/SHTOOLS.svg)](https://gitter.im/SHTOOLS/SHTOOLS?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Twitter](https://img.shields.io/twitter/follow/pyshtools.svg?style=social&label=Follow)](https://twitter.com/intent/follow?screen_name=pyshtools)

SHTOOLS/pyshtools is a Fortran-95/Python library that can be used to perform
spherical harmonic transforms, multitaper spectral analyses, expansions of functions into Slepian bases, and standard operations on global gravitational and magnetic field data.

### FEATURES ###

* Supports all standard normalizations and phase conventions of the spherical harmonic functions.

* Effortless conversion between real and complex harmonics, between phase conventions, and between 4π normalized, Schmidt semi-normalized, orthonormalized, and unnormalized harmonics.

* Use of both regularly sampled geographic grids and grids appropriate for Gauss-Legendre quadrature.

* Spherical harmonic transforms proven to be accurate up to about degree 2800.

* Perform localized multitaper spectral analyses, or expand functions in terms of localized Slepian bases.

* Support for standard data and file formats, including *xarray* and *netcdf*.

* Import research-grade gravity, topography, and magnetic field datasets with a single command.

* Creation of publication quality maps using [Cartopy](https://scitools.org.uk/cartopy) and [pygmt](https://www.pygmt.org/).

* OpenMP compatible and OpenMP thread-safe versions of the Fortran routines.

### INSTALLATION ###
#### pyshtools (for Python) ####

Install using `conda`:
```bash
conda install -c conda-forge pyshtools  # Linux and macOS only
conda update -c conda-forge pyshtools  # to upgrade a pre-existing installation
```

Install using `pip`:
```bash
pip install pyshtools
pip install --upgrade pyshtools  # to upgrade a pre-existing installation
pip install pyshtools --no-binary pyshtools  # build from source
pip install git+https://github.com/SHTOOLS/SHTOOLS@develop  # install the develop branch from source
```

For developers, install the requirements
```bash
# Linux: install gfortran, fftw3, blas, and lapack
sudo apt-get install g++ gfortran libfftw3-dev libblas-dev liblapack-dev
# macOS: install fftw using brew or macports
brew install fftw
sudo port install fftw-3
# macOS: for LAPACK, link to the system '-framework Accelerate' or install openblas
```

then clone the shtools repo and install manually:
```bash
git clone https://github.com/SHTOOLS/SHTOOLS.git
cd shtools
git checkout develop
pip install -e .  # install into the shtools folder and link to the active python environment
```

#### SHTOOLS (for Fortran 95) ####

Install using the [brew](http://brew.sh/) package manager (macOS, linux, windows):
```bash
brew install shtools
```

Install using the [macports](https://www.macports.org/) package manager (macOS)
```bash
sudo port install shtools
```

Install from source. Clone or download the shtools repo, and then execute one (or both) of the following commands in the shtools directory:
```bash
make fortran
make fortran-mp  # for OpenMP Fortran routines
```

Further installation instructions and options can be found in the [web documentation](https://shtools.github.io/SHTOOLS/).

### HOW TO USE ###

SHTOOLS can be invoked in any Fortran 95 or Python program. The core software is written in Fortran 95, and Python wrappers and dedicated classes allow simple access to the fortran-compiled routines. A variety of Python tutorials and guides are included that demonstrate the major features of the library.

To get started, click on the following Python tutorials and then run them interactively in Binder:

* [Spherical harmonic coefficients and grids](https://nbviewer.jupyter.org/github/SHTOOLS/SHTOOLS/blob/master/examples/notebooks/grids-and-coefficients.ipynb)
* [Localization windows and spectral analysis](https://nbviewer.jupyter.org/github/SHTOOLS/SHTOOLS/blob/master/examples/notebooks/localized-spectral-analysis.ipynb)
* [Gravity and magnetic fields](https://nbviewer.jupyter.org/github/SHTOOLS/SHTOOLS/blob/master/examples/notebooks/gravity-and-magnetic-fields.ipynb)
* [Plotting maps](https://nbviewer.jupyter.org/github/SHTOOLS/SHTOOLS/blob/master/examples/notebooks/plotting-maps.ipynb)

### DEVELOPERS ###

We work on the `develop` branch and only push releases to `master`. Please base all pull requests on `develop`.

### REFERENCE ###

Mark A. Wieczorek and Matthias Meschede (2018). SHTools --- Tools for working with spherical harmonics, *Geochemistry, Geophysics, Geosystems*, 19, 2574-2592, doi:[10.1029/2018GC007529](https://doi.org/10.1029/2018GC007529).


text:
define([
    'ko',
    'underscore',
    'mageUtils',
    'uiLayout',
    'uiElement'
], function (ko, _, utils, layout, Element) {
    'use strict';

    return Element.extend({
        defaults: {
            template: 'ui/grid/paging/paging',
            totalTmpl: 'ui/grid/paging-total',
            pageSize: 20,
            current: 1,
            selectProvider: '',

            sizesConfig: {
                component: 'Magento_Ui/js/grid/paging/sizes',
                name: '${ $.name }_sizes',
                storageConfig: {
                    provider: '${ $.storageConfig.provider }',
                    namespace: '${ $.storageConfig.namespace }'
                }
            },

            imports: {
                pageSize: '${ $.sizesConfig.name }:value',
                totalSelected: '${ $.selectProvider }:totalSelected',
                totalRecords: '${ $.provider }:data.totalRecords'
            },

            exports: {
                pageSize: '${ $.provider }:params.paging.pageSize',
                current: '${ $.provider }:params.paging.current'
            },

            listens: {
                'pages': 'onPagesChange',
                'pageSize': 'onPageSizeChange',
                'totalRecords': 'updateCounter',
                '${ $.provider }:params.filters': 'goFirst'
            },

            modules: {
                sizes: '${ $.sizesConfig.name }'
            }
        },

        /**
         * Initializes paging component.
         *
         * @returns {Paging} Chainable.
         */
        initialize: function () {
            this._super()
                .initSizes()
                .updateCounter();

            return this;
        },

        /**
         * Initializes observable properties.
         *
         * @returns {Paging} Chainable.
         */
        initObservable: function () {
            this._super()
                .track([
                    'totalSelected',
                    'totalRecords',
                    'pageSize',
                    'pages',
                    'current'
                ]);

            this._current = ko.pureComputed({
                read: ko.getObservable(this, 'current'),

                /**
                 * Validates page change according to user's input.
                 * Sets current observable to result of validation.
                 * Calls reload method then.
                 */
                write: function (value) {
                    this.setPage(value)
                        ._current.notifySubscribers(this.current);
                },

                owner: this
            });

            return this;
        },

        /**
         * Initializes sizes component.
         *
         * @returns {Paging} Chainable.
         */
        initSizes: function () {
            layout([this.sizesConfig]);

            return this;
        },

        /**
         * Sets cursor to the provied value.
         *
         * @param {(Number|String)} value - New value of the cursor.
         * @returns {Paging} Chainable.
         */
        setPage: function (value) {
            this.current = this.normalize(value);

            return this;
        },

        /**
         * Increments current page value.
         *
         * @returns {Paging} Chainable.
         */
        next: function () {
            this.setPage(this.current + 1);

            return this;
        },

        /**
         * Decrements current page value.
         *
         * @returns {Paging} Chainable.
         */
        prev: function () {
            this.setPage(this.current - 1);

            return this;
        },

        /**
         * Goes to the first page.
         *
         * @returns {Paging} Chainable.
         */
        goFirst: function () {
            this.current = 1;

            return this;
        },

        /**
         * Goes to the last page.
         *
         * @returns {Paging} Chainable.
         */
        goLast: function () {
            this.current = this.pages;

            return this;
        },

        /**
         * Checks if current page is the first one.
         *
         * @returns {Boolean}
         */
        isFirst: function () {
            return this.current === 1;
        },

        /**
         * Checks if current page is the last one.
         *
         * @returns {Boolean}
         */
        isLast: function () {
            return this.current === this.pages;
        },

        /**
         * Updates number of pages.
         */
        updateCounter: function () {
            this.pages = Math.ceil(this.totalRecords / this.pageSize) || 1;

            return this;
        },

        /**
         * Calculates new page cursor based on the
         * previous and current page size values.
         *
         * @returns {Number} Updated cursor value.
         */
        updateCursor: function () {
            var cursor  = this.current - 1,
                size    = this.pageSize,
                oldSize = this.previousSize,
                delta   = cursor * (oldSize  - size) / size;

            delta = size > oldSize ?
                Math.ceil(delta) :
                Math.floor(delta);

            cursor += delta + 1;

            this.previousSize = size;

            this.setPage(cursor);

            return this;
        },

        /**
         * Converts provided value to a number and puts
         * it in range between 1 and total amount of pages.
         *
         * @param {(Number|String)} value - Value to be normalized.
         * @returns {Number}
         */
        normalize: function (value) {
            value = +value;

            if (isNaN(value)) {
                return 1;
            }

            return utils.inRange(Math.round(value), 1, this.pages);
        },

        /**
         * Handles changes of the page size.
         */
        onPageSizeChange: function () {
            this.updateCounter()
                .updateCursor();
        },

        /**
         * Handles changes of the pages amount.
         */
        onPagesChange: function () {
            this.updateCursor();
        }
    });
});


text:
const LOGGER_LEVELS = require('sk/constants').LOGGER_LEVELS
const ELEMENT_ID = 'SKALD-LOGGER-'+Math.random().toString(16).substring(2)

/**
 * Not yet implemented.
 *
 * @param {String} message - The message string.
 * @param {LOGGER_LEVELS} level - The logger level.
 */
function domHandler(message, level) {
  let element = document.getElementById(ELEMENT_ID)
  if (!element) {
    element = _createElement()
  }

  _createParagraph(element, message, level)
  _pruneChildren(element)
}

function _createElement() {
  let container = document.createElement('div')
  container.setAttribute('id', ELEMENT_ID)
  container.style['position'] = 'fixed'
  container.style['bottom'] = '0'
  container.style['left'] = '0'
  container.style['right'] = '0'
  container.style['height'] = '30px'
  container.style['padding'] = '10px'
  container.style['border-top'] = '10px solid #565656'
  container.style['background'] = '#e3e3e3'
  container.style['overflow'] = 'auto'
  document.body.appendChild(container)

  container.onclick = function() {
    if (container.style['height'] === '30px') {
      container.style['height'] = '30vw'
    } else {
      container.style['height'] = '30px'
    }
  }

  return container
}

function _createParagraph(element, text, level) {
  let p = document.createElement('p')
  p.innerHTML = text
  p.style['font-family'] = 'monospace'
  p.style['font-size'] = '10pt'

  if (level === LOGGER_LEVELS.ERROR || level === LOGGER_LEVELS.FATAL){
    p.style['color'] = '#832918'
  }

  else if (level === LOGGER_LEVELS.WARN) {
    p.style['color'] = '#EC9612'
  }

  else if (level === LOGGER_LEVELS.DEBUG || level === LOGGER_LEVELS.TRACE) {
    p.style['color'] = '#A0A0A0'
  }

  element.insertBefore(p, element.firstChild)
}

function _pruneChildren(element) {
  if (element.children.length > 100) {
    let children = Array.from(element.children).slice(100)
    for (let i=0; i<children.length; i++) {
      element.removeChild(children[i])
    }
  }
}

module.exports = domHandler


text:
/*
 * DO NOT EDIT.  THIS FILE IS GENERATED FROM /builds/slave/rel-m-rel-xr-osx64-bld/build/netwerk/base/public/nsIEncodedChannel.idl
 */

#ifndef __gen_nsIEncodedChannel_h__
#define __gen_nsIEncodedChannel_h__

#ifndef __gen_nsISupports_h__
#include "nsISupports.h"
#endif

/* For IDL files that don't want to include root IDL files. */
#ifndef NS_NO_VTABLE
#define NS_NO_VTABLE
#endif
class nsIUTF8StringEnumerator; /* forward declaration */

/* starting interface:    nsIEncodedChannel */
#define NS_IENCODEDCHANNEL_IID_STR "30d7ec3a-f376-4652-9276-3092ec57abb6"

#define NS_IENCODEDCHANNEL_IID \
  {0x30d7ec3a, 0xf376, 0x4652, \
    { 0x92, 0x76, 0x30, 0x92, 0xec, 0x57, 0xab, 0xb6 }}

class NS_NO_VTABLE NS_SCRIPTABLE nsIEncodedChannel : public nsISupports {
 public:

  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IENCODEDCHANNEL_IID)

  /* readonly attribute nsIUTF8StringEnumerator contentEncodings; */
  NS_SCRIPTABLE NS_IMETHOD GetContentEncodings(nsIUTF8StringEnumerator * *aContentEncodings) = 0;

  /* attribute boolean applyConversion; */
  NS_SCRIPTABLE NS_IMETHOD GetApplyConversion(PRBool *aApplyConversion) = 0;
  NS_SCRIPTABLE NS_IMETHOD SetApplyConversion(PRBool aApplyConversion) = 0;

};

  NS_DEFINE_STATIC_IID_ACCESSOR(nsIEncodedChannel, NS_IENCODEDCHANNEL_IID)

/* Use this macro when declaring classes that implement this interface. */
#define NS_DECL_NSIENCODEDCHANNEL \
  NS_SCRIPTABLE NS_IMETHOD GetContentEncodings(nsIUTF8StringEnumerator * *aContentEncodings); \
  NS_SCRIPTABLE NS_IMETHOD GetApplyConversion(PRBool *aApplyConversion); \
  NS_SCRIPTABLE NS_IMETHOD SetApplyConversion(PRBool aApplyConversion);

/* Use this macro to declare functions that forward the behavior of this interface to another object. */
#define NS_FORWARD_NSIENCODEDCHANNEL(_to) \
  NS_SCRIPTABLE NS_IMETHOD GetContentEncodings(nsIUTF8StringEnumerator * *aContentEncodings) { return _to GetContentEncodings(aContentEncodings); } \
  NS_SCRIPTABLE NS_IMETHOD GetApplyConversion(PRBool *aApplyConversion) { return _to GetApplyConversion(aApplyConversion); } \
  NS_SCRIPTABLE NS_IMETHOD SetApplyConversion(PRBool aApplyConversion) { return _to SetApplyConversion(aApplyConversion); }

/* Use this macro to declare functions that forward the behavior of this interface to another object in a safe way. */
#define NS_FORWARD_SAFE_NSIENCODEDCHANNEL(_to) \
  NS_SCRIPTABLE NS_IMETHOD GetContentEncodings(nsIUTF8StringEnumerator * *aContentEncodings) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetContentEncodings(aContentEncodings); } \
  NS_SCRIPTABLE NS_IMETHOD GetApplyConversion(PRBool *aApplyConversion) { return !_to ? NS_ERROR_NULL_POINTER : _to->GetApplyConversion(aApplyConversion); } \
  NS_SCRIPTABLE NS_IMETHOD SetApplyConversion(PRBool aApplyConversion) { return !_to ? NS_ERROR_NULL_POINTER : _to->SetApplyConversion(aApplyConversion); }

#if 0
/* Use the code below as a template for the implementation class for this interface. */

/* Header file */
class nsEncodedChannel : public nsIEncodedChannel
{
public:
  NS_DECL_ISUPPORTS
  NS_DECL_NSIENCODEDCHANNEL

  nsEncodedChannel();

private:
  ~nsEncodedChannel();

protected:
  /* additional members */
};

/* Implementation file */
NS_IMPL_ISUPPORTS1(nsEncodedChannel, nsIEncodedChannel)

nsEncodedChannel::nsEncodedChannel()
{
  /* member initializers and constructor code */
}

nsEncodedChannel::~nsEncodedChannel()
{
  /* destructor code */
}

/* readonly attribute nsIUTF8StringEnumerator contentEncodings; */
NS_IMETHODIMP nsEncodedChannel::GetContentEncodings(nsIUTF8StringEnumerator * *aContentEncodings)
{
    return NS_ERROR_NOT_IMPLEMENTED;
}

/* attribute boolean applyConversion; */
NS_IMETHODIMP nsEncodedChannel::GetApplyConversion(PRBool *aApplyConversion)
{
    return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsEncodedChannel::SetApplyConversion(PRBool aApplyConversion)
{
    return NS_ERROR_NOT_IMPLEMENTED;
}

/* End of implementation class template. */
#endif

#endif /* __gen_nsIEncodedChannel_h__ */


text:
require([
	"App",
	"routers/AppRouter",
	"controllers/Controller",
	"marionette"
],function(
	App,
	AppRouter,
	AppController
){

    App.appRouter = new AppRouter({
        controller: new AppController()
    });
    App.start();

});


text:
<!doctype html>

	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>VirtualText | @phosphor/virtualdom</title>
	<meta name="description" content="">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" href="../assets/css/main.css">

						Search
						<input id="tsd-search-field" type="text" />

Preparing search index...

The search index is not available

					@phosphor/virtualdom

						Options

								All

Public

Public/Protected

All

							<input type="checkbox" id="tsd-filter-inherited" checked />
							Inherited
							<input type="checkbox" id="tsd-filter-externals" checked />
							Externals

					Menu

					Globals

					VirtualText

Class VirtualText

A virtual node which represents plain text content.

Notes

User code will not typically create a VirtualText node directly.
					Instead, the h() function will be used to create an element tree.

Hierarchy

						VirtualText

Index

Constructors

constructor

Properties

content

type

Constructors

constructor

new <wbr>Virtual<wbr>Text(content: string): VirtualText

Defined in index.ts:689

Construct a new virtual text node.

Parameters

content: string

The text content for the node.

Returns VirtualText

Properties

content

content: string

Defined in index.ts:681

The text content for the node.

type

type: "text" = "text"

Defined in index.ts:689

The type of the node.

This value can be used as a type guard for discriminating the
						VirtualNode union type.

						Globals

						Virtual<wbr>Element

						Virtual<wbr>Text

								constructor

								content

								type

						CSSProperty<wbr>Names

						Element<wbr>Attr<wbr>Names

						Element<wbr>Attrs

						Element<wbr>Base<wbr>Attrs

						Element<wbr>Dataset

						Element<wbr>Event<wbr>Attrs

						Element<wbr>Event<wbr>Map

						Element<wbr>Inline<wbr>Style

						Element<wbr>Special<wbr>Attrs

						Virtual<wbr>Node

Legend

Module

Object literal

Variable

Function

Function with type parameter

Index signature

Type alias

Enumeration

Enumeration member

Property

Method

Interface

Interface with type parameter

Constructor

Property

Method

Index signature

Class

Class with type parameter

Constructor

Property

Method

Accessor

Index signature

Inherited constructor

Inherited property

Inherited method

Inherited accessor

Protected property

Protected method

Protected accessor

Private property

Private method

Private accessor

Static property

Static method

Generated using TypeDoc


text:
<!DOCTYPE html>

  <title>Alex's DBC Journey</title>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">

  <link rel="stylesheet" type="text/css" href="stylesheets/enum.css">

Alex Mitzman

About me

Projects

Blog

Resume

Contact

Enumerables

#map

November 22nd, 2015

        What a difference a week makes.  Felt like we went from 0 to 60 real fast in Ruby.  This week was full of very difficult challenges that I spent most of my time sifting through the Ruby Docs researching methods and enumerables.  Enumerables are ways to search, sort and manipulate data and are very helpful when it comes to refactoring code.  One of the more popular enumerable I used was map.  Below are a couple of examples that show how to use map and how it works.

In this first example, I have an array of numbers.  I decided that I want to multiply each number by five, so I used the .map! enumerable on my array.  The first of the structure takes each element (which I called "num") then for the block of code I have the element being multiplied by five.  Then you can see the array with new values multiplied by five.  In this instance, I called the destructive method of map by using an !.  So this means when I call map!, it will modify my_array itself instead of creating a new array.

In this next example, I use map again, but the non destructive form.  For this one I had an array of greetings.  I decided I wanted to personalize the array so I called the map enumerable to add my name to each greeting.  It has the same set up as the previous example.  The biggest difference is that when I call my array, it doesn't have the modification.  This is because the non destructive map creates a brand new array and doesn't modify the original.

        Facebook
        LinkedIn
        Twitter
        GitHub


text:
ACCEPTED

#### According to
International Plant Names Index

#### Published in
null

#### Original name
Rabdosia pseudoirrorata C.Y.Wu

### Remarks
null


text:
<?xml version="1.0" encoding="UTF-8"?>
<jhove xmlns="http://hul.harvard.edu/ois/xml/ns/jhove"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       date="2019-02-05"
       name="epubcheck"
       release="4.2.0-beta-SNAPSHOT"
       xsi:schemaLocation="http://hul.harvard.edu/ois/xml/ns/jhove http://hul.harvard.edu/ois/xml/xsd/jhove/jhove.xsd">
   <date>2019-02-05T15:38:26+01:00</date>
   <repInfo uri="/Users/Romain/Work/epubcheck/epubcheck/target/test-classes/com/adobe/epubcheck/test/command_line/xmlfile.epub">
      <created>2019-02-05T15:38:16Z</created>
      <lastModified>2012-10-10T12:00:00Z</lastModified>
      <format>application/epub+zip</format>
      <version>3.0.1</version>
      <status>Well-formed</status>
      <messages>
         <message severity="info" subMessage="ACC-008">ACC-008, HINT, [Navigation Document has no 'landmarks nav' element.], OPS/toc.xhtml</message>
         <message severity="info" subMessage="HTM-010">HTM-010, HINT, [Namespace uri 'http://www.daisy.org/z3986/2005/ncx/' was found.], OPS/toc.ncx (2-68)</message>
         <message severity="info" subMessage="CSS-009">CSS-009, HINT, [Use of certain CSS such as Columns, Transforms, Transitions, box-sizing or KeyFrames can cause pagination issues.], OPS/style.css (3-23)</message>
         <message severity="info" subMessage="CSS-009">CSS-009, HINT, [Use of certain CSS such as Columns, Transforms, Transitions, box-sizing or KeyFrames can cause pagination issues.], OPS/style.css (8-23)</message>
         <message severity="info" subMessage="CSS-009">CSS-009, HINT, [Use of certain CSS such as Columns, Transforms, Transitions, box-sizing or KeyFrames can cause pagination issues.], OPS/style_tag_css.xhtml (8-31)</message>
         <message severity="info" subMessage="CSS-009">CSS-009, HINT, [Use of certain CSS such as Columns, Transforms, Transitions, box-sizing or KeyFrames can cause pagination issues.], OPS/style_tag_css.xhtml (13-31)</message>
         <message severity="info" subMessage="CSS-009">CSS-009, HINT, [Use of certain CSS such as Columns, Transforms, Transitions, box-sizing or KeyFrames can cause pagination issues.], OPS/style_tag_css.xhtml (5-28)</message>
         <message severity="info" subMessage="ACC-013">ACC-013, HINT, [Content file contains at least one inline style declaration.], OPS/inline_css.xhtml (10-119)</message>
         <message severity="info" subMessage="ACC-013">ACC-013, HINT, [Content file contains at least one inline style declaration.], OPS/inline_css.xhtml (11-115)</message>
         <message severity="info" subMessage="ACC-013">ACC-013, HINT, [Content file contains at least one inline style declaration.], OPS/inline_css.xhtml (14-116)</message>
         <message severity="info" subMessage="ACC-013">ACC-013, HINT, [Content file contains at least one inline style declaration.], OPS/inline_css.xhtml (15-114)</message>
      </messages>
      <mimeType>application/epub+zip</mimeType>
      <properties>
         <property>
            <name>FileName</name>
            <values arity="Scalar" type="String">
               <value>xmlfile.epub</value>
            </values>
         </property>
         <property>
            <name>CharacterCount</name>
            <values arity="Scalar" type="Long">
               <value>648</value>
            </values>
         </property>
         <property>
            <name>Language</name>
            <values arity="Scalar" type="String">
               <value>en</value>
            </values>
         </property>
         <property>
            <name>Info</name>
            <values arity="List" type="Property">
               <property>
                  <name>Identifier</name>
                  <values arity="Scalar" type="String">
                     <value>000000000000000000</value>
                  </values>
               </property>
               <property>
                  <name>CreationDate</name>
                  <values arity="Scalar" type="Date">
                     <value>2019-02-05T15:38:16Z</value>
                  </values>
               </property>
               <property>
                  <name>ModDate</name>
                  <values arity="Scalar" type="Date">
                     <value>2012-10-10T12:00:00Z</value>
                  </values>
               </property>
               <property>
                  <name>Title</name>
                  <values arity="Scalar" type="String">
                     <value>Transform Sample Book</value>
                  </values>
               </property>
            </values>
         </property>
         <property>
            <name>MediaTypes</name>
            <values arity="Array" type="String">
               <value>application/x-dtbncx+xml</value>
               <value>application/xhtml+xml</value>
               <value>text/css</value>
            </values>
         </property>
      </properties>
   </repInfo>
</jhove>


text:
<?php

class ModelNonStandardTest extends PHPUnit_Framework_TestCase
{

    function testDifferentTableName()
    {
        $item = new Different();
        $this->assertEquals('nonstandard', $item->getTableName());
        $this->assertEquals('different_id', $item->getPrimaryKey());
    }

    function testDifferentPrimaryKey()
    {
        $item = new Differentb();
        $this->assertEquals('differentbs', $item->getTableName());
        $this->assertEquals('id', $item->getPrimaryKey());
    }

    function testDifferentPrimaryKeyAndTable()
    {
        $item = new Differentc();
        $this->assertEquals('randomtable', $item->getTableName());
        $this->assertEquals('foobar', $item->getPrimaryKey());
    }

    function testUsingNonStandard()
    {
        $item = new Differentc();
        $item->title = 'My Title';
        $item->save();
        $this->assertEquals(1, $item->foobar);

        $other = new Differentc(1);
        $this->assertEquals('My Title', $other->title);
    }

    function testDifferentDisplayField()
    {
        $item = new Differentd();
        $this->assertEquals('kazi', $item->getDisplayField()->getFieldName());
    }

    function testDifferentDisplayValue()
    {
        $item = new Differentd();
        $item->kazi = 'My Name';
        $item->save();

        $this->assertEquals('My Name', $item->getDisplayValue());
        $other = new Differentd(1);
        $this->assertEquals('My Name', $other->getDisplayValue());
    }

    function testFindDifferentDisplayValue()
    {
        return $this->markTestSkipped("This is not good behavior, I think.");

        $item = new Differentd();
        $item->kazi = 'My Other Name';
        $item->save();

        $other = new Differentd('My Other Name');
        $this->assertEquals(2, $other->differentd_id);
    }

    function testRowNotFound()
    {
        $item = new Different(5);
        $this->assertEquals(5, $item->different_id);
    }

    /**
     * @expectedException Octopus_Model_Exception
     */
    function testUnknownPropertyGet()
    {
        $item = new Different();
        $try = $item->nonexisting;

    }

    /**
     * @expectedException Octopus_Model_Exception
     */
    function testUnknownPropertySet()
    {
        $item = new Different();
        $item->nonexisting = 'foo';

    }

    function testPluralize() {

        $cat = new Category();
        $cat->name = 'foo';
        $cat->save();

        $cat = new Category(1);
        $this->assertEquals('foo', $cat->name);

    }

    function testNoDisplayField() {

        return $this->markTestSkipped("No display field should return the ID.");

        $lack = new Lack();
        $lack->notitle = 'foo';

        $this->assertEquals('foo', $lack->getDisplayValue());
        $this->assertEquals('foo', (string)$lack);

    }

    function testNoDisplayFieldNoText() {

        $item = new Notext();
        $item->number = 42;
        $item->save();

        $this->assertEquals(1, $item->getDisplayValue());
        $this->assertEquals(1, (string)$item);

    }

    function testNoDisplayFieldNoTextNotSaved() {

        $item = new Notext();
        $item->number = 42;

        $this->assertEquals('', $item->getDisplayValue());
        $this->assertEquals('', (string)$item);

    }

}

/**
 * @internal
 * @copyright (c) 2012 Codestruck, LLC.
 * @license http://opensource.org/licenses/mit-license.php/
 */
class Different extends Octopus_Model {
    protected $table = 'nonstandard';
    protected $fields = array(
        'title' => array(),
        'created',
        'updated',
    );
}

/**
 * @internal
 * @copyright (c) 2012 Codestruck, LLC.
 * @license http://opensource.org/licenses/mit-license.php/
 */
class Differentb extends Octopus_Model {
    protected $primaryKey = 'id';
    protected $fields = array(
        'title' => array(),
        'created',
        'updated',
    );
}

/**
 * @internal
 * @copyright (c) 2012 Codestruck, LLC.
 * @license http://opensource.org/licenses/mit-license.php/
 */
class Differentc extends Octopus_Model {
    protected $primaryKey = 'foobar';
    protected $table = 'randomtable';
    protected $fields = array(
        'title' => array(),
        'created',
        'updated',
    );
}

/**
 * @internal
 * @copyright (c) 2012 Codestruck, LLC.
 * @license http://opensource.org/licenses/mit-license.php/
 */
class Differentd extends Octopus_Model {
    protected $displayField = 'kazi';
    protected $fields = array(
        'kazi' => array(),
        'created',
        'updated',
    );
}

/**
 * @internal
 * @copyright (c) 2012 Codestruck, LLC.
 * @license http://opensource.org/licenses/mit-license.php/
 */
class Category extends Octopus_Model {
    protected $fields = array(
        'name' => array(),
    );
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace hepa.WebUI.Models.Home
{
    public class Login
    {
    }
}


text:
define(['kbaseSamplePropertyHistogram'], (Widget) => {
    'use strict';
    describe('The kbaseSamplePropertyHistogram widget', () => {
        it('should be defined', () => {
            expect(Widget).toBeDefined();
        });
    });
});