text: /*
   * Paper.js
   *
   * This file is part of Paper.js, a JavaScript Vector Graphics Library,
   * based on Scriptographer.org and designed to be largely API compatible.
   * http://paperjs.org/
   * http://scriptographer.org/
   *
   * Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
   * http://lehni.org/ & http://jonathanpuckey.com/
   *
   * Distributed under the MIT license. See LICENSE file for details.
   *
   * All rights reserved.
   */
  
  /**
   * @name CompoundPath
   *
   * @class A compound path contains two or more paths, holes are drawn
   * where the paths overlap. All the paths in a compound path take on the
   * style of the backmost path and can be accessed through its
   * {@link Item#children} list.
   *
   * @extends PathItem
   */
  var CompoundPath = this.CompoundPath = PathItem.extend(/** @lends CompoundPath# */{
  	_type: 'compoundpath',
  	/**
  	 * Creates a new compound path item and places it in the active layer.
  	 *
  	 * @param {Path[]} [paths] the paths to place within the compound path.
  	 *
  	 * @example {@paperscript}
  	 * // Create a circle shaped path with a hole in it:
  	 * var circle = new Path.Circle(new Point(50, 50), 30);
  	 * var innerCircle = new Path.Circle(new Point(50, 50), 10);
  	 * var compoundPath = new CompoundPath([circle, innerCircle]);
  	 * compoundPath.fillColor = 'red';
  	 *
  	 * // Move the inner circle 5pt to the right:
  	 * compoundPath.children[1].position.x += 5;
  	 */
  	initialize: function(arg) {
  		this.base();
  		// CompoundPath has children and supports named children.
  		this._children = [];
  		this._namedChildren = {};
  		if (!this._setProperties(arg))
  			this.addChildren(Array.isArray(arg) ? arg : arguments);
  	},
  
  	insertChild: function(index, item, _cloning) {
  		// Only allow the insertion of paths
  		if (item._type !== 'path')
  			return null;
  		item = this.base(index, item);
  		// All children except for the bottom one (first one in list) are set
  		// to anti-clockwise orientation, so that they appear as holes, but
  		// only if their orientation was not already specified before
  		// (= _clockwise is defined).
  		if (!_cloning && item && item._clockwise === undefined)
  			item.setClockwise(item._index == 0);
  		return item;
  	},
  
  	/**
  	 * If this is a compound path with only one path inside,
  	 * the path is moved outside and the compound path is erased.
  	 * Otherwise, the compound path is returned unmodified.
  	 *
  	 * @return {CompoundPath|Path} the flattened compound path
  	 */
  	reduce: function() {
  		if (this._children.length == 1) {
  			var child = this._children[0];
  			child.insertAbove(this);
  			this.remove();
  			return child;
  		}
  		return this;
  	},
  
  	smooth: function() {
  		for (var i = 0, l = this._children.length; i < l; i++)
  			this._children[i].smooth();
  	},
  
  	/**
  	 * All the curves contained within the compound-path, from all its child
  	 * {@link Path} items.
  	 *
  	 * @type Curve[]
  	 * @bean
  	 */
  	getCurves: function() {
  		var curves = [];
  		for (var i = 0, l = this._children.length; i < l; i++)
  			curves = curves.concat(this._children[i].getCurves());
  		return curves;
  	},
  
  	isEmpty: function() {
  		return this._children.length == 0;
  	},
  
  	contains: function(point) {
  		point = Point.read(arguments);
  		var count = 0;
  		for (var i = 0, l = this._children.length; i < l; i++) {
  			if (this._children[i].contains(point))
  				count++;
  		}
  		return (count & 1) == 1;
  	},
  
  	_hitTest: function(point, options) {
  		return this.base(point, Base.merge(options, { fill: false }))
  			|| options.fill && this._style._fillColor && this.contains(point)
  				? new HitResult('fill', this)
  				: null;
  	},
  
  	draw: function(ctx, param) {
  		var children = this._children,
  			style = this._style;
  		// Return early if the compound path doesn't have any children:
  		if (children.length == 0)
  			return;
  		ctx.beginPath();
  		param.compound = true;
  		for (var i = 0, l = children.length; i < l; i++)
  			Item.draw(children[i], ctx, param);
  		param.compound = false;
  		if (this._clipMask) {
  			ctx.clip();
  		} else {
  			this._setStyles(ctx);
  			if (style._fillColor)
  				ctx.fill();
  			if (style._strokeColor)
  				ctx.stroke();
  		}
  	}
  }, new function() { // Injection scope for PostScript-like drawing functions
  	/**
  	 * Helper method that returns the current path and checks if a moveTo()
  	 * command is required first.
  	 */
  	function getCurrentPath(that) {
  		if (!that._children.length)
  			throw new Error('Use a moveTo() command first');
  		return that._children[that._children.length - 1];
  	}
  
  	var fields = {
  		// Note: Documentation for these methods is found in PathItem, as they
  		// are considered abstract methods of PathItem and need to be defined in
  		// all implementing classes.
  		moveTo: function(point) {
  			var path = new Path();
  			this.addChild(path);
  			path.moveTo.apply(path, arguments);
  		},
  
  		moveBy: function(point) {
  			this.moveTo(getCurrentPath(this).getLastSegment()._point.add(
  					Point.read(arguments)));
  		},
  
  		closePath: function() {
  			getCurrentPath(this).setClosed(true);
  		}
  	};
  
  	// Redirect all other drawing commands to the current path
  	Base.each(['lineTo', 'cubicCurveTo', 'quadraticCurveTo', 'curveTo',
  			'arcTo', 'lineBy', 'curveBy', 'arcBy'], function(key) {
  		fields[key] = function() {
  			var path = getCurrentPath(this);
  			path[key].apply(path, arguments);
  		};
  	});
  
  	return fields;
  });
  