/*!
 * jQuery UI Dialog 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/dialog/
 */
(function( factory ) {
	if ( typeof define === "function" && define.amd ) {

		// AMD. Register as an anonymous module.
		define([
			"jquery",
			"./core",
			"./widget",
			"./button",
			"./draggable",
			"./mouse",
			"./position",
			"./resizable"
		], factory );
	} else {

		// Browser globals
		factory( jQuery );
	}
}(function( $ ) {

return $.widget( "ui.dialog", {
	version: "1.11.4",
	options: {
		appendTo: "body",
		autoOpen: true,
		buttons: [],
		closeOnEscape: true,
		closeText: "Close",
		dialogClass: "",
		draggable: true,
		hide: null,
		height: "auto",
		maxHeight: null,
		maxWidth: null,
		minHeight: 150,
		minWidth: 150,
		modal: false,
		position: {
			my: "center",
			at: "center",
			of: window,
			collision: "fit",
			// Ensure the titlebar is always visible
			using: function( pos ) {
				var topOffset = $( this ).css( pos ).offset().top;
				if ( topOffset < 0 ) {
					$( this ).css( "top", pos.top - topOffset );
				}
			}
		},
		resizable: true,
		show: null,
		title: null,
		width: 300,

		// callbacks
		beforeClose: null,
		close: null,
		drag: null,
		dragStart: null,
		dragStop: null,
		focus: null,
		open: null,
		resize: null,
		resizeStart: null,
		resizeStop: null
	},

	sizeRelatedOptions: {
		buttons: true,
		height: true,
		maxHeight: true,
		maxWidth: true,
		minHeight: true,
		minWidth: true,
		width: true
	},

	resizableRelatedOptions: {
		maxHeight: true,
		maxWidth: true,
		minHeight: true,
		minWidth: true
	},

	_create: function() {
		this.originalCss = {
			display: this.element[ 0 ].style.display,
			width: this.element[ 0 ].style.width,
			minHeight: this.element[ 0 ].style.minHeight,
			maxHeight: this.element[ 0 ].style.maxHeight,
			height: this.element[ 0 ].style.height
		};
		this.originalPosition = {
			parent: this.element.parent(),
			index: this.element.parent().children().index( this.element )
		};
		this.originalTitle = this.element.attr( "title" );
		this.options.title = this.options.title || this.originalTitle;

		this._createWrapper();

		this.element
			.show()
			.removeAttr( "title" )
			.addClass( "ui-dialog-content ui-widget-content" )
			.appendTo( this.uiDialog );

		this._createTitlebar();
		this._createButtonPane();

		if ( this.options.draggable && $.fn.draggable ) {
			this._makeDraggable();
		}
		if ( this.options.resizable && $.fn.resizable ) {
			this._makeResizable();
		}

		this._isOpen = false;

		this._trackFocus();
	},

	_init: function() {
		if ( this.options.autoOpen ) {
			this.open();
		}
	},

	_appendTo: function() {
		var element = this.options.appendTo;
		if ( element && (element.jquery || element.nodeType) ) {
			return $( element );
		}
		return this.document.find( element || "body" ).eq( 0 );
	},

	_destroy: function() {
		var next,
			originalPosition = this.originalPosition;

		this._untrackInstance();
		this._destroyOverlay();

		this.element
			.removeUniqueId()
			.removeClass( "ui-dialog-content ui-widget-content" )
			.css( this.originalCss )
			// Without detaching first, the following becomes really slow
			.detach();

		this.uiDialog.stop( true, true ).remove();

		if ( this.originalTitle ) {
			this.element.attr( "title", this.originalTitle );
		}

		next = originalPosition.parent.children().eq( originalPosition.index );
		// Don't try to place the dialog next to itself (#8613)
		if ( next.length && next[ 0 ] !== this.element[ 0 ] ) {
			next.before( this.element );
		} else {
			originalPosition.parent.append( this.element );
		}
	},

	widget: function() {
		return this.uiDialog;
	},

	disable: $.noop,
	enable: $.noop,

	close: function( event ) {
		var activeElement,
			that = this;

		if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
			return;
		}

		this._isOpen = false;
		this._focusedElement = null;
		this._destroyOverlay();
		this._untrackInstance();

		if ( !this.opener.filter( ":focusable" ).focus().length ) {

			// support: IE9
			// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
			try {
				activeElement = this.document[ 0 ].activeElement;

				// Support: IE9, IE10
				// If the <body> is blurred, IE will switch windows, see #4520
				if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {

					// Hiding a focused element doesn't trigger blur in WebKit
					// so in case we have nothing to focus on, explicitly blur the active element
					// https://bugs.webkit.org/show_bug.cgi?id=47182
					$( activeElement ).blur();
				}
			} catch ( error ) {}
		}

		this._hide( this.uiDialog, this.options.hide, function() {
			that._trigger( "close", event );
		});
	},

	isOpen: function() {
		return this._isOpen;
	},

	moveToTop: function() {
		this._moveToTop();
	},

	_moveToTop: function( event, silent ) {
		var moved = false,
			zIndices = this.uiDialog.siblings( ".ui-front:visible" ).map(function() {
				return +$( this ).css( "z-index" );
			}).get(),
			zIndexMax = Math.max.apply( null, zIndices );

		if ( zIndexMax >= +this.uiDialog.css( "z-index" ) ) {
			this.uiDialog.css( "z-index", zIndexMax + 1 );
			moved = true;
		}

		if ( moved && !silent ) {
			this._trigger( "focus", event );
		}
		return moved;
	},

	open: function() {
		var that = this;
		if ( this._isOpen ) {
			if ( this._moveToTop() ) {
				this._focusTabbable();
			}
			return;
		}

		this._isOpen = true;
		this.opener = $( this.document[ 0 ].activeElement );

		this._size();
		this._position();
		this._createOverlay();
		this._moveToTop( null, true );

		// Ensure the overlay is moved to the top with the dialog, but only when
		// opening. The overlay shouldn't move after the dialog is open so that
		// modeless dialogs opened after the modal dialog stack properly.
		if ( this.overlay ) {
			this.overlay.css( "z-index", this.uiDialog.css( "z-index" ) - 1 );
		}

		this._show( this.uiDialog, this.options.show, function() {
			that._focusTabbable();
			that._trigger( "focus" );
		});

		// Track the dialog immediately upon openening in case a focus event
		// somehow occurs outside of the dialog before an element inside the
		// dialog is focused (#10152)
		this._makeFocusTarget();

		this._trigger( "open" );
	},

	_focusTabbable: function() {
		// Set focus to the first match:
		// 1. An element that was focused previously
		// 2. First element inside the dialog matching [autofocus]
		// 3. Tabbable element inside the content element
		// 4. Tabbable element inside the buttonpane
		// 5. The close button
		// 6. The dialog itself
		var hasFocus = this._focusedElement;
		if ( !hasFocus ) {
			hasFocus = this.element.find( "[autofocus]" );
		}
		if ( !hasFocus.length ) {
			hasFocus = this.element.find( ":tabbable" );
		}
		if ( !hasFocus.length ) {
			hasFocus = this.uiDialogButtonPane.find( ":tabbable" );
		}
		if ( !hasFocus.length ) {
			hasFocus = this.uiDialogTitlebarClose.filter( ":tabbable" );
		}
		if ( !hasFocus.length ) {
			hasFocus = this.uiDialog;
		}
		hasFocus.eq( 0 ).focus();
	},

	_keepFocus: function( event ) {
		function checkFocus() {
			var activeElement = this.document[0].activeElement,
				isActive = this.uiDialog[0] === activeElement ||
					$.contains( this.uiDialog[0], activeElement );
			if ( !isActive ) {
				this._focusTabbable();
			}
		}
		event.preventDefault();
		checkFocus.call( this );
		// support: IE
		// IE <= 8 doesn't prevent moving focus even with event.preventDefault()
		// so we check again later
		this._delay( checkFocus );
	},

	_createWrapper: function() {
		this.uiDialog = $("<div>")
			.addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
				this.options.dialogClass )
			.hide()
			.attr({
				// Setting tabIndex makes the div focusable
				tabIndex: -1,
				role: "dialog"
			})
			.appendTo( this._appendTo() );

		this._on( this.uiDialog, {
			keydown: function( event ) {
				if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
						event.keyCode === $.ui.keyCode.ESCAPE ) {
					event.preventDefault();
					this.close( event );
					return;
				}

				// prevent tabbing out of dialogs
				if ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {
					return;
				}
				var tabbables = this.uiDialog.find( ":tabbable" ),
					first = tabbables.filter( ":first" ),
					last = tabbables.filter( ":last" );

				if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
					this._delay(function() {
						first.focus();
					});
					event.preventDefault();
				} else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
					this._delay(function() {
						last.focus();
					});
					event.preventDefault();
				}
			},
			mousedown: function( event ) {
				if ( this._moveToTop( event ) ) {
					this._focusTabbable();
				}
			}
		});

		// We assume that any existing aria-describedby attribute means
		// that the dialog content is marked up properly
		// otherwise we brute force the content as the description
		if ( !this.element.find( "[aria-describedby]" ).length ) {
			this.uiDialog.attr({
				"aria-describedby": this.element.uniqueId().attr( "id" )
			});
		}
	},

	_createTitlebar: function() {
		var uiDialogTitle;

		this.uiDialogTitlebar = $( "<div>" )
			.addClass( "ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix" )
			.prependTo( this.uiDialog );
		this._on( this.uiDialogTitlebar, {
			mousedown: function( event ) {
				// Don't prevent click on close button (#8838)
				// Focusing a dialog that is partially scrolled out of view
				// causes the browser to scroll it into view, preventing the click event
				if ( !$( event.target ).closest( ".ui-dialog-titlebar-close" ) ) {
					// Dialog isn't getting focus when dragging (#8063)
					this.uiDialog.focus();
				}
			}
		});

		// support: IE
		// Use type="button" to prevent enter keypresses in textboxes from closing the
		// dialog in IE (#9312)
		this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
			.button({
				label: this.options.closeText,
				icons: {
					primary: "ui-icon-closethick"
				},
				text: false
			})
			.addClass( "ui-dialog-titlebar-close" )
			.appendTo( this.uiDialogTitlebar );
		this._on( this.uiDialogTitlebarClose, {
			click: function( event ) {
				event.preventDefault();
				this.close( event );
			}
		});

		uiDialogTitle = $( "<span>" )
			.uniqueId()
			.addClass( "ui-dialog-title" )
			.prependTo( this.uiDialogTitlebar );
		this._title( uiDialogTitle );

		this.uiDialog.attr({
			"aria-labelledby": uiDialogTitle.attr( "id" )
		});
	},

	_title: function( title ) {
		if ( !this.options.title ) {
			title.html( "&#160;" );
		}
		title.text( this.options.title );
	},

	_createButtonPane: function() {
		this.uiDialogButtonPane = $( "<div>" )
			.addClass( "ui-dialog-buttonpane ui-widget-content ui-helper-clearfix" );

		this.uiButtonSet = $( "<div>" )
			.addClass( "ui-dialog-buttonset" )
			.appendTo( this.uiDialogButtonPane );

		this._createButtons();
	},

	_createButtons: function() {
		var that = this,
			buttons = this.options.buttons;

		// if we already have a button pane, remove it
		this.uiDialogButtonPane.remove();
		this.uiButtonSet.empty();

		if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
			this.uiDialog.removeClass( "ui-dialog-buttons" );
			return;
		}

		$.each( buttons, function( name, props ) {
			var click, buttonOptions;
			props = $.isFunction( props ) ?
				{ click: props, text: name } :
				props;
			// Default to a non-submitting button
			props = $.extend( { type: "button" }, props );
			// Change the context for the click callback to be the main element
			click = props.click;
			props.click = function() {
				click.apply( that.element[ 0 ], arguments );
			};
			buttonOptions = {
				icons: props.icons,
				text: props.showText
			};
			delete props.icons;
			delete props.showText;
			$( "<button></button>", props )
				.button( buttonOptions )
				.appendTo( that.uiButtonSet );
		});
		this.uiDialog.addClass( "ui-dialog-buttons" );
		this.uiDialogButtonPane.appendTo( this.uiDialog );
	},

	_makeDraggable: function() {
		var that = this,
			options = this.options;

		function filteredUi( ui ) {
			return {
				position: ui.position,
				offset: ui.offset
			};
		}

		this.uiDialog.draggable({
			cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
			handle: ".ui-dialog-titlebar",
			containment: "document",
			start: function( event, ui ) {
				$( this ).addClass( "ui-dialog-dragging" );
				that._blockFrames();
				that._trigger( "dragStart", event, filteredUi( ui ) );
			},
			drag: function( event, ui ) {
				that._trigger( "drag", event, filteredUi( ui ) );
			},
			stop: function( event, ui ) {
				var left = ui.offset.left - that.document.scrollLeft(),
					top = ui.offset.top - that.document.scrollTop();

				options.position = {
					my: "left top",
					at: "left" + (left >= 0 ? "+" : "") + left + " " +
						"top" + (top >= 0 ? "+" : "") + top,
					of: that.window
				};
				$( this ).removeClass( "ui-dialog-dragging" );
				that._unblockFrames();
				that._trigger( "dragStop", event, filteredUi( ui ) );
			}
		});
	},

	_makeResizable: function() {
		var that = this,
			options = this.options,
			handles = options.resizable,
			// .ui-resizable has position: relative defined in the stylesheet
			// but dialogs have to use absolute or fixed positioning
			position = this.uiDialog.css("position"),
			resizeHandles = typeof handles === "string" ?
				handles	:
				"n,e,s,w,se,sw,ne,nw";

		function filteredUi( ui ) {
			return {
				originalPosition: ui.originalPosition,
				originalSize: ui.originalSize,
				position: ui.position,
				size: ui.size
			};
		}

		this.uiDialog.resizable({
			cancel: ".ui-dialog-content",
			containment: "document",
			alsoResize: this.element,
			maxWidth: options.maxWidth,
			maxHeight: options.maxHeight,
			minWidth: options.minWidth,
			minHeight: this._minHeight(),
			handles: resizeHandles,
			start: function( event, ui ) {
				$( this ).addClass( "ui-dialog-resizing" );
				that._blockFrames();
				that._trigger( "resizeStart", event, filteredUi( ui ) );
			},
			resize: function( event, ui ) {
				that._trigger( "resize", event, filteredUi( ui ) );
			},
			stop: function( event, ui ) {
				var offset = that.uiDialog.offset(),
					left = offset.left - that.document.scrollLeft(),
					top = offset.top - that.document.scrollTop();

				options.height = that.uiDialog.height();
				options.width = that.uiDialog.width();
				options.position = {
					my: "left top",
					at: "left" + (left >= 0 ? "+" : "") + left + " " +
						"top" + (top >= 0 ? "+" : "") + top,
					of: that.window
				};
				$( this ).removeClass( "ui-dialog-resizing" );
				that._unblockFrames();
				that._trigger( "resizeStop", event, filteredUi( ui ) );
			}
		})
		.css( "position", position );
	},

	_trackFocus: function() {
		this._on( this.widget(), {
			focusin: function( event ) {
				this._makeFocusTarget();
				this._focusedElement = $( event.target );
			}
		});
	},

	_makeFocusTarget: function() {
		this._untrackInstance();
		this._trackingInstances().unshift( this );
	},

	_untrackInstance: function() {
		var instances = this._trackingInstances(),
			exists = $.inArray( this, instances );
		if ( exists !== -1 ) {
			instances.splice( exists, 1 );
		}
	},

	_trackingInstances: function() {
		var instances = this.document.data( "ui-dialog-instances" );
		if ( !instances ) {
			instances = [];
			this.document.data( "ui-dialog-instances", instances );
		}
		return instances;
	},

	_minHeight: function() {
		var options = this.options;

		return options.height === "auto" ?
			options.minHeight :
			Math.min( options.minHeight, options.height );
	},

	_position: function() {
		// Need to show the dialog to get the actual offset in the position plugin
		var isVisible = this.uiDialog.is( ":visible" );
		if ( !isVisible ) {
			this.uiDialog.show();
		}
		this.uiDialog.position( this.options.position );
		if ( !isVisible ) {
			this.uiDialog.hide();
		}
	},

	_setOptions: function( options ) {
		var that = this,
			resize = false,
			resizableOptions = {};

		$.each( options, function( key, value ) {
			that._setOption( key, value );

			if ( key in that.sizeRelatedOptions ) {
				resize = true;
			}
			if ( key in that.resizableRelatedOptions ) {
				resizableOptions[ key ] = value;
			}
		});

		if ( resize ) {
			this._size();
			this._position();
		}
		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
			this.uiDialog.resizable( "option", resizableOptions );
		}
	},

	_setOption: function( key, value ) {
		var isDraggable, isResizable,
			uiDialog = this.uiDialog;

		if ( key === "dialogClass" ) {
			uiDialog
				.removeClass( this.options.dialogClass )
				.addClass( value );
		}

		if ( key === "disabled" ) {
			return;
		}

		this._super( key, value );

		if ( key === "appendTo" ) {
			this.uiDialog.appendTo( this._appendTo() );
		}

		if ( key === "buttons" ) {
			this._createButtons();
		}

		if ( key === "closeText" ) {
			this.uiDialogTitlebarClose.button({
				// Ensure that we always pass a string
				label: "" + value
			});
		}

		if ( key === "draggable" ) {
			isDraggable = uiDialog.is( ":data(ui-draggable)" );
			if ( isDraggable && !value ) {
				uiDialog.draggable( "destroy" );
			}

			if ( !isDraggable && value ) {
				this._makeDraggable();
			}
		}

		if ( key === "position" ) {
			this._position();
		}

		if ( key === "resizable" ) {
			// currently resizable, becoming non-resizable
			isResizable = uiDialog.is( ":data(ui-resizable)" );
			if ( isResizable && !value ) {
				uiDialog.resizable( "destroy" );
			}

			// currently resizable, changing handles
			if ( isResizable && typeof value === "string" ) {
				uiDialog.resizable( "option", "handles", value );
			}

			// currently non-resizable, becoming resizable
			if ( !isResizable && value !== false ) {
				this._makeResizable();
			}
		}

		if ( key === "title" ) {
			this._title( this.uiDialogTitlebar.find( ".ui-dialog-title" ) );
		}
	},

	_size: function() {
		// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
		// divs will both have width and height set, so we need to reset them
		var nonContentHeight, minContentHeight, maxContentHeight,
			options = this.options;

		// Reset content sizing
		this.element.show().css({
			width: "auto",
			minHeight: 0,
			maxHeight: "none",
			height: 0
		});

		if ( options.minWidth > options.width ) {
			options.width = options.minWidth;
		}

		// reset wrapper sizing
		// determine the height of all the non-content elements
		nonContentHeight = this.uiDialog.css({
				height: "auto",
				width: options.width
			})
			.outerHeight();
		minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
		maxContentHeight = typeof options.maxHeight === "number" ?
			Math.max( 0, options.maxHeight - nonContentHeight ) :
			"none";

		if ( options.height === "auto" ) {
			this.element.css({
				minHeight: minContentHeight,
				maxHeight: maxContentHeight,
				height: "auto"
			});
		} else {
			this.element.height( Math.max( 0, options.height - nonContentHeight ) );
		}

		if ( this.uiDialog.is( ":data(ui-resizable)" ) ) {
			this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
		}
	},

	_blockFrames: function() {
		this.iframeBlocks = this.document.find( "iframe" ).map(function() {
			var iframe = $( this );

			return $( "<div>" )
				.css({
					position: "absolute",
					width: iframe.outerWidth(),
					height: iframe.outerHeight()
				})
				.appendTo( iframe.parent() )
				.offset( iframe.offset() )[0];
		});
	},

	_unblockFrames: function() {
		if ( this.iframeBlocks ) {
			this.iframeBlocks.remove();
			delete this.iframeBlocks;
		}
	},

	_allowInteraction: function( event ) {
		if ( $( event.target ).closest( ".ui-dialog" ).length ) {
			return true;
		}

		// TODO: Remove hack when datepicker implements
		// the .ui-front logic (#8989)
		return !!$( event.target ).closest( ".ui-datepicker" ).length;
	},

	_createOverlay: function() {
		if ( !this.options.modal ) {
			return;
		}

		// We use a delay in case the overlay is created from an
		// event that we're going to be cancelling (#2804)
		var isOpening = true;
		this._delay(function() {
			isOpening = false;
		});

		if ( !this.document.data( "ui-dialog-overlays" ) ) {

			// Prevent use of anchors and inputs
			// Using _on() for an event handler shared across many instances is
			// safe because the dialogs stack and must be closed in reverse order
			this._on( this.document, {
				focusin: function( event ) {
					if ( isOpening ) {
						return;
					}

					if ( !this._allowInteraction( event ) ) {
						event.preventDefault();
						this._trackingInstances()[ 0 ]._focusTabbable();
					}
				}
			});
		}

		this.overlay = $( "<div>" )
			.addClass( "ui-widget-overlay ui-front" )
			.appendTo( this._appendTo() );
		this._on( this.overlay, {
			mousedown: "_keepFocus"
		});
		this.document.data( "ui-dialog-overlays",
			(this.document.data( "ui-dialog-overlays" ) || 0) + 1 );
	},

	_destroyOverlay: function() {
		if ( !this.options.modal ) {
			return;
		}

		if ( this.overlay ) {
			var overlays = this.document.data( "ui-dialog-overlays" ) - 1;

			if ( !overlays ) {
				this.document
					.unbind( "focusin" )
					.removeData( "ui-dialog-overlays" );
			} else {
				this.document.data( "ui-dialog-overlays", overlays );
			}

			this.overlay.remove();
			this.overlay = null;
		}
	}
});

}));

/*!
 * jQuery UI Mouse 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/mouse/
 */
(function( factory ) {
	if ( typeof define === "function" && define.amd ) {

		// AMD. Register as an anonymous module.
		define([
			"jquery",
			"./widget"
		], factory );
	} else {

		// Browser globals
		factory( jQuery );
	}
}(function( $ ) {

var mouseHandled = false;
$( document ).mouseup( function() {
	mouseHandled = false;
});

return $.widget("ui.mouse", {
	version: "1.11.4",
	options: {
		cancel: "input,textarea,button,select,option",
		distance: 1,
		delay: 0
	},
	_mouseInit: function() {
		var that = this;

		this.element
			.bind("mousedown." + this.widgetName, function(event) {
				return that._mouseDown(event);
			})
			.bind("click." + this.widgetName, function(event) {
				if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
					$.removeData(event.target, that.widgetName + ".preventClickEvent");
					event.stopImmediatePropagation();
					return false;
				}
			});

		this.started = false;
	},

	// TODO: make sure destroying one instance of mouse doesn't mess with
	// other instances of mouse
	_mouseDestroy: function() {
		this.element.unbind("." + this.widgetName);
		if ( this._mouseMoveDelegate ) {
			this.document
				.unbind("mousemove." + this.widgetName, this._mouseMoveDelegate)
				.unbind("mouseup." + this.widgetName, this._mouseUpDelegate);
		}
	},

	_mouseDown: function(event) {
		// don't let more than one widget handle mouseStart
		if ( mouseHandled ) {
			return;
		}

		this._mouseMoved = false;

		// we may have missed mouseup (out of window)
		(this._mouseStarted && this._mouseUp(event));

		this._mouseDownEvent = event;

		var that = this,
			btnIsLeft = (event.which === 1),
			// event.target.nodeName works around a bug in IE 8 with
			// disabled inputs (#7620)
			elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
			return true;
		}

		this.mouseDelayMet = !this.options.delay;
		if (!this.mouseDelayMet) {
			this._mouseDelayTimer = setTimeout(function() {
				that.mouseDelayMet = true;
			}, this.options.delay);
		}

		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
			this._mouseStarted = (this._mouseStart(event) !== false);
			if (!this._mouseStarted) {
				event.preventDefault();
				return true;
			}
		}

		// Click event may never have fired (Gecko & Opera)
		if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
			$.removeData(event.target, this.widgetName + ".preventClickEvent");
		}

		// these delegates are required to keep context
		this._mouseMoveDelegate = function(event) {
			return that._mouseMove(event);
		};
		this._mouseUpDelegate = function(event) {
			return that._mouseUp(event);
		};

		this.document
			.bind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
			.bind( "mouseup." + this.widgetName, this._mouseUpDelegate );

		event.preventDefault();

		mouseHandled = true;
		return true;
	},

	_mouseMove: function(event) {
		// Only check for mouseups outside the document if you've moved inside the document
		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
		// fire a mousemove event if content is placed under the cursor. See #7778
		// Support: IE <9
		if ( this._mouseMoved ) {
			// IE mouseup check - mouseup happened when mouse was out of window
			if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
				return this._mouseUp(event);

			// Iframe mouseup check - mouseup occurred in another document
			} else if ( !event.which ) {
				return this._mouseUp( event );
			}
		}

		if ( event.which || event.button ) {
			this._mouseMoved = true;
		}

		if (this._mouseStarted) {
			this._mouseDrag(event);
			return event.preventDefault();
		}

		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
			this._mouseStarted =
				(this._mouseStart(this._mouseDownEvent, event) !== false);
			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
		}

		return !this._mouseStarted;
	},

	_mouseUp: function(event) {
		this.document
			.unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate )
			.unbind( "mouseup." + this.widgetName, this._mouseUpDelegate );

		if (this._mouseStarted) {
			this._mouseStarted = false;

			if (event.target === this._mouseDownEvent.target) {
				$.data(event.target, this.widgetName + ".preventClickEvent", true);
			}

			this._mouseStop(event);
		}

		mouseHandled = false;
		return false;
	},

	_mouseDistanceMet: function(event) {
		return (Math.max(
				Math.abs(this._mouseDownEvent.pageX - event.pageX),
				Math.abs(this._mouseDownEvent.pageY - event.pageY)
			) >= this.options.distance
		);
	},

	_mouseDelayMet: function(/* event */) {
		return this.mouseDelayMet;
	},

	// These are placeholder methods, to be overriden by extending plugin
	_mouseStart: function(/* event */) {},
	_mouseDrag: function(/* event */) {},
	_mouseStop: function(/* event */) {},
	_mouseCapture: function(/* event */) { return true; }
});

}));

/*!
 * jQuery UI Draggable 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/draggable/
 */
(function( factory ) {
	if ( typeof define === "function" && define.amd ) {

		// AMD. Register as an anonymous module.
		define([
			"jquery",
			"./core",
			"./mouse",
			"./widget"
		], factory );
	} else {

		// Browser globals
		factory( jQuery );
	}
}(function( $ ) {

$.widget("ui.draggable", $.ui.mouse, {
	version: "1.11.4",
	widgetEventPrefix: "drag",
	options: {
		addClasses: true,
		appendTo: "parent",
		axis: false,
		connectToSortable: false,
		containment: false,
		cursor: "auto",
		cursorAt: false,
		grid: false,
		handle: false,
		helper: "original",
		iframeFix: false,
		opacity: false,
		refreshPositions: false,
		revert: false,
		revertDuration: 500,
		scope: "default",
		scroll: true,
		scrollSensitivity: 20,
		scrollSpeed: 20,
		snap: false,
		snapMode: "both",
		snapTolerance: 20,
		stack: false,
		zIndex: false,

		// callbacks
		drag: null,
		start: null,
		stop: null
	},
	_create: function() {

		if ( this.options.helper === "original" ) {
			this._setPositionRelative();
		}
		if (this.options.addClasses){
			this.element.addClass("ui-draggable");
		}
		if (this.options.disabled){
			this.element.addClass("ui-draggable-disabled");
		}
		this._setHandleClassName();

		this._mouseInit();
	},

	_setOption: function( key, value ) {
		this._super( key, value );
		if ( key === "handle" ) {
			this._removeHandleClassName();
			this._setHandleClassName();
		}
	},

	_destroy: function() {
		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
			this.destroyOnClear = true;
			return;
		}
		this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
		this._removeHandleClassName();
		this._mouseDestroy();
	},

	_mouseCapture: function(event) {
		var o = this.options;

		this._blurActiveElement( event );

		// among others, prevent a drag on a resizable-handle
		if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
			return false;
		}

		//Quit if we're not on a valid handle
		this.handle = this._getHandle(event);
		if (!this.handle) {
			return false;
		}

		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );

		return true;

	},

	_blockFrames: function( selector ) {
		this.iframeBlocks = this.document.find( selector ).map(function() {
			var iframe = $( this );

			return $( "<div>" )
				.css( "position", "absolute" )
				.appendTo( iframe.parent() )
				.outerWidth( iframe.outerWidth() )
				.outerHeight( iframe.outerHeight() )
				.offset( iframe.offset() )[ 0 ];
		});
	},

	_unblockFrames: function() {
		if ( this.iframeBlocks ) {
			this.iframeBlocks.remove();
			delete this.iframeBlocks;
		}
	},

	_blurActiveElement: function( event ) {
		var document = this.document[ 0 ];

		// Only need to blur if the event occurred on the draggable itself, see #10527
		if ( !this.handleElement.is( event.target ) ) {
			return;
		}

		// support: IE9
		// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
		try {

			// Support: IE9, IE10
			// If the <body> is blurred, IE will switch windows, see #9520
			if ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== "body" ) {

				// Blur any element that currently has focus, see #4261
				$( document.activeElement ).blur();
			}
		} catch ( error ) {}
	},

	_mouseStart: function(event) {

		var o = this.options;

		//Create and append the visible helper
		this.helper = this._createHelper(event);

		this.helper.addClass("ui-draggable-dragging");

		//Cache the helper size
		this._cacheHelperProportions();

		//If ddmanager is used for droppables, set the global draggable
		if ($.ui.ddmanager) {
			$.ui.ddmanager.current = this;
		}

		/*
		 * - Position generation -
		 * This block generates everything position related - it's the core of draggables.
		 */

		//Cache the margins of the original element
		this._cacheMargins();

		//Store the helper's css position
		this.cssPosition = this.helper.css( "position" );
		this.scrollParent = this.helper.scrollParent( true );
		this.offsetParent = this.helper.offsetParent();
		this.hasFixedAncestor = this.helper.parents().filter(function() {
				return $( this ).css( "position" ) === "fixed";
			}).length > 0;

		//The element's absolute position on the page minus margins
		this.positionAbs = this.element.offset();
		this._refreshOffsets( event );

		//Generate the original position
		this.originalPosition = this.position = this._generatePosition( event, false );
		this.originalPageX = event.pageX;
		this.originalPageY = event.pageY;

		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
		(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));

		//Set a containment if given in the options
		this._setContainment();

		//Trigger event + callbacks
		if (this._trigger("start", event) === false) {
			this._clear();
			return false;
		}

		//Recache the helper size
		this._cacheHelperProportions();

		//Prepare the droppable offsets
		if ($.ui.ddmanager && !o.dropBehaviour) {
			$.ui.ddmanager.prepareOffsets(this, event);
		}

		// Reset helper's right/bottom css if they're set and set explicit width/height instead
		// as this prevents resizing of elements with right/bottom set (see #7772)
		this._normalizeRightBottom();

		this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position

		//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
		if ( $.ui.ddmanager ) {
			$.ui.ddmanager.dragStart(this, event);
		}

		return true;
	},

	_refreshOffsets: function( event ) {
		this.offset = {
			top: this.positionAbs.top - this.margins.top,
			left: this.positionAbs.left - this.margins.left,
			scroll: false,
			parent: this._getParentOffset(),
			relative: this._getRelativeOffset()
		};

		this.offset.click = {
			left: event.pageX - this.offset.left,
			top: event.pageY - this.offset.top
		};
	},

	_mouseDrag: function(event, noPropagation) {
		// reset any necessary cached properties (see #5009)
		if ( this.hasFixedAncestor ) {
			this.offset.parent = this._getParentOffset();
		}

		//Compute the helpers position
		this.position = this._generatePosition( event, true );
		this.positionAbs = this._convertPositionTo("absolute");

		//Call plugins and callbacks and use the resulting position if something is returned
		if (!noPropagation) {
			var ui = this._uiHash();
			if (this._trigger("drag", event, ui) === false) {
				this._mouseUp({});
				return false;
			}
			this.position = ui.position;
		}

		this.helper[ 0 ].style.left = this.position.left + "px";
		this.helper[ 0 ].style.top = this.position.top + "px";

		if ($.ui.ddmanager) {
			$.ui.ddmanager.drag(this, event);
		}

		return false;
	},

	_mouseStop: function(event) {

		//If we are using droppables, inform the manager about the drop
		var that = this,
			dropped = false;
		if ($.ui.ddmanager && !this.options.dropBehaviour) {
			dropped = $.ui.ddmanager.drop(this, event);
		}

		//if a drop comes from outside (a sortable)
		if (this.dropped) {
			dropped = this.dropped;
			this.dropped = false;
		}

		if ((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
			$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
				if (that._trigger("stop", event) !== false) {
					that._clear();
				}
			});
		} else {
			if (this._trigger("stop", event) !== false) {
				this._clear();
			}
		}

		return false;
	},

	_mouseUp: function( event ) {
		this._unblockFrames();

		//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
		if ( $.ui.ddmanager ) {
			$.ui.ddmanager.dragStop(this, event);
		}

		// Only need to focus if the event occurred on the draggable itself, see #10527
		if ( this.handleElement.is( event.target ) ) {
			// The interaction is over; whether or not the click resulted in a drag, focus the element
			this.element.focus();
		}

		return $.ui.mouse.prototype._mouseUp.call(this, event);
	},

	cancel: function() {

		if (this.helper.is(".ui-draggable-dragging")) {
			this._mouseUp({});
		} else {
			this._clear();
		}

		return this;

	},

	_getHandle: function(event) {
		return this.options.handle ?
			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
			true;
	},

	_setHandleClassName: function() {
		this.handleElement = this.options.handle ?
			this.element.find( this.options.handle ) : this.element;
		this.handleElement.addClass( "ui-draggable-handle" );
	},

	_removeHandleClassName: function() {
		this.handleElement.removeClass( "ui-draggable-handle" );
	},

	_createHelper: function(event) {

		var o = this.options,
			helperIsFunction = $.isFunction( o.helper ),
			helper = helperIsFunction ?
				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
				( o.helper === "clone" ?
					this.element.clone().removeAttr( "id" ) :
					this.element );

		if (!helper.parents("body").length) {
			helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
		}

		// http://bugs.jqueryui.com/ticket/9446
		// a helper function can return the original element
		// which wouldn't have been set to relative in _create
		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
			this._setPositionRelative();
		}

		if (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
			helper.css("position", "absolute");
		}

		return helper;

	},

	_setPositionRelative: function() {
		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
			this.element[ 0 ].style.position = "relative";
		}
	},

	_adjustOffsetFromHelper: function(obj) {
		if (typeof obj === "string") {
			obj = obj.split(" ");
		}
		if ($.isArray(obj)) {
			obj = { left: +obj[0], top: +obj[1] || 0 };
		}
		if ("left" in obj) {
			this.offset.click.left = obj.left + this.margins.left;
		}
		if ("right" in obj) {
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
		}
		if ("top" in obj) {
			this.offset.click.top = obj.top + this.margins.top;
		}
		if ("bottom" in obj) {
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
		}
	},

	_isRootNode: function( element ) {
		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
	},

	_getParentOffset: function() {

		//Get the offsetParent and cache its position
		var po = this.offsetParent.offset(),
			document = this.document[ 0 ];

		// This is a special case where we need to modify a offset calculated on start, since the following happened:
		// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
		//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
		if (this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
			po.left += this.scrollParent.scrollLeft();
			po.top += this.scrollParent.scrollTop();
		}

		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
			po = { top: 0, left: 0 };
		}

		return {
			top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"), 10) || 0),
			left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"), 10) || 0)
		};

	},

	_getRelativeOffset: function() {
		if ( this.cssPosition !== "relative" ) {
			return { top: 0, left: 0 };
		}

		var p = this.element.position(),
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );

		return {
			top: p.top - ( parseInt(this.helper.css( "top" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
			left: p.left - ( parseInt(this.helper.css( "left" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
		};

	},

	_cacheMargins: function() {
		this.margins = {
			left: (parseInt(this.element.css("marginLeft"), 10) || 0),
			top: (parseInt(this.element.css("marginTop"), 10) || 0),
			right: (parseInt(this.element.css("marginRight"), 10) || 0),
			bottom: (parseInt(this.element.css("marginBottom"), 10) || 0)
		};
	},

	_cacheHelperProportions: function() {
		this.helperProportions = {
			width: this.helper.outerWidth(),
			height: this.helper.outerHeight()
		};
	},

	_setContainment: function() {

		var isUserScrollable, c, ce,
			o = this.options,
			document = this.document[ 0 ];

		this.relativeContainer = null;

		if ( !o.containment ) {
			this.containment = null;
			return;
		}

		if ( o.containment === "window" ) {
			this.containment = [
				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
				$( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
				$( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
			];
			return;
		}

		if ( o.containment === "document") {
			this.containment = [
				0,
				0,
				$( document ).width() - this.helperProportions.width - this.margins.left,
				( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
			];
			return;
		}

		if ( o.containment.constructor === Array ) {
			this.containment = o.containment;
			return;
		}

		if ( o.containment === "parent" ) {
			o.containment = this.helper[ 0 ].parentNode;
		}

		c = $( o.containment );
		ce = c[ 0 ];

		if ( !ce ) {
			return;
		}

		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );

		this.containment = [
			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
				this.helperProportions.width -
				this.margins.left -
				this.margins.right,
			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
				this.helperProportions.height -
				this.margins.top -
				this.margins.bottom
		];
		this.relativeContainer = c;
	},

	_convertPositionTo: function(d, pos) {

		if (!pos) {
			pos = this.position;
		}

		var mod = d === "absolute" ? 1 : -1,
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );

		return {
			top: (
				pos.top	+																// The absolute mouse position
				this.offset.relative.top * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
				this.offset.parent.top * mod -										// The offsetParent's offset without borders (offset + border)
				( ( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)
			),
			left: (
				pos.left +																// The absolute mouse position
				this.offset.relative.left * mod +										// Only for relative positioned nodes: Relative offset from element to offset parent
				this.offset.parent.left * mod	-										// The offsetParent's offset without borders (offset + border)
				( ( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)
			)
		};

	},

	_generatePosition: function( event, constrainPosition ) {

		var containment, co, top, left,
			o = this.options,
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
			pageX = event.pageX,
			pageY = event.pageY;

		// Cache the scroll
		if ( !scrollIsRootNode || !this.offset.scroll ) {
			this.offset.scroll = {
				top: this.scrollParent.scrollTop(),
				left: this.scrollParent.scrollLeft()
			};
		}

		/*
		 * - Position constraining -
		 * Constrain the position to a mix of grid, containment.
		 */

		// If we are not dragging yet, we won't check for options
		if ( constrainPosition ) {
			if ( this.containment ) {
				if ( this.relativeContainer ){
					co = this.relativeContainer.offset();
					containment = [
						this.containment[ 0 ] + co.left,
						this.containment[ 1 ] + co.top,
						this.containment[ 2 ] + co.left,
						this.containment[ 3 ] + co.top
					];
				} else {
					containment = this.containment;
				}

				if (event.pageX - this.offset.click.left < containment[0]) {
					pageX = containment[0] + this.offset.click.left;
				}
				if (event.pageY - this.offset.click.top < containment[1]) {
					pageY = containment[1] + this.offset.click.top;
				}
				if (event.pageX - this.offset.click.left > containment[2]) {
					pageX = containment[2] + this.offset.click.left;
				}
				if (event.pageY - this.offset.click.top > containment[3]) {
					pageY = containment[3] + this.offset.click.top;
				}
			}

			if (o.grid) {
				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
				top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
				pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;

				left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
				pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
			}

			if ( o.axis === "y" ) {
				pageX = this.originalPageX;
			}

			if ( o.axis === "x" ) {
				pageY = this.originalPageY;
			}
		}

		return {
			top: (
				pageY -																	// The absolute mouse position
				this.offset.click.top	-												// Click offset (relative to the element)
				this.offset.relative.top -												// Only for relative positioned nodes: Relative offset from element to offset parent
				this.offset.parent.top +												// The offsetParent's offset without borders (offset + border)
				( this.cssPosition === "fixed" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
			),
			left: (
				pageX -																	// The absolute mouse position
				this.offset.click.left -												// Click offset (relative to the element)
				this.offset.relative.left -												// Only for relative positioned nodes: Relative offset from element to offset parent
				this.offset.parent.left +												// The offsetParent's offset without borders (offset + border)
				( this.cssPosition === "fixed" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
			)
		};

	},

	_clear: function() {
		this.helper.removeClass("ui-draggable-dragging");
		if (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
			this.helper.remove();
		}
		this.helper = null;
		this.cancelHelperRemoval = false;
		if ( this.destroyOnClear ) {
			this.destroy();
		}
	},

	_normalizeRightBottom: function() {
		if ( this.options.axis !== "y" && this.helper.css( "right" ) !== "auto" ) {
			this.helper.width( this.helper.width() );
			this.helper.css( "right", "auto" );
		}
		if ( this.options.axis !== "x" && this.helper.css( "bottom" ) !== "auto" ) {
			this.helper.height( this.helper.height() );
			this.helper.css( "bottom", "auto" );
		}
	},

	// From now on bulk stuff - mainly helpers

	_trigger: function( type, event, ui ) {
		ui = ui || this._uiHash();
		$.ui.plugin.call( this, type, [ event, ui, this ], true );

		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
		if ( /^(drag|start|stop)/.test( type ) ) {
			this.positionAbs = this._convertPositionTo( "absolute" );
			ui.offset = this.positionAbs;
		}
		return $.Widget.prototype._trigger.call( this, type, event, ui );
	},

	plugins: {},

	_uiHash: function() {
		return {
			helper: this.helper,
			position: this.position,
			originalPosition: this.originalPosition,
			offset: this.positionAbs
		};
	}

});

$.ui.plugin.add( "draggable", "connectToSortable", {
	start: function( event, ui, draggable ) {
		var uiSortable = $.extend( {}, ui, {
			item: draggable.element
		});

		draggable.sortables = [];
		$( draggable.options.connectToSortable ).each(function() {
			var sortable = $( this ).sortable( "instance" );

			if ( sortable && !sortable.options.disabled ) {
				draggable.sortables.push( sortable );

				// refreshPositions is called at drag start to refresh the containerCache
				// which is used in drag. This ensures it's initialized and synchronized
				// with any changes that might have happened on the page since initialization.
				sortable.refreshPositions();
				sortable._trigger("activate", event, uiSortable);
			}
		});
	},
	stop: function( event, ui, draggable ) {
		var uiSortable = $.extend( {}, ui, {
			item: draggable.element
		});

		draggable.cancelHelperRemoval = false;

		$.each( draggable.sortables, function() {
			var sortable = this;

			if ( sortable.isOver ) {
				sortable.isOver = 0;

				// Allow this sortable to handle removing the helper
				draggable.cancelHelperRemoval = true;
				sortable.cancelHelperRemoval = false;

				// Use _storedCSS To restore properties in the sortable,
				// as this also handles revert (#9675) since the draggable
				// may have modified them in unexpected ways (#8809)
				sortable._storedCSS = {
					position: sortable.placeholder.css( "position" ),
					top: sortable.placeholder.css( "top" ),
					left: sortable.placeholder.css( "left" )
				};

				sortable._mouseStop(event);

				// Once drag has ended, the sortable should return to using
				// its original helper, not the shared helper from draggable
				sortable.options.helper = sortable.options._helper;
			} else {
				// Prevent this Sortable from removing the helper.
				// However, don't set the draggable to remove the helper
				// either as another connected Sortable may yet handle the removal.
				sortable.cancelHelperRemoval = true;

				sortable._trigger( "deactivate", event, uiSortable );
			}
		});
	},
	drag: function( event, ui, draggable ) {
		$.each( draggable.sortables, function() {
			var innermostIntersecting = false,
				sortable = this;

			// Copy over variables that sortable's _intersectsWith uses
			sortable.positionAbs = draggable.positionAbs;
			sortable.helperProportions = draggable.helperProportions;
			sortable.offset.click = draggable.offset.click;

			if ( sortable._intersectsWith( sortable.containerCache ) ) {
				innermostIntersecting = true;

				$.each( draggable.sortables, function() {
					// Copy over variables that sortable's _intersectsWith uses
					this.positionAbs = draggable.positionAbs;
					this.helperProportions = draggable.helperProportions;
					this.offset.click = draggable.offset.click;

					if ( this !== sortable &&
							this._intersectsWith( this.containerCache ) &&
							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
						innermostIntersecting = false;
					}

					return innermostIntersecting;
				});
			}

			if ( innermostIntersecting ) {
				// If it intersects, we use a little isOver variable and set it once,
				// so that the move-in stuff gets fired only once.
				if ( !sortable.isOver ) {
					sortable.isOver = 1;

					// Store draggable's parent in case we need to reappend to it later.
					draggable._parent = ui.helper.parent();

					sortable.currentItem = ui.helper
						.appendTo( sortable.element )
						.data( "ui-sortable-item", true );

					// Store helper option to later restore it
					sortable.options._helper = sortable.options.helper;

					sortable.options.helper = function() {
						return ui.helper[ 0 ];
					};

					// Fire the start events of the sortable with our passed browser event,
					// and our own helper (so it doesn't create a new one)
					event.target = sortable.currentItem[ 0 ];
					sortable._mouseCapture( event, true );
					sortable._mouseStart( event, true, true );

					// Because the browser event is way off the new appended portlet,
					// modify necessary variables to reflect the changes
					sortable.offset.click.top = draggable.offset.click.top;
					sortable.offset.click.left = draggable.offset.click.left;
					sortable.offset.parent.left -= draggable.offset.parent.left -
						sortable.offset.parent.left;
					sortable.offset.parent.top -= draggable.offset.parent.top -
						sortable.offset.parent.top;

					draggable._trigger( "toSortable", event );

					// Inform draggable that the helper is in a valid drop zone,
					// used solely in the revert option to handle "valid/invalid".
					draggable.dropped = sortable.element;

					// Need to refreshPositions of all sortables in the case that
					// adding to one sortable changes the location of the other sortables (#9675)
					$.each( draggable.sortables, function() {
						this.refreshPositions();
					});

					// hack so receive/update callbacks work (mostly)
					draggable.currentItem = draggable.element;
					sortable.fromOutside = draggable;
				}

				if ( sortable.currentItem ) {
					sortable._mouseDrag( event );
					// Copy the sortable's position because the draggable's can potentially reflect
					// a relative position, while sortable is always absolute, which the dragged
					// element has now become. (#8809)
					ui.position = sortable.position;
				}
			} else {
				// If it doesn't intersect with the sortable, and it intersected before,
				// we fake the drag stop of the sortable, but make sure it doesn't remove
				// the helper by using cancelHelperRemoval.
				if ( sortable.isOver ) {

					sortable.isOver = 0;
					sortable.cancelHelperRemoval = true;

					// Calling sortable's mouseStop would trigger a revert,
					// so revert must be temporarily false until after mouseStop is called.
					sortable.options._revert = sortable.options.revert;
					sortable.options.revert = false;

					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
					sortable._mouseStop( event, true );

					// restore sortable behaviors that were modfied
					// when the draggable entered the sortable area (#9481)
					sortable.options.revert = sortable.options._revert;
					sortable.options.helper = sortable.options._helper;

					if ( sortable.placeholder ) {
						sortable.placeholder.remove();
					}

					// Restore and recalculate the draggable's offset considering the sortable
					// may have modified them in unexpected ways. (#8809, #10669)
					ui.helper.appendTo( draggable._parent );
					draggable._refreshOffsets( event );
					ui.position = draggable._generatePosition( event, true );

					draggable._trigger( "fromSortable", event );

					// Inform draggable that the helper is no longer in a valid drop zone
					draggable.dropped = false;

					// Need to refreshPositions of all sortables just in case removing
					// from one sortable changes the location of other sortables (#9675)
					$.each( draggable.sortables, function() {
						this.refreshPositions();
					});
				}
			}
		});
	}
});

$.ui.plugin.add("draggable", "cursor", {
	start: function( event, ui, instance ) {
		var t = $( "body" ),
			o = instance.options;

		if (t.css("cursor")) {
			o._cursor = t.css("cursor");
		}
		t.css("cursor", o.cursor);
	},
	stop: function( event, ui, instance ) {
		var o = instance.options;
		if (o._cursor) {
			$("body").css("cursor", o._cursor);
		}
	}
});

$.ui.plugin.add("draggable", "opacity", {
	start: function( event, ui, instance ) {
		var t = $( ui.helper ),
			o = instance.options;
		if (t.css("opacity")) {
			o._opacity = t.css("opacity");
		}
		t.css("opacity", o.opacity);
	},
	stop: function( event, ui, instance ) {
		var o = instance.options;
		if (o._opacity) {
			$(ui.helper).css("opacity", o._opacity);
		}
	}
});

$.ui.plugin.add("draggable", "scroll", {
	start: function( event, ui, i ) {
		if ( !i.scrollParentNotHidden ) {
			i.scrollParentNotHidden = i.helper.scrollParent( false );
		}

		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
			i.overflowOffset = i.scrollParentNotHidden.offset();
		}
	},
	drag: function( event, ui, i  ) {

		var o = i.options,
			scrolled = false,
			scrollParent = i.scrollParentNotHidden[ 0 ],
			document = i.document[ 0 ];

		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
			if ( !o.axis || o.axis !== "x" ) {
				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {
					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
				}
			}

			if ( !o.axis || o.axis !== "y" ) {
				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {
					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
				}
			}

		} else {

			if (!o.axis || o.axis !== "x") {
				if (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
					scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
				} else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
					scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
				}
			}

			if (!o.axis || o.axis !== "y") {
				if (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
					scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
				} else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
					scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
				}
			}

		}

		if (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
			$.ui.ddmanager.prepareOffsets(i, event);
		}

	}
});

$.ui.plugin.add("draggable", "snap", {
	start: function( event, ui, i ) {

		var o = i.options;

		i.snapElements = [];

		$(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
			var $t = $(this),
				$o = $t.offset();
			if (this !== i.element[0]) {
				i.snapElements.push({
					item: this,
					width: $t.outerWidth(), height: $t.outerHeight(),
					top: $o.top, left: $o.left
				});
			}
		});

	},
	drag: function( event, ui, inst ) {

		var ts, bs, ls, rs, l, r, t, b, i, first,
			o = inst.options,
			d = o.snapTolerance,
			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;

		for (i = inst.snapElements.length - 1; i >= 0; i--){

			l = inst.snapElements[i].left - inst.margins.left;
			r = l + inst.snapElements[i].width;
			t = inst.snapElements[i].top - inst.margins.top;
			b = t + inst.snapElements[i].height;

			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
				if (inst.snapElements[i].snapping) {
					(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
				}
				inst.snapElements[i].snapping = false;
				continue;
			}

			if (o.snapMode !== "inner") {
				ts = Math.abs(t - y2) <= d;
				bs = Math.abs(b - y1) <= d;
				ls = Math.abs(l - x2) <= d;
				rs = Math.abs(r - x1) <= d;
				if (ts) {
					ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top;
				}
				if (bs) {
					ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top;
				}
				if (ls) {
					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left;
				}
				if (rs) {
					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left;
				}
			}

			first = (ts || bs || ls || rs);

			if (o.snapMode !== "outer") {
				ts = Math.abs(t - y1) <= d;
				bs = Math.abs(b - y2) <= d;
				ls = Math.abs(l - x1) <= d;
				rs = Math.abs(r - x2) <= d;
				if (ts) {
					ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top;
				}
				if (bs) {
					ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top;
				}
				if (ls) {
					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left;
				}
				if (rs) {
					ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left;
				}
			}

			if (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
				(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
			}
			inst.snapElements[i].snapping = (ts || bs || ls || rs || first);

		}

	}
});

$.ui.plugin.add("draggable", "stack", {
	start: function( event, ui, instance ) {
		var min,
			o = instance.options,
			group = $.makeArray($(o.stack)).sort(function(a, b) {
				return (parseInt($(a).css("zIndex"), 10) || 0) - (parseInt($(b).css("zIndex"), 10) || 0);
			});

		if (!group.length) { return; }

		min = parseInt($(group[0]).css("zIndex"), 10) || 0;
		$(group).each(function(i) {
			$(this).css("zIndex", min + i);
		});
		this.css("zIndex", (min + group.length));
	}
});

$.ui.plugin.add("draggable", "zIndex", {
	start: function( event, ui, instance ) {
		var t = $( ui.helper ),
			o = instance.options;

		if (t.css("zIndex")) {
			o._zIndex = t.css("zIndex");
		}
		t.css("zIndex", o.zIndex);
	},
	stop: function( event, ui, instance ) {
		var o = instance.options;

		if (o._zIndex) {
			$(ui.helper).css("zIndex", o._zIndex);
		}
	}
});

return $.ui.draggable;

}));

/*!
 * jQuery UI Position 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/position/
 */
(function( factory ) {
	if ( typeof define === "function" && define.amd ) {

		// AMD. Register as an anonymous module.
		define( [ "jquery" ], factory );
	} else {

		// Browser globals
		factory( jQuery );
	}
}(function( $ ) {
(function() {

$.ui = $.ui || {};

var cachedScrollbarWidth, supportsOffsetFractions,
	max = Math.max,
	abs = Math.abs,
	round = Math.round,
	rhorizontal = /left|center|right/,
	rvertical = /top|center|bottom/,
	roffset = /[\+\-]\d+(\.[\d]+)?%?/,
	rposition = /^\w+/,
	rpercent = /%$/,
	_position = $.fn.position;

function getOffsets( offsets, width, height ) {
	return [
		parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
		parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
	];
}

function parseCss( element, property ) {
	return parseInt( $.css( element, property ), 10 ) || 0;
}

function getDimensions( elem ) {
	var raw = elem[0];
	if ( raw.nodeType === 9 ) {
		return {
			width: elem.width(),
			height: elem.height(),
			offset: { top: 0, left: 0 }
		};
	}
	if ( $.isWindow( raw ) ) {
		return {
			width: elem.width(),
			height: elem.height(),
			offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
		};
	}
	if ( raw.preventDefault ) {
		return {
			width: 0,
			height: 0,
			offset: { top: raw.pageY, left: raw.pageX }
		};
	}
	return {
		width: elem.outerWidth(),
		height: elem.outerHeight(),
		offset: elem.offset()
	};
}

$.position = {
	scrollbarWidth: function() {
		if ( cachedScrollbarWidth !== undefined ) {
			return cachedScrollbarWidth;
		}
		var w1, w2,
			div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
			innerDiv = div.children()[0];

		$( "body" ).append( div );
		w1 = innerDiv.offsetWidth;
		div.css( "overflow", "scroll" );

		w2 = innerDiv.offsetWidth;

		if ( w1 === w2 ) {
			w2 = div[0].clientWidth;
		}

		div.remove();

		return (cachedScrollbarWidth = w1 - w2);
	},
	getScrollInfo: function( within ) {
		var overflowX = within.isWindow || within.isDocument ? "" :
				within.element.css( "overflow-x" ),
			overflowY = within.isWindow || within.isDocument ? "" :
				within.element.css( "overflow-y" ),
			hasOverflowX = overflowX === "scroll" ||
				( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
			hasOverflowY = overflowY === "scroll" ||
				( overflowY === "auto" && within.height < within.element[0].scrollHeight );
		return {
			width: hasOverflowY ? $.position.scrollbarWidth() : 0,
			height: hasOverflowX ? $.position.scrollbarWidth() : 0
		};
	},
	getWithinInfo: function( element ) {
		var withinElement = $( element || window ),
			isWindow = $.isWindow( withinElement[0] ),
			isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
		return {
			element: withinElement,
			isWindow: isWindow,
			isDocument: isDocument,
			offset: withinElement.offset() || { left: 0, top: 0 },
			scrollLeft: withinElement.scrollLeft(),
			scrollTop: withinElement.scrollTop(),

			// support: jQuery 1.6.x
			// jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
			width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
			height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
		};
	}
};

$.fn.position = function( options ) {
	if ( !options || !options.of ) {
		return _position.apply( this, arguments );
	}

	// make a copy, we don't want to modify arguments
	options = $.extend( {}, options );

	var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
		target = $( options.of ),
		within = $.position.getWithinInfo( options.within ),
		scrollInfo = $.position.getScrollInfo( within ),
		collision = ( options.collision || "flip" ).split( " " ),
		offsets = {};

	dimensions = getDimensions( target );
	if ( target[0].preventDefault ) {
		// force left top to allow flipping
		options.at = "left top";
	}
	targetWidth = dimensions.width;
	targetHeight = dimensions.height;
	targetOffset = dimensions.offset;
	// clone to reuse original targetOffset later
	basePosition = $.extend( {}, targetOffset );

	// force my and at to have valid horizontal and vertical positions
	// if a value is missing or invalid, it will be converted to center
	$.each( [ "my", "at" ], function() {
		var pos = ( options[ this ] || "" ).split( " " ),
			horizontalOffset,
			verticalOffset;

		if ( pos.length === 1) {
			pos = rhorizontal.test( pos[ 0 ] ) ?
				pos.concat( [ "center" ] ) :
				rvertical.test( pos[ 0 ] ) ?
					[ "center" ].concat( pos ) :
					[ "center", "center" ];
		}
		pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
		pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";

		// calculate offsets
		horizontalOffset = roffset.exec( pos[ 0 ] );
		verticalOffset = roffset.exec( pos[ 1 ] );
		offsets[ this ] = [
			horizontalOffset ? horizontalOffset[ 0 ] : 0,
			verticalOffset ? verticalOffset[ 0 ] : 0
		];

		// reduce to just the positions without the offsets
		options[ this ] = [
			rposition.exec( pos[ 0 ] )[ 0 ],
			rposition.exec( pos[ 1 ] )[ 0 ]
		];
	});

	// normalize collision option
	if ( collision.length === 1 ) {
		collision[ 1 ] = collision[ 0 ];
	}

	if ( options.at[ 0 ] === "right" ) {
		basePosition.left += targetWidth;
	} else if ( options.at[ 0 ] === "center" ) {
		basePosition.left += targetWidth / 2;
	}

	if ( options.at[ 1 ] === "bottom" ) {
		basePosition.top += targetHeight;
	} else if ( options.at[ 1 ] === "center" ) {
		basePosition.top += targetHeight / 2;
	}

	atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
	basePosition.left += atOffset[ 0 ];
	basePosition.top += atOffset[ 1 ];

	return this.each(function() {
		var collisionPosition, using,
			elem = $( this ),
			elemWidth = elem.outerWidth(),
			elemHeight = elem.outerHeight(),
			marginLeft = parseCss( this, "marginLeft" ),
			marginTop = parseCss( this, "marginTop" ),
			collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
			collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
			position = $.extend( {}, basePosition ),
			myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );

		if ( options.my[ 0 ] === "right" ) {
			position.left -= elemWidth;
		} else if ( options.my[ 0 ] === "center" ) {
			position.left -= elemWidth / 2;
		}

		if ( options.my[ 1 ] === "bottom" ) {
			position.top -= elemHeight;
		} else if ( options.my[ 1 ] === "center" ) {
			position.top -= elemHeight / 2;
		}

		position.left += myOffset[ 0 ];
		position.top += myOffset[ 1 ];

		// if the browser doesn't support fractions, then round for consistent results
		if ( !supportsOffsetFractions ) {
			position.left = round( position.left );
			position.top = round( position.top );
		}

		collisionPosition = {
			marginLeft: marginLeft,
			marginTop: marginTop
		};

		$.each( [ "left", "top" ], function( i, dir ) {
			if ( $.ui.position[ collision[ i ] ] ) {
				$.ui.position[ collision[ i ] ][ dir ]( position, {
					targetWidth: targetWidth,
					targetHeight: targetHeight,
					elemWidth: elemWidth,
					elemHeight: elemHeight,
					collisionPosition: collisionPosition,
					collisionWidth: collisionWidth,
					collisionHeight: collisionHeight,
					offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
					my: options.my,
					at: options.at,
					within: within,
					elem: elem
				});
			}
		});

		if ( options.using ) {
			// adds feedback as second argument to using callback, if present
			using = function( props ) {
				var left = targetOffset.left - position.left,
					right = left + targetWidth - elemWidth,
					top = targetOffset.top - position.top,
					bottom = top + targetHeight - elemHeight,
					feedback = {
						target: {
							element: target,
							left: targetOffset.left,
							top: targetOffset.top,
							width: targetWidth,
							height: targetHeight
						},
						element: {
							element: elem,
							left: position.left,
							top: position.top,
							width: elemWidth,
							height: elemHeight
						},
						horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
						vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
					};
				if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
					feedback.horizontal = "center";
				}
				if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
					feedback.vertical = "middle";
				}
				if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
					feedback.important = "horizontal";
				} else {
					feedback.important = "vertical";
				}
				options.using.call( this, props, feedback );
			};
		}

		elem.offset( $.extend( position, { using: using } ) );
	});
};

$.ui.position = {
	fit: {
		left: function( position, data ) {
			var within = data.within,
				withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
				outerWidth = within.width,
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
				overLeft = withinOffset - collisionPosLeft,
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
				newOverRight;

			// element is wider than within
			if ( data.collisionWidth > outerWidth ) {
				// element is initially over the left side of within
				if ( overLeft > 0 && overRight <= 0 ) {
					newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
					position.left += overLeft - newOverRight;
				// element is initially over right side of within
				} else if ( overRight > 0 && overLeft <= 0 ) {
					position.left = withinOffset;
				// element is initially over both left and right sides of within
				} else {
					if ( overLeft > overRight ) {
						position.left = withinOffset + outerWidth - data.collisionWidth;
					} else {
						position.left = withinOffset;
					}
				}
			// too far left -> align with left edge
			} else if ( overLeft > 0 ) {
				position.left += overLeft;
			// too far right -> align with right edge
			} else if ( overRight > 0 ) {
				position.left -= overRight;
			// adjust based on position and margin
			} else {
				position.left = max( position.left - collisionPosLeft, position.left );
			}
		},
		top: function( position, data ) {
			var within = data.within,
				withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
				outerHeight = data.within.height,
				collisionPosTop = position.top - data.collisionPosition.marginTop,
				overTop = withinOffset - collisionPosTop,
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
				newOverBottom;

			// element is taller than within
			if ( data.collisionHeight > outerHeight ) {
				// element is initially over the top of within
				if ( overTop > 0 && overBottom <= 0 ) {
					newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
					position.top += overTop - newOverBottom;
				// element is initially over bottom of within
				} else if ( overBottom > 0 && overTop <= 0 ) {
					position.top = withinOffset;
				// element is initially over both top and bottom of within
				} else {
					if ( overTop > overBottom ) {
						position.top = withinOffset + outerHeight - data.collisionHeight;
					} else {
						position.top = withinOffset;
					}
				}
			// too far up -> align with top
			} else if ( overTop > 0 ) {
				position.top += overTop;
			// too far down -> align with bottom edge
			} else if ( overBottom > 0 ) {
				position.top -= overBottom;
			// adjust based on position and margin
			} else {
				position.top = max( position.top - collisionPosTop, position.top );
			}
		}
	},
	flip: {
		left: function( position, data ) {
			var within = data.within,
				withinOffset = within.offset.left + within.scrollLeft,
				outerWidth = within.width,
				offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
				collisionPosLeft = position.left - data.collisionPosition.marginLeft,
				overLeft = collisionPosLeft - offsetLeft,
				overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
				myOffset = data.my[ 0 ] === "left" ?
					-data.elemWidth :
					data.my[ 0 ] === "right" ?
						data.elemWidth :
						0,
				atOffset = data.at[ 0 ] === "left" ?
					data.targetWidth :
					data.at[ 0 ] === "right" ?
						-data.targetWidth :
						0,
				offset = -2 * data.offset[ 0 ],
				newOverRight,
				newOverLeft;

			if ( overLeft < 0 ) {
				newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
				if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
					position.left += myOffset + atOffset + offset;
				}
			} else if ( overRight > 0 ) {
				newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
				if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
					position.left += myOffset + atOffset + offset;
				}
			}
		},
		top: function( position, data ) {
			var within = data.within,
				withinOffset = within.offset.top + within.scrollTop,
				outerHeight = within.height,
				offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
				collisionPosTop = position.top - data.collisionPosition.marginTop,
				overTop = collisionPosTop - offsetTop,
				overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
				top = data.my[ 1 ] === "top",
				myOffset = top ?
					-data.elemHeight :
					data.my[ 1 ] === "bottom" ?
						data.elemHeight :
						0,
				atOffset = data.at[ 1 ] === "top" ?
					data.targetHeight :
					data.at[ 1 ] === "bottom" ?
						-data.targetHeight :
						0,
				offset = -2 * data.offset[ 1 ],
				newOverTop,
				newOverBottom;
			if ( overTop < 0 ) {
				newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
				if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
					position.top += myOffset + atOffset + offset;
				}
			} else if ( overBottom > 0 ) {
				newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
				if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
					position.top += myOffset + atOffset + offset;
				}
			}
		}
	},
	flipfit: {
		left: function() {
			$.ui.position.flip.left.apply( this, arguments );
			$.ui.position.fit.left.apply( this, arguments );
		},
		top: function() {
			$.ui.position.flip.top.apply( this, arguments );
			$.ui.position.fit.top.apply( this, arguments );
		}
	}
};

// fraction support test
(function() {
	var testElement, testElementParent, testElementStyle, offsetLeft, i,
		body = document.getElementsByTagName( "body" )[ 0 ],
		div = document.createElement( "div" );

	//Create a "fake body" for testing based on method used in jQuery.support
	testElement = document.createElement( body ? "div" : "body" );
	testElementStyle = {
		visibility: "hidden",
		width: 0,
		height: 0,
		border: 0,
		margin: 0,
		background: "none"
	};
	if ( body ) {
		$.extend( testElementStyle, {
			position: "absolute",
			left: "-1000px",
			top: "-1000px"
		});
	}
	for ( i in testElementStyle ) {
		testElement.style[ i ] = testElementStyle[ i ];
	}
	testElement.appendChild( div );
	testElementParent = body || document.documentElement;
	testElementParent.insertBefore( testElement, testElementParent.firstChild );

	div.style.cssText = "position: absolute; left: 10.7432222px;";

	offsetLeft = $( div ).offset().left;
	supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;

	testElement.innerHTML = "";
	testElementParent.removeChild( testElement );
})();

})();

return $.ui.position;

}));

/*!
 * jQuery UI Effects 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/category/effects-core/
 */
(function( factory ) {
	if ( typeof define === "function" && define.amd ) {

		// AMD. Register as an anonymous module.
		define( [ "jquery" ], factory );
	} else {

		// Browser globals
		factory( jQuery );
	}
}(function( $ ) {

var dataSpace = "ui-effects-",

	// Create a local jQuery because jQuery Color relies on it and the
	// global may not exist with AMD and a custom build (#10199)
	jQuery = $;

$.effects = {
	effect: {}
};

/*!
 * jQuery Color Animations v2.1.2
 * https://github.com/jquery/jquery-color
 *
 * Copyright 2014 jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * Date: Wed Jan 16 08:47:09 2013 -0600
 */
(function( jQuery, undefined ) {

	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",

	// plusequals test for += 100 -= 100
	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
	// a set of RE's that can match strings and generate color tuples.
	stringParsers = [ {
			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
			parse: function( execResult ) {
				return [
					execResult[ 1 ],
					execResult[ 2 ],
					execResult[ 3 ],
					execResult[ 4 ]
				];
			}
		}, {
			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
			parse: function( execResult ) {
				return [
					execResult[ 1 ] * 2.55,
					execResult[ 2 ] * 2.55,
					execResult[ 3 ] * 2.55,
					execResult[ 4 ]
				];
			}
		}, {
			// this regex ignores A-F because it's compared against an already lowercased string
			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
			parse: function( execResult ) {
				return [
					parseInt( execResult[ 1 ], 16 ),
					parseInt( execResult[ 2 ], 16 ),
					parseInt( execResult[ 3 ], 16 )
				];
			}
		}, {
			// this regex ignores A-F because it's compared against an already lowercased string
			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
			parse: function( execResult ) {
				return [
					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
				];
			}
		}, {
			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
			space: "hsla",
			parse: function( execResult ) {
				return [
					execResult[ 1 ],
					execResult[ 2 ] / 100,
					execResult[ 3 ] / 100,
					execResult[ 4 ]
				];
			}
		} ],

	// jQuery.Color( )
	color = jQuery.Color = function( color, green, blue, alpha ) {
		return new jQuery.Color.fn.parse( color, green, blue, alpha );
	},
	spaces = {
		rgba: {
			props: {
				red: {
					idx: 0,
					type: "byte"
				},
				green: {
					idx: 1,
					type: "byte"
				},
				blue: {
					idx: 2,
					type: "byte"
				}
			}
		},

		hsla: {
			props: {
				hue: {
					idx: 0,
					type: "degrees"
				},
				saturation: {
					idx: 1,
					type: "percent"
				},
				lightness: {
					idx: 2,
					type: "percent"
				}
			}
		}
	},
	propTypes = {
		"byte": {
			floor: true,
			max: 255
		},
		"percent": {
			max: 1
		},
		"degrees": {
			mod: 360,
			floor: true
		}
	},
	support = color.support = {},

	// element for support tests
	supportElem = jQuery( "<p>" )[ 0 ],

	// colors = jQuery.Color.names
	colors,

	// local aliases of functions called often
	each = jQuery.each;

// determine rgba support immediately
supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;

// define cache name and alpha properties
// for rgba and hsla spaces
each( spaces, function( spaceName, space ) {
	space.cache = "_" + spaceName;
	space.props.alpha = {
		idx: 3,
		type: "percent",
		def: 1
	};
});

function clamp( value, prop, allowEmpty ) {
	var type = propTypes[ prop.type ] || {};

	if ( value == null ) {
		return (allowEmpty || !prop.def) ? null : prop.def;
	}

	// ~~ is an short way of doing floor for positive numbers
	value = type.floor ? ~~value : parseFloat( value );

	// IE will pass in empty strings as value for alpha,
	// which will hit this case
	if ( isNaN( value ) ) {
		return prop.def;
	}

	if ( type.mod ) {
		// we add mod before modding to make sure that negatives values
		// get converted properly: -10 -> 350
		return (value + type.mod) % type.mod;
	}

	// for now all property types without mod have min and max
	return 0 > value ? 0 : type.max < value ? type.max : value;
}

function stringParse( string ) {
	var inst = color(),
		rgba = inst._rgba = [];

	string = string.toLowerCase();

	each( stringParsers, function( i, parser ) {
		var parsed,
			match = parser.re.exec( string ),
			values = match && parser.parse( match ),
			spaceName = parser.space || "rgba";

		if ( values ) {
			parsed = inst[ spaceName ]( values );

			// if this was an rgba parse the assignment might happen twice
			// oh well....
			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
			rgba = inst._rgba = parsed._rgba;

			// exit each( stringParsers ) here because we matched
			return false;
		}
	});

	// Found a stringParser that handled it
	if ( rgba.length ) {

		// if this came from a parsed string, force "transparent" when alpha is 0
		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
		if ( rgba.join() === "0,0,0,0" ) {
			jQuery.extend( rgba, colors.transparent );
		}
		return inst;
	}

	// named colors
	return colors[ string ];
}

color.fn = jQuery.extend( color.prototype, {
	parse: function( red, green, blue, alpha ) {
		if ( red === undefined ) {
			this._rgba = [ null, null, null, null ];
			return this;
		}
		if ( red.jquery || red.nodeType ) {
			red = jQuery( red ).css( green );
			green = undefined;
		}

		var inst = this,
			type = jQuery.type( red ),
			rgba = this._rgba = [];

		// more than 1 argument specified - assume ( red, green, blue, alpha )
		if ( green !== undefined ) {
			red = [ red, green, blue, alpha ];
			type = "array";
		}

		if ( type === "string" ) {
			return this.parse( stringParse( red ) || colors._default );
		}

		if ( type === "array" ) {
			each( spaces.rgba.props, function( key, prop ) {
				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
			});
			return this;
		}

		if ( type === "object" ) {
			if ( red instanceof color ) {
				each( spaces, function( spaceName, space ) {
					if ( red[ space.cache ] ) {
						inst[ space.cache ] = red[ space.cache ].slice();
					}
				});
			} else {
				each( spaces, function( spaceName, space ) {
					var cache = space.cache;
					each( space.props, function( key, prop ) {

						// if the cache doesn't exist, and we know how to convert
						if ( !inst[ cache ] && space.to ) {

							// if the value was null, we don't need to copy it
							// if the key was alpha, we don't need to copy it either
							if ( key === "alpha" || red[ key ] == null ) {
								return;
							}
							inst[ cache ] = space.to( inst._rgba );
						}

						// this is the only case where we allow nulls for ALL properties.
						// call clamp with alwaysAllowEmpty
						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
					});

					// everything defined but alpha?
					if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
						// use the default of 1
						inst[ cache ][ 3 ] = 1;
						if ( space.from ) {
							inst._rgba = space.from( inst[ cache ] );
						}
					}
				});
			}
			return this;
		}
	},
	is: function( compare ) {
		var is = color( compare ),
			same = true,
			inst = this;

		each( spaces, function( _, space ) {
			var localCache,
				isCache = is[ space.cache ];
			if (isCache) {
				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
				each( space.props, function( _, prop ) {
					if ( isCache[ prop.idx ] != null ) {
						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
						return same;
					}
				});
			}
			return same;
		});
		return same;
	},
	_space: function() {
		var used = [],
			inst = this;
		each( spaces, function( spaceName, space ) {
			if ( inst[ space.cache ] ) {
				used.push( spaceName );
			}
		});
		return used.pop();
	},
	transition: function( other, distance ) {
		var end = color( other ),
			spaceName = end._space(),
			space = spaces[ spaceName ],
			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
			start = startColor[ space.cache ] || space.to( startColor._rgba ),
			result = start.slice();

		end = end[ space.cache ];
		each( space.props, function( key, prop ) {
			var index = prop.idx,
				startValue = start[ index ],
				endValue = end[ index ],
				type = propTypes[ prop.type ] || {};

			// if null, don't override start value
			if ( endValue === null ) {
				return;
			}
			// if null - use end
			if ( startValue === null ) {
				result[ index ] = endValue;
			} else {
				if ( type.mod ) {
					if ( endValue - startValue > type.mod / 2 ) {
						startValue += type.mod;
					} else if ( startValue - endValue > type.mod / 2 ) {
						startValue -= type.mod;
					}
				}
				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
			}
		});
		return this[ spaceName ]( result );
	},
	blend: function( opaque ) {
		// if we are already opaque - return ourself
		if ( this._rgba[ 3 ] === 1 ) {
			return this;
		}

		var rgb = this._rgba.slice(),
			a = rgb.pop(),
			blend = color( opaque )._rgba;

		return color( jQuery.map( rgb, function( v, i ) {
			return ( 1 - a ) * blend[ i ] + a * v;
		}));
	},
	toRgbaString: function() {
		var prefix = "rgba(",
			rgba = jQuery.map( this._rgba, function( v, i ) {
				return v == null ? ( i > 2 ? 1 : 0 ) : v;
			});

		if ( rgba[ 3 ] === 1 ) {
			rgba.pop();
			prefix = "rgb(";
		}

		return prefix + rgba.join() + ")";
	},
	toHslaString: function() {
		var prefix = "hsla(",
			hsla = jQuery.map( this.hsla(), function( v, i ) {
				if ( v == null ) {
					v = i > 2 ? 1 : 0;
				}

				// catch 1 and 2
				if ( i && i < 3 ) {
					v = Math.round( v * 100 ) + "%";
				}
				return v;
			});

		if ( hsla[ 3 ] === 1 ) {
			hsla.pop();
			prefix = "hsl(";
		}
		return prefix + hsla.join() + ")";
	},
	toHexString: function( includeAlpha ) {
		var rgba = this._rgba.slice(),
			alpha = rgba.pop();

		if ( includeAlpha ) {
			rgba.push( ~~( alpha * 255 ) );
		}

		return "#" + jQuery.map( rgba, function( v ) {

			// default to 0 when nulls exist
			v = ( v || 0 ).toString( 16 );
			return v.length === 1 ? "0" + v : v;
		}).join("");
	},
	toString: function() {
		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
	}
});
color.fn.parse.prototype = color.fn;

// hsla conversions adapted from:
// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021

function hue2rgb( p, q, h ) {
	h = ( h + 1 ) % 1;
	if ( h * 6 < 1 ) {
		return p + ( q - p ) * h * 6;
	}
	if ( h * 2 < 1) {
		return q;
	}
	if ( h * 3 < 2 ) {
		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
	}
	return p;
}

spaces.hsla.to = function( rgba ) {
	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
		return [ null, null, null, rgba[ 3 ] ];
	}
	var r = rgba[ 0 ] / 255,
		g = rgba[ 1 ] / 255,
		b = rgba[ 2 ] / 255,
		a = rgba[ 3 ],
		max = Math.max( r, g, b ),
		min = Math.min( r, g, b ),
		diff = max - min,
		add = max + min,
		l = add * 0.5,
		h, s;

	if ( min === max ) {
		h = 0;
	} else if ( r === max ) {
		h = ( 60 * ( g - b ) / diff ) + 360;
	} else if ( g === max ) {
		h = ( 60 * ( b - r ) / diff ) + 120;
	} else {
		h = ( 60 * ( r - g ) / diff ) + 240;
	}

	// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
	if ( diff === 0 ) {
		s = 0;
	} else if ( l <= 0.5 ) {
		s = diff / add;
	} else {
		s = diff / ( 2 - add );
	}
	return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
};

spaces.hsla.from = function( hsla ) {
	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
		return [ null, null, null, hsla[ 3 ] ];
	}
	var h = hsla[ 0 ] / 360,
		s = hsla[ 1 ],
		l = hsla[ 2 ],
		a = hsla[ 3 ],
		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
		p = 2 * l - q;

	return [
		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
		Math.round( hue2rgb( p, q, h ) * 255 ),
		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
		a
	];
};

each( spaces, function( spaceName, space ) {
	var props = space.props,
		cache = space.cache,
		to = space.to,
		from = space.from;

	// makes rgba() and hsla()
	color.fn[ spaceName ] = function( value ) {

		// generate a cache for this space if it doesn't exist
		if ( to && !this[ cache ] ) {
			this[ cache ] = to( this._rgba );
		}
		if ( value === undefined ) {
			return this[ cache ].slice();
		}

		var ret,
			type = jQuery.type( value ),
			arr = ( type === "array" || type === "object" ) ? value : arguments,
			local = this[ cache ].slice();

		each( props, function( key, prop ) {
			var val = arr[ type === "object" ? key : prop.idx ];
			if ( val == null ) {
				val = local[ prop.idx ];
			}
			local[ prop.idx ] = clamp( val, prop );
		});

		if ( from ) {
			ret = color( from( local ) );
			ret[ cache ] = local;
			return ret;
		} else {
			return color( local );
		}
	};

	// makes red() green() blue() alpha() hue() saturation() lightness()
	each( props, function( key, prop ) {
		// alpha is included in more than one space
		if ( color.fn[ key ] ) {
			return;
		}
		color.fn[ key ] = function( value ) {
			var vtype = jQuery.type( value ),
				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
				local = this[ fn ](),
				cur = local[ prop.idx ],
				match;

			if ( vtype === "undefined" ) {
				return cur;
			}

			if ( vtype === "function" ) {
				value = value.call( this, cur );
				vtype = jQuery.type( value );
			}
			if ( value == null && prop.empty ) {
				return this;
			}
			if ( vtype === "string" ) {
				match = rplusequals.exec( value );
				if ( match ) {
					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
				}
			}
			local[ prop.idx ] = value;
			return this[ fn ]( local );
		};
	});
});

// add cssHook and .fx.step function for each named hook.
// accept a space separated string of properties
color.hook = function( hook ) {
	var hooks = hook.split( " " );
	each( hooks, function( i, hook ) {
		jQuery.cssHooks[ hook ] = {
			set: function( elem, value ) {
				var parsed, curElem,
					backgroundColor = "";

				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
					value = color( parsed || value );
					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
						while (
							(backgroundColor === "" || backgroundColor === "transparent") &&
							curElem && curElem.style
						) {
							try {
								backgroundColor = jQuery.css( curElem, "backgroundColor" );
								curElem = curElem.parentNode;
							} catch ( e ) {
							}
						}

						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
							backgroundColor :
							"_default" );
					}

					value = value.toRgbaString();
				}
				try {
					elem.style[ hook ] = value;
				} catch ( e ) {
					// wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
				}
			}
		};
		jQuery.fx.step[ hook ] = function( fx ) {
			if ( !fx.colorInit ) {
				fx.start = color( fx.elem, hook );
				fx.end = color( fx.end );
				fx.colorInit = true;
			}
			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
		};
	});

};

color.hook( stepHooks );

jQuery.cssHooks.borderColor = {
	expand: function( value ) {
		var expanded = {};

		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
			expanded[ "border" + part + "Color" ] = value;
		});
		return expanded;
	}
};

// Basic color names only.
// Usage of any of the other color names requires adding yourself or including
// jquery.color.svg-names.js.
colors = jQuery.Color.names = {
	// 4.1. Basic color keywords
	aqua: "#00ffff",
	black: "#000000",
	blue: "#0000ff",
	fuchsia: "#ff00ff",
	gray: "#808080",
	green: "#008000",
	lime: "#00ff00",
	maroon: "#800000",
	navy: "#000080",
	olive: "#808000",
	purple: "#800080",
	red: "#ff0000",
	silver: "#c0c0c0",
	teal: "#008080",
	white: "#ffffff",
	yellow: "#ffff00",

	// 4.2.3. "transparent" color keyword
	transparent: [ null, null, null, 0 ],

	_default: "#ffffff"
};

})( jQuery );

/******************************************************************************/
/****************************** CLASS ANIMATIONS ******************************/
/******************************************************************************/
(function() {

var classAnimationActions = [ "add", "remove", "toggle" ],
	shorthandStyles = {
		border: 1,
		borderBottom: 1,
		borderColor: 1,
		borderLeft: 1,
		borderRight: 1,
		borderTop: 1,
		borderWidth: 1,
		margin: 1,
		padding: 1
	};

$.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
	$.fx.step[ prop ] = function( fx ) {
		if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
			jQuery.style( fx.elem, prop, fx.end );
			fx.setAttr = true;
		}
	};
});

function getElementStyles( elem ) {
	var key, len,
		style = elem.ownerDocument.defaultView ?
			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
			elem.currentStyle,
		styles = {};

	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
		len = style.length;
		while ( len-- ) {
			key = style[ len ];
			if ( typeof style[ key ] === "string" ) {
				styles[ $.camelCase( key ) ] = style[ key ];
			}
		}
	// support: Opera, IE <9
	} else {
		for ( key in style ) {
			if ( typeof style[ key ] === "string" ) {
				styles[ key ] = style[ key ];
			}
		}
	}

	return styles;
}

function styleDifference( oldStyle, newStyle ) {
	var diff = {},
		name, value;

	for ( name in newStyle ) {
		value = newStyle[ name ];
		if ( oldStyle[ name ] !== value ) {
			if ( !shorthandStyles[ name ] ) {
				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
					diff[ name ] = value;
				}
			}
		}
	}

	return diff;
}

// support: jQuery <1.8
if ( !$.fn.addBack ) {
	$.fn.addBack = function( selector ) {
		return this.add( selector == null ?
			this.prevObject : this.prevObject.filter( selector )
		);
	};
}

$.effects.animateClass = function( value, duration, easing, callback ) {
	var o = $.speed( duration, easing, callback );

	return this.queue( function() {
		var animated = $( this ),
			baseClass = animated.attr( "class" ) || "",
			applyClassChange,
			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;

		// map the animated objects to store the original styles.
		allAnimations = allAnimations.map(function() {
			var el = $( this );
			return {
				el: el,
				start: getElementStyles( this )
			};
		});

		// apply class change
		applyClassChange = function() {
			$.each( classAnimationActions, function(i, action) {
				if ( value[ action ] ) {
					animated[ action + "Class" ]( value[ action ] );
				}
			});
		};
		applyClassChange();

		// map all animated objects again - calculate new styles and diff
		allAnimations = allAnimations.map(function() {
			this.end = getElementStyles( this.el[ 0 ] );
			this.diff = styleDifference( this.start, this.end );
			return this;
		});

		// apply original class
		animated.attr( "class", baseClass );

		// map all animated objects again - this time collecting a promise
		allAnimations = allAnimations.map(function() {
			var styleInfo = this,
				dfd = $.Deferred(),
				opts = $.extend({}, o, {
					queue: false,
					complete: function() {
						dfd.resolve( styleInfo );
					}
				});

			this.el.animate( this.diff, opts );
			return dfd.promise();
		});

		// once all animations have completed:
		$.when.apply( $, allAnimations.get() ).done(function() {

			// set the final class
			applyClassChange();

			// for each animated element,
			// clear all css properties that were animated
			$.each( arguments, function() {
				var el = this.el;
				$.each( this.diff, function(key) {
					el.css( key, "" );
				});
			});

			// this is guarnteed to be there if you use jQuery.speed()
			// it also handles dequeuing the next anim...
			o.complete.call( animated[ 0 ] );
		});
	});
};

$.fn.extend({
	addClass: (function( orig ) {
		return function( classNames, speed, easing, callback ) {
			return speed ?
				$.effects.animateClass.call( this,
					{ add: classNames }, speed, easing, callback ) :
				orig.apply( this, arguments );
		};
	})( $.fn.addClass ),

	removeClass: (function( orig ) {
		return function( classNames, speed, easing, callback ) {
			return arguments.length > 1 ?
				$.effects.animateClass.call( this,
					{ remove: classNames }, speed, easing, callback ) :
				orig.apply( this, arguments );
		};
	})( $.fn.removeClass ),

	toggleClass: (function( orig ) {
		return function( classNames, force, speed, easing, callback ) {
			if ( typeof force === "boolean" || force === undefined ) {
				if ( !speed ) {
					// without speed parameter
					return orig.apply( this, arguments );
				} else {
					return $.effects.animateClass.call( this,
						(force ? { add: classNames } : { remove: classNames }),
						speed, easing, callback );
				}
			} else {
				// without force parameter
				return $.effects.animateClass.call( this,
					{ toggle: classNames }, force, speed, easing );
			}
		};
	})( $.fn.toggleClass ),

	switchClass: function( remove, add, speed, easing, callback) {
		return $.effects.animateClass.call( this, {
			add: add,
			remove: remove
		}, speed, easing, callback );
	}
});

})();

/******************************************************************************/
/*********************************** EFFECTS **********************************/
/******************************************************************************/

(function() {

$.extend( $.effects, {
	version: "1.11.4",

	// Saves a set of properties in a data storage
	save: function( element, set ) {
		for ( var i = 0; i < set.length; i++ ) {
			if ( set[ i ] !== null ) {
				element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
			}
		}
	},

	// Restores a set of previously saved properties from a data storage
	restore: function( element, set ) {
		var val, i;
		for ( i = 0; i < set.length; i++ ) {
			if ( set[ i ] !== null ) {
				val = element.data( dataSpace + set[ i ] );
				// support: jQuery 1.6.2
				// http://bugs.jquery.com/ticket/9917
				// jQuery 1.6.2 incorrectly returns undefined for any falsy value.
				// We can't differentiate between "" and 0 here, so we just assume
				// empty string since it's likely to be a more common value...
				if ( val === undefined ) {
					val = "";
				}
				element.css( set[ i ], val );
			}
		}
	},

	setMode: function( el, mode ) {
		if (mode === "toggle") {
			mode = el.is( ":hidden" ) ? "show" : "hide";
		}
		return mode;
	},

	// Translates a [top,left] array into a baseline value
	// this should be a little more flexible in the future to handle a string & hash
	getBaseline: function( origin, original ) {
		var y, x;
		switch ( origin[ 0 ] ) {
			case "top": y = 0; break;
			case "middle": y = 0.5; break;
			case "bottom": y = 1; break;
			default: y = origin[ 0 ] / original.height;
		}
		switch ( origin[ 1 ] ) {
			case "left": x = 0; break;
			case "center": x = 0.5; break;
			case "right": x = 1; break;
			default: x = origin[ 1 ] / original.width;
		}
		return {
			x: x,
			y: y
		};
	},

	// Wraps the element around a wrapper that copies position properties
	createWrapper: function( element ) {

		// if the element is already wrapped, return it
		if ( element.parent().is( ".ui-effects-wrapper" )) {
			return element.parent();
		}

		// wrap the element
		var props = {
				width: element.outerWidth(true),
				height: element.outerHeight(true),
				"float": element.css( "float" )
			},
			wrapper = $( "<div></div>" )
				.addClass( "ui-effects-wrapper" )
				.css({
					fontSize: "100%",
					background: "transparent",
					border: "none",
					margin: 0,
					padding: 0
				}),
			// Store the size in case width/height are defined in % - Fixes #5245
			size = {
				width: element.width(),
				height: element.height()
			},
			active = document.activeElement;

		// support: Firefox
		// Firefox incorrectly exposes anonymous content
		// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
		try {
			active.id;
		} catch ( e ) {
			active = document.body;
		}

		element.wrap( wrapper );

		// Fixes #7595 - Elements lose focus when wrapped.
		if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
			$( active ).focus();
		}

		wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element

		// transfer positioning properties to the wrapper
		if ( element.css( "position" ) === "static" ) {
			wrapper.css({ position: "relative" });
			element.css({ position: "relative" });
		} else {
			$.extend( props, {
				position: element.css( "position" ),
				zIndex: element.css( "z-index" )
			});
			$.each([ "top", "left", "bottom", "right" ], function(i, pos) {
				props[ pos ] = element.css( pos );
				if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
					props[ pos ] = "auto";
				}
			});
			element.css({
				position: "relative",
				top: 0,
				left: 0,
				right: "auto",
				bottom: "auto"
			});
		}
		element.css(size);

		return wrapper.css( props ).show();
	},

	removeWrapper: function( element ) {
		var active = document.activeElement;

		if ( element.parent().is( ".ui-effects-wrapper" ) ) {
			element.parent().replaceWith( element );

			// Fixes #7595 - Elements lose focus when wrapped.
			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
				$( active ).focus();
			}
		}

		return element;
	},

	setTransition: function( element, list, factor, value ) {
		value = value || {};
		$.each( list, function( i, x ) {
			var unit = element.cssUnit( x );
			if ( unit[ 0 ] > 0 ) {
				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
			}
		});
		return value;
	}
});

// return an effect options object for the given parameters:
function _normalizeArguments( effect, options, speed, callback ) {

	// allow passing all options as the first parameter
	if ( $.isPlainObject( effect ) ) {
		options = effect;
		effect = effect.effect;
	}

	// convert to an object
	effect = { effect: effect };

	// catch (effect, null, ...)
	if ( options == null ) {
		options = {};
	}

	// catch (effect, callback)
	if ( $.isFunction( options ) ) {
		callback = options;
		speed = null;
		options = {};
	}

	// catch (effect, speed, ?)
	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
		callback = speed;
		speed = options;
		options = {};
	}

	// catch (effect, options, callback)
	if ( $.isFunction( speed ) ) {
		callback = speed;
		speed = null;
	}

	// add options to effect
	if ( options ) {
		$.extend( effect, options );
	}

	speed = speed || options.duration;
	effect.duration = $.fx.off ? 0 :
		typeof speed === "number" ? speed :
		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
		$.fx.speeds._default;

	effect.complete = callback || options.complete;

	return effect;
}

function standardAnimationOption( option ) {
	// Valid standard speeds (nothing, number, named speed)
	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
		return true;
	}

	// Invalid strings - treat as "normal" speed
	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
		return true;
	}

	// Complete callback
	if ( $.isFunction( option ) ) {
		return true;
	}

	// Options hash (but not naming an effect)
	if ( typeof option === "object" && !option.effect ) {
		return true;
	}

	// Didn't match any standard API
	return false;
}

$.fn.extend({
	effect: function( /* effect, options, speed, callback */ ) {
		var args = _normalizeArguments.apply( this, arguments ),
			mode = args.mode,
			queue = args.queue,
			effectMethod = $.effects.effect[ args.effect ];

		if ( $.fx.off || !effectMethod ) {
			// delegate to the original method (e.g., .show()) if possible
			if ( mode ) {
				return this[ mode ]( args.duration, args.complete );
			} else {
				return this.each( function() {
					if ( args.complete ) {
						args.complete.call( this );
					}
				});
			}
		}

		function run( next ) {
			var elem = $( this ),
				complete = args.complete,
				mode = args.mode;

			function done() {
				if ( $.isFunction( complete ) ) {
					complete.call( elem[0] );
				}
				if ( $.isFunction( next ) ) {
					next();
				}
			}

			// If the element already has the correct final state, delegate to
			// the core methods so the internal tracking of "olddisplay" works.
			if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
				elem[ mode ]();
				done();
			} else {
				effectMethod.call( elem[0], args, done );
			}
		}

		return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
	},

	show: (function( orig ) {
		return function( option ) {
			if ( standardAnimationOption( option ) ) {
				return orig.apply( this, arguments );
			} else {
				var args = _normalizeArguments.apply( this, arguments );
				args.mode = "show";
				return this.effect.call( this, args );
			}
		};
	})( $.fn.show ),

	hide: (function( orig ) {
		return function( option ) {
			if ( standardAnimationOption( option ) ) {
				return orig.apply( this, arguments );
			} else {
				var args = _normalizeArguments.apply( this, arguments );
				args.mode = "hide";
				return this.effect.call( this, args );
			}
		};
	})( $.fn.hide ),

	toggle: (function( orig ) {
		return function( option ) {
			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
				return orig.apply( this, arguments );
			} else {
				var args = _normalizeArguments.apply( this, arguments );
				args.mode = "toggle";
				return this.effect.call( this, args );
			}
		};
	})( $.fn.toggle ),

	// helper functions
	cssUnit: function(key) {
		var style = this.css( key ),
			val = [];

		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
			if ( style.indexOf( unit ) > 0 ) {
				val = [ parseFloat( style ), unit ];
			}
		});
		return val;
	}
});

})();

/******************************************************************************/
/*********************************** EASING ***********************************/
/******************************************************************************/

(function() {

// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)

var baseEasings = {};

$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
	baseEasings[ name ] = function( p ) {
		return Math.pow( p, i + 2 );
	};
});

$.extend( baseEasings, {
	Sine: function( p ) {
		return 1 - Math.cos( p * Math.PI / 2 );
	},
	Circ: function( p ) {
		return 1 - Math.sqrt( 1 - p * p );
	},
	Elastic: function( p ) {
		return p === 0 || p === 1 ? p :
			-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
	},
	Back: function( p ) {
		return p * p * ( 3 * p - 2 );
	},
	Bounce: function( p ) {
		var pow2,
			bounce = 4;

		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
	}
});

$.each( baseEasings, function( name, easeIn ) {
	$.easing[ "easeIn" + name ] = easeIn;
	$.easing[ "easeOut" + name ] = function( p ) {
		return 1 - easeIn( 1 - p );
	};
	$.easing[ "easeInOut" + name ] = function( p ) {
		return p < 0.5 ?
			easeIn( p * 2 ) / 2 :
			1 - easeIn( p * -2 + 2 ) / 2;
	};
});

})();

return $.effects;

}));

/*!
 * jQuery UI Effects Bounce 1.11.4
 * http://jqueryui.com
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/bounce-effect/
 */
(function( factory ) {
	if ( typeof define === "function" && define.amd ) {

		// AMD. Register as an anonymous module.
		define([
			"jquery",
			"./effect"
		], factory );
	} else {

		// Browser globals
		factory( jQuery );
	}
}(function( $ ) {

return $.effects.effect.bounce = function( o, done ) {
	var el = $( this ),
		props = [ "position", "top", "bottom", "left", "right", "height", "width" ],

		// defaults:
		mode = $.effects.setMode( el, o.mode || "effect" ),
		hide = mode === "hide",
		show = mode === "show",
		direction = o.direction || "up",
		distance = o.distance,
		times = o.times || 5,

		// number of internal animations
		anims = times * 2 + ( show || hide ? 1 : 0 ),
		speed = o.duration / anims,
		easing = o.easing,

		// utility:
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
		motion = ( direction === "up" || direction === "left" ),
		i,
		upAnim,
		downAnim,

		// we will need to re-assemble the queue to stack our animations in place
		queue = el.queue(),
		queuelen = queue.length;

	// Avoid touching opacity to prevent clearType and PNG issues in IE
	if ( show || hide ) {
		props.push( "opacity" );
	}

	$.effects.save( el, props );
	el.show();
	$.effects.createWrapper( el ); // Create Wrapper

	// default distance for the BIGGEST bounce is the outer Distance / 3
	if ( !distance ) {
		distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
	}

	if ( show ) {
		downAnim = { opacity: 1 };
		downAnim[ ref ] = 0;

		// if we are showing, force opacity 0 and set the initial position
		// then do the "first" animation
		el.css( "opacity", 0 )
			.css( ref, motion ? -distance * 2 : distance * 2 )
			.animate( downAnim, speed, easing );
	}

	// start at the smallest distance if we are hiding
	if ( hide ) {
		distance = distance / Math.pow( 2, times - 1 );
	}

	downAnim = {};
	downAnim[ ref ] = 0;
	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
	for ( i = 0; i < times; i++ ) {
		upAnim = {};
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;

		el.animate( upAnim, speed, easing )
			.animate( downAnim, speed, easing );

		distance = hide ? distance * 2 : distance / 2;
	}

	// Last Bounce when Hiding
	if ( hide ) {
		upAnim = { opacity: 0 };
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;

		el.animate( upAnim, speed, easing );
	}

	el.queue(function() {
		if ( hide ) {
			el.hide();
		}
		$.effects.restore( el, props );
		$.effects.removeWrapper( el );
		done();
	});

	// inject all the animations we just queued to be first in line (after "inprogress")
	if ( queuelen > 1) {
		queue.splice.apply( queue,
			[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
	}
	el.dequeue();

};

}));

/*!
Waypoints - 3.1.1
Copyright © 2011-2015 Caleb Troughton
Licensed under the MIT license.
https://github.com/imakewebthings/waypoints/blog/master/licenses.txt
*/
(function() {
  'use strict'

  var keyCounter = 0
  var allWaypoints = {}

  /* http://imakewebthings.com/waypoints/api/waypoint */
  function Waypoint(options) {
    if (!options) {
      throw new Error('No options passed to Waypoint constructor')
    }
    if (!options.element) {
      throw new Error('No element option passed to Waypoint constructor')
    }
    if (!options.handler) {
      throw new Error('No handler option passed to Waypoint constructor')
    }

    this.key = 'waypoint-' + keyCounter
    this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)
    this.element = this.options.element
    this.adapter = new Waypoint.Adapter(this.element)
    this.callback = options.handler
    this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
    this.enabled = this.options.enabled
    this.triggerPoint = null
    this.group = Waypoint.Group.findOrCreate({
      name: this.options.group,
      axis: this.axis
    })
    this.context = Waypoint.Context.findOrCreateByElement(this.options.context)

    if (Waypoint.offsetAliases[this.options.offset]) {
      this.options.offset = Waypoint.offsetAliases[this.options.offset]
    }
    this.group.add(this)
    this.context.add(this)
    allWaypoints[this.key] = this
    keyCounter += 1
  }

  /* Private */
  Waypoint.prototype.queueTrigger = function(direction) {
    this.group.queueTrigger(this, direction)
  }

  /* Private */
  Waypoint.prototype.trigger = function(args) {
    if (!this.enabled) {
      return
    }
    if (this.callback) {
      this.callback.apply(this, args)
    }
  }

  /* Public */
  /* http://imakewebthings.com/waypoints/api/destroy */
  Waypoint.prototype.destroy = function() {
    this.context.remove(this)
    this.group.remove(this)
    delete allWaypoints[this.key]
  }

  /* Public */
  /* http://imakewebthings.com/waypoints/api/disable */
  Waypoint.prototype.disable = function() {
    this.enabled = false
    return this
  }

  /* Public */
  /* http://imakewebthings.com/waypoints/api/enable */
  Waypoint.prototype.enable = function() {
    this.context.refresh()
    this.enabled = true
    return this
  }

  /* Public */
  /* http://imakewebthings.com/waypoints/api/next */
  Waypoint.prototype.next = function() {
    return this.group.next(this)
  }

  /* Public */
  /* http://imakewebthings.com/waypoints/api/previous */
  Waypoint.prototype.previous = function() {
    return this.group.previous(this)
  }

  /* Private */
  Waypoint.invokeAll = function(method) {
    var allWaypointsArray = []
    for (var waypointKey in allWaypoints) {
      allWaypointsArray.push(allWaypoints[waypointKey])
    }
    for (var i = 0, end = allWaypointsArray.length; i < end; i++) {
      allWaypointsArray[i][method]()
    }
  }

  /* Public */
  /* http://imakewebthings.com/waypoints/api/destroy-all */
  Waypoint.destroyAll = function() {
    Waypoint.invokeAll('destroy')
  }

  /* Public */
  /* http://imakewebthings.com/waypoints/api/disable-all */
  Waypoint.disableAll = function() {
    Waypoint.invokeAll('disable')
  }

  /* Public */
  /* http://imakewebthings.com/waypoints/api/enable-all */
  Waypoint.enableAll = function() {
    Waypoint.invokeAll('enable')
  }

  /* Public */
  /* http://imakewebthings.com/waypoints/api/refresh-all */
  Waypoint.refreshAll = function() {
    Waypoint.Context.refreshAll()
  }

  /* Public */
  /* http://imakewebthings.com/waypoints/api/viewport-height */
  Waypoint.viewportHeight = function() {
    return window.innerHeight || document.documentElement.clientHeight
  }

  /* Public */
  /* http://imakewebthings.com/waypoints/api/viewport-width */
  Waypoint.viewportWidth = function() {
    return document.documentElement.clientWidth
  }

  Waypoint.adapters = []

  Waypoint.defaults = {
    context: window,
    continuous: true,
    enabled: true,
    group: 'default',
    horizontal: false,
    offset: 0
  }

  Waypoint.offsetAliases = {
    'bottom-in-view': function() {
      return this.context.innerHeight() - this.adapter.outerHeight()
    },
    'right-in-view': function() {
      return this.context.innerWidth() - this.adapter.outerWidth()
    }
  }

  window.Waypoint = Waypoint
}())
;(function() {
  'use strict'

  function requestAnimationFrameShim(callback) {
    window.setTimeout(callback, 1000 / 60)
  }

  var keyCounter = 0
  var contexts = {}
  var Waypoint = window.Waypoint
  var oldWindowLoad = window.onload

  /* http://imakewebthings.com/waypoints/api/context */
  function Context(element) {
    this.element = element
    this.Adapter = Waypoint.Adapter
    this.adapter = new this.Adapter(element)
    this.key = 'waypoint-context-' + keyCounter
    this.didScroll = false
    this.didResize = false
    this.oldScroll = {
      x: this.adapter.scrollLeft(),
      y: this.adapter.scrollTop()
    }
    this.waypoints = {
      vertical: {},
      horizontal: {}
    }

    element.waypointContextKey = this.key
    contexts[element.waypointContextKey] = this
    keyCounter += 1

    this.createThrottledScrollHandler()
    this.createThrottledResizeHandler()
  }

  /* Private */
  Context.prototype.add = function(waypoint) {
    var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'
    this.waypoints[axis][waypoint.key] = waypoint
    this.refresh()
  }

  /* Private */
  Context.prototype.checkEmpty = function() {
    var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)
    var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)
    if (horizontalEmpty && verticalEmpty) {
      this.adapter.off('.waypoints')
      delete contexts[this.key]
    }
  }

  /* Private */
  Context.prototype.createThrottledResizeHandler = function() {
    var self = this

    function resizeHandler() {
      self.handleResize()
      self.didResize = false
    }

    this.adapter.on('resize.waypoints', function() {
      if (!self.didResize) {
        self.didResize = true
        Waypoint.requestAnimationFrame(resizeHandler)
      }
    })
  }

  /* Private */
  Context.prototype.createThrottledScrollHandler = function() {
    var self = this
    function scrollHandler() {
      self.handleScroll()
      self.didScroll = false
    }

    this.adapter.on('scroll.waypoints', function() {
      if (!self.didScroll || Waypoint.isTouch) {
        self.didScroll = true
        Waypoint.requestAnimationFrame(scrollHandler)
      }
    })
  }

  /* Private */
  Context.prototype.handleResize = function() {
    Waypoint.Context.refreshAll()
  }

  /* Private */
  Context.prototype.handleScroll = function() {
    var triggeredGroups = {}
    var axes = {
      horizontal: {
        newScroll: this.adapter.scrollLeft(),
        oldScroll: this.oldScroll.x,
        forward: 'right',
        backward: 'left'
      },
      vertical: {
        newScroll: this.adapter.scrollTop(),
        oldScroll: this.oldScroll.y,
        forward: 'down',
        backward: 'up'
      }
    }

    for (var axisKey in axes) {
      var axis = axes[axisKey]
      var isForward = axis.newScroll > axis.oldScroll
      var direction = isForward ? axis.forward : axis.backward

      for (var waypointKey in this.waypoints[axisKey]) {
        var waypoint = this.waypoints[axisKey][waypointKey]
        var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint
        var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint
        var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint
        var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint
        if (crossedForward || crossedBackward) {
          waypoint.queueTrigger(direction)
          triggeredGroups[waypoint.group.id] = waypoint.group
        }
      }
    }

    for (var groupKey in triggeredGroups) {
      triggeredGroups[groupKey].flushTriggers()
    }

    this.oldScroll = {
      x: axes.horizontal.newScroll,
      y: axes.vertical.newScroll
    }
  }

  /* Private */
  Context.prototype.innerHeight = function() {
    /*eslint-disable eqeqeq */
    if (this.element == this.element.window) {
      return Waypoint.viewportHeight()
    }
    /*eslint-enable eqeqeq */
    return this.adapter.innerHeight()
  }

  /* Private */
  Context.prototype.remove = function(waypoint) {
    delete this.waypoints[waypoint.axis][waypoint.key]
    this.checkEmpty()
  }

  /* Private */
  Context.prototype.innerWidth = function() {
    /*eslint-disable eqeqeq */
    if (this.element == this.element.window) {
      return Waypoint.viewportWidth()
    }
    /*eslint-enable eqeqeq */
    return this.adapter.innerWidth()
  }

  /* Public */
  /* http://imakewebthings.com/waypoints/api/context-destroy */
  Context.prototype.destroy = function() {
    var allWaypoints = []
    for (var axis in this.waypoints) {
      for (var waypointKey in this.waypoints[axis]) {
        allWaypoints.push(this.waypoints[axis][waypointKey])
      }
    }
    for (var i = 0, end = allWaypoints.length; i < end; i++) {
      allWaypoints[i].destroy()
    }
  }

  /* Public */
  /* http://imakewebthings.com/waypoints/api/context-refresh */
  Context.prototype.refresh = function() {
    /*eslint-disable eqeqeq */
    var isWindow = this.element == this.element.window
    /*eslint-enable eqeqeq */
    var contextOffset = this.adapter.offset()
    var triggeredGroups = {}
    var axes

    this.handleScroll()
    axes = {
      horizontal: {
        contextOffset: isWindow ? 0 : contextOffset.left,
        contextScroll: isWindow ? 0 : this.oldScroll.x,
        contextDimension: this.innerWidth(),
        oldScroll: this.oldScroll.x,
        forward: 'right',
        backward: 'left',
        offsetProp: 'left'
      },
      vertical: {
        contextOffset: isWindow ? 0 : contextOffset.top,
        contextScroll: isWindow ? 0 : this.oldScroll.y,
        contextDimension: this.innerHeight(),
        oldScroll: this.oldScroll.y,
        forward: 'down',
        backward: 'up',
        offsetProp: 'top'
      }
    }

    for (var axisKey in axes) {
      var axis = axes[axisKey]
      for (var waypointKey in this.waypoints[axisKey]) {
        var waypoint = this.waypoints[axisKey][waypointKey]
        var adjustment = waypoint.options.offset
        var oldTriggerPoint = waypoint.triggerPoint
        var elementOffset = 0
        var freshWaypoint = oldTriggerPoint == null
        var contextModifier, wasBeforeScroll, nowAfterScroll
        var triggeredBackward, triggeredForward

        if (waypoint.element !== waypoint.element.window) {
          elementOffset = waypoint.adapter.offset()[axis.offsetProp]
        }

        if (typeof adjustment === 'function') {
          adjustment = adjustment.apply(waypoint)
        }
        else if (typeof adjustment === 'string') {
          adjustment = parseFloat(adjustment)
          if (waypoint.options.offset.indexOf('%') > - 1) {
            adjustment = Math.ceil(axis.contextDimension * adjustment / 100)
          }
        }

        contextModifier = axis.contextScroll - axis.contextOffset
        waypoint.triggerPoint = elementOffset + contextModifier - adjustment
        wasBeforeScroll = oldTriggerPoint < axis.oldScroll
        nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll
        triggeredBackward = wasBeforeScroll && nowAfterScroll
        triggeredForward = !wasBeforeScroll && !nowAfterScroll

        if (!freshWaypoint && triggeredBackward) {
          waypoint.queueTrigger(axis.backward)
          triggeredGroups[waypoint.group.id] = waypoint.group
        }
        else if (!freshWaypoint && triggeredForward) {
          waypoint.queueTrigger(axis.forward)
          triggeredGroups[waypoint.group.id] = waypoint.group
        }
        else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {
          waypoint.queueTrigger(axis.forward)
          triggeredGroups[waypoint.group.id] = waypoint.group
        }
      }
    }

    for (var groupKey in triggeredGroups) {
      triggeredGroups[groupKey].flushTriggers()
    }

    return this
  }

  /* Private */
  Context.findOrCreateByElement = function(element) {
    return Context.findByElement(element) || new Context(element)
  }

  /* Private */
  Context.refreshAll = function() {
    for (var contextId in contexts) {
      contexts[contextId].refresh()
    }
  }

  /* Public */
  /* http://imakewebthings.com/waypoints/api/context-find-by-element */
  Context.findByElement = function(element) {
    return contexts[element.waypointContextKey]
  }

  window.onload = function() {
    if (oldWindowLoad) {
      oldWindowLoad()
    }
    Context.refreshAll()
  }

  Waypoint.requestAnimationFrame = function(callback) {
    var requestFn = window.requestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.webkitRequestAnimationFrame ||
      requestAnimationFrameShim
    requestFn.call(window, callback)
  }
  Waypoint.Context = Context
}())
;(function() {
  'use strict'

  function byTriggerPoint(a, b) {
    return a.triggerPoint - b.triggerPoint
  }

  function byReverseTriggerPoint(a, b) {
    return b.triggerPoint - a.triggerPoint
  }

  var groups = {
    vertical: {},
    horizontal: {}
  }
  var Waypoint = window.Waypoint

  /* http://imakewebthings.com/waypoints/api/group */
  function Group(options) {
    this.name = options.name
    this.axis = options.axis
    this.id = this.name + '-' + this.axis
    this.waypoints = []
    this.clearTriggerQueues()
    groups[this.axis][this.name] = this
  }

  /* Private */
  Group.prototype.add = function(waypoint) {
    this.waypoints.push(waypoint)
  }

  /* Private */
  Group.prototype.clearTriggerQueues = function() {
    this.triggerQueues = {
      up: [],
      down: [],
      left: [],
      right: []
    }
  }

  /* Private */
  Group.prototype.flushTriggers = function() {
    for (var direction in this.triggerQueues) {
      var waypoints = this.triggerQueues[direction]
      var reverse = direction === 'up' || direction === 'left'
      waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)
      for (var i = 0, end = waypoints.length; i < end; i += 1) {
        var waypoint = waypoints[i]
        if (waypoint.options.continuous || i === waypoints.length - 1) {
          waypoint.trigger([direction])
        }
      }
    }
    this.clearTriggerQueues()
  }

  /* Private */
  Group.prototype.next = function(waypoint) {
    this.waypoints.sort(byTriggerPoint)
    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
    var isLast = index === this.waypoints.length - 1
    return isLast ? null : this.waypoints[index + 1]
  }

  /* Private */
  Group.prototype.previous = function(waypoint) {
    this.waypoints.sort(byTriggerPoint)
    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
    return index ? this.waypoints[index - 1] : null
  }

  /* Private */
  Group.prototype.queueTrigger = function(waypoint, direction) {
    this.triggerQueues[direction].push(waypoint)
  }

  /* Private */
  Group.prototype.remove = function(waypoint) {
    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
    if (index > -1) {
      this.waypoints.splice(index, 1)
    }
  }

  /* Public */
  /* http://imakewebthings.com/waypoints/api/first */
  Group.prototype.first = function() {
    return this.waypoints[0]
  }

  /* Public */
  /* http://imakewebthings.com/waypoints/api/last */
  Group.prototype.last = function() {
    return this.waypoints[this.waypoints.length - 1]
  }

  /* Private */
  Group.findOrCreate = function(options) {
    return groups[options.axis][options.name] || new Group(options)
  }

  Waypoint.Group = Group
}())
;(function() {
  'use strict'

  var $ = window.jQuery
  var Waypoint = window.Waypoint

  function JQueryAdapter(element) {
    this.$element = $(element)
  }

  $.each([
    'innerHeight',
    'innerWidth',
    'off',
    'offset',
    'on',
    'outerHeight',
    'outerWidth',
    'scrollLeft',
    'scrollTop'
  ], function(i, method) {
    JQueryAdapter.prototype[method] = function() {
      var args = Array.prototype.slice.call(arguments)
      return this.$element[method].apply(this.$element, args)
    }
  })

  $.each([
    'extend',
    'inArray',
    'isEmptyObject'
  ], function(i, method) {
    JQueryAdapter[method] = $[method]
  })

  Waypoint.adapters.push({
    name: 'jquery',
    Adapter: JQueryAdapter
  })
  Waypoint.Adapter = JQueryAdapter
}())
;(function() {
  'use strict'

  var Waypoint = window.Waypoint

  function createExtension(framework) {
    return function() {
      var waypoints = []
      var overrides = arguments[0]

      if (framework.isFunction(arguments[0])) {
        overrides = framework.extend({}, arguments[1])
        overrides.handler = arguments[0]
      }

      this.each(function() {
        var options = framework.extend({}, overrides, {
          element: this
        })
        if (typeof options.context === 'string') {
          options.context = framework(this).closest(options.context)[0]
        }
        waypoints.push(new Waypoint(options))
      })

      return waypoints
    }
  }

  if (window.jQuery) {
    window.jQuery.fn.waypoint = createExtension(window.jQuery)
  }
  if (window.Zepto) {
    window.Zepto.fn.waypoint = createExtension(window.Zepto)
  }
}())
;
/*!
Waypoints Sticky Element Shortcut - 3.1.1
Copyright © 2011-2015 Caleb Troughton
Licensed under the MIT license.
https://github.com/imakewebthings/waypoints/blog/master/licenses.txt
*/
(function() {
  'use strict'

  var $ = window.jQuery
  var Waypoint = window.Waypoint

  /* http://imakewebthings.com/waypoints/shortcuts/sticky-elements */
  function Sticky(options) {
    this.options = $.extend({}, Waypoint.defaults, Sticky.defaults, options)
    this.element = this.options.element
    this.$element = $(this.element)
    this.createWrapper()
    this.createWaypoint()
  }

  /* Private */
  Sticky.prototype.createWaypoint = function() {
    var originalHandler = this.options.handler

    this.waypoint = new Waypoint($.extend({}, this.options, {
      element: this.wrapper,
      handler: $.proxy(function(direction) {
        var shouldBeStuck = this.options.direction.indexOf(direction) > -1
        var wrapperHeight = shouldBeStuck ? this.$element.outerHeight(true) : ''

        this.$wrapper.height(wrapperHeight)
        this.$element.toggleClass(this.options.stuckClass, shouldBeStuck)

        if (originalHandler) {
          originalHandler.call(this, direction)
        }
      }, this)
    }))
  }

  /* Private */
  Sticky.prototype.createWrapper = function() {
    this.$element.wrap(this.options.wrapper)
    this.$wrapper = this.$element.parent()
    this.wrapper = this.$wrapper[0]
  }

  /* Public */
  Sticky.prototype.destroy = function() {
    if (this.$element.parent()[0] === this.wrapper) {
      this.waypoint.destroy()
      this.$element.removeClass(this.options.stuckClass).unwrap()
    }
  }

  Sticky.defaults = {
    wrapper: '<div class="sticky-wrapper" />',
    stuckClass: 'stuck',
    direction: 'down right'
  }

  Waypoint.Sticky = Sticky
}())
;
(function(b){b.fn.replaceText=function(b,d){return this.each(function(){var c,a;if(this&&(this.nodeType===3||this.innerHTML!=void 0))if(c=this.nodeValue?this.nodeValue:this.innerHTML,a=c.replace(b,d),a!==c&&(this.nodeValue=a,this.innerHTML))this.innerHTML=a})}})(jQuery);
// -----------------------------------------------------------------------
// Eros Fratini - eros@recoding.it
// jqprint 0.3
//
// - 19/06/2009 - some new implementations, added Opera support
// - 11/05/2009 - first sketch
//
// Printing plug-in for jQuery, evolution of jPrintArea: http://plugins.jquery.com/project/jPrintArea
// requires jQuery 1.3.x
//
// Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php
//------------------------------------------------------------------------

(function ($) {
    var opt;

    $.fn.jqprint = function (options) {
        opt = $.extend({}, $.fn.jqprint.defaults, options);

        var $element = (this instanceof jQuery) ? this : $(this);

        if (opt.operaSupport && $.browser.opera) {
            var tab = window.open("", "jqPrint-preview");
            tab.document.open();

            var doc = tab.document;
        }
        else {
            var $iframe = $("<iframe  />");

            if (!opt.debug) { $iframe.css({ position: "absolute", width: "0px", height: "0px", left: "-600px", top: "-600px" }); }

            $iframe.appendTo("body");
            var doc = $iframe[0].contentWindow.document;
        }

        if (opt.importCSS) {
            var $css = "";
            if ($("link[media=print]").length > 0) {
                $("link[media=print]").each(function () {
                    $css += "<link type='text/css' rel='stylesheet' href='" + $(this).attr("href") + "' media='print' />";                    
                });
            }
            else {
                $("link").each(function () {
                    $css += "<link type='text/css' rel='stylesheet' href='" + $(this).attr("href") + "' />";
                });
            }
            doc.write($css);
        }

        if (detectIE()) {
            var printWindow = window.open('', '', 'height=400,width=800');
            printWindow.document.write('<html><head>');
            printWindow.document.write($css);
            printWindow.document.write('</head><body >');
            printWindow.document.write($element.html());
            printWindow.document.write('</body></html>');
            printWindow.document.close();
            printWindow.print();
            setTimeout(function () { printWindow.close(); }, 1000);
            return;
        }
        
        if (opt.printContainer) { doc.write($element.outer()); }
        else { $element.each(function () { doc.write($(this).html()); }); }

        doc.close();

        (opt.operaSupport && $.browser.opera ? tab : $iframe[0].contentWindow).focus();
        setTimeout(function () { (opt.operaSupport && $.browser.opera ? tab : $iframe[0].contentWindow).print(); if (tab) { tab.close(); } }, 1000);
    }

    $.fn.jqprint.defaults = {
        debug: false,
        importCSS: true,
        printContainer: true,
        operaSupport: true
    };

    // Thanks to 9__, found at http://users.livejournal.com/9__/380664.html
    jQuery.fn.outer = function () {
        return $($('<div></div>').html(this.clone())).html();
    }
})(jQuery);


/**
 * detect IE
 * returns true is browser is IE or Edge
 */
function detectIE() {
    var ua = window.navigator.userAgent;

    var msie = ua.indexOf('MSIE ');
    if (msie > 0) {
        return true;
    }

    var trident = ua.indexOf('Trident/');
    if (trident > 0) {
        return true;
    }

    var edge = ua.indexOf('Edge/');
    if (edge > 0) {
        return true;
    }

    // other browser
    return false;
}
!function($){var launched=!1;$.findOnPage=function(el,options,callback){var base=this;base.$el=$(el),base.el=el,base.$el.data("findOnPage",base),base.callback=function(){callback&&callback.apply()},base.init=function(){function stripSpecialRegexCharacter(t){var e=["\\\\","\\[","\\]","\\(","\\)","\\/","\\*","\\+","\\?","\\{","\\}"],n=t;for(var a in e)n=n.replace(new RegExp(e[a],"g"),".");return n}function innerHighlight(t,e){var n=0;if(3===t.nodeType){var a=t.data.search(e);if(a>=0&&t.data.length>0){var i=t.data.match(e),o=document.createElement("span");o.className=base.options.textHighlightClass;var s=t.splitText(a),c=(s.splitText(i[0].length),s.cloneNode(!0));o.appendChild(c),s.parentNode.replaceChild(o,s),n=1}}else if(1===t.nodeType&&t.childNodes&&!/(script|style)/i.test(t.tagName))for(var r=0;r<t.childNodes.length;r++)r+=innerHighlight(t.childNodes[r],e);return n}function isNumber(t){return isNaN(t)||""==t?(base.options.minLength=3,!1):(base.options.minLength=1,!0)}function scrollToMatch(t){var e=$("span."+base.options.textHighlightClass).eq(t),n=$(window).height();switch($("html, body").animate({scrollTop:e.offset().top-n/2},800),t){case 0:$("button#fop_search-bw").attr("disabled",!0),matchCount>1&&$("button#fop_search-fw").attr("disabled",!1);break;case matchCount-1:$("button#fop_search-fw").attr("disabled",!0),matchCount>1&&$("button#fop_search-bw").attr("disabled",!1);break;default:$("button#fop_search-fw").attr("disabled",!1),$("button#fop_search-bw").attr("disabled",!1)}}("undefined"==typeof callback||null===callback)&&(callback="null"),base.callback=callback,base.options=$.extend({},$.findOnPage.defaultOptions,options),base.options.caseSensitive||(jQuery.expr[":"].contains=function(t,e,n){var a=$(t).text().match(new RegExp(n[3],"ig"));return null!=a&&a.length>0});var $closeButton=$("<button id='close-fop_search_box-container' >X</button>"),$searchBox=$("<input id='input-text' type='text' />"),$searchNavigationButtons=$("<div id='fop_search_text_buttons-container'><button disabled='disabled' id='fop_search-bw'>&lt;&lt;</button><button disabled='disabled' type='button' id='fop_search-fw' >&gt;&gt;</button></div>"),$searchMatchesContainer=$("<span id='fop_search_matching-container'>0</span>"),$searchBoxContainer=$("<div id='fop_search_box-container' />"),currentMatchIndex=0,matchCount=0,isScrolled=!1;launched||($searchBoxContainer.append($closeButton,$searchBox,$searchNavigationButtons,$searchMatchesContainer),$searchBoxContainer.appendTo("body").slideDown(1500,"easeOutBounce",base.callback),$searchBox.focus()),$closeButton.click(function(){$(this).parent().slideUp(750),$("."+base.options.textHighlightClass).contents().unwrap(),launched=!1}),$searchBox.keyup(function(event){matchCount=0;var $this=$(this);if(currentMatchIndex=0,(0==$this.val().length||$this.val().length>base.options.minLength-1)&&$("."+base.options.textHighlightClass).contents().unwrap().filter(function(){if(this.parentNode)with(this.parentNode)normalize()}),isNumber($this.val())||$this.val().length>base.options.minLength){var filteredString=stripSpecialRegexCharacter($this.val()).replace(new RegExp("\\s","i"),"\\s+").replace(new RegExp("'","g"),"\\'"),regex=base.options.caseSensitive?new RegExp(filteredString):new RegExp(filteredString,"i");innerHighlight($(base.options.parentContainer)[0],regex),matchCount=$("span."+base.options.textHighlightClass).filter(function(){return 0===$(this).closest(":hidden").length}).length,matchCount>1?$("button#fop_search-fw").attr("disabled",!1):$searchBoxContainer.find("button:not(#close-fop_search_box-container)").attr("disabled",!0),0===matchCount?($searchMatchesContainer.text(0),$("html").scrollTop(0)):$searchMatchesContainer.text(currentMatchIndex+1+"/"+matchCount),$("span."+base.options.textHighlightClass).length&&!isScrolled&&(scrollToMatch(0),isScrolled=!0)}else $searchMatchesContainer.text(0),$searchBoxContainer.find("button:not(#close-fop_search_box-container)").attr("disabled",!0),isScrolled=!1}),$("#fop_search_text_buttons-container button:not(#close-fop_search_box-container)").click(function(){var t=$(this).attr("id");return 2>matchCount?($("button.match-nav").attr("disabled",!0),!1):("fop_search-fw"==t&&matchCount-1>currentMatchIndex&&(currentMatchIndex++,scrollToMatch(currentMatchIndex)),"fop_search-bw"==t&&currentMatchIndex>0&&(currentMatchIndex--,scrollToMatch(currentMatchIndex)),void $searchMatchesContainer.text(currentMatchIndex+1+"/"+matchCount))}),launched=!0},base.init()},$.findOnPage.defaultOptions={caseSensitive:!1,excludedChildElements:"a,b",textHighlightClass:"text-found",minLength:3,parentContainer:"body"},$.fn.findOnPage=function(t,e){var n=this;this.bind("click",function(a){return a.preventDefault(),launched?void 0:new $.findOnPage(n,t,e)})}}(jQuery);
/// <reference path="iHJ-Main.js" />
/// <reference path="jquery-1.8.3.js" />
$(document).ready(function () {
    /* RESOLUCION SHOW   
    ----------------------------------------------------------*/

    $.fn.renderHallazgos = function () {
        var itemCount = 0;
        var previousSectionID = $(".section").eq(0).attr("id");

        $(this).find("p").each(function (i, el) {

            if ($(el).children().eq(0).hasClass("item-number"))
                itemCount++;

            //reset counter when section changes
            if ($(el).closest(".section").attr("id") != previousSectionID) {
                itemCount = 1;
                previousSectionID = $(el).closest(".section").attr("id");
            }

            if (!$(el).children().eq(0).hasClass("item-number")) {
                var $this = $(el);

                var $itemNumberAndPlaceHolder = $("<span class='text-placeholder'>" + itemCount + " [...] </span>");

                if ($(el).prev(":hidden").length && !$(el).prevAll(":visible").first().children("span.text-placeholder").length)
                    $(el).prepend($itemNumberAndPlaceHolder);

                //removes redundant items numbers in placeholder, already shown
                if ($(el).parent().find(".item-number").eq(0).is(":visible"))
                    $(el).children(".text-placeholder").text(" [...] ");

                //appends placeholder at the end of paragraphs followed by omitted ones
                if ($(el).next(":hidden").length && !$(el).next().children().eq(0).hasClass("item-number"))
                    $(el).append("<span class='text-placeholder'> [...] </span>");
            }
        });
        //handles decorators
        $(".section_item-container").has("p:visible").each(function (i, el) {
            var itemNumberSpanText = $(this).find(".item-number").eq(0).text();
            var currentItemNumber = itemNumberSpanText ? parseInt(itemNumberSpanText.substring(0, itemNumberSpanText.indexOf("."))) : 0;

            if (!$(el).prev().find("div#resolucion-container strong").length && (currentItemNumber !== 1))
                $(el).addClass("findings-decorator-top");

            if (!$(el).next().find("div#resolucion-container strong").length && (currentItemNumber !== itemCount))
                $(el).addClass("findings-decorator-bottom");

        });

    };


    var uriHash = window.location.hash ? window.location.hash : "#complete_resolucion";
    var currentUriHash = window.location.hash;
    var resolucionSection = "";
    var innerResolucionSection = "";
    var target = "";

    //method to update the resolucion view
    function updateResolucionView(tabsGroup, element) {
        if (tabsGroup == "upper") {

            $("#resolucion-upper_nav-container a").each(function () { $(this).removeClass("selected") });
            element.addClass("selected");
            resolucionSection = element.attr("href");
            $(".main-section").hide();
            $(resolucionSection).show();

            if ($("#complete_resolucion").is(":hidden")) {
                $("#resolucion-inner_nav .inner_nav").css("visibility", "hidden");
            }
            else {
                $("#resolucion-inner_nav .inner_nav").css("visibility", "visible");
            }
            if ($.browser.msie) {
                $("div#nav_panel-container").parent().removeClass("sticky");
            }

            $("#resolucion-container").removeClass("sticky");

            //  $("html, body").scrollTop(0);
        }
        if (tabsGroup == "inner") {
            $(".resolucion-inner_nav-buttons").removeClass("ui-state-highlight");
            element.addClass("ui-state-highlight");
            target = element.attr("data-view");
            //restores original displayed items
            $(".section_item-container").removeClass("findings-decorator-bottom findings-decorator-top");
            $("#kings-name, div.section .section-title").show();
            $("span.text-placeholder").remove();
            
            if (uriHash.indexOf("&") != -1)
                uriHash = uriHash.substring(0, uriHash.indexOf("&"))

            switch (target) {

                case "fundamentos":
                    $("div#resolucion-container div.section p").removeClass("hidden");
                    $('div#resolucion-container div.section')
                    .show()
                    .not("div#fundamentos-container")
                    .hide();
                    break;
                case "dictamen":
                    $("div#resolucion-container div.section p").removeClass("hidden");
                    $('div#resolucion-container div.section')
                    .show()
                    .not("div#dictamen-container")
                    .hide();
                    break;
                case "votos":
                    $("div#resolucion-container div.section p").removeClass("hidden");
                    $('div#resolucion-container div.section')
                        .show()
                        .not("div#votos-container")
                        .hide();
                    break;
                case "completa":
                    $("div#resolucion-container div.section p").removeClass("hidden");
                    $('div#resolucion-container div.section')
                    .show();
                    break;
                case "hallazgos":
                    $("#kings-name, div.section .section-title").hide();
                    $('div#resolucion-container div.section')
                    .show();
                    $("div#resolucion-container div.section p:not(:has(strong))").each(function () {
                        $(this).addClass("hidden");
                    });
                    //shows only the visible section's title
                    $('div.section').each(function () {
                        if ($(this).find('p:not(.hidden)').length)
                            $(this).find('.section-title').show();
                    });
                    if ($("div#resolucion-container").length)
                        $("div#resolucion-container").renderHallazgos();
                    break;
                case "hallazgos-fundamentos":
                    $("#kings-name").hide();
                    $("div.section .section-title").show();
                    $('div#resolucion-container div.section')
                    .show()
                    .not("div#fundamentos-container")
                    .hide();
                    //hides paragraphs without findings
                    $("div#resolucion-container div#fundamentos-container p:not(:has(strong))").each(function () {
                        $(this).addClass("hidden");
                    });
                    if ($("div#resolucion-container div#fundamentos-container").length)
                        $("div#resolucion-container div#fundamentos-container").renderHallazgos();
                    break;
            }
            if ($("#fop_search_box-container").css("display") == "block") {
                $("#input-text").keyup();
            }
            $("html, body").scrollTop(0);            
        }
    }

    //updates arrow navigation anchors
    function updateArrowsLinks() {
        $('html, body').animate({ scrollTop: 0 }, 'slow');

        if ($("a#page-switcher-start").length) {
            var prevResolucionLink = $("a#page-switcher-start").attr("href");
            //remove hash from uri
            if (prevResolucionLink.indexOf("#") >= 0)
                prevResolucionLink = prevResolucionLink.substr(0, prevResolucionLink.indexOf("#"));

            $("a#page-switcher-start").attr("href", prevResolucionLink + uriHash);
        }

        if ($("a#page-switcher-end").length) {
            var nextResolucionLink = $("a#page-switcher-end").attr("href");

            //remove hash from uri
            if (nextResolucionLink.indexOf("#") >= 0)
                nextResolucionLink = nextResolucionLink.substr(0, nextResolucionLink.indexOf("#"))

            $("a#page-switcher-end").attr("href", nextResolucionLink + uriHash);
        }
    }

    //resolucion extended info (upper tabs)
    $("#resolucion-upper_nav-container ul#nav-tabs a").click(function (event) {
        event.preventDefault();
        updateResolucionView("upper", $(this));
        uriHash = resolucionSection;
        window.location.hash = uriHash;
        updateArrowsLinks();
    });

    //inner navigation
    $(".resolucion-inner_nav-buttons").button().click(function (event, i) {
        event.preventDefault();
        updateResolucionView("inner", $(this));
        uriHash += "&" + target;
        window.location.hash = uriHash;
        updateArrowsLinks();
    });

    //set current view according to hash when loading the page
    if (currentUriHash) {
        if (currentUriHash.indexOf("&") != -1) {
            innerResolucionSection = currentUriHash.substr(currentUriHash.indexOf("&") + 1);
            currentUriHash = currentUriHash.substring(0, currentUriHash.indexOf("&"));
        }
        var $upperTab = $("#nav-tabs a[href=" + currentUriHash + "]");
        if ($upperTab.length) {
            updateResolucionView("upper", $upperTab);
            uriHash = resolucionSection;
        }

        if (innerResolucionSection) {
            var $innerTab = $("#resolucion-inner_nav a[data-view=" + innerResolucionSection + "]");
            if ($innerTab.length) {
                updateResolucionView("inner", $innerTab);
                uriHash += "&" + target;
            }
        }

        updateArrowsLinks();
    }


    //hides hallazgos buttons accordingly
    if (!$("#fundamentos-container strong").length) {
        $(".inner_nav a[data-view='hallazgos-fundamentos']").hide();
    }
    if (!$("#complete_resolucion strong").length) {
        $(".inner_nav a[data-view='hallazgos']").hide();
    }

    //Keeps the resolution nav panel always on top


    var sticky = new Waypoint.Sticky({
        element: $('#nav_panel-container')[0]
    })

    /* Toolbox */
    function getSelectionText() {
        var text = "";
        if (window.getSelection) {
            text = window.getSelection().toString();
        } else if (document.selection && document.selection.type != "Control") {
            text = document.selection.createRange().text;
        }
        return text;
    }

    $("a#resolucion-print").click(function (event) {
        event.preventDefault();

        var textToPrint = getSelectionText();

        var resolucionIdentifier = jQuery("#resolucion-identifier").text();

        resolucionIdentifier = $("<h3>" + resolucionIdentifier + "</h3>");
        if (textToPrint.length) {
            $.getScript('/Scripts/tc-jqueryprint.js', function () {
                var $selectedText = jQuery("<div>" + textToPrint + "</div>");//.css({ "text-align": "justify" });
                $selectedText.prepend(resolucionIdentifier);
                $selectedText.jqprint();
            });
        } else {
            $("#complete_resolucion").prepend(resolucionIdentifier).jqprint();
        }

        resolucionIdentifier.remove();

        return false;
    });

    //search in document
    $("ul#tool_box-container a#resolucion-search").css("visibility", "visible");
    $("ul#tool_box-container a#resolucion-search").css("margin-right", "-10px");
    $("a#resolucion-search").findOnPage();
    //ends search in document

    // buzón de sugerencias descriptores

    var $descriptorEmail = $("#descriptor-suggestions-form #descriptor-email"),
            $descriptorSuggestion = $("#descriptor-suggestions-form #descriptor-suggestion"),
            $descriptorReasoning = $("#descriptor-suggestions-form #descriptor-reasoning"),
            $descriptorGrounds = $("#descriptor-suggestions-form #descriptor-grounds");
    var $descriptorAllFields = $([]).add($descriptorEmail).add($descriptorSuggestion).add($descriptorReasoning).add($descriptorGrounds),
        $descriptorTips = $("#descriptor-tips");

    function updateTipsDescriptor(t) {
        $descriptorTips.text(t).addClass("ui-state-highlight");
        setTimeout(function () {
            $descriptorTips.removeClass("ui-state-highlight", 1500);
        }, 500);
    }

    function checkLengthDescriptor(o, n, min, max) {
        if (o.val().length > max || o.val().length < min) {
            o.addClass("ui-state-error");
            updateTipsDescriptor(translate("length_error", new Array(n, min, max)));
            return false;
        } else {
            return true;
        }
    }

    function checkRegexpDescriptor(o, regexp, n) {
        if (!o.val()) {
            return true;
        }

        if (!(regexp.test(o.val()))) {
            o.addClass("ui-state-error");
            updateTipsDescriptor(n);
            return false;
        } else {
            return true;
        }
    }

    $("#descriptor-dialog-form").dialog({
        autoOpen: false,
        height: 579,
        width: 700,
        modal: true,
        buttons: [{
            text: translate("send_suggestion"),
            click: function () {
                var $this = $(this);
                var bValid = true;
                $descriptorAllFields.removeClass("ui-state-error");

                bValid = bValid && checkLengthDescriptor($descriptorSuggestion, "descriptor", 3, 255);
                bValid = bValid && checkLengthDescriptor($descriptorGrounds, "fundamentos", 0, 500);
                bValid = bValid && checkLengthDescriptor($descriptorReasoning, "motivación", 0, 1000);
                bValid = bValid && checkRegexpDescriptor($descriptorEmail, /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i, "ej. nombre@ejemplo.com");

                if (bValid) {
                    var data = "{'suggestedDescriptor':'" + $descriptorSuggestion.val() + "', 'grounds':'" + $descriptorGrounds.val() + "', " +
                                 "'reasoning':'" + $descriptorReasoning.val() + "', 'contactInformation':'" + $descriptorEmail.val() + "'}";
                    $.ajax({
                        type: "POST",
                        contentType: "application/json; charset=utf-8",
                        url: REALPATH + CURRENT_LANG + "/Descriptor/SendSuggestion",
                        data: data,
                        dataType: "json",
                        async: true,
                        success: function (response) {
                            if (!response["success"]) {
                                showFlashMessage(response["error"]);
                            }
                            else {
                                $this.find("fieldset").html("<b>" + translate("suggestion_success") + "</b>");
                                setTimeout(function () {
                                    $this.parent().fadeOut(750, function () {
                                        $this.dialog("close")
                                    });
                                }, 4000);
                            }
                        },
                        error: function (result) {
                            showFlashMessage(translate("unexpected_error_sending_data"));
                        }
                    });
                }
            }
        },
            {
                text: translate("cancel"),
                click: function () {
                    $(this).dialog("close");
                }
            }],
        close: function () {
            $descriptorAllFields.val("").removeClass("ui-state-error");
        }
    });

    $("a#descriptor_suggestion_box-launcher").click(function (event) {
        event.preventDefault();
        $("#descriptor-dialog-form").dialog("open");
        return false;
    });

    // end buzón de sugerencias descriptores

    //buzón de sugerencias

    var $name = $("#suggestions-form #name"),
            $email = $("#suggestions-form #email"),
            $sugerencia = $("#suggestions-form #sugerencia"),
            $section = $("#suggestions-form #section");
    var $allFields = $([]).add($name).add($email).add($section).add($sugerencia),
        $tips = $("#tips");

    function updateTips(t) {
        $tips.text(t).addClass("ui-state-highlight");
        setTimeout(function () {
            $tips.removeClass("ui-state-highlight", 1500);
        }, 500);
    }

    function checkLength(o, n, min, max) {
        if (o.val().length > max || o.val().length < min) {
            o.addClass("ui-state-error");
            updateTips(translate("length_error", new Array(n, min, max)));
            return false;
        } else {
            return true;
        }
    }

    function checkRegexp(o, regexp, n) {
        if (!(regexp.test(o.val()))) {
            o.addClass("ui-state-error");
            updateTips(n);
            return false;
        } else {
            return true;
        }
    }

    $("#dialog-form").dialog({
        autoOpen: false,
        height: 535,
        width: 700,
        modal: true,
        buttons: [{
            text: translate("send_suggestion"),
            click: function () {
                var $this = $(this);
                var bValid = true;
                $allFields.removeClass("ui-state-error");
                /*De momento se comenta la validación de nombre y email, por si en un futuro
                se decide volver a utilizarlo. */

                //                bValid = bValid && checkLength($name, "name", 3, 50);
                //                bValid = bValid && checkLength($email, "email", 6, 80);
                bValid = bValid && checkLength($sugerencia, "sugerencia", 5, 1000);
                //                bValid = bValid && checkRegexp($email, /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i, "ej. nombre@ejemplo.com");

                if (bValid) {

                    var data = "{'suggestionText':'" + $sugerencia.val() + "', section: " + $section.val() + "}";
                    $.ajax({
                        type: "POST",
                        contentType: "application/json; charset=utf-8",
                        url: REALPATH + CURRENT_LANG + "/Resolucion/SendSuggestion",
                        data: data,
                        dataType: "json",
                        async: true,
                        success: function (response) {
                            if (!response["success"]) {
                                showFlashMessage(response["error"]);
                            }
                            else {
                                $this.find("fieldset").html("<b>" + translate("suggestion_success") + "</b>");
                                setTimeout(function () {
                                    $this.parent().fadeOut(750, function () {
                                        $this.dialog("close")
                                    });
                                }, 4000);
                            }
                        },
                        error: function (result) {
                            showFlashMessage(translate("unexpected_error_sending_data"));
                        }
                    });
                }
            }
        },
            {
                text: translate("cancel"),
                click: function () {
                    $(this).dialog("close");
                }
            }],
        close: function () {
            $allFields.val("").removeClass("ui-state-error");
        }
    });

    $("a#suggestion_box-launcher").click(function (event) {
        event.preventDefault();
        $("#dialog-form").dialog("open");
        return false;
    });

    //Download doc
    $("a#resolucion-doc").click(function (event) {
        var href = $(this).attr("href");
        $("#download_dialog-confirm").dialog({
            resizable: false,
            height: 250,
            width: 500,
            modal: true,
            buttons: [{
                text: translate("download"),
                click: function () {
                    window.open(href);
                    $(this).dialog("close");
                }
            },
                {
                    text: translate("cancel"),
                    click: function () {
                        $(this).dialog("close");
                    }
                }
            ]
        });
        return false;
    });

    /* ends toolbox*/

    /* Detalle índices */

    $("ul#indices-nav li").click(function () {
        $("ul#indices-nav li").removeClass("selected");
        $(this).addClass("selected");
        $("ul.indice-group").removeClass("selected");
        var indiceGroupContainer = $(this).attr("data-view");

        $("#" + indiceGroupContainer).addClass("selected");
    });


    $('.js-indiceLink').click(function (e) {
        e.preventDefault();
        var idarticulo = $(this).parent().parent().data('idarticulo');
        //alert("idarticulo test: " + idarticulo);
        showIResolutions(idarticulo);
    });

    //$("ul.indice-group li a").on("click", function (event) {
    //    event.preventDefault();
    //    //var idarticulo = $(this).parent().data("idarticulo");
    //    var idarticulo = $("#idarticulo").val();
    //    var idindicor = "15186";
    //    //var idmodifier = $(this).parent().data("idarticulo");
    //    alert("idarticulo  (ul.indice-group li a):" + idarticulo + " " + idindicor);

    //    showIResolutions(idarticulo);
    //});

    function showIResolutions(idarticulo) {
        var arguments = "{'articuloID':'" + idarticulo + "'";
        arguments += "}";
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: REALPATH + CURRENT_LANG + "/Indice/SearchSingle",
            data: arguments,
            dataType: "json",
            async: true,
            success: function (response) {
                if (!parseInt(response["success"])) {
                    showFlashMessage(response["error"]);
                }
                else {
                    window.open(REALPATH + CURRENT_LANG + "/Resolucion/List");
                }
            },

            error: function (result) {
                showFlashMessage(translate("unexpected_error_sending_data"));
            }
        });     
    }

    /* ends detalle índices */

    /* Detalle Descriptores */

    $("ul#descriptores-nav li").click(function () {
        $("ul#descriptores-nav li").removeClass("selected");
        $(this).addClass("selected");
        $("ul.descriptor-group").removeClass("selected");
        var descriptorGroupContainer = $(this).attr("data-view");

        if (descriptorGroupContainer == "descriptorTreeView") {
            $("#canvasDescriptores").css("display", "block");
        }
        else {
            $("#" + descriptorGroupContainer).addClass("selected");
            $("#canvasDescriptores").css("display", "none");
        }
    });

    $("ul.descriptor-group li a").on("click", function (event) {
        event.preventDefault();
        var iddescriptor = $(this).parent().data("iddescriptor");
        var idmodifier = $(this).parent().data("idmodificador");

        showResolutions(iddescriptor, idmodifier);
    });

    function showResolutions(iddescriptor, idmodifier) {
        var arguments = "{'descriptorID':'" + iddescriptor + "'";
        if (idmodifier && idmodifier > 0) {
            arguments += ", 'modificadorID':'" + idmodifier + "'";
        }

        arguments += "}";

        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: REALPATH + CURRENT_LANG + "/Descriptor/SearchSingle",
            data: arguments,
            dataType: "json",
            async: true,
            success: function (response) {
                if (!parseInt(response["success"])) {
                    showFlashMessage(response["error"]);
                }
                else {
                    window.open(REALPATH + CURRENT_LANG + "/Resolucion/List");
                }
            },
            error: function (result) {
                showFlashMessage(translate("unexpected_error_sending_data"));
            }
            
        });
    }

    /* ends detalle Descriptores */

    /* Starts readspeaker section */
    //called from $("#resolucion-upper_nav-container ul#nav-tabs a").click();
    function launchPlayer() {
        $.ajax({
            url: "/Scripts/readspeaker/ReadSpeaker.js",
            dataType: "script",
            success: function () { }
        });

        $('div#readspeaker_button1').after($('div#complete_resolucion').html());

    }

    /* Ends readspeaker section */

    $("a.js-descriptorLink").each(function () {
        var idDescriptor = $(this).parent().data("iddescriptor");
        var $this = $(this);
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: REALPATH + CURRENT_LANG + "/Descriptor/GetAscendantsTitle",
            data: "{'descriptorID':'" + idDescriptor + "'}",
            dataType: "json",
            async: true,
            success: function (response) {
                if (parseInt(response["success"], 10) == 1) {
                    $this.prop("title", response["ascendants"]);
                    var descriptor = response["ascendants"].substring(response["ascendants"].lastIndexOf(" >> ") + 4);
                    var antecesores = response["ascendants"].substring(0, response["ascendants"].lastIndexOf(" >> "));

                    $this.prop("text", descriptor);
                }
            },
            error: function (result) {

            }
        });
    });

    //$("a.js-indiceLink").each(function () {
    //    var idarticulo = $(this).parent().data("idarticulo");
    //    var $this = $(this);
    //    alert("idarticulo (a.js-indiceLink):", idarticulo);
    //    $.ajax({
    //        type: "POST",
    //        contentType: "application/json; charset=utf-8",
    //        url: REALPATH + CURRENT_LANG + "/Indice/GetAscendantsTitle",
    //        data: "{'articuloID':'" + idarticulo + "'}",
    //        dataType: "json",
    //        async: true,
    //        success: function (response) {
    //            if (parseInt(response["success"], 10) == 1) {
    //                $this.prop("title", response["ascendants"]);
    //                var articulo = response["ascendants"].substring(response["ascendants"].lastIndexOf(" >> ") + 4);
    //               // var antecesores = response["ascendants"].substring(0, response["ascendants"].lastIndexOf(" >> "));
                    
    //                $this.prop("text", articulo);
    //            }
    //        },
    //        error: function (result) {

    //        }
    //    });
    //});

    $("span.js-descriptorAntecesores").each(function () {
        var idDescriptor = $(this).parent().data("iddescriptor");
        var $this = $(this);
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: REALPATH + CURRENT_LANG + "/Descriptor/GetAscendantsTitle",
            data: "{'descriptorID':'" + idDescriptor + "'}",
            dataType: "json",
            async: true,
            success: function (response) {
                if (parseInt(response["success"], 10) == 1) {
                    $this.prop("title", response["ascendants"]);
                    //$this.prop("text", response["ascendants"]);

                    var descriptor = response["ascendants"].substring(response["ascendants"].lastIndexOf(" >> ") + 4);
                    var antecesores = response["ascendants"].substring(0, response["ascendants"].lastIndexOf(" >> "));
                    if (antecesores != null) {
                        $this.html("- " + antecesores + " >> ");
                    }
                    else {
                        $this.html("- " + antecesores);
                    }
                }
            },
            error: function (result) {

            }
        });
    });
    /* ENDS RESOLUCION SHOW   
    ----------------------------------------------------------*/

});

!function(){function n(n){return n&&(n.ownerDocument||n.document||n).documentElement}function t(n){return n&&(n.ownerDocument&&n.ownerDocument.defaultView||n.document&&n||n.defaultView)}function e(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function r(n){return null===n?0/0:+n}function u(n){return!isNaN(n)}function i(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function c(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function l(){this._=Object.create(null)}function s(n){return(n+="")===pa||n[0]===va?va+n:n}function f(n){return(n+="")[0]===va?n.slice(1):n}function h(n){return s(n)in this._}function g(n){return(n=s(n))in this._&&delete this._[n]}function p(){var n=[];for(var t in this._)n.push(f(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function m(){this._=Object.create(null)}function y(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=da.length;r>e;++e){var u=da[e]+t;if(u in n)return u}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new l;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function S(){ta.event.preventDefault()}function k(){for(var n,t=ta.event;n=t.sourceEvent;)t=n;return t}function E(n){for(var t=new _,e=0,r=arguments.length;++e<r;)t[arguments[e]]=w(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=ta.event;u.target=n,ta.event=u,t[u.type].apply(e,r)}finally{ta.event=i}}},t}function A(n){return ya(n,_a),n}function N(n){return"function"==typeof n?n:function(){return Ma(n,this)}}function C(n){return"function"==typeof n?n:function(){return xa(n,this)}}function z(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=ta.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function q(n){return n.trim().replace(/\s+/g," ")}function L(n){return new RegExp("(?:^|\\s+)"+ta.requote(n)+"(?:\\s+|$)","g")}function T(n){return(n+"").trim().split(/^|\s+/)}function R(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=T(n).map(D);var u=n.length;return"function"==typeof t?r:e}function D(n){var t=L(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",q(u+" "+n))):e.setAttribute("class",q(u.replace(t," ")))}}function P(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function U(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function j(n){function t(){var t=this.ownerDocument,e=this.namespaceURI;return e?t.createElementNS(e,n):t.createElement(n)}function e(){return this.ownerDocument.createElementNS(n.space,n.local)}return"function"==typeof n?n:(n=ta.ns.qualify(n)).local?e:t}function F(){var n=this.parentNode;n&&n.removeChild(this)}function H(n){return{__data__:n}}function O(n){return function(){return ba(this,n)}}function I(n){return arguments.length||(n=e),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function Y(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function Z(n){return ya(n,Sa),n}function V(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function X(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,ra(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+ta.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=$;a>0&&(n=n.slice(0,a));var l=ka.get(n);return l&&(n=l,c=B),a?t?u:r:t?b:i}function $(n,t){return function(e){var r=ta.event;ta.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ta.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Aa,u="click"+r,i=ta.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ea&&(Ea="onselectstart"in e?!1:x(e.style,"userSelect")),Ea){var o=n(e).style,a=o[Ea];o[Ea]="none"}return function(n){if(i.on(r,null),Ea&&(o[Ea]=a),n){var t=function(){i.on(u,null)};i.on(u,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var u=r.createSVGPoint();if(0>Na){var i=t(n);if(i.scrollX||i.scrollY){r=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Na=!(o.f||o.e),r.remove()}}return Na?(u.x=e.pageX,u.y=e.pageY):(u.x=e.clientX,u.y=e.clientY),u=u.matrixTransform(n.getScreenCTM().inverse()),[u.x,u.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ta.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nt(n){return n>1?0:-1>n?qa:Math.acos(n)}function tt(n){return n>1?Ra:-1>n?-Ra:Math.asin(n)}function et(n){return((n=Math.exp(n))-1/n)/2}function rt(n){return((n=Math.exp(n))+1/n)/2}function ut(n){return((n=Math.exp(2*n))-1)/(n+1)}function it(n){return(n=Math.sin(n/2))*n}function ot(){}function at(n,t,e){return this instanceof at?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof at?new at(n.h,n.s,n.l):bt(""+n,_t,at):new at(n,t,e)}function ct(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new mt(u(n+120),u(n),u(n-120))}function lt(n,t,e){return this instanceof lt?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof lt?new lt(n.h,n.c,n.l):n instanceof ft?gt(n.l,n.a,n.b):gt((n=wt((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new lt(n,t,e)}function st(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new ft(e,Math.cos(n*=Da)*t,Math.sin(n)*t)}function ft(n,t,e){return this instanceof ft?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof ft?new ft(n.l,n.a,n.b):n instanceof lt?st(n.h,n.c,n.l):wt((n=mt(n)).r,n.g,n.b):new ft(n,t,e)}function ht(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=pt(u)*Xa,r=pt(r)*$a,i=pt(i)*Ba,new mt(dt(3.2404542*u-1.5371385*r-.4985314*i),dt(-.969266*u+1.8760108*r+.041556*i),dt(.0556434*u-.2040259*r+1.0572252*i))}function gt(n,t,e){return n>0?new lt(Math.atan2(e,t)*Pa,Math.sqrt(t*t+e*e),n):new lt(0/0,0/0,n)}function pt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function vt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function dt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mt(n,t,e){return this instanceof mt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mt?new mt(n.r,n.g,n.b):bt(""+n,mt,ct):new mt(n,t,e)}function yt(n){return new mt(n>>16,n>>8&255,255&n)}function Mt(n){return yt(n)+""}function xt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function bt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(kt(u[0]),kt(u[1]),kt(u[2]))}return(i=Ga.get(n.toLowerCase()))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function _t(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new at(r,u,c)}function wt(n,t,e){n=St(n),t=St(t),e=St(e);var r=vt((.4124564*n+.3575761*t+.1804375*e)/Xa),u=vt((.2126729*n+.7151522*t+.072175*e)/$a),i=vt((.0193339*n+.119192*t+.9503041*e)/Ba);return ft(116*u-16,500*(r-u),200*(u-i))}function St(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function kt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function Et(n){return"function"==typeof n?n:function(){return n}}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return void o.error.call(i,r)}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=ta.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!this.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=ta.event;ta.event=n;try{o.progress.call(i,c)}finally{ta.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ra(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},ta.rebind(i,o,"on"),null==r?i:i.get(Ct(r))}function Ct(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qt(){var n=Lt(),t=Tt()-n;t>24?(isFinite(t)&&(clearTimeout(tc),tc=setTimeout(qt,t)),nc=0):(nc=1,rc(qt))}function Lt(){var n=Date.now();for(ec=Ka;ec;)n>=ec.t&&(ec.f=ec.c(n-ec.t)),ec=ec.n;return n}function Tt(){for(var n,t=Ka,e=1/0;t;)t.f?t=n?n.n=t.n:Ka=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return Qa=n,e}function Rt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Dt(n,t){var e=Math.pow(10,3*ga(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:y;return function(n){var e=ic.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":y=!1;case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=oc.get(g)||Ut;var M=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=ta.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!l&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new cc(e-1)),1),e}function i(n,e){return t(n=new cc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{cc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{cc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{cc=jt;var r=new jt;return r._=t,n(r,e)._}finally{cc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.slice(c,a)),null!=(u=sc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=N[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.slice(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&cc!==jt,o=new(i?jt:cc);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,l=e.length;c>a;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=C[o in sc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,N.c.toString(),t,r)}function c(n,t,r){return e(n,N.x.toString(),t,r)}function l(n,t,r){return e(n,N.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{cc=jt;var t=new cc;return t._=n,r(t)}finally{cc=Date}}var r=t(n);return e.parse=function(n){try{cc=jt;var t=r.parse(n);return t&&t._}finally{cc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=Yt(v),b=Zt(v),_=Yt(d),w=Zt(d),S=Yt(m),k=Zt(m),E=Yt(y),A=Zt(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var N={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return It(n.getDate(),t,2)},e:function(n,t){return It(n.getDate(),t,2)},H:function(n,t){return It(n.getHours(),t,2)},I:function(n,t){return It(n.getHours()%12||12,t,2)},j:function(n,t){return It(1+ac.dayOfYear(n),t,3)},L:function(n,t){return It(n.getMilliseconds(),t,3)},m:function(n,t){return It(n.getMonth()+1,t,2)},M:function(n,t){return It(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return It(n.getSeconds(),t,2)},U:function(n,t){return It(ac.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return It(ac.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return It(n.getFullYear()%100,t,2)},Y:function(n,t){return It(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},C={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function It(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Yt(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new l,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Vt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Xt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.U=+r[0],e+r[0].length):-1}function $t(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e));return r?(n.W=+r[0],e+r[0].length):-1}function Bt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Wt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.y=Gt(+r[0]),e+r[0].length):-1}function Jt(n,t,e){return/^[+-]\d{4}$/.test(t=t.slice(e,e+5))?(n.Z=-t,e+5):-1}function Gt(n){return n+(n>68?1900:2e3)}function Kt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){fc.lastIndex=0;var r=fc.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=ga(t)/60|0,u=ga(t)%60;return e+It(r,"0",2)+It(u,"0",2)}function oe(n,t,e){hc.lastIndex=0;var r=hc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function ce(){}function le(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function se(n,t){n&&dc.hasOwnProperty(n.type)&&dc[n.type](n,t)}function fe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function he(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)fe(n[e],t,1);t.polygonEnd()}function ge(){function n(n,t){n*=Da,t=t*Da/2+qa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);yc.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;Mc.point=function(o,a){Mc.point=n,r=(t=o)*Da,u=Math.cos(a=(e=a)*Da/2+qa/4),i=Math.sin(a)},Mc.lineEnd=function(){n(t,e)}}function pe(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Me(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function xe(n){return[Math.atan2(n[1],n[0]),tt(n[2])]}function be(n,t){return ga(n[0]-t[0])<Ca&&ga(n[1]-t[1])<Ca}function _e(n,t){n*=Da;var e=Math.cos(t*=Da);we(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function we(n,t,e){++xc,_c+=(n-_c)/xc,wc+=(t-wc)/xc,Sc+=(e-Sc)/xc}function Se(){function n(n,u){n*=Da;var i=Math.cos(u*=Da),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),l=Math.atan2(Math.sqrt((l=e*c-r*a)*l+(l=r*o-t*c)*l+(l=t*a-e*o)*l),t*o+e*a+r*c);bc+=l,kc+=l*(t+(t=o)),Ec+=l*(e+(e=a)),Ac+=l*(r+(r=c)),we(t,e,r)}var t,e,r;qc.point=function(u,i){u*=Da;var o=Math.cos(i*=Da);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),qc.point=n,we(t,e,r)}}function ke(){qc.point=_e}function Ee(){function n(n,t){n*=Da;var e=Math.cos(t*=Da),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),l=u*c-i*a,s=i*o-r*c,f=r*a-u*o,h=Math.sqrt(l*l+s*s+f*f),g=r*o+u*a+i*c,p=h&&-nt(g)/h,v=Math.atan2(h,g);Nc+=p*l,Cc+=p*s,zc+=p*f,bc+=v,kc+=v*(r+(r=o)),Ec+=v*(u+(u=a)),Ac+=v*(i+(i=c)),we(r,u,i)}var t,e,r,u,i;qc.point=function(o,a){t=o,e=a,qc.point=n,o*=Da;var c=Math.cos(a*=Da);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),we(r,u,i)},qc.lineEnd=function(){n(t,e),qc.lineEnd=ke,qc.point=_e}}function Ae(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function Ne(){return!0}function Ce(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(be(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return void u.lineEnd()}var c=new qe(e,n,null,!0),l=new qe(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new qe(r,n,null,!1),l=new qe(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),ze(i),ze(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ze(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function qe(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Le(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function l(){y.point=o,d.lineEnd()}function s(n,t){v.push([n,t]);var e=u(n,t);x.point(e[0],e[1])}function f(){x.lineStart(),v=[]}function h(){s(v[0][0],v[0][1]),x.lineEnd();var n,t=x.clean(),e=M.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r)if(1&t){n=e[0];var u,r=n.length-1,o=-1;if(r>0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);i.lineEnd()}}else r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=ta.merge(g);var n=Fe(m,p);g.length?(b||(i.polygonStart(),b=!0),Ce(g,De,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Re(),x=t(M),b=!1;return y}}function Te(n){return n.length>1}function Re(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function De(n,t){return((n=n.x)[0]<0?n[1]-Ra-Ca:Ra-n[1])-((t=t.x)[0]<0?t[1]-Ra-Ca:Ra-t[1])}function Pe(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?qa:-qa,c=ga(i-e);ga(c-qa)<Ca?(n.point(e,r=(r+o)/2>0?Ra:-Ra),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=qa&&(ga(e-u)<Ca&&(e-=u*Ca),ga(i-a)<Ca&&(i-=a*Ca),r=Ue(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function Ue(n,t,e,r){var u,i,o=Math.sin(n-e);return ga(o)>Ca?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function je(n,t,e,r){var u;if(null==n)u=e*Ra,r.point(-qa,u),r.point(0,u),r.point(qa,u),r.point(qa,0),r.point(qa,-u),r.point(0,-u),r.point(-qa,-u),r.point(-qa,0),r.point(-qa,u);else if(ga(n[0]-t[0])>Ca){var i=n[0]<t[0]?qa:-qa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Fe(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;yc.reset();for(var a=0,c=t.length;c>a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+qa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+qa/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>qa,k=p*M;if(yc.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*La:b,S^h>=e^m>=e){var E=de(pe(f),pe(n));Me(E);var A=de(u,E);Me(A);var N=(S^b>=0?-1:1)*tt(A[2]);(r>N||r===N&&(E[0]||E[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Ca>i||Ca>i&&0>yc)^1&o}function He(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?qa:-qa),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ca,p[1]+=Ca,v=t(p[0],p[1]))),v!==c)s=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(s=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&be(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),M=m*m-y*(ve(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=ye(d,(-m-x)/y);if(me(b,p),b=xe(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=ga(A-qa)<Ca,C=N||Ca>A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(ga(b[0]-w)<Ca?k:E):k<=b[1]&&b[1]<=E:A>qa^(w<=b[0]&&b[0]<=S)){var z=ye(d,(-m+x)/y);return me(z,p),[b,xe(z)]}}}function u(t,e){var r=o?n:qa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ga(i)>Ca,c=gr(n,6*Da);return Le(t,e,c,o?[0,-n]:[-qa,n-qa])}function Oe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-l,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-l,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Ie(n,t,e,r){function u(r,u){return ga(r[0]-n)<Ca?u>0?0:3:ga(r[0]-e)<Ca?u>0?2:1:ga(r[1]-t)<Ca?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&Q(l,i,n)>0&&++t:i[1]<=r&&Q(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=0/0}function g(){v&&(p(y,M),x&&w&&A.rejoin(),v.push(A.buffer())),C.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Tc,Math.min(Tc,n)),t=Math.max(-Tc,Math.min(Tc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};N(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,E=a,A=Re(),N=Oe(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=ta.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return C}}function Ye(n){var t=0,e=qa/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*qa/180,e=n[1]*qa/180):[t/qa*180,e/qa*180]},u}function Ze(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,tt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Dc+=u*n-r*t,r=n,u=t}var t,e,r,u;Hc.point=function(i,o){Hc.point=n,t=r=i,e=u=o},Hc.lineEnd=function(){n(t,e)}}function Xe(n,t){Pc>n&&(Pc=n),n>jc&&(jc=n),Uc>t&&(Uc=t),t>Fc&&(Fc=t)}function $e(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Be(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){_c+=n,wc+=t,++Sc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);kc+=o*(t+n)/2,Ec+=o*(e+r)/2,Ac+=o,We(t=n,e=r)}var t,e;Ic.point=function(r,u){Ic.point=n,We(t=r,e=u)}}function Ge(){Ic.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);kc+=o*(r+n)/2,Ec+=o*(u+t)/2,Ac+=o,o=u*n-r*t,Nc+=o*(r+n),Cc+=o*(u+t),zc+=3*o,We(r=n,u=t)}var t,e,r,u;Ic.point=function(i,o){Ic.point=n,We(t=r=i,e=u=o)},Ic.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,La)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(M,x,y,b,_,w,M=o[0],x=o[1],y=e,b=i[0],_=i[1],w=i[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c
},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,l,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=a+g,_=c+p,w=l+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),E=ga(ga(w)-1)<Ca||ga(r-h)<Ca?(r+h)/2:Math.atan2(_,b),A=n(E,k),N=A[0],C=A[1],z=N-t,q=C-e,L=M*z-y*q;(L*L/x>i||ga((y*z+M*q)/x-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,N,C,E,b/=S,_/=S,w,d,m),m.point(N,C),u(N,C,E,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Da),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Pa,e*Pa])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*Da,n[1]*Da),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Pa,n[1]*Pa]}function r(){a=Ae(o=lr(m,M,x),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,M=0,x=0,b=Lc,_=y,w=null,S=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(b(o,f(_(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Lc):He((w=+n)*Da),u()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Ie(n[0][0],n[0][1],n[1][0],n[1][1]):y,u()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Da,d=n[1]%360*Da,r()):[v*Pa,d*Pa]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Da,M=n[1]%360*Da,x=n.length>2?n[2]%360*Da:0,r()):[m*Pa,M*Pa,x*Pa]},ta.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*Da,e*Da)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>qa?n-La:-qa>n?n+La:n,t]}function lr(n,t,e){return n?t||e?Ae(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>qa?t-La:-qa>t?t+La:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),tt(s*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),tt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*La)):(u=n+o*La,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=xe([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,Me(e);var r=nt(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ca)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=ta.range(n,t-Ca,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function Mr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(it(r-t)+u*o*it(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Pa,Math.atan2(o,Math.sqrt(r*r+u*u))*Pa]}:function(){return[n*Pa,t*Pa]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Da),o=Math.cos(u),a=ga((n*=Da)-t),c=Math.cos(a);Yc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Zc.point=function(u,i){t=u*Da,e=Math.sin(i*=Da),r=Math.cos(i),Zc.point=n},Zc.lineEnd=function(){Zc.point=Zc.lineEnd=b}}function br(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function _r(n,t){function e(n,t){o>0?-Ra+Ca>t&&(t=-Ra+Ca):t>Ra-Ca&&(t=Ra-Ca);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(qa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=K(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ra]},e):Sr}function wr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ga(u)<Ca?ar:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-K(u)*Math.sqrt(n*n+e*e)]},e)}function Sr(n,t){return[n,Math.log(Math.tan(qa/4+t/2))]}function kr(n){var t,e=ur(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=qa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function Er(n,t){return[Math.log(Math.tan(qa/4+t/2)),-n]}function Ar(n){return n[0]}function Nr(n){return n[1]}function Cr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function qr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Lr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function Tr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=el.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),Qc.remove(n),el.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&ga(e-c.circle.x)<Ca&&ga(r-c.circle.cy)<Ca;)i=c.P,a.unshift(c),Pr(c),c=i;a.unshift(c),Xr(c);for(var l=o;l.circle&&ga(e-l.circle.x)<Ca&&ga(r-l.circle.cy)<Ca;)o=l.N,a.push(l),Pr(l),l=o;a.push(l),Xr(l);var s,f=a.length;for(s=1;f>s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Qc._;a;)if(r=Fr(a,o)-i,r>Ca)a=a.L;else{if(u=i-Hr(a,o),!(u>Ca)){r>-Ca?(t=a.P,e=a):u>-Ca?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(Qc.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),Qc.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),void Vr(e);if(!e)return void(c.edge=Jr(t.site,c.site));Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};Kr(e.edge,l,p,x),c.edge=Jr(l,n,null,x),e.edge=Jr(n,p,null,x),Vr(t),Vr(e)}}function Fr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Ir(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Kc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(ga(r-t)>Ca||ga(u-e)>Ca)&&(a.splice(o,0,new Qr(Gr(i.site,s,ga(r-f)<Ca&&p-u>Ca?{x:f,y:ga(t-f)<Ca?e:p}:ga(u-p)<Ca&&h-r>Ca?{x:ga(e-p)<Ca?t:h,y:p}:ga(r-h)<Ca&&u-g>Ca?{x:h,y:ga(t-h)<Ca?e:g}:ga(u-g)<Ca&&r-f>Ca?{x:ga(e-g)<Ca?t:f,y:g}:null),i.site,null)),++c)}function Yr(n,t){return t.angle-n.angle}function Zr(){tu(this),this.x=this.y=this.arc=this.site=this.cy=null}function Vr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,l=r.y-a,s=i.x-o,f=i.y-a,h=2*(c*f-l*s);if(!(h>=-za)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=rl.pop()||new Zr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,M=tl._;M;)if(m.y<M.y||m.y===M.y&&m.x<=M.x){if(!M.L){y=M.P;break}M=M.L}else{if(!M.R){y=M;break}M=M.R}tl.insert(y,m),y||(nl=m)}}}}function Xr(n){var t=n.circle;t&&(t.P||(nl=t.N),tl.remove(t),rl.push(t),tu(t),n.circle=null)}function $r(n){for(var t,e=Gc,r=Oe(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Br(t,n)||!r(t)||ga(t.a.x-t.b.x)<Ca&&ga(t.a.y-t.b.y)<Ca)&&(t.a=t.b=null,e.splice(u,1))}function Br(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],l=t[1][1],s=n.l,f=n.r,h=s.x,g=s.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.y<c)return}else i={x:d,y:l};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}else{if(i){if(i.y<c)return}else i={x:(l-u)/r,y:l};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Wr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Jr(n,t,e,r){var u=new Wr(n,t);return Gc.push(u),e&&Kr(u,n,t,e),r&&Kr(u,t,n,r),Kc[n.i].edges.push(new Qr(u,n,t)),Kc[t.i].edges.push(new Qr(u,t,n)),u}function Gr(n,t,e){var r=new Wr(n,null);return r.a=t,r.b=e,Gc.push(r),r}function Kr(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Qr(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function nu(){this._=null}function tu(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function eu(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function ru(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function uu(n){for(;n.L;)n=n.L;return n}function iu(n,t){var e,r,u,i=n.sort(ou).pop();for(Gc=[],Kc=new Array(n.length),Qc=new nu,tl=new nu;;)if(u=nl,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Kc[i.i]=new Or(i),jr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;Ur(u.arc)}t&&($r(t),Ir(t));var o={cells:Kc,edges:Gc};return Qc=tl=Gc=Kc=null,o}function ou(n,t){return t.y-n.y||t.x-n.x}function au(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function cu(n){return n.x}function lu(n){return n.y}function su(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function fu(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&fu(n,c[0],e,r,o,a),c[1]&&fu(n,c[1],o,r,u,a),c[2]&&fu(n,c[2],e,a,o,i),c[3]&&fu(n,c[3],o,a,u,i)}}function hu(n,t,e,r,u,i,o){var a,c=1/0;return function l(n,s,f,h,g){if(!(s>i||f>o||r>h||u>g)){if(p=n.point){var p,v=t-n.x,d=e-n.y,m=v*v+d*d;if(c>m){var y=Math.sqrt(c=m);r=t-y,u=e-y,i=t+y,o=e+y,a=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:l(n,s,f,x,b);break;case 1:l(n,x,f,h,b);break;case 2:l(n,s,b,x,g);break;case 3:l(n,x,b,h,g)}}}(n,r,u,i,o),a}function gu(n,t){n=ta.rgb(n),t=ta.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+xt(Math.round(e+i*n))+xt(Math.round(r+o*n))+xt(Math.round(u+a*n))}}function pu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=mu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function vu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function du(n,t){var e,r,u,i=il.lastIndex=ol.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=il.exec(n))&&(r=ol.exec(t));)(u=r.index)>i&&(u=t.slice(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:vu(e,r)})),i=ol.lastIndex;return i<t.length&&(u=t.slice(i),a[o]?a[o]+=u:a[++o]=u),a.length<2?c[0]?(t=c[0].x,function(n){return t(n)+""}):function(){return t}:(t=c.length,function(n){for(var e,r=0;t>r;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function mu(n,t){for(var e,r=ta.interpolators.length;--r>=0&&!(e=ta.interpolators[r](n,t)););return e}function yu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(mu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function Mu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function bu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function wu(n){return n*n*n}function Su(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function ku(n){return function(t){return Math.pow(t,n)}}function Eu(n){return 1-Math.cos(n*Ra)}function Au(n){return Math.pow(2,10*(n-1))}function Nu(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/La*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*La/t)}}function zu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function qu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Lu(n,t){n=ta.hcl(n),t=ta.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return st(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=ta.hsl(n),t=ta.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){n=ta.lab(n),t=ta.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ht(e+i*n,r+o*n,u+a*n)+""}}function Du(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Pu(n){var t=[n.a,n.b],e=[n.c,n.d],r=ju(t),u=Uu(t,e),i=ju(Fu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*Pa,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*Pa:0}function Uu(n,t){return n[0]*t[0]+n[1]*t[1]}function ju(n){var t=Math.sqrt(Uu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function Fu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Hu(n,t){var e,r=[],u=[],i=ta.transform(n),o=ta.transform(t),a=i.translate,c=o.translate,l=i.rotate,s=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:vu(a[0],c[0])},{i:3,x:vu(a[1],c[1])})):r.push(c[0]||c[1]?"translate("+c+")":""),l!=s?(l-s>180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:vu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:vu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:vu(g[0],p[0])},{i:e-2,x:vu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Ou(n,t){return t=(t-=n=+n)||1/t,function(e){return(e-n)/t}}function Iu(n,t){return t=(t-=n=+n)||1/t,function(e){return Math.max(0,Math.min(1,(e-n)/t))}}function Yu(n){for(var t=n.source,e=n.target,r=Vu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function Zu(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Vu(n,t){if(n===t)return n;for(var e=Zu(n),r=Zu(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Xu(n){n.fixed|=2}function $u(n){n.fixed&=-7}function Bu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Wu(n){n.fixed&=-5}function Ju(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Ju(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var l=t*e[n.point.index];n.charge+=n.pointCharge=l,r+=l*n.point.x,u+=l*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Gu(n,t){return ta.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=ri,n}function Ku(n,t){for(var e=[n];null!=(n=e.pop());)if(t(n),(u=n.children)&&(r=u.length))for(var r,u;--r>=0;)e.push(u[r])}function Qu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++o<u;)e.push(i[o]);for(;null!=(n=r.pop());)t(n)}function ni(n){return n.children}function ti(n){return n.value}function ei(n,t){return t.value-n.value}function ri(n){return ta.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function ui(n){return n.x}function ii(n){return n.y}function oi(n,t,e){n.y0=t,n.y=e}function ai(n){return ta.range(n.length)}function ci(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function li(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function si(n){return n.reduce(fi,0)}function fi(n,t){return n+t[1]}function hi(n,t){return gi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function gi(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function pi(n){return[ta.min(n),ta.max(n)]}function vi(n,t){return n.value-t.value}function di(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function mi(n,t){n._pack_next=t,t._pack_prev=n}function yi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function Mi(n){function t(n){s=Math.min(n.x-n.r,s),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],wi(r,u,i),t(i),di(r,i),r._pack_prev=i,di(i,u),u=r._pack_next,o=3;l>o;o++){wi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(yi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!yi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?mi(r,u=a):mi(r=c,u),o--):(di(r,i),u=i,t(i))}var m=(s+f)/2,y=(h+g)/2,M=0;for(o=0;l>o;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(bi)}}function xi(n){n._pack_next=n._pack_prev=n}function bi(n){delete n._pack_next,delete n._pack_prev}function _i(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)_i(u[i],t,e,r)}function wi(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),l=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+l*i,e.y=n.y+c*i-l*u}else e.x=n.x+r,e.y=n.y}function Si(n,t){return n.parent==t.parent?1:2}function ki(n){var t=n.children;return t.length?t[0]:n.t}function Ei(n){var t,e=n.children;return(t=e.length)?e[t-1]:n.t}function Ai(n,t,e){var r=e/(t.i-n.i);t.c-=r,t.s+=e,n.c+=r,t.z+=e,t.m+=e}function Ni(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function zi(n){return 1+ta.max(n,function(n){return n.y})}function qi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function Ri(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Di(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Pi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ui(n){return n.rangeExtent?n.rangeExtent():Pi(n.range())}function ji(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Fi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Hi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ml}function Oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=ta.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Ii(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?Oi:ji,c=r?Iu:Ou;return o=u(n,t,c,e),a=u(t,n,c,mu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Du)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Xi(n,t)},i.tickFormat=function(t,e){return $i(n,t,e)},i.nice=function(t){return Zi(n,t),u()},i.copy=function(){return Ii(n,t,e,r)},u()}function Yi(n,t){return ta.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Zi(n,t){return Fi(n,Hi(Vi(n,t)[2]))}function Vi(n,t){null==t&&(t=10);var e=Pi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Xi(n,t){return ta.range.apply(ta,Vi(n,t))}function $i(n,t,e){var r=Vi(n,t);if(e){var u=ic.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(ga(r[0]),ga(r[1])));return u[7]||(u[7]="."+Bi(i.scale(r[2]))),u[8]="f",e=ta.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Wi(u[8],r)),e=u.join("")}else e=",."+Bi(r[2])+"f";return ta.format(e)}function Bi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Wi(n,t){var e=Bi(t[2]);return n in yl?Math.abs(e-Bi(Math.max(ga(t[0]),ga(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ji(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Fi(r.map(u),e?Math:xl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Pi(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++<s;)for(var h=f-1;h>0;h--)o.push(i(l)*h);for(l=0;o[l]<a;l++);for(s=o.length;o[s-1]>c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return Ml;arguments.length<2?t=Ml:"function"!=typeof t&&(t=ta.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Ji(n.copy(),t,e,r)},Yi(o,n)}function Gi(n,t,e){function r(t){return n(u(t))}var u=Ki(t),i=Ki(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Xi(e,n)},r.tickFormat=function(n,t){return $i(e,n,t)},r.nice=function(n){return r.domain(Zi(e,n))},r.exponent=function(o){return arguments.length?(u=Ki(t=o),i=Ki(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Gi(n.copy(),t,e)},Yi(r,n)}function Ki(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Qi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return ta.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new l;for(var i,o=-1,a=r.length;++o<a;)u.has(i=r[o])||u.set(i,n.push(i));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(i=n,o=0,t={t:"range",a:arguments},e):i},e.rangePoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=(c+l)/2,0):(l-c)/(n.length-1+a);return i=r(c+s*a/2,s),o=0,t={t:"rangePoints",a:arguments},e},e.rangeRoundPoints=function(u,a){arguments.length<2&&(a=0);var c=u[0],l=u[1],s=n.length<2?(c=l=Math.round((c+l)/2),0):(l-c)/(n.length-1+a)|0;return i=r(c+Math.round(s*a/2+(l-c-(n.length-1+a)*s)/2),s),o=0,t={t:"rangeRoundPoints",a:arguments},e},e.rangeBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=(f-s)/(n.length-a+2*c);return i=r(s+h*c,h),l&&i.reverse(),o=h*(1-a),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,a,c){arguments.length<2&&(a=0),arguments.length<3&&(c=a);var l=u[1]<u[0],s=u[l-0],f=u[1-l],h=Math.floor((f-s)/(n.length-a+2*c));return i=r(s+Math.round((f-s-(n.length-a)*h)/2),h),l&&i.reverse(),o=Math.round(h*(1-a)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return o},e.rangeExtent=function(){return Pi(t.a[0])},e.copy=function(){return Qi(n,t)},e.domain(n)}function no(n,t){function i(){var e=0,r=t.length;for(a=[];++e<r;)a[e-1]=ta.quantile(n,e/r);return o}function o(n){return isNaN(n=+n)?void 0:t[ta.bisect(a,n)]}var a;return o.domain=function(t){return arguments.length?(n=t.map(r).filter(u).sort(e),i()):n},o.range=function(n){return arguments.length?(t=n,i()):t},o.quantiles=function(){return a},o.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?a[e-1]:n[0],e<a.length?a[e]:n[n.length-1]]},o.copy=function(){return no(n,t)},i()}function to(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return to(n,t,e)},u()}function eo(n,t){function e(e){return e>=e?t[ta.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return eo(n,t)},e}function ro(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Xi(n,t)},t.tickFormat=function(t,e){return $i(n,t,e)},t.copy=function(){return ro(n)},t}function uo(){return 0}function io(n){return n.innerRadius}function oo(n){return n.outerRadius}function ao(n){return n.startAngle}function co(n){return n.endAngle}function lo(n){return n&&n.padAngle}function so(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function fo(n,t,e,r,u){var i=n[0]-t[0],o=n[1]-t[1],a=(u?r:-r)/Math.sqrt(i*i+o*o),c=a*o,l=-a*i,s=n[0]+c,f=n[1]+l,h=t[0]+c,g=t[1]+l,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(M*M*y-x*x),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,E=_-p,A=w-v,N=S-p,C=k-v;return E*E+A*A>N*N+C*C&&(_=S,w=k),[[_-c,w-l],[_*e/M,w*e/M]]}function ho(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=Et(e),p=Et(r);++f<h;)u.call(this,c=t[f],f)?s.push([+g.call(this,c,f),+p.call(this,c,f)]):s.length&&(o(),s=[]);return s.length&&o(),l.length?l.join(""):null}var e=Ar,r=Nr,u=Ne,i=go,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=El.get(n)||go).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function go(n){return n.join("L")}function po(n){return go(n)+"Z"}function vo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function mo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function yo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function Mo(n,t){return n.length<4?go(n):n[1]+_o(n.slice(1,-1),wo(n,t))}function xo(n,t){return n.length<3?go(n):n[0]+_o((n.push(n[0]),n),wo([n[n.length-2]].concat(n,[n[1]]),t))}function bo(n,t){return n.length<3?go(n):n[0]+_o(n,wo(n,t))}function _o(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return go(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var l=2;l<t.length;l++,c++)i=n[c],a=t[l],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var s=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+s[0]+","+s[1]}return r}function wo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function So(n){if(n.length<3)return go(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",No(Cl,o),",",No(Cl,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),Co(c,o,a);return n.pop(),c.push("L",r),c.join("")}function ko(n){if(n.length<4)return go(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(No(Cl,i)+","+No(Cl,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),Co(e,i,o);return e.join("")}function Eo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[No(Cl,o),",",No(Cl,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),Co(t,o,a);return t.join("")}function Ao(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,l=-1;++l<=e;)r=n[l],u=l/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return So(n)}function No(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function Co(n,t,e){n.push("C",No(Al,t),",",No(Al,e),",",No(Nl,t),",",No(Nl,e),",",No(Cl,t),",",No(Cl,e))}function zo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function qo(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=zo(u,i);++t<e;)r[t]=(o+(o=zo(u=i,i=n[t+1])))/2;return r[t]=o,r}function Lo(n){for(var t,e,r,u,i=[],o=qo(n),a=-1,c=n.length-1;++a<c;)t=zo(n[a],n[a+1]),ga(t)<Ca?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function To(n){return n.length<3?go(n):n[0]+_o(n,Lo(n))}function Ro(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]-Ra,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Do(n){function t(t){function c(){v.push("M",a(n(m),f),s,l(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,M=t.length,x=Et(e),b=Et(u),_=e===r?function(){return g}:Et(r),w=u===i?function(){return p}:Et(i);++y<M;)o.call(this,h=t[y],y)?(d.push([g=+x.call(this,h,y),p=+b.call(this,h,y)]),m.push([+_.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=Ar,r=Ar,u=0,i=Nr,o=Ne,a=go,c=a.key,l=a,s="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r
},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=El.get(n)||go).key,l=a.reverse||a,s=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function Po(n){return n.radius}function Uo(n){return[n.x,n.y]}function jo(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]-Ra;return[e*Math.cos(r),e*Math.sin(r)]}}function Fo(){return 64}function Ho(){return"circle"}function Oo(n){var t=Math.sqrt(n/qa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Io(n){return function(){var t,e;(t=this[n])&&(e=t[t.active])&&(--t.count?delete t[t.active]:delete this[n],t.active+=.5,e.event&&e.event.interrupt.call(this,this.__data__,e.index))}}function Yo(n,t,e){return ya(n,Pl),n.namespace=t,n.id=e,n}function Zo(n,t,e,r){var u=n.id,i=n.namespace;return Y(n,"function"==typeof e?function(n,o,a){n[i][u].tween.set(t,r(e.call(n,n.__data__,o,a)))}:(e=r(e),function(n){n[i][u].tween.set(t,e)}))}function Vo(n){return null==n&&(n=""),function(){this.textContent=n}}function Xo(n){return null==n?"__transition__":"__transition_"+n+"__"}function $o(n,t,e,r,u){var i=n[e]||(n[e]={active:0,count:0}),o=i[r];if(!o){var a=u.time;o=i[r]={tween:new l,time:a,delay:u.delay,duration:u.duration,ease:u.ease,index:t},u=null,++i.count,ta.timer(function(u){function c(e){if(i.active>r)return s();var u=i[i.active];u&&(--i.count,delete i[i.active],u.event&&u.event.interrupt.call(n,n.__data__,u.index)),i.active=r,o.event&&o.event.start.call(n,n.__data__,t),o.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&v.push(r)}),h=o.ease,f=o.duration,ta.timer(function(){return p.c=l(e||1)?Ne:l,1},0,a)}function l(e){if(i.active!==r)return 1;for(var u=e/f,a=h(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,n.__data__,t),s()):void 0}function s(){return--i.count?delete i[r]:delete n[e],1}var f,h,g=o.delay,p=ec,v=[];return p.t=g+a,u>=g?c(u-g):void(p.c=c)},0,a)}}function Bo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Wo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Jo(n){return n.toISOString()}function Go(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=ta.bisect(Vl,u);return i==Vl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Vl[i-1]<Vl[i]/u?i-1:i]:[Bl,Vi(n,e)[2]]}return r.invert=function(t){return Ko(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Ko)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Ko(+e+1),t).length}var i=r.domain(),o=Pi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Fi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Ko(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Ko(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Pi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Ko(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Go(n.copy(),t,e)},Yi(r,n)}function Ko(n){return new Date(n)}function Qo(n){return JSON.parse(n.responseText)}function na(n){var t=ua.createRange();return t.selectNode(ua.body),t.createContextualFragment(n.responseText)}var ta={version:"3.5.5"},ea=[].slice,ra=function(n){return ea.call(n)},ua=this.document;if(ua)try{ra(ua.documentElement.childNodes)[0].nodeType}catch(ia){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),ua)try{ua.createElement("DIV").style.setProperty("opacity",0,"")}catch(oa){var aa=this.Element.prototype,ca=aa.setAttribute,la=aa.setAttributeNS,sa=this.CSSStyleDeclaration.prototype,fa=sa.setProperty;aa.setAttribute=function(n,t){ca.call(this,n,t+"")},aa.setAttributeNS=function(n,t,e){la.call(this,n,t,e+"")},sa.setProperty=function(n,t,e){fa.call(this,n,t+"",e)}}ta.ascending=e,ta.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ta.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i;)if(null!=(r=n[u])&&r>=r){e=r;break}for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i;)if(null!=(r=t.call(n,n[u],u))&&r>=r){e=r;break}for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o;)if(null!=(r=n[i])&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o;)if(null!=(r=t.call(n,n[i],i))&&r>=r){e=u=r;break}for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},ta.sum=function(n,t){var e,r=0,i=n.length,o=-1;if(1===arguments.length)for(;++o<i;)u(e=+n[o])&&(r+=e);else for(;++o<i;)u(e=+t.call(n,n[o],o))&&(r+=e);return r},ta.mean=function(n,t){var e,i=0,o=n.length,a=-1,c=o;if(1===arguments.length)for(;++a<o;)u(e=r(n[a]))?i+=e:--c;else for(;++a<o;)u(e=r(t.call(n,n[a],a)))?i+=e:--c;return c?i/c:void 0},ta.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},ta.median=function(n,t){var i,o=[],a=n.length,c=-1;if(1===arguments.length)for(;++c<a;)u(i=r(n[c]))&&o.push(i);else for(;++c<a;)u(i=r(t.call(n,n[c],c)))&&o.push(i);return o.length?ta.quantile(o.sort(e),.5):void 0},ta.variance=function(n,t){var e,i,o=n.length,a=0,c=0,l=-1,s=0;if(1===arguments.length)for(;++l<o;)u(e=r(n[l]))&&(i=e-a,a+=i/++s,c+=i*(e-a));else for(;++l<o;)u(e=r(t.call(n,n[l],l)))&&(i=e-a,a+=i/++s,c+=i*(e-a));return s>1?c/(s-1):void 0},ta.deviation=function(){var n=ta.variance.apply(this,arguments);return n?Math.sqrt(n):n};var ha=i(e);ta.bisectLeft=ha.left,ta.bisect=ta.bisectRight=ha.right,ta.bisector=function(n){return i(1===n.length?function(t,r){return e(n(t),r)}:n)},ta.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=Math.random()*i--|0,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},ta.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ta.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},ta.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=ta.min(arguments,o),e=new Array(t);++n<t;)for(var r,u=-1,i=e[n]=new Array(r);++u<r;)i[u]=arguments[u][n];return e},ta.transpose=function(n){return ta.zip.apply(ta,n)},ta.keys=function(n){var t=[];for(var e in n)t.push(e);return t},ta.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},ta.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},ta.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ga=Math.abs;ta.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,u=[],i=a(ga(e)),o=-1;if(n*=i,t*=i,e*=i,0>e)for(;(r=n+e*++o)>t;)u.push(r/i);else for(;(r=n+e*++o)<t;)u.push(r/i);return u},ta.map=function(n,t){var e=new l;if(n instanceof l)n.forEach(function(n,t){e.set(n,t)});else if(Array.isArray(n)){var r,u=-1,i=n.length;if(1===arguments.length)for(;++u<i;)e.set(u,n[u]);else for(;++u<i;)e.set(t.call(n,r=n[u],u),r)}else for(var o in n)e.set(o,n[o]);return e};var pa="__proto__",va="\x00";c(l,{has:h,get:function(n){return this._[s(n)]},set:function(n,t){return this._[s(n)]=t},remove:g,keys:p,values:function(){var n=[];for(var t in this._)n.push(this._[t]);return n},entries:function(){var n=[];for(var t in this._)n.push({key:f(t),value:this._[t]});return n},size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t),this._[t])}}),ta.nest=function(){function n(t,o,a){if(a>=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var c,s,f,h,g=-1,p=o.length,v=i[a++],d=new l;++g<p;)(h=d.get(c=v(s=o[g])))?h.push(s):d.set(c,[s]);return t?(s=t(),f=function(e,r){s.set(e,n(t,r,a))}):(s={},f=function(e,r){s[e]=n(t,r,a)}),d.forEach(f),s}function t(n,e){if(e>=i.length)return n;var r=[],u=o[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ta.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ta.set=function(n){var t=new m;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},c(m,{has:h,add:function(n){return this._[s(n+="")]=!0,n},remove:g,values:p,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,f(t))}}),ta.behavior={},ta.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=M(n,t,t[e]);return n};var da=["webkit","ms","moz","Moz","o","O"];ta.dispatch=function(){for(var n=new _,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=w(n);return n},_.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ta.event=null,ta.requote=function(n){return n.replace(ma,"\\$&")};var ma=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ya={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},Ma=function(n,t){return t.querySelector(n)},xa=function(n,t){return t.querySelectorAll(n)},ba=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(ba=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(Ma=function(n,t){return Sizzle(n,t)[0]||null},xa=Sizzle,ba=Sizzle.matchesSelector),ta.selection=function(){return ta.select(ua.documentElement)};var _a=ta.selection.prototype=[];_a.select=function(n){var t,e,r,u,i=[];n=N(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,l=r.length;++c<l;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return A(i)},_a.selectAll=function(n){var t,e,r=[];n=C(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=ra(n.call(e,e.__data__,a,u))),t.parentNode=e);return A(r)};var wa={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};ta.ns={prefix:wa,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.slice(0,t),n=n.slice(t+1)),wa.hasOwnProperty(e)?{space:wa[e],local:n}:n}},_a.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ta.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},_a.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!L(n[u]).test(t))return!1;return!0}for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},_a.style=function(n,e,r){var u=arguments.length;if(3>u){if("string"!=typeof n){2>u&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>u){var i=this.node();return t(i).getComputedStyle(i,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},_a.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},_a.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},_a.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},_a.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},_a.insert=function(n,t){return n=j(n),t=N(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},_a.remove=function(){return this.each(F)},_a.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new l,y=new Array(o);for(r=-1;++r<o;)m.has(d=t.call(u=n[r],u.__data__,r))?v[r]=u:m.set(d,u),y[r]=d;for(r=-1;++r<f;)(u=m.get(d=t.call(e,i=e[r],r)))?u!==!0&&(g[r]=u,u.__data__=i):p[r]=H(i),m.set(d,!0);for(r=-1;++r<o;)m.get(y[r])!==!0&&(v[r]=n[r])}else{for(r=-1;++r<h;)u=n[r],i=e[r],u?(u.__data__=i,g[r]=u):p[r]=H(i);for(;f>r;++r)p[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,a.push(p),c.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++i<o;)(u=r[i])&&(n[i]=u.__data__);return n}var a=Z([]),c=A([]),s=A([]);if("function"==typeof n)for(;++i<o;)e(r=this[i],n.call(r,r.parentNode.__data__,i));else for(;++i<o;)e(r=this[i],n);return c.enter=function(){return a},c.exit=function(){return s},c},_a.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},_a.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return A(u)},_a.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},_a.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},_a.each=function(n){return Y(this,function(t,e,r){n.call(t,t.__data__,e,r)})},_a.call=function(n){var t=ra(arguments);return n.apply(t[0]=this,t),this},_a.empty=function(){return!this.node()},_a.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},_a.size=function(){var n=0;return Y(this,function(){++n}),n};var Sa=[];ta.selection.enter=Z,ta.selection.enter.prototype=Sa,Sa.append=_a.append,Sa.empty=_a.empty,Sa.node=_a.node,Sa.call=_a.call,Sa.size=_a.size,Sa.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var l=-1,s=u.length;++l<s;)(i=u[l])?(t.push(r[l]=e=n.call(u.parentNode,i.__data__,l,a)),e.__data__=i.__data__):t.push(null)}return A(o)},Sa.insert=function(n,t){return arguments.length<2&&(t=V(this)),_a.insert.call(this,n,t)},ta.select=function(t){var e;return"string"==typeof t?(e=[Ma(t,ua)],e.parentNode=ua.documentElement):(e=[t],e.parentNode=n(t)),A([e])},ta.selectAll=function(n){var t;return"string"==typeof n?(t=ra(xa(n,ua)),t.parentNode=ua.documentElement):(t=n,t.parentNode=null),A([t])},_a.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var ka=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});ua&&ka.forEach(function(n){"on"+n in ua&&ka.remove(n)});var Ea,Aa=0;ta.mouse=function(n){return J(n,k())};var Na=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return J(n,r)},ta.behavior.drag=function(){function n(){this.on("mousedown.drag",i).on("touchstart.drag",o)}function e(n,t,e,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&ta.event.target===f),g({type:"dragend"}))}var l,s=this,f=ta.event.target,h=s.parentNode,g=r.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(e(f)).on(i+d,a).on(o+d,c),y=W(f),M=t(h,v);u?(l=u.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var r=E(n,"drag","dragstart","dragend"),u=null,i=e(b,ta.mouse,t,"mousemove","mouseup"),o=e(G,ta.touch,y,"touchmove","touchend");return n.origin=function(t){return arguments.length?(u=t,n):u},ta.rebind(n,r,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?ra(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Ca=1e-6,za=Ca*Ca,qa=Math.PI,La=2*qa,Ta=La-Ca,Ra=qa/2,Da=qa/180,Pa=180/qa,Ua=Math.SQRT2,ja=2,Fa=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=rt(v),o=i/(ja*h)*(e*ut(Ua*t+v)-et(v));return[r+o*l,u+o*s,i*e/rt(Ua*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Ua*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Fa*f)/(2*i*ja*h),p=(c*c-i*i-Fa*f)/(2*c*ja*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ua;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(q,f).on(Oa+".zoom",g).on("dblclick.zoom",p).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function u(n){k.k=Math.max(N[0],Math.min(N[1],n))}function i(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},u(Math.pow(2,o)),i(d=e,r),t=ta.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function c(n){z++||n({type:"zoomstart"})}function l(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function s(n){--z||n({type:"zoomend"}),d=null}function f(){function n(){f=1,i(ta.mouse(u),g),l(a)}function r(){h.on(L,null).on(T,null),p(f&&ta.event.target===o),s(a)}var u=this,o=ta.event.target,a=D.of(u,arguments),f=0,h=ta.select(t(u)).on(L,n).on(T,r),g=e(ta.mouse(u)),p=W(u);Dl.call(u),c(a)}function h(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ta.event.target;ta.select(t).on(x,r).on(b,a),_.push(t);for(var e=ta.event.changedTouches,u=0,i=e.length;i>u;++u)d[e[u].identifier]=null;var c=n(),l=Date.now();if(1===c.length){if(500>l-M){var s=c[0];o(p,s,d[s.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=l}else if(c.length>1){var s=c[0],f=c[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function r(){var n,t,e,r,o=ta.touches(p);Dl.call(p);for(var a=0,c=o.length;c>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],u(f*g)}M=null,i(n,t),l(v)}function a(){if(ta.event.touches.length){for(var t=ta.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}ta.selectAll(_).on(y,null),w.on(q,f).on(R,h),E(),s(v)}var g,p=this,v=D.of(p,arguments),d={},m=0,y=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+y,b="touchend"+y,_=[],w=ta.select(p),E=W(p);t(),c(v),w.on(q,null).on(R,t)}function g(){var n=D.of(this,arguments);y?clearTimeout(y):(v=e(d=m||ta.mouse(this)),Dl.call(this),c(n)),y=setTimeout(function(){y=null,s(n)},50),S(),u(Math.pow(2,.002*Ha())*k.k),i(d,v),l(n)}function p(){var n=ta.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ta.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,m,y,M,x,b,_,w,k={x:0,y:0,k:1},A=[960,500],N=Ia,C=250,z=0,q="mousedown.zoom",L="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=E(n,"zoomstart","zoom","zoomend");return Oa||(Oa="onwheel"in ua?(Ha=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Ha=function(){return ta.event.wheelDelta},"mousewheel"):(Ha=function(){return-ta.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Tl?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},c(n)}).tween("zoom:zoom",function(){var e=A[0],r=A[1],u=d?d[0]:e/2,i=d?d[1]:r/2,o=ta.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:u-r[0]*a,y:i-r[1]*a,k:a},l(n)}}).each("interrupt.zoom",function(){s(n)}).each("end.zoom",function(){s(n)}):(this.__chart__=k,c(n),l(n),s(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(N=null==t?Ia:[+t[0],+t[1]],n):N},n.center=function(t){return arguments.length?(m=t&&[+t[0],+t[1]],n):m},n.size=function(t){return arguments.length?(A=t&&[+t[0],+t[1]],n):A},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ta.rebind(n,D,"on")};var Ha,Oa,Ia=[0,1/0];ta.color=ot,ot.prototype.toString=function(){return this.rgb()+""},ta.hsl=at;var Ya=at.prototype=new ot;Ya.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,this.l/n)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new at(this.h,this.s,n*this.l)},Ya.rgb=function(){return ct(this.h,this.s,this.l)},ta.hcl=lt;var Za=lt.prototype=new ot;Za.brighter=function(n){return new lt(this.h,this.c,Math.min(100,this.l+Va*(arguments.length?n:1)))},Za.darker=function(n){return new lt(this.h,this.c,Math.max(0,this.l-Va*(arguments.length?n:1)))},Za.rgb=function(){return st(this.h,this.c,this.l).rgb()},ta.lab=ft;var Va=18,Xa=.95047,$a=1,Ba=1.08883,Wa=ft.prototype=new ot;Wa.brighter=function(n){return new ft(Math.min(100,this.l+Va*(arguments.length?n:1)),this.a,this.b)},Wa.darker=function(n){return new ft(Math.max(0,this.l-Va*(arguments.length?n:1)),this.a,this.b)},Wa.rgb=function(){return ht(this.l,this.a,this.b)},ta.rgb=mt;var Ja=mt.prototype=new ot;Ja.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new mt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mt(u,u,u)},Ja.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mt(n*this.r,n*this.g,n*this.b)},Ja.hsl=function(){return _t(this.r,this.g,this.b)},Ja.toString=function(){return"#"+xt(this.r)+xt(this.g)+xt(this.b)};var Ga=ta.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ga.forEach(function(n,t){Ga.set(n,yt(t))}),ta.functor=Et,ta.xhr=At(y),ta.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++<l;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}s=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++s):10===r&&(u=!0),n.slice(t+1,e).replace(/""/g,'"')}for(;l>s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,f++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new m,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},ta.csv=ta.dsv(",","text/csv"),ta.tsv=ta.dsv("	","text/tab-separated-values");var Ka,Qa,nc,tc,ec,rc=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ta.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Qa?Qa.n=i:Ka=i,Qa=i,nc||(tc=clearTimeout(tc),nc=1,rc(qt))},ta.timer.flush=function(){Lt(),Tt()},ta.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var uc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);ta.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ta.round(n,Rt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),uc[8+e/3]};var ic=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,oc=ta.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ta.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),ac=ta.time={},cc=Date;jt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){lc.setUTCDate.apply(this._,arguments)},setDay:function(){lc.setUTCDay.apply(this._,arguments)},setFullYear:function(){lc.setUTCFullYear.apply(this._,arguments)},setHours:function(){lc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){lc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){lc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){lc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){lc.setUTCSeconds.apply(this._,arguments)},setTime:function(){lc.setTime.apply(this._,arguments)}};var lc=Date.prototype;ac.year=Ft(function(n){return n=ac.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ac.years=ac.year.range,ac.years.utc=ac.year.utc.range,ac.day=Ft(function(n){var t=new cc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ac.days=ac.day.range,ac.days.utc=ac.day.utc.range,ac.dayOfYear=function(n){var t=ac.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ac[n]=Ft(function(n){return(n=ac.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ac[n+"s"]=e.range,ac[n+"s"].utc=e.utc.range,ac[n+"OfYear"]=function(n){var e=ac.year(n).getDay();return Math.floor((ac.dayOfYear(n)+(e+t)%7)/7)}}),ac.week=ac.sunday,ac.weeks=ac.sunday.range,ac.weeks.utc=ac.sunday.utc.range,ac.weekOfYear=ac.sundayOfYear;var sc={"-":"",_:" ",0:"0"},fc=/^\s*\d+/,hc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var gc=ta.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ta.format=gc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,pc),le(pc.s,this.s,this),this.s?this.t+=pc.t:this.s=pc.t
},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var pc=new ce;ta.geo.stream=function(n,t){n&&vc.hasOwnProperty(n.type)?vc[n.type](n,t):se(n,t)};var vc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)se(e[r].geometry,t)}},dc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){fe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)fe(e[r],t,0)},Polygon:function(n,t){he(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)he(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)se(e[r],t)}};ta.geo.area=function(n){return mc=0,ta.geo.stream(n,Mc),mc};var mc,yc=new ce,Mc={sphere:function(){mc+=4*qa},point:b,lineStart:b,lineEnd:b,polygonStart:function(){yc.reset(),Mc.lineStart=ge},polygonEnd:function(){var n=2*yc;mc+=0>n?4*qa+n:n,Mc.lineStart=Mc.lineEnd=Mc.point=b}};ta.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*Da,e*Da]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);Me(o),o=xe(o);var c=t-p,l=c>0?1:-1,v=o[0]*Pa*l,d=ga(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Pa;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Pa;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ga(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Mc.point(n,e),t(n,e)}function i(){Mc.lineStart()}function o(){u(v,d),Mc.lineEnd(),ga(y)>Ca&&(s=-(h=180)),x[0]=s,x[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var s,f,h,g,p,v,d,m,y,M,x,b={point:n,lineStart:e,lineEnd:r,polygonStart:function(){b.point=u,b.lineStart=i,b.lineEnd=o,y=0,Mc.polygonStart()},polygonEnd:function(){Mc.polygonEnd(),b.point=n,b.lineStart=e,b.lineEnd=r,0>yc?(s=-(h=180),f=-(g=90)):y>Ca?g=90:-Ca>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ta.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ta.geo.centroid=function(n){xc=bc=_c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,qc);var t=Nc,e=Cc,r=zc,u=t*t+e*e+r*r;return za>u&&(t=kc,e=Ec,r=Ac,Ca>bc&&(t=_c,e=wc,r=Sc),u=t*t+e*e+r*r,za>u)?[0/0,0/0]:[Math.atan2(e,t)*Pa,tt(r/Math.sqrt(u))*Pa]};var xc,bc,_c,wc,Sc,kc,Ec,Ac,Nc,Cc,zc,qc={sphere:b,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){qc.lineStart=Ee},polygonEnd:function(){qc.lineStart=Se}},Lc=Le(Ne,Pe,je,[-qa,-qa/2]),Tc=1e9;ta.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ie(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ta.geo.conicEqualArea=function(){return Ye(Ze)}).raw=Ze,ta.geo.albers=function(){return ta.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ta.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=ta.geo.albers(),o=ta.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ta.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Ca,f+.12*l+Ca],[s-.214*l-Ca,f+.234*l-Ca]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ca,f+.166*l+Ca],[s-.115*l-Ca,f+.234*l-Ca]]).stream(c).point,n},n.scale(1070)};var Rc,Dc,Pc,Uc,jc,Fc,Hc={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Dc=0,Hc.lineStart=Ve},polygonEnd:function(){Hc.lineStart=Hc.lineEnd=Hc.point=b,Rc+=ga(Dc/2)}},Oc={point:Xe,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Ic={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Ic.lineStart=Ke},polygonEnd:function(){Ic.point=We,Ic.lineStart=Je,Ic.lineEnd=Ge}};ta.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),ta.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Rc=0,ta.geo.stream(n,u(Hc)),Rc},n.centroid=function(n){return _c=wc=Sc=kc=Ec=Ac=Nc=Cc=zc=0,ta.geo.stream(n,u(Ic)),zc?[Nc/zc,Cc/zc]:Ac?[kc/Ac,Ec/Ac]:Sc?[_c/Sc,wc/Sc]:[0/0,0/0]},n.bounds=function(n){return jc=Fc=-(Pc=Uc=1/0),ta.geo.stream(n,u(Oc)),[[Pc,Uc],[jc,Fc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):y,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(ta.geo.albersUsa()).context(null)},ta.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ta.geo.projection=ur,ta.geo.projectionMutator=ir,(ta.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,ta.geo.rotation=function(n){function t(t){return t=n(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t}return n=lr(n[0]%360*Da,n[1]*Da,n.length>2?n[2]*Da:0),t.invert=function(t){return t=n.invert(t[0]*Da,t[1]*Da),t[0]*=Pa,t[1]*=Pa,t},t},cr.invert=ar,ta.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*Da,-n[1]*Da,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Pa,n[1]*=Pa}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=gr((t=+r)*Da,u*Da),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Da,(u=+r)*Da),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Da,u=n[1]*Da,i=t[1]*Da,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},ta.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ta.range(Math.ceil(i/d)*d,u,d).map(h).concat(ta.range(Math.ceil(l/m)*m,c,m).map(g)).concat(ta.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ga(n%d)>Ca}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ga(n%m)>Ca}).map(f))}var e,r,u,i,o,a,c,l,s,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(l).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ca],[180,90-Ca]]).minorExtent([[-180,-80-Ca],[180,80+Ca]])},ta.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return ta.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},ta.geo.interpolate=function(n,t){return Mr(n[0]*Da,n[1]*Da,t[0]*Da,t[1]*Da)},ta.geo.length=function(n){return Yc=0,ta.geo.stream(n,Zc),Yc};var Yc,Zc={sphere:b,point:b,lineStart:xr,lineEnd:b,polygonStart:b,polygonEnd:b},Vc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Vc)}).raw=Vc;var Xc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},y);(ta.geo.azimuthalEquidistant=function(){return ur(Xc)}).raw=Xc,(ta.geo.conicConformal=function(){return Ye(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ye(wr)}).raw=wr;var $c=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur($c)}).raw=$c,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ra]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Bc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Bc)}).raw=Bc;var Wc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Wc)}).raw=Wc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ra]},(ta.geo.transverseMercator=function(){var n=kr(Er),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Er,ta.geom={},ta.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=Et(e),i=Et(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Cr(a),s=Cr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t<s.length-h;++t)g.push(n[a[s[t]][2]]);return g}var e=Ar,r=Nr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},ta.geom.polygon=function(n){return ya(n,Jc),n};var Jc=ta.geom.polygon.prototype=[];Jc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Jc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Jc.clip=function(n){for(var t,e,r,u,i,o,a=Tr(n),c=-1,l=this.length-Tr(this),s=this[l-1];++c<l;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],qr(o,s,u)?(qr(i,s,u)||n.push(Lr(i,o,s,u)),n.push(o)):qr(i,s,u)&&n.push(Lr(i,o,s,u)),i=o;a&&n.push(n[0]),s=u}return n};var Gc,Kc,Qc,nl,tl,el=[],rl=[];Or.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(Yr),t.length},Qr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},nu.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=uu(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(eu(this,e),n=e,e=n.U),e.C=!1,r.C=!0,ru(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(ru(this,e),n=e,e=n.U),e.C=!1,r.C=!0,eu(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?uu(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return void(n.C=!1);do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,eu(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,ru(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,eu(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,ru(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,eu(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,ru(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},ta.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return iu(e(n),a).cells.forEach(function(e,a){var c=e.edges,l=e.site,s=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):l.x>=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ca)*Ca,y:Math.round(o(n,t)/Ca)*Ca,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=ul;return n?t(n):(t.links=function(n){return iu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Yr),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c<l;)u=s,i=f,s=a[c].edge,f=s.l===o?s.r:s.l,r<i.i&&r<f.i&&au(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=Et(r=n),t):r},t.y=function(n){return arguments.length?(o=Et(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?ul:n,t):a===ul?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===ul?null:a&&a[1]},t)};var ul=[[-1e6,-1e6],[1e6,1e6]];ta.geom.delaunay=function(n){return ta.geom.voronoi().triangles(n)},ta.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,s=n.y;if(null!=c)if(ga(c-e)+ga(s-r)<.01)l(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,l(n,f,c,s,u,i,o,a),l(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else l(n,t,e,r,u,i,o,a)}function l(n,t,e,r,u,o,a,c){var l=.5*(u+a),s=.5*(o+c),f=e>=l,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,M=Et(a),x=Et(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)s=n[g],s.x<v&&(v=s.x),s.y<d&&(d=s.y),s.x>m&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=s=null,k}var o,a=Ar,c=Nr;return(o=arguments.length)?(a=cu,c=lu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},ta.interpolateRgb=gu,ta.interpolateObject=pu,ta.interpolateNumber=vu,ta.interpolateString=du;var il=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,ol=new RegExp(il.source,"g");ta.interpolate=mu,ta.interpolators=[function(n,t){var e=typeof t;return("string"===e?Ga.has(t)||/^(#|rgb\(|hsl\()/.test(t)?gu:du:t instanceof ot?gu:Array.isArray(t)?yu:"object"===e&&isNaN(t)?pu:vu)(n,t)}],ta.interpolateArray=yu;var al=function(){return y},cl=ta.map({linear:al,poly:ku,quad:function(){return _u},cubic:function(){return wu},sin:function(){return Eu},exp:function(){return Au},circle:function(){return Nu},elastic:Cu,back:zu,bounce:function(){return qu}}),ll=ta.map({"in":y,out:xu,"in-out":bu,"out-in":function(n){return bu(xu(n))}});ta.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=cl.get(e)||al,r=ll.get(r)||y,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:sl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var sl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Yu(n[e]));return t}},ta.layout.chord=function(){function n(){var n,l,f,h,g,p={},v=[],d=ta.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(l=0,g=-1;++g<i;)l+=u[h][g];v.push(l),m.push(ta.range(i)),n+=l}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(La-s*i)/n,l=0,h=-1;++h<i;){for(f=l,g=-1;++g<i;){var y=d[h],M=m[y][g],x=u[y][M],b=l,_=l+=x*n;p[y+"-"+M]={index:y,subindex:M,startAngle:b,endAngle:_,value:x}}r[y]={index:y,startAngle:f,endAngle:l,value:(l-f)/n},l+=s}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,l={},s=0;return l.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,l):u},l.padding=function(n){return arguments.length?(s=n,e=r=null,l):s},l.sortGroups=function(n){return arguments.length?(o=n,e=r=null,l):o},l.sortSubgroups=function(n){return arguments.length?(a=n,e=null,l):a},l.sortChords=function(n){return arguments.length?(c=n,e&&t(),l):c},l.chords=function(){return e||n(),e},l.groups=function(){return r||n(),r},l},ta.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=fl,h=hl,g=-30,p=gl,v=.1,d=.64,m=[],M=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,y,x,b=m.length,_=M.length;for(e=0;_>e;++e)a=M[e],f=a.source,h=a.target,y=h.x-f.x,x=h.y-f.y,(p=y*y+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,y*=p,x*=p,h.x-=y*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=y*(d=1-d),f.y+=x*d);if((d=r*v)&&(y=l[0]/2,x=l[1]/2,e=-1,d))for(;++e<b;)a=m[e],a.x+=(y-a.x)*d,a.y+=(x-a.y)*d;if(g)for(Ju(t=ta.geom.quadtree(m),r,o),e=-1;++e<b;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<b;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*s,a.y-=(a.py-(a.py=a.y))*s);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(M=n,a):M},a.size=function(n){return arguments.length?(l=n,a):l},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(s=+n,a):s},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=M[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,l=o.length;++a<l;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,s=M.length,p=l[0],v=l[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>t;++t)r=M[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;s>t;++t)u[t]=+f.call(this,M[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,M[t],t);else for(t=0;s>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=ta.behavior.drag().origin(y).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?void this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e):e},ta.rebind(a,c,"on")};var fl=20,hl=1,gl=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ta.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,l=-1;for(r=t.value?r/t.value:0;++l<o;)n(a=i[l],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=ta.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Gu(e,r)},ta.layout.pie=function(){function n(o){var a,c=o.length,l=o.map(function(e,r){return+t.call(n,e,r)}),s=+("function"==typeof r?r.apply(this,arguments):r),f=("function"==typeof u?u.apply(this,arguments):u)-s,h=Math.min(Math.abs(f)/c,+("function"==typeof i?i.apply(this,arguments):i)),g=h*(0>f?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===pl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=pl,r=0,u=La,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var pl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=y,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:vl.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:dl.get(t)||ci,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var vl=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),dl=ta.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=l[i],a>=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=Et(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:Et(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(f,function(n){n.x<g.x&&(g=n),n.x>p.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Ni(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=ta.layout.hierarchy().sort(null).value(null),e=Si,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Gu(n,t)},ta.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++i<o;)u=n[i],u.x=a,u.y=l,u.dy=s,a+=u.dx=Math.min(e.x+e.dx-a,s?c(u.area/s):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=s,e.dy-=s}else{for((r||s>e.dx)&&(s=e.dx);++i<o;)u=n[i],u.x=a,u.y=l,u.dx=s,l+=u.dy=Math.min(e.y+e.dy-l,s?c(u.area/s):0);u.z=!1,u.dy+=e.y+e.dy-l,e.x+=s,e.dx-=s}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=l[0],i.dy=l[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=ta.layout.hierarchy(),c=Math.round,l=[1,1],s=null,f=Ri,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));
return i.size=function(n){return arguments.length?(l=n,i):l},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ri(t):Di(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return Di(t,n)}if(!arguments.length)return s;var r;return f=null==(s=n)?Ri:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Gu(i,a)},ta.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ta.scale={};var ml={floor:y,ceil:y};ta.scale.linear=function(){return Ii([0,1],[0,1],mu,!1)};var yl={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var Ml=ta.format(".0e"),xl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(bl)},ta.scale.category20=function(){return ta.scale.ordinal().range(_l)},ta.scale.category20b=function(){return ta.scale.ordinal().range(wl)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Sl)};var bl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(Mt),_l=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(Mt),wl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(Mt),Sl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(Mt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-Ra,f=a.apply(this,arguments)-Ra,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ta)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===kl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=tt(d/l*Math.sin(m))),n&&(E=tt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=qa?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=qa?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),I=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],I[1][0],I[1][1]),",",g," ",I[1],"A",H,",",H," 0 0,",v," ",I[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",I[0])}else N.push("M",y,",",M);if(null!=S){var Y=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-Y,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-Y,g);p===Y?N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",Y,",",Y," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",Y,",",Y," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=kl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=Et(t),n):e},n.outerRadius=function(t){return arguments.length?(r=Et(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=Et(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==kl?kl:Et(t),n):i},n.startAngle=function(t){return arguments.length?(o=Et(t),n):o},n.endAngle=function(t){return arguments.length?(a=Et(t),n):a},n.padAngle=function(t){return arguments.length?(c=Et(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Ra;return[Math.cos(t)*n,Math.sin(t)*n]},n};var kl="auto";ta.svg.line=function(){return ho(y)};var El=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});El.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Al=[0,2/3,1/3,0],Nl=[0,1/3,2/3,0],Cl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(y)},ta.svg.area.radial=function(){var n=Do(Ro);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)-Ra,s=l.call(n,u,r)-Ra;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>qa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=Et(t),n):a},n.source=function(t){return arguments.length?(i=Et(t),n):i},n.target=function(t){return arguments.length?(o=Et(t),n):o},n.startAngle=function(t){return arguments.length?(c=Et(t),n):c},n.endAngle=function(t){return arguments.length?(l=Et(t),n):l},n},ta.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=Et(e),n):t},n.target=function(t){return arguments.length?(e=Et(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(zl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=Et(e),n):t},n.size=function(t){return arguments.length?(e=Et(t),n):e},n};var zl=ta.map({circle:Oo,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Ll)),e=t*Ll;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/ql),e=t*ql/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=zl.keys();var ql=Math.sqrt(3),Ll=Math.tan(30*Da);_a.transition=function(n){for(var t,e,r=Tl||++Ul,u=Xo(n),i=[],o=Rl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++a<c;){i.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(e=l[s])&&$o(e,s,u,r,o),t.push(e)}return Yo(i,u,r)},_a.interrupt=function(n){return this.each(null==n?Dl:Io(Xo(n)))};var Tl,Rl,Dl=Io(Xo()),Pl=[],Ul=0;Pl.call=_a.call,Pl.empty=_a.empty,Pl.node=_a.node,Pl.size=_a.size,ta.transition=function(n,t){return n&&n.transition?Tl?n.transition(t):n:ta.selection().transition(n)},ta.transition.prototype=Pl,Pl.select=function(n){var t,e,r,u=this.id,i=this.namespace,o=[];n=N(n);for(var a=-1,c=this.length;++a<c;){o.push(t=[]);for(var l=this[a],s=-1,f=l.length;++s<f;)(r=l[s])&&(e=n.call(r,r.__data__,s,a))?("__data__"in r&&(e.__data__=r.__data__),$o(e,s,i,u,r[i][u]),t.push(e)):t.push(null)}return Yo(o,i,u)},Pl.selectAll=function(n){var t,e,r,u,i,o=this.id,a=this.namespace,c=[];n=C(n);for(var l=-1,s=this.length;++l<s;)for(var f=this[l],h=-1,g=f.length;++h<g;)if(r=f[h]){i=r[a][o],e=n.call(r,r.__data__,h,l),c.push(t=[]);for(var p=-1,v=e.length;++p<v;)(u=e[p])&&$o(u,p,a,o,i),t.push(u)}return Yo(c,a,o)},Pl.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=O(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Yo(u,this.namespace,this.id)},Pl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Pl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Pl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Pl.style=function(n,e,r){function u(){this.style.removeProperty(n)}function i(e){return null==e?u:(e+="",function(){var u,i=t(this).getComputedStyle(this,null).getPropertyValue(n);return i!==e&&(u=mu(i,e),function(t){this.style.setProperty(n,u(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Zo(this,"style."+n,e,i)},Pl.styleTween=function(n,e,r){function u(u,i){var o=e.call(this,u,i,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,u)},Pl.text=function(n){return Zo(this,"text",n,Vo)},Pl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Pl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),Y(this,function(r){r[e][t].ease=n}))},Pl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Pl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Pl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=Rl,i=Tl;try{Tl=e,Y(this,function(t,u,i){Rl=t[r][e],n.call(t,t.__data__,u,i)})}finally{Rl=u,Tl=i}}else Y(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Pl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ul,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Yo(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):y:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ca),d=ta.transition(p.exit()).style("opacity",Ca).remove(),m=ta.transition(p.order()).style("opacity",1),M=Math.max(u,0)+o,x=Ui(f),b=l.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ta.transition(b));v.append("line"),v.append("text");var w,S,k,E,A=v.select("line"),N=m.select("line"),C=p.select("text").text(g),z=v.select("text"),q=m.select("text"),L="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,w="x",k="y",S="x2",E="y2",C.attr("dy",0>L?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+L*i+"V0H"+x[1]+"V"+L*i)):(n=Wo,w="y",k="x",S="y2",E="x2",C.attr("dy",".32em").style("text-anchor",0>L?"end":"start"),_.attr("d","M"+L*i+","+x[0]+"H0V"+x[1]+"H"+L*i)),A.attr(E,L*u),z.attr(k,L*M),N.attr(S,0).attr(E,L*u),q.attr(w,0).attr(k,L*M),f.rangeBand){var T=f,R=T.rangeBand()/2;s=f=function(n){return T(n)+R}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=jl,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Fl?t+"":jl,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var jl="bottom",Fl={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(t){t.each(function(){var t=ta.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",i).on("touchstart.brush",i),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,y);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Hl[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var c,f=ta.transition(t),h=ta.transition(o);l&&(c=Ui(l),h.attr("x",c[0]).attr("width",c[1]-c[0]),r(f)),s&&(c=Ui(s),h.attr("y",c[0]).attr("height",c[1]-c[0]),u(f)),e(f)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+f[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",f[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",f[1]-f[0])}function u(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function i(){function i(){32==ta.event.keyCode&&(C||(M=null,q[0]-=f[1],q[1]-=h[1],C=2),S())}function v(){32==ta.event.keyCode&&2==C&&(q[0]+=f[1],q[1]+=h[1],C=0,S())}function d(){var n=ta.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ta.event.altKey?(M||(M=[(f[0]+f[1])/2,(h[0]+h[1])/2]),q[0]=f[+(n[0]<M[0])],q[1]=h[+(n[1]<M[1])]):M=null),A&&m(n,l,0)&&(r(k),t=!0),N&&m(n,s,1)&&(u(k),t=!0),t&&(e(k),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,i=Ui(t),c=i[0],l=i[1],s=q[e],v=e?h:f,d=v[1]-v[0];return C&&(c-=s,l-=d+s),r=(e?p:g)?Math.max(c,Math.min(l,n[e])):n[e],C?u=(r+=s)+d:(M&&(s=Math.max(c,Math.min(l,2*M[e]-r))),r>s?(u=r,r=s):u=s),v[0]!=r||v[1]!=u?(e?a=null:o=null,v[0]=r,v[1]=u,!0):void 0}function y(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ta.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ta.select(ta.event.target),w=c.of(b,arguments),k=ta.select(b),E=_.datum(),A=!/^(n|s)$/.test(E)&&l,N=!/^(e|w)$/.test(E)&&s,C=_.classed("extent"),z=W(b),q=ta.mouse(b),L=ta.select(t(b)).on("keydown.brush",i).on("keyup.brush",v);if(ta.event.changedTouches?L.on("touchmove.brush",d).on("touchend.brush",y):L.on("mousemove.brush",d).on("mouseup.brush",y),k.interrupt().selectAll("*").interrupt(),C)q[0]=f[0]-q[0],q[1]=h[0]-q[1];else if(E){var T=+/w$/.test(E),R=+/^n/.test(E);x=[f[1-T]-q[0],h[1-R]-q[1]],q[0]=f[T],q[1]=h[R]}else ta.event.altKey&&(M=q.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,c=E(n,"brushstart","brush","brushend"),l=null,s=null,f=[0,0],h=[0,0],g=!0,p=!0,v=Ol[0];return n.event=function(n){n.each(function(){var n=c.of(this,arguments),t={x:f,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Tl?ta.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,f=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(f,t.x),r=yu(h,t.y);return o=a=null,function(u){f=t.x=e(u),h=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(l=t,v=Ol[!l<<1|!s],n):l},n.y=function(t){return arguments.length?(s=t,v=Ol[!l<<1|!s],n):s},n.clamp=function(t){return arguments.length?(l&&s?(g=!!t[0],p=!!t[1]):l?g=!!t:s&&(p=!!t),n):l&&s?[g,p]:l?g:s?p:null},n.extent=function(t){var e,r,u,i,c;return arguments.length?(l&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),o=[e,r],l.invert&&(e=l(e),r=l(r)),e>r&&(c=e,e=r,r=c),(e!=f[0]||r!=f[1])&&(f=[e,r])),s&&(u=t[0],i=t[1],l&&(u=u[1],i=i[1]),a=[u,i],s.invert&&(u=s(u),i=s(i)),u>i&&(c=u,u=i,i=c),(u!=h[0]||i!=h[1])&&(h=[u,i])),n):(l&&(o?(e=o[0],r=o[1]):(e=f[0],r=f[1],l.invert&&(e=l.invert(e),r=l.invert(r)),e>r&&(c=e,e=r,r=c))),s&&(a?(u=a[0],i=a[1]):(u=h[0],i=h[1],s.invert&&(u=s.invert(u),i=s.invert(i)),u>i&&(c=u,u=i,i=c))),l&&s?[[e,u],[r,i]]:l?[e,r]:s&&[u,i])},n.clear=function(){return n.empty()||(f=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!l&&f[0]==f[1]||!!s&&h[0]==h[1]},ta.rebind(n,c,"on")};var Hl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Ol=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Il=ac.format=gc.timeFormat,Yl=Il.utc,Zl=Yl("%Y-%m-%dT%H:%M:%S.%LZ");Il.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Zl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Zl.toString,ac.second=Ft(function(n){return new cc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ac.seconds=ac.second.range,ac.seconds.utc=ac.second.utc.range,ac.minute=Ft(function(n){return new cc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ac.minutes=ac.minute.range,ac.minutes.utc=ac.minute.utc.range,ac.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new cc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ac.hours=ac.hour.range,ac.hours.utc=ac.hour.utc.range,ac.month=Ft(function(n){return n=ac.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ac.months=ac.month.range,ac.months.utc=ac.month.utc.range;var Vl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Xl=[[ac.second,1],[ac.second,5],[ac.second,15],[ac.second,30],[ac.minute,1],[ac.minute,5],[ac.minute,15],[ac.minute,30],[ac.hour,1],[ac.hour,3],[ac.hour,6],[ac.hour,12],[ac.day,1],[ac.day,2],[ac.week,1],[ac.month,1],[ac.month,3],[ac.year,1]],$l=Il.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",Ne]]),Bl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:y,ceil:y};Xl.year=ac.year,ac.scale=function(){return Go(ta.scale.linear(),Xl,$l)};var Wl=Xl.map(function(n){return[n[0].utc,n[1]]}),Jl=Yl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",Ne]]);Wl.year=ac.year.utc,ac.scale.utc=function(){return Go(ta.scale.linear(),Wl,Jl)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}();
var colorToolTip = "#DFEFFC"; //"#E7CEFF";
var colorStrokeTooltip = "#2A5790";// colorLuminance(colorToolTip.substring(1), -0.5);

$(document).ready(function () {
    $(document.body).append('<svg id="canvasContextMenu" display="none"></svg><div id="cm-tooltip" class="tooltip"></div>');
    var d3canvasContextMenu = d3.select("#canvasContextMenu");
    var processClick = false;

    $(document).on("click", function () {
        if (!processClick) {
            $("#canvasContextMenu").css("display", "none");
        }
        $("#cm-tooltip").css("display", "none");
        processClick = false;
    });

    function showDetails(descriptorID, text) {
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: REALPATH + CURRENT_LANG + "/Descriptor/GetDetails",
            data: "{'descriptorID':'" + descriptorID + "'}",
            dataType: "html",
            async: true,
            success: function (response) {
                $("#descriptorDetails").html("");
                $("#descriptorDetails").append("<div class='descriptorDetailsClose' onclick='closeDescriptorDetails()'>X</div>");
                $("#descriptorDetails").append("<h2 class='descriptorDetailsTitle'>" + text + "</h2>");
                $("#descriptorDetails").append(response);
                $("#descriptorDetails").css("display", "inline");

                $("#menuDescriptorDetails li").on("click", function () {
                    $("#menuDescriptorDetails li.ui-state-active").removeClass("ui-state-active");
                    $(this).addClass("ui-state-active");
                    $(".descriptorFileListItem").css("display", "none");
                    $("#" + $(this).data("tab")).css("display", "inline");
                    $("#canvasContextMenu").css("display", "none");
                });

                $("#relacionados li").on("contextmenu", function (event) {
                    d3canvasContextMenu.datum({ action: "related", idSelected: $(this).data("id"), numberChildren: $(this).data("numberchildren"), numberResolutions: $(this).data("numberresolutions"), text: $(this).children("p").eq(0).text() });

                    var posx = event.pageX + 5;
                    var posy = event.pageY + 5;

                    contextMenuToolTips();
                    showContextMenu(posx, posy);
                    event.preventDefault();
                }).each(function () {
                    $(this).data("text", $(this).children("p").eq(0).text());
                    $(this).data("numberResolutions", $(this).data("numberresolutions"));
                    $(this).data("numberChildren", $(this).data("numberchildren"));
                });

                var svgs = d3.selectAll("#relacionados li svg");
                renderPopupListToolbar(svgs, "related");

                $("#modificadores li").on("contextmenu", function (event) {
                    d3canvasContextMenu.datum({ action: "modifier", idSelected: $(this).data("id"), idmodifier: $(this).data("idmodifier"), numberChildren: 0, numberResolutions: $(this).data("numberresolutions"), text: $(this).children("p").eq(0).text() });

                    var posx = event.pageX + 5;
                    var posy = event.pageY + 5;

                    contextMenuToolTips();
                    showContextMenu(posx, posy);
                    event.preventDefault();
                }).each(function () {
                    $(this).data("text", $(this).children("p").eq(0).text());
                    $(this).data("numberResolutions", $(this).data("numberresolutions"));
                    $(this).data("numberChildren", $(this).data("numberchildren"));
                    $(this).data("idmodifier", $(this).data("idmodifier"));
                });

                svgs = d3.selectAll("#modificadores li svg");
                renderPopupListToolbar(svgs, "modifier");

                $("#hijos li").on("contextmenu", function (event) {
                    d3canvasContextMenu.datum({ action: "child", idSelected: $(this).data("id"), numberChildren: $(this).data("numberchildren"), numberResolutions: $(this).data("numberresolutions"), text: $(this).children("p").eq(0).text() });

                    var posx = event.pageX + 5;
                    var posy = event.pageY + 5;

                    contextMenuToolTips();
                    showContextMenu(posx, posy);
                    event.preventDefault();
                }).each(function () {
                    $(this).data("text", $(this).children("p").eq(0).text());
                    $(this).data("numberResolutions", $(this).data("numberresolutions"));
                    $(this).data("numberChildren", $(this).data("numberchildren"));
                });

                var svgs = d3.selectAll("#hijos li svg");
                renderPopupListToolbar(svgs, "child");
            },
            error: function (result) {
                showFlashMessage(translate("unexpected_error_sending_data"));
            }
        });
    }
    
    $("ul#descriptores-nav li[data-view='descriptorTreeView']").on("click", function () {
        var resolucionID = $("#resolucionID").val();
        GetDescriptorData(resolucionID);
    });

    if ($("ul#descriptores-nav li[data-view='descriptorTreeView']").hasClass("selected")) {
        var resolucionID = $("#resolucionID").val();
        GetDescriptorData(resolucionID);
    }

    function renderPopupListToolbar(svgs, action) {
        svgs.append("rect").attr("height", 20).attr("width", 20).attr("x", 7).style("fill", "url(#list-icon)")
                            .style("cursor", function () { return action == "modifier" ? "auto" : "pointer" })
                            .style("opacity", function () { return action == "modifier" ? 0.3 : 1 })
                            .on("click", function () {
                                d3.event.stopPropagation();
                                if (action == "modifier") {
                                    return;
                                }
                                var id = d3.select(this.parentNode).attr("data-id");
                                var text = $(d3.select(this.parentNode.parentNode)[0][0]).data("text");
                                showDetails(id, text);
                                $("#canvasContextMenu").css("display", "none");
                                $("#cm-tooltip").css("display", "none");
                            })
                            .each(function () {
                                if (action == "modifier") {
                                    addToolTip(d3.select(this), "Sin detalles");
                                }
                                else {
                                    addToolTip(d3.select(this), "Detalles del descriptor");
                                }
                            });
        svgs.append("rect").attr("height", 20).attr("width", 20).attr("x", 37).style("fill", "url(#detail-icon)")
                            .style("cursor", function () { return $(d3.select(this.parentNode.parentNode)[0][0]).data("numberResolutions") == 0 ? "auto" : "pointer" })
                            .style("opacity", function () { return $(d3.select(this.parentNode.parentNode)[0][0]).data("numberResolutions") == 0 ? 0.3 : 1 })
                            .on("click", function () {
                                d3.event.stopPropagation();
                                var id = d3.select(this.parentNode).attr("data-id");
                                if ($(d3.select(this.parentNode.parentNode)[0][0]).data("numberResolutions") == 0) {
                                    return;
                                }
                                ;
                                showResolutions(id);
                                $("#canvasContextMenu").css("display", "none");
                                $("#cm-tooltip").css("display", "none");
                            })
                            .each(function () {
                                var numberResolutions = $(d3.select(this.parentNode.parentNode)[0][0]).data("numberResolutions");
                                if (numberResolutions > 0) {
                                    addToolTip(d3.select(this), "Resoluciones asociadas (" + numberResolutions + ")");
                                }
                                else {
                                    addToolTip(d3.select(this), "No hay resoluciones asociadas");
                                }
                            });        
    }

    /* MENÚ CONTEXTUAL */
    function createContextMenu() {
        var container = d3canvasContextMenu.append("rect").style("pointer-events", "all").attr("height", 30).attr("width", 60).attr("x", 2).attr("y", 2).attr("rx", 10).attr("ry", 10).style("stroke", colorStrokeTooltip).style("stroke-width", 1).style("fill", colorToolTip);
        var detailsIcon = d3canvasContextMenu.append("rect").attr("id", "cm-details").attr("height", 20).attr("width", 20).attr("x", 7).attr("y", 7).style("fill", "url(#list-icon)").style("cursor", "pointer");
        var listIcon = d3canvasContextMenu.append("rect").attr("id", "cm-list").attr("height", 20).attr("width", 20).attr("x", 37).attr("y", 7).style("fill", "url(#detail-icon)").style("cursor", "pointer");
        
        $("#canvasContextMenu").css("width", (parseInt(container.attr("width"), 10) + 3) + "px");
        $("#canvasContextMenu").css("height", (parseInt(container.attr("height"), 10) + 3) + "px");

        detailsIcon.on("click", function () {
            var id = d3canvasContextMenu.datum().idSelected;            
            $("#canvasContextMenu").css("display", "none");
            $("#cm-tooltip").css("display", "none");

            if (id[0] == "t") {
                return;
            }

            showDetails(id.substring(1), d3canvasContextMenu.datum().text);            
        });

        listIcon.on("click", function () {
            var id = d3canvasContextMenu.datum().idSelected;
            
            $("#canvasContextMenu").css("display", "none");
            $("#cm-tooltip").css("display", "none");

            if (d3canvasContextMenu.datum().numberResolutions == 0 || id[0] == "t") {
                return;
            }

            showResolutions(id.substring(1), d3canvasContextMenu.datum().idmodifier);
        });
    }

    function contextMenuToolTips() {
        if (d3canvasContextMenu.datum().action == 'modifier' || d3canvasContextMenu.datum().idSelected[0] == "t") {
            d3canvasContextMenu.select("#cm-details").style("opacity", 0.3).style("cursor", "default");
            addToolTip(d3canvasContextMenu.select("#cm-details"), "Sin detalles");
        }
        else {
            d3canvasContextMenu.select("#cm-details").style("opacity", 1).style("cursor", "pointer");
            addToolTip(d3canvasContextMenu.select("#cm-details"), "Detalles del descriptor");
        }

        if (d3canvasContextMenu.datum().numberResolutions == 0) {
            d3canvasContextMenu.select("#cm-list").style("opacity", 0.3).style("cursor", "default");
            addToolTip(d3canvasContextMenu.select("#cm-list"), "No hay resoluciones asociadas");
        }
        else {
            d3canvasContextMenu.select("#cm-list").style("opacity", 1).style("cursor", "pointer");
            addToolTip(d3canvasContextMenu.select("#cm-list"), "Resoluciones asociadas (" + d3canvasContextMenu.datum().numberResolutions + ")");
        }
    }

    function addToolTip(element, tip) {
        element.on("mouseover", function () {
            $("#cm-tooltip").text(tip);
            $("#cm-tooltip").css("display", "block");
        });

        element.on("mousemove", function (event) {
            var ev = d3.event != null ? d3.event : event;
            var posx = ev.pageX + 15;
            var posy = ev.pageY + 15;

            $("#cm-tooltip").css("left", posx + "px");
            $("#cm-tooltip").css("top", posy + "px");
        });

        element.on("mouseout", function () {
            $("#cm-tooltip").css("display", "none");
        });
    }

    /* FIN MENÜ CONTEXTUAL */

    createContextMenu();    
    var loaded = false;
    function GetDescriptorData(resolucionID) {
        if (loaded) {
            return;
        }
        var arguments = "{'resolucionID':'" + resolucionID + "'";
        arguments += "}";

        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: REALPATH + CURRENT_LANG + "/Descriptor/GetDescriptorsRelathionshipsFromResolution",
            data: arguments,
            dataType: "json",
            async: true,
            success: function (response) {
                if (parseInt(response["success"])) {
                    var data = response["data"];
                    renderTree(data, 1, 0);
                    sortGroups();
                    var superh = treeSort(data[0]);
                    drawLines(data[0]);
                    d3.select("#canvasDescriptores").attr("height", superh);
                    loaded = true;
                }
            },
            error: function (result) {
                showFlashMessage(translate("unexpected_error_sending_data"));
            }
        });
    }

    function colorLuminance(hex, lum) {
        lum = lum || 0;

        // convert to decimal and change luminosity
        var rgb = "#", c, i;
        for (i = 0; i < 3; i++) {
            c = parseInt(hex.substr(i * 2, 2), 16);
            c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);
            rgb += ("00" + c).substr(c.length);
        }

        return rgb;
    }

    var seguir = true;
    var grid = [];
    function renderTree(data, nivel) {
        var colorStar = colorLuminance("FFCC33", 0.1);

        var maxwidth = 0;
        var nextTop = 0;
        var canvas = d3.select("#canvasDescriptores");

        if (nivel >= 3) {
            seguir = false;
        }

        if (!grid[nivel]) {
            grid[nivel] = 0;
        }

        for (var i = 0; i < data.length; i++) {
            var id = (data[i].IsConceptualType ? "t" : "d") + data[i].ID;

            var radius = 5;
            
            if (data[i].numberGrounds > 0) {
                radius = data[i].numberGroundsPercent / 2;
            }
            
            radius = Math.max(5, radius);
            
            var element = addDescriptor(canvas, 0, nextTop, radius, 0, data[i].IsAssociatedWithResolution ? colorStar : "#2E6E9E", id, data[i].text, data[i], false);
            element.datum().nivel = nivel;
            element.datum().index = grid[nivel];
            element.attr("data-nivel", nivel);
            element.attr("data-index", grid[nivel]);
            data[i].element = element;
            var size = calculateSize(element);

            maxwidth = Math.max(size, maxwidth);
            nextTop += element.datum().height + 10;

            if (data[i].children.length > 0) {
                renderTree(data[i].children, nivel + 1);
            }

            grid[nivel]++;
        }

        return data.length;
    }

    function sortGroups() {
        var nivel = 1;
        var widthprevious = 60;
        var heightprevious = 60;
        var maxwidthnext = 0;
        var maxheight = 0;
        while (true) {

            var element = d3.selectAll("g[data-nivel='" + nivel + "']");

            if (!element[0][0]) {
                break;
            }

            element.each(function () {
                var item = d3.select(this);
                item.attr("transform", "translate(" + widthprevious + "," + heightprevious + ")");

                heightprevious += item.datum().height + 10;
                maxwidthnext = Math.max(maxwidthnext, item.datum().width);

                maxheight = Math.max(maxheight, heightprevious);
            });

            nivel++;
            heightprevious = 60;
            widthprevious += maxwidthnext + 20;
            maxwidthnext = 0;
        }

        d3.select("#canvasDescriptores").attr("height", maxheight);
    }

    function addTop(data, i, top) {
        for (var j = i; j < data.length; j++) {
            var item = data[i];
            var posx = d3.transform(item.element.attr("transform")).translate[0];
            var posy = d3.transform(item.element.attr("transform")).translate[1];
            item.element.attr("transform", "translate(" + posx + "," + (posy + top) + ")");
            addTop(item.children, 0, top);
        }
    }

    var gridTop = [];
    function treeSort(data, fatherTop) {
        if (!data.element) {
            return 0;
        }

        if (!fatherTop) {
            fatherTop = 0;
        }

        var nivel = data.element.datum().nivel;
        if (!gridTop[nivel]) {
            gridTop[nivel] = 60;
        }

        var posx = d3.transform(data.element.attr("transform")).translate[0];
        var posy = d3.transform(data.element.attr("transform")).translate[1];
        if (gridTop[nivel] > posy) {
            posy = gridTop[nivel];
        }

        if (fatherTop > posy) {
            posy = fatherTop;
        }

        if (data.children.length == 0) {
            data.element.attr("transform", "translate(" + posx + "," + posy + ")");
            return data.element.datum().height;
        }

        var height = 0;
        for (var i = 0; i < data.children.length; i++) {
            height += treeSort(data.children[i], posy + height) + 10;
        }

        var finalposy = posy + Math.abs(height / 2 - data.element.datum().height / 2) - 5;
        data.element.attr("transform", "translate(" + posx + "," + finalposy + ")");

        height = Math.max(height, data.element.datum().height);

        gridTop[nivel] = posy + height;

        return height;
    }

    function drawLines(data) {
        var posx = d3.transform(data.element.attr("transform")).translate[0];
        var posy = d3.transform(data.element.attr("transform")).translate[1];
        for (var i = 0; i < data.children.length; i++) {
            var posix = d3.transform(data.children[i].element.attr("transform")).translate[0];
            var posiy = d3.transform(data.children[i].element.attr("transform")).translate[1];

            d3.select("#canvasDescriptores").insert("line", ":first-child")
                                .attr("x1", posx).attr("y1", posy)
                                .attr("x2", posix).attr("y2", posiy)
                                .style("stroke-width", 1)
                                .style("stroke", "lightblue");

            drawLines(data.children[i]);
        }
    }

    function calculateSize(element) {
        //var labelMeta = element.select("text").node().getBBox();
        var labelMeta = element.node().getBBox();
        var size = element.datum().radiusCrown > 0 ? element.datum().radiusCrown * 2 : element.datum().radius * 2;

        element.datum().width = size;
        element.datum().height = size;

        if (size < labelMeta.width) {
            size = labelMeta.width;
        }

        if (size < labelMeta.height) {
            size = labelMeta.height;
        }

        if (element.datum().width < labelMeta.width) {
            element.datum().width = labelMeta.width;
        }

        if (element.datum().height < labelMeta.height) {
            element.datum().height = labelMeta.height;
        }

        element.datum().size = size;

        return size;
    }

    function wrap(text, width, hardlimit) {
        hardlimit = typeof hardlimit !== 'undefined' ? hardlimit : false;

        if (width < 50) {
            width = 50;
        }

        var words = text.text().split(/\s+/).reverse(),
            word,
            line = [],
            lineNumber = 0,
            lineHeight = 1.1, // ems
            dy = parseFloat(text.attr("dy")),
            tspan = text.text(null).append("tspan").attr("x", 0).attr("dy", dy);

        dy = -15;

        word = words.pop();
        line.push(word);
        tspan.text(line.join(" "));

        while (word = words.pop()) {
            line.push(word);
            tspan.text(line.join(" "));
            if (tspan.node().getComputedTextLength() > width) {
                if (!hardlimit && word.length <= 3) {
                    continue;
                }

                line.pop();
                tspan.text(line.join(" "));
                line = [word];
                tspan = text.append("tspan").attr("x", 0).attr("dy", --lineNumber * lineHeight - dy).text(word);
            }
        }
    }

    function addDescriptor(d3canvas, posx, posy, radius, radiusCrown, color, id, text, datum, doStartAnimation) {
        doStartAnimation = typeof doStartAnimation !== 'undefined' ? doStartAnimation : true;

        var element = d3canvas.append("g")
                            .datum(datum)
                            .attr("transform", "translate(" + posx + "," + posy + ")")
                            .attr("data-type", "descriptor")
                            .attr("id", id);

        element.datum().radius = radius;
        element.datum().radiusCrown = radiusCrown;

        function translationDelta(item) {
            var radius = item.datum().radius;

            return function () {
                return function (t) {
                    return t * radius;
                }
            }
        }

        if (radiusCrown > 0) {
            var outerCircle = element.append("circle")
                                .datum({ originalColor: colorCrown, radius: radiusCrown, originalOpacity: 0.5 })
                                .attr("r", radiusCrown)
                                .attr("opacity", 0.5)
                                .style("fill", colorCrown);

            if (doStartAnimation) {
                outerCircle.transition().duration(1000)
                                .attrTween("r", translationDelta(outerCircle));
            }

            //outerCircle.on("click", function () {
            //    processClick = true;
            //});
        }

        var innerCircle = element.append("circle")
                            .datum({ originalColor: color, radius: radius, originalOpacity: 1 })
                            .attr("r", radius)
                            .style("fill", color);

        if (doStartAnimation) {
            innerCircle.transition().duration(1000)
                                .attrTween("r", translationDelta(innerCircle));
        }

        //innerCircle.on("click", function () {
        //    processClick = true;
        //});

        var dy = Math.min(-20, (radiusCrown > 0 ? radiusCrown : radius) / -2);

        var label = element.append("text")
                            .attr("dy", dy)
                            .attr("text-anchor", "middle")
                            .text(text);

        //label.on("click", function () {
        //    processClick = true;
        //});

        wrap(label, Math.max(radius * 2, text.length * 2));
        
        element.on("contextmenu", function () {
            d3.event.preventDefault();
            if (id[0] == "t") {
                return;
            }            
            starOnRightClick(id, d3.event);            
        });

        element.on("click", function () {
            d3.event.preventDefault();
            if (id[0] == "t") {
                return;
            }
            starOnRightClick(id, d3.event);
            processClick = true;
        });

        return element;
    }

    function starOnRightClick(id, event) {
        var element = d3.select("#" + id);
        d3canvasContextMenu.datum({ action: "actual", idSelected: id, numberResolutions: element.datum().numberResolutions, text: element.datum().text });

        var posx = event.pageX + 5;
        var posy = event.pageY + 5;

        contextMenuToolTips();
        showContextMenu(posx, posy);
    }

    function showContextMenu(posx, posy) {
        $("#canvasContextMenu").css("top", posy);
        $("#canvasContextMenu").css("left", posx);
        d3canvasContextMenu.style("display", "block");        
    }

    $("#descriptorDetails").draggable({ handle: ".descriptorDetailsTitle" });
});

function showResolutions(iddescriptor, idmodifier) {
    var arguments = "{'descriptorID':'" + iddescriptor + "'";
    if (idmodifier) {
        arguments += ", 'modificadorID':'" + idmodifier + "'";
    }

    arguments += "}";

    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: REALPATH + CURRENT_LANG + "/Descriptor/SearchSingle",
        data: arguments,
        dataType: "json",
        async: true,
        success: function (response) {
            if (!parseInt(response["success"])) {
                showFlashMessage(response["error"]);
            }
            else {
                window.open(REALPATH + CURRENT_LANG + "/Resolucion/List");
            }
        },
        error: function (result) {
            showFlashMessage(translate("unexpected_error_sending_data"));
        }
    });
}

function closeDescriptorDetails() {
    $("#descriptorDetails").css("display", "none");
    $("#canvasContextMenu").css("display", "none");
    $("#cm-tooltip").css("display", "none");
}
// $("#wrapper").css("background-color", "rgba(235, 235, 235, 1)");

function executeAction(obj)
{
    var url = obj.attr('data-action');

    if (url !== undefined)
        window.location.href = url;
}

$('#divEnlace').click(function () {
    executeAction($(this));
});

$('#divEnlaceCabecera').click(function () {
    executeAction($(this));
});

//var MINPAGINA = 785;
//    var MAXPAGINA = 815;
//    var MINIMUMCHARACTERSPERLINE = 50;
var BOOKMARKS = {};
var FLIPBOOK = {};
var resolucionVisibleIndex = -1;
var extraPage = false;
// Navegación
var pageHistory = [];
// Variables para el precargado
var loaded = false; // Indica al phantomJS si se ha terminado de cargar el tomo
var success = false; // Indica al phantomJS si todo ha ido bien en el lado del servidor
var totalRenderTime; // Para debug, indica el tiempo total de renderizado en cliente
var annoCabecera;
var semestreCabecera;

var sonido = document.getElementById("sonido");
var paginacionActual = 1;
var anchoImagen = 1;

$(document).ready(function () {
    $("#hojasDer").click(function () {
        //console.log("pulsada imagen")
        goTo($("#flipbook").turn("page") + 2);
        //sonido.play();
        //console.log("despues de sonido")
    });

    $("#hojasIzq").click(function () {
        // console.log("pulsada imagen")
        goTo($("#flipbook").turn("page") - 2);
        //sonido.play();
        // console.log("despues de sonido")
    });


    $("#hojasDer").mousemove(function (e) {
        //// var elemento = $("#hojasDer");
        //// var posicion = elemento.position();
        //// console.log("left: " + posicion.left + ", top: " + posicion.top + ", right: " + posicion.right);

        // var offset = $(this).offset();

        // event.stopPropagation();
        // var right = $(window).width() - $(this).width();
        // right = offset.left - right;
        // console.log( this.tagName +" coords ( " + offset.left + ", " + right + " )" );



        // var x = e.pageX - this.offsetLeft;
        // var y = e.pageY - this.offsetTop;
        // console.log("--------------------------x: " + x);
        // console.log("--------------------------y: " + y);
        //// $('#status2').html(x + ', ' + y);
    });
});

function changePagesSize(pageActual) {
    var paginacion = pageActual.toString();
    console.log("ancho imagen1: " + anchoImagen)
    var totalPaginas = FLIPBOOK.totalPages;
    if (paginacion.indexOf('-') != -1) {
        var paginaActual = paginacion.substring(0, paginacion.indexOf('-'));
    }
    else {
        var paginaActual = 1;
    }

    console.log("ancho imagen2: " + anchoImagen)
    var anchuraDerecha = anchoImagen - (paginaActual / totalPaginas) * anchoImagen;
    var anchuraIzquierda = (paginaActual / totalPaginas) * anchoImagen;
    if (paginaActual >= totalPaginas - 20 && paginaActual < totalPaginas - 1 && anchuraDerecha < 1) {
        anchuraDerecha = 1;
    }
    if (paginaActual != 1 && paginaActual <= 50 && anchuraIzquierda < 1) {
        anchuraIzquierda = 1;
    }
    $("#hojasDer").css("width", anchuraDerecha);// $("#hojasDer").css('width').replace('px', '') - 10);

    $("#hojasIzq").css("width", anchuraIzquierda);//anchoImagen - (paginaActual / totalPaginas) * anchoImagen);

    var anchoDiferencia = anchoImagen - (paginaActual / totalPaginas) * anchoImagen;
    $("#divHojaIzq").css("left", 235 + anchoDiferencia);//239

    $("#hojasIzq").css("display", "block");

}

// Funciones de navegación
function goTo(basePage, bookmark, id) {
    //console.log("goTo: " + basePage + " " + bookmark + " " + BOOKMARKS[bookmark]);            
    var destiny = basePage;
    if (bookmark && BOOKMARKS[bookmark]) {
        destiny += BOOKMARKS[bookmark];
        pageHistory.push($("#flipbook").turn("page"));
        $("#nav-back").attr("disabled", false);
    }
    if (destiny <= 0) {
        destiny = 1;
    }
    if (destiny > FLIPBOOK.totalPages) {
        destiny = FLIPBOOK.totalPages;
    }
    $("#flipbook").turn("page", destiny);

    //para que se marque en que sección estamos dentro del libro
    $(".menu").each(function (index, value) {
        var idEnlace = $(this).attr("id");
        if (idEnlace == id) {
            $(this).css({ 'color': 'green', 'font-size': '13px' });
        }
        else {
            $(this).css({ 'color': 'black', 'font-size': '12px' });
        }
    });
}

function sonidoPagina(direccion, pageActual) {
    var paginaActual = pageActual.substring(0, pageActual.indexOf(' '));//$("#pages-legend").text().substring(0, $("#pages-legend").text().indexOf(' '));
    var paginaFin = pageActual.substring($("#pages-legend").text().indexOf('-') + 1, pageActual.indexOf('\\')).trim();//$("#pages-legend").text().substring($("#pages-legend").text().indexOf('-') + 1, $("#pages-legend").text().indexOf('\\')).trim();
    if ((direccion == undefined && (paginaActual == '1' || paginaFin >= FLIPBOOK.totalPages)) || (direccion != undefined && ((direccion == 'anterior' && paginaActual == '1') || (direccion == 'siguiente' && paginaFin >= FLIPBOOK.totalPages)))) //'anterior' 'siguiente'//(direccion != undefined && ((direccion == 'anterior' && destiny == 1) || (direccion == 'siguiente' && destiny == FLIPBOOK.totalPages))) //'anterior' 'siguiente'
    {
        return false;
    }
    else
    {
        sonido.play();
    }
}

function goBack() {
    $("#flipbook").turn("page", pageHistory.pop());
    if (pageHistory.length == 0) {
        $("#nav-back").attr("disabled", true);
    }
}

// Función de debug, llamar sólo para depurar una resolución concreta
//function VerResolucion() {
//    $.ajax({
//        type: "POST",
//        contentType: "application/json; charset=utf-8",
//        url: "../WebServices/Gaceta.asmx/GetResolucionFlipBook",
//        data: "{'id': '" + "6239" + "', 'textoIntegro':'true'}",
//        dataType: "json",
//        async: true,
//        success: function (data) {
//            generateFlipBook(data.d, "#flipbook", 'S');

//            $("#flipbook").removeClass("cargando");

//            $("#flipbook").turn({
//                width: 1220,
//                height: 876,
//                autoCenter: true
//            });
//        },
//        error: function (result) {
//            console.log("Debido a un error inesperado no podemos cargar los datos");
//        }
//    });
//}

// A esta función se la llama al final, si procede (cuando el campo oculto está definido)
function loadTome(tomeID) {
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: REALPATH + CURRENT_LANG + "/Gaceta/GetGacetaFlipBook",
        data: "{'gacetaID': '" + tomeID + "'}",
        dataType: "html",
        async: true,
        success: function (data) {
            var start = new Date().getTime();
            var sidebar = $("#contenedorPaginadorTomo .flipbook-sidebar");

            FLIPBOOK = JSON.parse(data.lastIndexOf('FLIPBOOK = JSON.parse') + 22, data.length - 10);

            $("#contenedorPaginadorTomo").html(data);

            $("#contenedorPaginadorTomo").append($("<div id='sideflipbook'></div>")); // Por si acaso
            $("#contenedorPaginadorTomo").prepend(sidebar);
            var end = new Date().getTime();

            //console.log("Tiempo de carga de las páginas: " + (end - start));
            initFlipBook();

            var resolutionID = $("#hfResolucionID").val();

            //resolutionID = 6789;/* 34*/
            //var resolutionID = $("#hfResolucionID").val();
            //if (resolutionID) {
            //    // FLIPBOOK.resolucionIDToIndex = {};
            //    console.log("indexresolucion")
            //    var indexResolucion = FLIPBOOK.resolucionIDToIndex[resolutionID];
            //    console.log (indexResolucion)
            //    resolucionVisibleIndex = indexResolucion;
            //    var destinyPage = FLIPBOOK.listaResoluciones[indexResolucion].page;               
            //    $("#flipbook").turn("page", destinyPage);                
            //}
        },
        error: function (result) {
            console.log("Debido a un error inesperado no podemos cargar los datos");
        }
    });
}

//// función para llamar desde PhantomJS, no desde el usuario
//// ejecutar con debug = true para depurar a mano
//function preloadTome(tomoID, semestre, textoIntegro, debug) {
//    $.ajax({
//        type: "POST",
//        contentType: "application/json; charset=utf-8",
//        url: "../WebServices/Gaceta.asmx/GetGacetaFlipBookPreload",
//        data: "{'gacetaID': '" + tomoID + "', 'textoIntegro':'" + textoIntegro + "'}",
//        dataType: "json",
//        async: true,
//        success: function (data) {
//            $("#labelCargando").remove();
//            var start = new Date().getTime();
//            generateTomeHTML(data.d, true, semestre);
//            if (debug) {
//                initFlipBook();
//            }
//            var end = new Date().getTime();
//            totalRenderTime = end - start;
//            success = true;
//            loaded = true;
//        },
//        error: function (result) {
//            loaded = true;
//        }
//    });
//}

// Genera el HTML de las páginas, poner full a true para generarlo todo, false para usar cargado dinámico de páginas
//function generateTomeHTML(data, full, semestre) {
//    var start = new Date().getTime();
//    data.resolucionIDToIndex = {};
//    var mostrarCabecera = 'S';
//    annoCabecera = data.annoCabecera;
//    if (semestre == '1') {
//        semestreCabecera = 'Primer semestre';// data.semestreCabecera;
//    }
//    else if (semestre == '2') {
//        semestreCabecera = 'Segundo semestre';
//    }
//    else {
//        semestreCabecera = '';
//    }

//    generateFlipBook(data.portada, "#flipbook", 'N');

//    data.paginaSumario = $("#flipbook .pagina").length;
//    //  if (paginaActual % 2 == 0) paginaActual++;
//    generateFlipBook(data.sumario, "#flipbook", 'S', 1, true);

//    var end = new Date().getTime();
//    var timeGenerate = end - start;
//    //console.log('Tiempo de construcción sumarios: ' + timeGenerate + ", Número de páginas: " + $("#flipbook .pagina").length);
//    start = end;
//    // if (paginaActual % 2 == 0) paginaActual++;
//    data.paginaSentencias = 0;
//    data.numeroSentencias = 0;
//    if (data.tituloSentencias.length > 0) {
//        var tituloSentencias = {};
//        tituloSentencias.listaItems = data.tituloSentencias;
//        data.paginaSentencias = $("#flipbook .pagina").length;
//        generateFlipBook(tituloSentencias, "#flipbook", "S", 1, true);

//        if (full) {
//            var i;
//            for (i = 0; i < data.listaResoluciones.length; i++) {
//                var resolucion = data.listaResoluciones[i];
//                if (resolucion.tipoResolucion != "SENTENCIA")
//                    break;
//                var page = $("#flipbook .pagina").length;
//                insertResolutionPreload(i, resolucion, page, false);

//                data.resolucionIDToIndex[resolucion.ID] = i;
//            }
//            data.numeroSentencias = i;
//        }
//    }

//    data.paginaDeclaraciones = 0;
//    data.numeroDeclaraciones = 0;
//    if (data.tituloDeclaraciones.length > 0) {
//        var tituloDeclaraciones = {};
//        tituloDeclaraciones.listaItems = data.tituloDeclaraciones;
//        data.paginDeclaraciones = $("#flipbook .pagina").length;
//        generateFlipBook(tituloDeclaraciones, "#flipbook", "S", 1, true);

//        if (full) {
//            var i;
//            for (i = data.numeroSentencias; i < data.listaResoluciones.length; i++) {
//                var resolucion = data.listaResoluciones[i];
//                if (resolucion.tipoResolucion != "DECLARACIÓN")
//                    break;
//                var page = $("#flipbook .pagina").length;
//                insertResolutionPreload(i, resolucion, page, false);

//                data.resolucionIDToIndex[resolucion.ID] = i;
//            }
//            data.numeroDeclaraciones = i - data.numeroSentencias;
//        }
//    }

//    data.paginaAutos = 0;
//    data.numeroAutos = 0;

//    if (data.tituloAutos.length > 0) {
//        var tituloAutos = {};
//        tituloAutos.listaItems = data.tituloAutos;
//        data.paginaAutos = $("#flipbook .pagina").length;
//        generateFlipBook(tituloAutos, "#flipbook", "S", 1, true);

//        if (full) {
//            var i;
//            for (i = data.numeroSentencias + data.numeroDeclaraciones; i < data.listaResoluciones.length; i++) {
//                var resolucion = data.listaResoluciones[i];
//                var page = $("#flipbook .pagina").length;
//                insertResolutionPreload(i, resolucion, page, false);

//                data.resolucionIDToIndex[resolucion.ID] = i;
//            }
//            data.numeroAutos = i - data.numeroSentencias - data.numeroDeclaraciones;
//        }
//    }
//    end = new Date().getTime();
//    timeGenerate = end - start;
//    //console.log('Tiempo de construcción resoluciones: ' + timeGenerate + ", Número de páginas: " + $("#flipbook .pagina").length);
//    start = end;

//    // if (paginaActual % 2 == 0) paginaActual++;
//    var tituloIndices = {};
//    tituloIndices.listaItems = data.tituloIndices;
//    generateFlipBook(tituloIndices, "#flipbook", 'S');
//    data.paginaTituloIndices = $("#flipbook .pagina").length;

//    var pagesIndices = 0;
//    for (var i = 0; i < data.indices.length; i++) {
//        pagesIndices = generateFlipBook(data.indices[i], "#flipbook", 'S', pagesIndices + 1);

//        end = new Date().getTime();
//        timeGenerate = end - start;
//        //console.log('Tiempo de construcción indice ' + (i + 1) + ': ' + timeGenerate + ", Número de páginas: " + $("#flipbook .pagina").length);
//        start = end;
//    }

//    if (data.voces) {
//        data.paginaVoces = $("#flipbook .pagina").length;
//        generateFlipBook(data.voces, "#flipbook", 'S');
//    }

//    end = new Date().getTime();
//    timeGenerate = end - start;
//    //console.log('Tiempo de construcción voces: ' + timeGenerate + ", Número de páginas: " + $("#flipbook .pagina").length);
//    start = end;
//    if (data.descriptores) {
//        data.paginaDescriptores = $("#flipbook .pagina").length;
//        generateFlipBook(data.descriptores, "#flipbook", 'S');
//    }

//    if (data.descriptoresAlfabetico) {
//        data.paginaDescriptoresAlfabetico = $("#flipbook .pagina").length;
//        generateFlipBook(data.descriptoresAlfabetico, "#flipbook", 'S');
//    }

//    var end = new Date().getTime();
//    var timeGenerate = end - start;
//    //console.log('Tiempo de construcción descriptores: ' + timeGenerate + ", Número de páginas: " + $("#flipbook .pagina").length);

//    FLIPBOOK = data;
//}

// Llama a la librería turn.js para la creación del flipbook (asume que hay páginas cargadas en #flipbook)
function initFlipBook() {
    var start = new Date().getTime();
    $("#flipbook").removeClass("cargando");

    $("#flipbook").css("float", "left");
    //$("#flipbook").css("margin-left", "4%");
    $("#flipbook").css("margin-left", "104px");

    $("#flipbook").turn({

        width: 1200, /*1220*/
        height: 876,
        autoCenter: true
    });
    console.log("turn")
    FLIPBOOK.totalPages = $('#flipbook').turn('pages');
    $("#pages-legend").text("1 \\ " + FLIPBOOK.totalPages);

    var posicionSumario = 1;

    if (FLIPBOOK.numeroSentencias > 0) {
        if (FLIPBOOK.rangoSentencias) {
            $("#nav-sentencias").text(posicionSumario + ". " + $("#nav-sentencias").text() + ": " + FLIPBOOK.rangoSentencias);
        }
        $("a#nav-sentencias").css("display", "block");
        posicionSumario = posicionSumario + 1;
    }
    else {
        $("a#nav-sentencias").css("display", "none");
    }

    if (FLIPBOOK.numeroDeclaraciones > 0) {
        if (FLIPBOOK.rangoDeclaraciones) {
            $("#nav-declaraciones").text(posicionSumario + ". " + $("#nav-declaraciones").text() + ": " + FLIPBOOK.rangoDeclaraciones);
        }
        $("a#nav-declaraciones").css("display", "block");
        posicionSumario = posicionSumario + 1;
    }
    else {
        $("a#nav-declaraciones").css("display", "none");
    }

    if (FLIPBOOK.numeroAutos > 0) {
        if (FLIPBOOK.rangoAutos) {
            $("#nav-autos").text(posicionSumario + ". " + $("#nav-autos").text() + ": " + FLIPBOOK.rangoAutos);
        }
        $("a#nav-autos").css("display", "block");
        posicionSumario = posicionSumario + 1;
    }
    else {
        $("a#nav-autos").css("display", "none");
    }

    for (var i = 1; i <= 5; i++) {
        if (BOOKMARKS["indice" + i]) {
            if (FLIPBOOK.rangoSentencias || FLIPBOOK.rangoDeclaraciones || FLIPBOOK.rangoAutos) {
                $("a#nav-indice" + i).text(posicionSumario + ". " + $("a#nav-indice" + i).text());
            }
            $("a#nav-indice" + i).css("display", "block");
            posicionSumario = posicionSumario + 1;
        }
        else {
            $("a#nav-indice" + i).css("display", "none");
        }
    }

    if (FLIPBOOK.rangoSentencias || FLIPBOOK.rangoDeclaraciones || FLIPBOOK.rangoAutos) {
        $("a#nav-da").text(posicionSumario + ". " + $("a#nav-da").text());
    }

    $("a#nav-da").css("display", "block");


    var end = new Date().getTime();
    var tiempoTurn = end - start;
    //console.log('Tiempo de turn.js: ' + tiempoTurn);
    //console.log("Número de páginas generadas: " + FLIPBOOK.totalPages);       
    // Evento que controla el paso de páginas, si hay páginas dinámicas va cargando páginas conforme sea menester
    $("#flipbook").bind("turned", function (event, page, view) {

        if ($("#pages-legend").text().indexOf('-') == -1) {
            var PA = $("#pages-legend").text().substring(0, $("#pages-legend").text().indexOf('\\'));
        }
        else {
            var PA = $("#pages-legend").text().substring($("#pages-legend").text().indexOf('-') + 1, $("#pages-legend").text().indexOf('\\')).trim();// $("#pages-legend").text().substring(0, $("#pages-legend").text().indexOf('-'));
        }


        if (PA == page || (PA == page || PA == page + 1))//  FLIPBOOK.totalPages || page -1 >= FLIPBOOK.totalPages)// || PA - 1 == FLIPBOOK.totalPages)
        {
            // console.log("paso por aqui")
            //No poner sonido de paso de página
        }
        else if (PA == page || PA == page + 1)//(PA >= page && (PA == FLIPBOOK.totalPages || PA == FLIPBOOK.totalPages + 1))// && (PA == FLIPBOOK.totalPages || PA == FLIPBOOK.totalPages-1)))
        {
            // console.log("paso por aqui2")
        }
        else if (PA > page) {
            sonidoPagina("anterior", $("#pages-legend").text());
        }
        else {
            sonidoPagina("siguiente", $("#pages-legend").text());
        }


        if (page == 1) {
            $("#pages-legend").text("1 \\ " + FLIPBOOK.totalPages);
        }
        else {
            if (page % 2 == 1)
                page--;

            $("#pages-legend").text(page + "-" + (page + 1) + " \\ " + FLIPBOOK.totalPages);
        }

        changePagesSize($("#pages-legend").text());

        if (page < FLIPBOOK.paginaSentencias) {
            resolucionVisibleIndex = -1;
        }

        /* Si estamos en el sumario y se cargó una página extra durante una navegación anterior, la quitamos*/
        if (resolucionVisibleIndex == -1 && extraPage) {
            manageExtraPage();
        }

        /* Caso especial de estar hojeando el título inicial de sentencias, hay que asegurarse de precargar la primera sentencia */
        if (FLIPBOOK.paginaSentencias - 4 <= page && page < FLIPBOOK.paginaSentencias) {
            insertResolutionsMinimumPages(0, 4);

            resolucionVisibleIndex = -1;
        }

        /* Cuando se está pasando del sumario a las sentencias hay que asegurarse de precargar la primera sentencia
        y de poner que la resolución visible es la 0 */
        if (resolucionVisibleIndex == -1 && FLIPBOOK.listaResoluciones.length > 0 && FLIPBOOK.listaResoluciones[0].loaded) {
            var paginaPrimeraResolucion = FLIPBOOK.listaResoluciones[0].page;
            if (paginaPrimeraResolucion & 1) {
                paginaPrimeraResolucion--;
            }

            if (paginaPrimeraResolucion != page) return;

            resolucionVisibleIndex = 0;

            if (!FLIPBOOK.listaResoluciones[1].loaded) {
                insertResolutionsMinimumPages(1, 4);
            }

            return;
        }

        if (page >= FLIPBOOK.paginaTituloIndices) {
            if (!FLIPBOOK.listaResoluciones[FLIPBOOK.listaResoluciones.length - 1].loaded) {
                /* Es imposible cargar contenido antes de la página actual, así que cambiamos a la página 1,
                cargamos contenido y luego volvemos a cargar la página "equivalente" a donde estábamos */
                $('#flipbook').turn('page', 1).turn('stop');

                var numPagesLoaded = insertResolutionsMinimumPagesBackwards(FLIPBOOK.listaResoluciones.length - 1, 4, mostrarCabecera);

                if (!FLIPBOOK.listaResoluciones[FLIPBOOK.listaResoluciones.length - 2].loaded) {
                    numPagesLoaded += insertResolutionsMinimumPagesBackwards(FLIPBOOK.listaResoluciones.length - 2, 4, mostrarCabecera);
                }

                // Si el número de páginas generadas es impar consideramos la página extra
                var extra = 0;
                if (numPagesLoaded & 1) {
                    extra = manageExtraPage();
                }

                $('#flipbook').turn('page', page + numPagesLoaded + extra).turn('stop');
            }

            resolucionVisibleIndex = FLIPBOOK.listaResoluciones.length;
            return;
        }

        if (page < FLIPBOOK.paginaTituloIndices - 1 && resolucionVisibleIndex >= FLIPBOOK.listaResoluciones.length) {
            resolucionVisibleIndex = FLIPBOOK.listaResoluciones.length - 1;
        }

        // page señala que se están hojeando secciones que no requieren precarga
        // o el índice de resolución visualizada es absurdo (o sea, no se está visualizando una resolución)
        if (resolucionVisibleIndex < 0 || resolucionVisibleIndex >= FLIPBOOK.listaResoluciones.length
            || page < FLIPBOOK.paginaSentencias || page >= FLIPBOOK.paginaTituloIndides)
            return;

        var resolucionData = FLIPBOOK.listaResoluciones[resolucionVisibleIndex];
        if (!resolucionData.loaded) // No debería ocurrir nunca
            return;

        // Caso de que se esté hojeando hacia atrás
        if (resolucionVisibleIndex > 0 && page < resolucionData.page) {
            resolucionVisibleIndex--;
            //console.log("resolucionVisibleIndex Final: " + resolucionVisibleIndex);
            if (resolucionVisibleIndex <= 0)
                return;

            // Miramos si las resoluciones anteriores están cargadas ya
            if (!needToLoadBackwards(resolucionVisibleIndex))
                return;

            /* Es imposible cargar contenido antes de la página actual, así que cambiamos a la página 1,
            cargamos contenido y luego volvemos a cargar la página "equivalente" a donde estábamos */
            $('#flipbook').turn('page', 1).turn('stop');

            var numPagesLoaded = insertResolutionsMinimumPagesBackwards(resolucionVisibleIndex - 1, 4);

            // Si el número de páginas generadas es impar consideramos la página extra
            var extra = 0;
            if (numPagesLoaded & 1) {
                extra = manageExtraPage();
            }

            //console.log("después de inserción, page: " + page + " numPagesLoaded: " + numPagesLoaded + " extra: " + extra);
            $('#flipbook').turn('page', page + numPagesLoaded + extra).turn('stop');
        }
            // Caso de si estamos ojeando hacia adelante
        else if (page >= resolucionData.page + resolucionData.numPages) {
            resolucionVisibleIndex++;
            if (resolucionVisibleIndex >= FLIPBOOK.listaResoluciones.length - 1)
                return;
            // Miramos si las resoluciones posteriores están cargardas ya
            if (!needToLoadForwards(resolucionVisibleIndex))
                return;

            insertResolutionsMinimumPages(resolucionVisibleIndex + 1, 4);
        }
    });
}

// Evento general para elementos clickables que muestran una resolución (y sus resoluciones adyacentes si es carga dinámica)
$('body').on('click', '.link', function () {
    var destinyPage = $('#flipbook').turn('page');
    pageHistory.push($("#flipbook").turn("page"));
    $("#nav-back").attr("disabled", false);

    $('#flipbook').turn('page', 1).turn('stop');
    var linkType = $(this).attr("data-link-type");
    var link = $(this).attr("data-link");

    if (linkType == "resolucionHJ") {
        var ruta = 'http://hj.tribunalconstitucional.es/es/Resolucion/Show/' + link;

        window.open(ruta, "_blank");
    }
    else
        if (linkType == "resolucion") {
            var idResolucion = parseInt(link, 10);
            var indexResolucion = FLIPBOOK.resolucionIDToIndex[idResolucion];

            insertResolutionsMinimumPages(indexResolucion, 4);

            if (indexResolucion > 0) {
                insertResolutionsMinimumPagesBackwards(indexResolucion - 1, 4);
            }

            if (indexResolucion < FLIPBOOK.listaResoluciones.length - 1) {
                insertResolutionsMinimumPages(indexResolucion + 1, 4);
            }

            resolucionVisibleIndex = indexResolucion;
            destinyPage = FLIPBOOK.listaResoluciones[indexResolucion].page;
        }
            //else if (linkType == "descriptor") {
            //    destinyPage = FLIPBOOK.paginaDescriptores + BOOKMARKS[link];
            //}
        else if (linkType == "descriptorAlfabetico") {
            destinyPage = FLIPBOOK.paginaDescriptoresAlfabetico + BOOKMARKS[link];
        }
        else if (linkType == "indice") {
            destinyPage = FLIPBOOK.paginaTituloIndices + BOOKMARKS[link];
        }
            //else if (linkType == "voces") {
            //    destinyPage = FLIPBOOK.paginaVoces + BOOKMARKS[link];
            //}
        else if (linkType == "sumario") {
            destinyPage = FLIPBOOK.paginaSumario + BOOKMARKS[link];
        }
        else if (BOOKMARKS[link]) {
            destinyPage = BOOKMARKS[link];
        }

    $('#flipbook').turn('page', destinyPage);
})

// Tras cargar una resolución, se actualizan los números de página de los elementos del tomo
// Si indexResolucion vale -1 se actualizan todos los valores
function updatePageNumbers(indexResolucion, numPages) {
    if (indexResolucion == -1) {
        FLIPBOOK.paginaSentencias += numPages;
    }

    if (indexResolucion == -1 || FLIPBOOK.listaResoluciones[indexResolucion].tipoResolucion == "SENTENCIA") {
        FLIPBOOK.paginaAutos += numPages;
    }

    for (var i = indexResolucion + 1; i < FLIPBOOK.listaResoluciones.length; i++) {
        if (FLIPBOOK.listaResoluciones[i].loaded) {
            FLIPBOOK.listaResoluciones[i].page += numPages;
        }
    }

    FLIPBOOK.paginaTituloIndices += numPages;
    //FLIPBOOK.paginaVoces += numPages;
    //FLIPBOOK.paginaDescriptores += numPages;
    FLIPBOOK.paginaDescriptoresAlfabetico += numPages;
}

// Calcula la página donde la resolución FLIPBOOK[indexResolucion] NO cargada debería ir
function calculateInsertionPoint(indexResolucion) {
    var insertionPoint = 0;
    var resolucionData = FLIPBOOK.listaResoluciones[indexResolucion];
    var i;
    for (i = indexResolucion + 1; i < FLIPBOOK.listaResoluciones.length; i++) {
        if (FLIPBOOK.listaResoluciones[i].tipoResolucion != resolucionData.tipoResolucion) {
            break;
        }
        if (FLIPBOOK.listaResoluciones[i].loaded) {
            return FLIPBOOK.listaResoluciones[i].page;
        }
    }

    for (i = indexResolucion - 1; i >= 0; i--) {
        if (FLIPBOOK.listaResoluciones[i].tipoResolucion != resolucionData.tipoResolucion) {
            break;
        }
        if (FLIPBOOK.listaResoluciones[i].loaded) {
            return FLIPBOOK.listaResoluciones[i].page + FLIPBOOK.listaResoluciones[i].numPages;
        }
    }

    return (resolucionData.tipoResolucion == "SENTENCIA" ? FLIPBOOK.paginaSentencias : (resolucionData.tipoResolucion == "AUTO" ? FLIPBOOK.paginaAutos : FLIPBOOK.paginaDeclaraciones));
}

// Chequea si las resoluciones previas están cargadas
function needToLoadBackwards(indexResolucion) {
    var numPagesPreLoaded = 0;
    for (var i = indexResolucion - 1; i >= 0; i--) {
        var resolucionData = FLIPBOOK.listaResoluciones[i];
        if (!resolucionData.loaded)
            return true;

        numPagesPreLoaded += resolucionData.numPages;
        if (numPagesPreLoaded >= 4)
            break;
    }

    return false;
}

// Chequea si las resoluciones posteriores están cargadas
function needToLoadForwards(indexResolucion) {
    var numPagesPreLoaded = 0;
    for (var i = indexResolucion + 1; i < FLIPBOOK.listaResoluciones.length; i++) {
        var resolucionData = FLIPBOOK.listaResoluciones[i];
        if (!resolucionData.loaded)
            return true;

        numPagesPreLoaded += resolucionData.numPages;
        if (numPagesPreLoaded >= 4)
            break;
    }

    return false;
}

//// Inserta una resolución en el tomo
//function insertResolutionPreload(resolucionIndex, resolutionData, page, empezarEnPaginaNueva) {
//    var numPages = generateFlipBook(resolutionData, "#flipbook", 'S', 1, empezarEnPaginaNueva);

//    resolutionData.page = page;
//    resolutionData.numPages = numPages;
//    resolutionData.loaded = true;

//    return numPages;
//}

// Inserta una resolución en el tomo de forma dinámica y actualiza las páginas del resto de elementos
function insertResolution(resolucionIndex, resolutionData, page, mostrarCabecera) {
    var numPages = insertContent(resolutionData, page, mostrarCabecera);

    resolutionData.page = page;
    resolutionData.numPages = numPages;
    resolutionData.loaded = true;

    updatePageNumbers(resolucionIndex, numPages);

    return numPages;
}

// Se asegura de insertar resoluciones hasta que se cumpla un mínimo de páginas insertadas
function insertResolutionsMinimumPages(indexToLoad, minimumPages) {
    var resolucionDataNext = FLIPBOOK.listaResoluciones[indexToLoad];
    var numPagesLoaded = 0;
    var numPagesPreLoaded = 0;
    do {
        if (!resolucionDataNext.loaded) {
            numPagesLoaded += insertResolution(indexToLoad, resolucionDataNext, calculateInsertionPoint(indexToLoad));
        }
        numPagesPreLoaded += resolucionDataNext.numPages;
        indexToLoad++;
        if (indexToLoad >= FLIPBOOK.listaResoluciones.length)
            break;
        resolucionDataNext = FLIPBOOK.listaResoluciones[indexToLoad];
    } while (numPagesPreLoaded < minimumPages);

    return numPagesLoaded;
}

// Se asegura de insertar resoluciones en dirección inversa hasta que se cumpla un mínimo de páginas insertadas
function insertResolutionsMinimumPagesBackwards(indexToLoad, minimumPages, mostrarCabecera) {
    var resolucionDataNext = FLIPBOOK.listaResoluciones[indexToLoad];
    var numPagesLoaded = 0;
    var numPagesPreLoaded = 0;
    do {
        if (!resolucionDataNext.loaded) {
            numPagesLoaded += insertResolution(indexToLoad, resolucionDataNext, calculateInsertionPoint(indexToLoad), mostrarCabecera);
        }
        numPagesPreLoaded += resolucionDataNext.numPages;
        indexToLoad--;
        if (indexToLoad < 0)
            break;
        resolucionDataNext = FLIPBOOK.listaResoluciones[indexToLoad];
    } while (numPagesPreLoaded < minimumPages);

    return numPagesLoaded;
}

// Quita o pone la página extra que se añade en caso de que alguna carga de contenido dinámico contenga páginas impares
function manageExtraPage() {
    if (extraPage) {
        $("#flipbook").turn("removePage", FLIPBOOK.paginaSentencias - 1);
        updatePageNumbers(-1, -1);
        extraPage = false;
        return -1;
    }
    else {
        var totalPages = $('#flipbook').turn('pages');
        var paginaRaw = '<div class="pagina"></div>';
        var pagina = $(paginaRaw);
        $("#sideflipbook").append(pagina);
        $('#flipbook').turn('pages', totalPages + 1);
        $("#flipbook").turn("addPage", pagina, FLIPBOOK.paginaSentencias);
        pagina.remove();
        updatePageNumbers(-1, 1);
        extraPage = true;
        return 1;
    }
}

// Inserta un contenido cualquiera comenzando en la página indicada
// data debe tener el formato correcto y page debe ser un número de página comprendido entre 1 y el número de páginas actuales del tomo
function insertContent(data, page) {
    var totalPages = $('#flipbook').turn('pages');
    generateFlipBook(data, "#sideflipbook", 'S');
    var newPages = $("#sideflipbook .pagina").length;
    $('#flipbook').turn('pages', totalPages + newPages);
    $("#sideflipbook .pagina").each(function () {
        $("#flipbook").turn("addPage", $(this), page++);
        $(this).remove();
    });

    return newPages;
}

//var paginaContinuar;
//var paginaActual;
//var debug = false;
// Genera páginas para un flipbook que cuelgan del div indicado según data
//function generateFlipBook(data, divFlipBook, mostrarCabecera, bookmarkReference, empezarEnPaginaNueva) {
//    var paginaRaw = '<div class="pagina"></div>';
//    var parrafoRaw = '<p class="parrafo"></p>';
//    var cabeceraLinea = '<p class="entrada-cabecera"><span class="line-separator"></span></p>';
//    var cabeceraAno = '<p class="entrada-cabecera-anno"><span class="texto-cabecera-zona-derecha">' + annoCabecera + '</span></p>';
//    var cabeceraCentral = '<p class="entrada-cabecera-titulo"><span class="texto-cabecera-zona-central">Gaceta de jurisprudencia constitucional</span></p>';       
//    var cabeceraSemestre = '<p class="entrada-cabecera-semestre"><span class="texto-cabecera-zona-derecha">' + semestreCabecera + '</span></p>';
//    var cabeceraLineaAbajo = '<p class="entrada-cabecera-fin"><span class="line-separator-abajo"></span></p>';
//    var imgRaw = '<img/>';
//    var esIndiceJerarquico = (data.esJerarquico != null && data.esJerarquico == "true") ? true : false;
//    var indiceJerarquicoDescriptor = "<p class='parrafo entrada-descriptores-jerarquico subirTitulo'><span class='titulo-numero-descriptores-jerarquico'>Descriptor Nº</span></p>"//'<p class="parrafo"><span>Descriptor Nº</span></p>';

//    var pagina = $(paginaRaw);
//    var parrafo;
//    var previousHeight = 0;
//    //var h = 0;
//    paginaActual = bookmarkReference ? bookmarkReference : 1;

//    if (typeof (empezarEnPaginaNueva) === 'undefined') empezarEnPaginaNueva = true;

//    if (empezarEnPaginaNueva) {
//        $(divFlipBook).append(pagina);

//        if (mostrarCabecera == 'S') {
//            pagina.append($(cabeceraLinea));
//            pagina.append($(cabeceraAno));
//            pagina.append($(cabeceraCentral));
//            pagina.append($(cabeceraSemestre));
//            pagina.append($(cabeceraLineaAbajo));
//        }
//    }
//    else {
//        pagina = paginaContinuar;
//        previousHeight = calculatePageHeight(pagina);
//    }

//    for (var index in data.listaItems) {
//        var item = data.listaItems[index];

//        /* casos raros */
//        // Salto de página                
//        if (item.newPage) {
//            pagina = $(paginaRaw);
//            $(divFlipBook).append(pagina);

//            if (mostrarCabecera == 'S') {
//                pagina.append($(cabeceraLinea));
//                pagina.append($(cabeceraAno));
//                pagina.append($(cabeceraCentral));
//                pagina.append($(cabeceraSemestre));
//                pagina.append($(cabeceraLineaAbajo));
//            }

//            if (esIndiceJerarquico) {
//                pagina.append($(indiceJerarquicoDescriptor));
//            }
//            paginaActual++;
//            continue;
//        }
//        // Varios intros seguidos
//        if (item.consecutiveCarriageReturns > 0) {
//            parrafo = $(parrafoRaw);
//            pagina.append(parrafo);
//            parrafo.css("height", 10 * item.consecutiveCarriageReturns);
//            continue;
//        }
//        /* fin de casos raros */

//        if (item.newParagraph) {
//            parrafo = $(parrafoRaw);
//            pagina.append(parrafo);
//            if (item.keepWithText) {
//                parrafo.addClass("keep-with-text");
//            }
//        }
//        parrafo.addClass(item.paragraphCssClass);

//        var span = itemToSpan(item);
//        // imágenes
//        if (item.imgURL) {
//            var img = $(imgRaw);
//            img.attr("src", item.imgURL);
//            img.addClass(item.imgCssClass);
//            span.append(img);
//        }
//        // hipervínculos
//        if (item.link || item.linkType) {
//            span.addClass("link");
//            span.attr("data-link", item.link);
//            span.attr("data-link-type", item.linkType);
//        }

//        parrafo.append(span);

//        var h = calculatePageHeight(pagina);
//        while (h >= MAXPAGINA) {// || previousHeight >= MAXPAGINA) {                    
//            // Quitamos esta clase si existe al principio de la página
//            pagina.children().first().removeClass("parrafo-junto-posterior");

//            if (previousHeight > MINPAGINA) {
//                pagina.children().last().remove();
//                pagina = $(paginaRaw);
//                $(divFlipBook).append(pagina);
//                paginaActual++;

//                var ultimoParrafoPaginaAnterior = pagina.prev().children().last();
//                if (ultimoParrafoPaginaAnterior.hasClass("keep-with-text"))// || previousHeight + 20 >= MAXPAGINA)// ||(!ultimoParrafoPaginaAnterior.hasClass("keep-with-text") && h > previousHeight)) {// && (previousHeight + 10 < MAXPAGINA)) {
//                {
//                    ultimoParrafoPaginaAnterior.remove();

//                    //traer texto sobrante de la anterior página
//                    if (mostrarCabecera == 'S') {
//                        pagina.append($(cabeceraLinea));
//                        pagina.append($(cabeceraAno));
//                        pagina.append($(cabeceraCentral));
//                        pagina.append($(cabeceraSemestre));
//                        pagina.append($(cabeceraLineaAbajo));
//                    }

//                    if (esIndiceJerarquico) {
//                        pagina.append($(indiceJerarquicoDescriptor));
//                    }
//                    pagina.append(ultimoParrafoPaginaAnterior);
//                    pagina.append(parrafo);
//                }
//                else {
//                    if (mostrarCabecera == 'S') {
//                        pagina.append($(cabeceraLinea));
//                        pagina.append($(cabeceraAno));
//                        pagina.append($(cabeceraCentral));
//                        pagina.append($(cabeceraSemestre));
//                        pagina.append($(cabeceraLineaAbajo));
//                    }

//                    if (esIndiceJerarquico) {
//                        pagina.append($(indiceJerarquicoDescriptor));
//                    }

//                    pagina.append(parrafo);
//                }
//            }
//            else {
//                var ultimoSpan = parrafo.children().last();
//                var text = ultimoSpan.html();
//                var previous = ultimoSpan.prev();

//                ultimoSpan.html("");
//                text = fixText(pagina, ultimoSpan, text);

//                var hayCabeceraRosaSola = previous.length > 0 && previous.next().text().length == 0;
//                // forzamos justificado en el último parrafo de la página anterior
//                if (hayCabeceraRosaSola) {
//                    parrafo.html("");
//                }
//                else {
//                    parrafo.addClass("fulljustify");
//                }

//                // añadimos nueva página
//                pagina = $(paginaRaw);
//                $(divFlipBook).append(pagina);

//                paginaActual++;
//                // creamos y añadimos párrafo con el texto restante
//                debug = false;
//                if (text && text.length > 0) {
//                    parrafo = $(parrafoRaw);
//                    parrafo.addClass(item.paragraphCssClass);
//                    if (hayCabeceraRosaSola) {
//                        parrafo.append(previous);
//                    }
//                    parrafo.append(ultimoSpan.clone().html(text));
//                }

//                var ultimoParrafoPaginaAnterior = pagina.prev().children().last();

//                if (ultimoParrafoPaginaAnterior.text()) {
//                    if (mostrarCabecera == 'S') {
//                        pagina.append($(cabeceraLinea));
//                        pagina.append($(cabeceraAno));
//                        pagina.append($(cabeceraCentral));
//                        pagina.append($(cabeceraSemestre));
//                        pagina.append($(cabeceraLineaAbajo));
//                    }

//                    if (esIndiceJerarquico) {
//                        pagina.append($(indiceJerarquicoDescriptor));
//                    }

//                    pagina.append(parrafo);
//                    parrafo.addClass("parrafo-partido");
//                }
//                else if (ultimoParrafoPaginaAnterior.prev().hasClass("keep-with-text")) {
//                    // Se supone que parte del párrafo se ha quedado en la página anterior y parte en la siguiente,
//                    // pero si el párrafo sólo tiene una línea, se acaba moviendo a la página siguiente dejando
//                    // un párrafo en blanco en la página anterior (o sea, ultimoParrafoPaginaAnterior.text() evalua a false)
//                    ultimoParrafoPaginaAnterior.remove();
//                    ultimoParrafoPaginaAnterior = pagina.prev().children().last();
//                    ultimoParrafoPaginaAnterior.remove();

//                    if (mostrarCabecera == 'S') {
//                        pagina.append($(cabeceraLinea));
//                        pagina.append($(cabeceraAno));
//                        pagina.append($(cabeceraCentral));
//                        pagina.append($(cabeceraSemestre));
//                        pagina.append($(cabeceraLineaAbajo));
//                    }

//                    if (esIndiceJerarquico) {
//                        pagina.append($(indiceJerarquicoDescriptor));
//                    }

//                    pagina.append(ultimoParrafoPaginaAnterior);

//                    // creamos y añadimos párrafo con el texto restante
//                    pagina.append(parrafo);
//                }
//                else {
//                    if (mostrarCabecera == 'S') {
//                        pagina.append($(cabeceraLinea));
//                        pagina.append($(cabeceraAno));
//                        pagina.append($(cabeceraCentral));
//                        pagina.append($(cabeceraSemestre));
//                        pagina.append($(cabeceraLineaAbajo));
//                    }
//                    if (esIndiceJerarquico) {
//                        pagina.append($(indiceJerarquicoDescriptor));
//                    }

//                    pagina.append(parrafo);
//                }
//            }

//            // Volvemos a calcular la altura de la página para que h guarde la altura de la página actual
//            h = calculatePageHeight(pagina);
//            previousHeight = 0;
//        }

//        // Quitamos esta clase si existe de la página
//        pagina.children().first().removeClass("parrafo-junto-posterior");

//        if (item.bookmark) {
//            BOOKMARKS[item.bookmark] = paginaActual;
//        }
//        previousHeight = h;
//        empezarEnPaginaNueva = true;
//    }

//    data.listaItems = null;
//    paginaContinuar = pagina;
//    return paginaActual;
//}

//// Función que intenta dividir un párrafo sucesivamente para ajustarlo al final de la página
//// Ajusta el párrafo y devuelve el texto que debería ir en la página siguiente
//function fixText(pagina, span, text) {
//    // Si el texto es demasiado corto (menos de una línea), se deja como está (y para evitar recursión infinita)
//    //if (span.html().length + text.length < MINIMUMCHARACTERSPERLINE) {
//    if (text.length < MINIMUMCHARACTERSPERLINE) {
//        return text;
//    }

//    var dividedText = divideTextInTwo(text);
//    //if (dividedText[0] == "") {
//    //    dividedText[0] == dividedText[1];
//    //}

//    dividedText = checkLineLength(dividedText, span);
//    if (debug) {
//        console.log(dividedText);
//    }
//    if (!dividedText[1] || dividedText[1] == "") {
//        return dividedText[0];
//        //return "";
//    }

//    dividedText = checkMarkings(dividedText);
//    // Si tenía un spam antes añadimos un espacio

//    var previousContent = span.html();
//    if (span.html().length > 0) {
//        //dividedText[0] = " " + dividedText[0];
//        span.html(span.html() + " " + dividedText[0]);
//    }
//    else {
//        span.html(dividedText[0]);
//    }
//    var h = calculatePageHeight(pagina);
//    if (h <= MINPAGINA) {
//        if (debug) {
//            console.log("caso 1");
//            console.log(span);
//            console.log(dividedText[1]);
//        }
//        return fixText(pagina, span, dividedText[1]);
//    }
//    else if (h >= MAXPAGINA) {
//        if (debug) {
//            console.log("caso 2");
//            console.log(span.html());
//        }
//        /*if (span.html().length < MINIMUMCHARACTERSPERLINE) {                    
//            return dividedText[1];
//        }*/
//        if (debug) {
//            console.log("caso 2bis");
//        }
//        span.html(previousContent);
//        if (debug) {
//            console.log(previousContent);
//            console.log(span.html());
//            console.log(dividedText[0]);
//        }

//        return fixText(pagina, span, dividedText[0]) + " " + dividedText[1];
//    }
//    else { // (MINPAGINA < h && h < MAXPAGINA)
//        if (debug) {
//            console.log("caso 3");
//            console.log(dividedText[1]);
//        }
//        return dividedText[1];
//    }
//}

//function checkLineLength(dividedText, span) {
//    while (true) {

//        if (dividedText[0].length > MINIMUMCHARACTERSPERLINE || span.siblings().length > 0) {
//            var previousBlank = span.html().length > 0 ? " " : "";
//            var previousContent = span.html();
//            span.html(span.html() + previousBlank + dividedText[0]);
//            // Recogemos el valor de la altura con el texto actual
//            var actualheight = span.parent().height();
//            span.html(previousContent);
//            // Realizamos la misma operación anterior, pero descontando un número de caracteres constante para ver si disminuye el número de líneas (la altura)
//            var truncatedText = dividedText[0].substring(0, dividedText[0].length - MINIMUMCHARACTERSPERLINE);
//            span.html(span.html() + previousBlank + truncatedText);
//            var newheight = span.parent().height();
//            span.html(previousContent);

//            // Si ambas alturas son iguales, entonces está todo bien y devolvemos el texto sin tocar
//            if (actualheight == newheight)
//                return dividedText;
//        }

//        // Cortamos una palabra de dividedText[1] y lo pasamos a dividedText[0] y repetimos bucle
//        var dividePosition = dividedText[1].indexOf(' ');
//        if (dividePosition > 0) {
//            var word = dividedText[1].substring(0, dividePosition);
//            if (word == "<a") {
//                var finLink = dividedText[1].indexOf("</a>");
//                word = dividedText[1].substring(0, finLink + 4);
//                dividePosition = finLink + 4;
//            }

//            dividedText[0] += " " + word;
//            dividedText[1] = dividedText[1].substring(dividePosition + 1);
//        }
//        else if (dividePosition == -1) { // dividedText[1] se ha quedado con una palabra solo... no debería pasar nunca
//            dividedText[0] += " " + dividedText[1];
//            dividedText[1] = "";
//            return dividedText;
//        }
//        else { // dividePosition == 0 ???, no debería pasar nunca, significaría un espacio al comienzo del texto (divideTextByTwo no debería consentir esto)
//            return dividedText;
//        }
//    }
//}

//// Función auxiliar de la anterior que divide un texto por la mitad (aproximadamente) sin cortar palabras
//function divideTextInTwo(text) {
//    var dividePosition = text.lastIndexOf(' ', text.length >> 1);
//    var dividedtext = new Array();
//    dividedtext.push(text.substring(0, dividePosition));
//    dividedtext.push(text.substring(dividePosition + 1));

//    if (dividedtext[1].indexOf("</a>") != -1) {
//        var index = 0;

//        if (dividedtext[0].substr(dividedtext[0].length - 2, 2) == "<a") {
//            index = dividedtext[0].length - 2;
//        }
//        else {
//            for (var i = dividedtext[0].length - 1; i >= 2; i--) {
//                if (dividedtext[0].substr(i - 2, 3) == "</a") { // falsa alarma
//                    return dividedtext;
//                }

//                if (dividedtext[0].substr(i - 2, 3) == "<a ") {
//                    index = i - 2;
//                    break;
//                }
//            }
//        }

//        if (index > 0) {
//            dividedtext[1] = dividedtext[0].substring(index) + " " + dividedtext[1];
//            dividedtext[0] = dividedtext[0].substring(0, index);
//        }
//    }

//    return dividedtext;
//}

//var pattern = /<\/?[a-z]+>/g;
//// Chequea la presencia de marcas y añade marcas si es necesario
//function checkMarkings(dividedText) {
//    var theMatch = dividedText[0].match(pattern);
//    if (theMatch) { // Si no hay coincidencias theMatch vale null
//        var lastTag = theMatch[theMatch.length - 1];
//        if (lastTag[1] != "/") { // Aquí se testa si lastTag es una tag de apertura buscando que su segundo carácter no sea "/"
//            dividedText[0] += lastTag.substring(0, 1) + "/" + lastTag.substring(1);
//            dividedText[1] = lastTag + dividedText[1];
//        }
//    }
//    return dividedText;
//}

//function itemToSpan(flipBookItem) {
//    return $('<span class="' + flipBookItem.cssClass + '">' + flipBookItem.text + '</span>');
//}

// Función auxiliar que calcula la altura de una página que se está construyendo
//function calculatePageHeight(pagina) {
//    var h = 0;
//    pagina.children().each(function () {
//        h += $(this).height() + parseInt($(this).css("padding-bottom"), 10) + parseInt($(this).css("padding-top"), 10) + parseInt($(this).css("margin-bottom"), 10) + parseInt($(this).css("margin-top"), 10);
//    });
//    return h;
//}

anchoImagen = 40;
var tomeID = $("#hfTomeID").val();
if (tomeID) {
    $("#flipbook").css("visible", "false");
    loadTome(tomeID);

    $("#flipbook").css("visible", "true");
}






//$("#wrapper").css("background-color", "rgba(235, 235, 235, 1)");
//var MINPAGINA = 780;//795;
//var MAXPAGINA = 800;//820
//var MINIMUMCHARACTERSPERLINE = 60;
var BOOKMARKS = {};
var FLIPBOOK = {};
var resolucionVisibleIndex = -1;
var extraPage = false;
// Navegación
var pageHistory = [];
// Variables para el precargado
var loaded = false; // Indica al phantomJS si se ha terminado de cargar el tomo
var success = false; // Indica al phantomJS si todo ha ido bien en el lado del servidor
//var totalRenderTime; // Para debug, indica el tiempo total de renderizado en cliente

var sonido = document.getElementById("sonido");
var paginacionActual = 1;
var anchoImagen = 1;


$(document).ready(function () {
    $("#hojasDer").click(function () {
        //console.log("pulsada imagen")
        goTo($("#flipbook").turn("page") + 2);
        //sonido.play();
        //console.log("despues de sonido")
    });

    $("#hojasIzq").click(function () {
       // console.log("pulsada imagen")
        goTo($("#flipbook").turn("page") - 2);
        //sonido.play();
       // console.log("despues de sonido")
    });
     

    $("#hojasDer").mousemove(function (e) {
       //// var elemento = $("#hojasDer");
       //// var posicion = elemento.position();
       //// console.log("left: " + posicion.left + ", top: " + posicion.top + ", right: " + posicion.right);

       // var offset = $(this).offset();

       // event.stopPropagation();
       // var right = $(window).width() - $(this).width();
       // right = offset.left - right;
       // console.log( this.tagName +" coords ( " + offset.left + ", " + right + " )" );



       // var x = e.pageX - this.offsetLeft;
       // var y = e.pageY - this.offsetTop;
       // console.log("--------------------------x: " + x);
       // console.log("--------------------------y: " + y);
       //// $('#status2').html(x + ', ' + y);
    });
});


//Funcion que muestra el div en la posicion del mouse

function showdiv(event) {

    ////determina un margen de pixels del div al raton

    //margin = 5;



    ////La variable IE determina si estamos utilizando IE

    //var IE = document.all ? true : false;

    ////Si no utilizamos IE capturamos el evento del mouse

    //if (!IE) document.captureEvents(Event.MOUSEMOVE)



    //var tempX = 0;

    //var tempY = 0;



    //if (IE) { //para IE

    //    tempX = event.clientX + document.body.scrollLeft;

    //    tempY = event.clientY + document.body.scrollTop;

    //} else { //para netscape

    //    tempX = event.pageX;

    //    tempY = event.pageY;

    //}

    //if (tempX < 0) { tempX = 0; }

    //if (tempY < 0) { tempY = 0; }



    ////modificamos el valor del id posicion para indicar la posicion del mouse

    //document.getElementById('posicion').innerHTML = "PosX = " + tempX + " | PosY = " + tempY;



    //document.getElementById('flotante').style.top = (tempY + margin);

    //document.getElementById('flotante').style.left = (tempX + margin);

    //document.getElementById('flotante').style.display = 'block';

    //return;

}




function changePagesSize(pageActual) {
    //console.log("total paginas:" + FLIPBOOK.totalPages);
    //console.log("paginación: " + $("#pages-legend").text());
    //console.log("paginaciónActualchangepagessize: " + pageActual);//$("#pages-legend").text());
    //if (paginacionActual == null) {
    //    var paginacion = $("#pages-legend").text().toString();
    //}
    //else {
    var paginacion = pageActual.toString();
    //}
    var totalPaginas = FLIPBOOK.totalPages;
    if (paginacion.indexOf('-') != -1) {
        var paginaActual = paginacion.substring(0, paginacion.indexOf('-'));
    }
    else {
        var paginaActual = 1;
    }

    //console.log('2----------------------' + pageActual)
    ////sonidoPagina(undefined, pageActual);
    ////alert (paginaActual)
    //console.log("paginacion: " + paginacion);
    //console.log("paginaActual: " + paginaActual);
    //console.log("anchoImagen " + anchoImagen)
    //console.log($("#hojasDer").width());
    //console.log(paginaActual / totalPaginas);
    //// var anchuraImagenDer = $("#hojasDer").width();
    //console.log(anchoImagen - ((paginaActual / totalPaginas) * anchoImagen / 100));
    ////$("#hojasDer").width(anchoImagen - (paginaActual / totalPaginas) * anchoImagen);
    //// $("#hojasDer").attr("left", 1000);
    //console.log("anchura después de asignar " + $("#hojasDer").width());

    // $("#hojasDer").offset().left = $("#hojasDer").offset() + 10;
    var anchuraDerecha = anchoImagen - (paginaActual / totalPaginas) * anchoImagen;
    var anchuraIzquierda = (paginaActual / totalPaginas) * anchoImagen;
    if (paginaActual >= totalPaginas - 20 && paginaActual < totalPaginas-1 && anchuraDerecha < 1)
    {
        anchuraDerecha = 1;
    }
    if (paginaActual != 1 && paginaActual <= 50 && anchuraIzquierda < 1) {
        anchuraIzquierda = 1;
    }
    $("#hojasDer").css("width", anchuraDerecha );// $("#hojasDer").css('width').replace('px', '') - 10);

    $("#hojasIzq").css("width", anchuraIzquierda);//anchoImagen - (paginaActual / totalPaginas) * anchoImagen);

    var anchoDiferencia = anchoImagen - (paginaActual / totalPaginas) * anchoImagen;
    //console.log("anchoDiferencia " + anchoDiferencia)
    $("#divHojaIzq").css("left", 235 + anchoDiferencia);//239


    $("#hojasIzq").css("display", "block");
   // console.log("anchura después de asignar " + $("#hojasDer").width()); 
}

// Funciones de navegación
function goTo(basePage, bookmark, id) {
    //console.log("goTo: " + basePage + " " + bookmark + " " + BOOKMARKS[bookmark]);            
    var destiny = basePage;
    if (bookmark && BOOKMARKS[bookmark]) {
        destiny += BOOKMARKS[bookmark];
        pageHistory.push($("#flipbook").turn("page"));
        $("#nav-back").attr("disabled", false);
    }
    if (destiny <= 0) {
        destiny = 1;
    }
    if (destiny > FLIPBOOK.totalPages) {
        destiny = FLIPBOOK.totalPages;
    }
    $("#flipbook").turn("page", destiny);


    //para que se marque en que sección estamos dentro del libro
    $(".menu").each(function (index, value) {
        var idEnlace = $(this).attr("id");
        if (idEnlace == id) {
            $(this).css({ 'color': 'green', 'font-size': '13px' });
        }
        else {
            $(this).css({ 'color': 'black', 'font-size': '12px' });
        }
    });  
}

function sonidoPagina(direccion, pageActual)
{
    //console.log(direccion)
    //console.log($("#pages-legend").text());
    var paginaActual = pageActual.substring(0, pageActual.indexOf(' '));//$("#pages-legend").text().substring(0, $("#pages-legend").text().indexOf(' '));
    var paginaFin = pageActual.substring($("#pages-legend").text().indexOf('-') + 1, pageActual.indexOf('\\')).trim();//$("#pages-legend").text().substring($("#pages-legend").text().indexOf('-') + 1, $("#pages-legend").text().indexOf('\\')).trim();
    //console.log(paginaFin)
    //console.log(FLIPBOOK.totalPages)
    if ((direccion == undefined && (paginaActual == '1' || paginaFin >= FLIPBOOK.totalPages)) || (direccion != undefined && ((direccion == 'anterior' && paginaActual == '1') || (direccion == 'siguiente' && paginaFin >= FLIPBOOK.totalPages)))) //'anterior' 'siguiente'//(direccion != undefined && ((direccion == 'anterior' && destiny == 1) || (direccion == 'siguiente' && destiny == FLIPBOOK.totalPages))) //'anterior' 'siguiente'
    {
        //console.log ("sin sonido")
        return false;
    }
    else //if (direccion != undefined)
    {
        //console.log("con sonido")
        sonido.play();
    }   
}

function goBack() {
    $("#flipbook").turn("page", pageHistory.pop());
    if (pageHistory.length == 0) {
        $("#nav-back").attr("disabled", true);
    }
}

// A esta función se la llama al final, si procede (cuando el campo oculto está definido)
function loadTome(tomeID) {
    CURRENT_LANG = "es-ES";
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: REALPATH + CURRENT_LANG + "/Tomo/GetTomoFlipBook",
        data: "{'tomoID': '" + tomeID + "'}",
        dataType: "html",
        async: true,
        success: function (data) {
            var start = new Date().getTime();
            var sidebar = $("#contenedorPaginadorTomo .flipbook-sidebar");
            FLIPBOOK = JSON.parse(data.lastIndexOf('FLIPBOOK = JSON.parse') + 22, data.length - 10);

            data = data.replace("../DynamicData/Content/Images/escudo.png", "../../../../Content/css/themes/redmond/images/escudoTC.png");

            $("#contenedorPaginadorTomo").html(data);
            $("#contenedorPaginadorTomo").append($("<div id='sideflipbook'></div>")); // Por si acaso
            $("#contenedorPaginadorTomo").prepend(sidebar);
            var end = new Date().getTime();

            //console.log("Tiempo de carga de las páginas: " + (end - start));

            initFlipBook();           
        },
        error: function (result) {
            alert("Debido a un error inesperado no podemos cargar los datos");
        }
    });
}


// Llama a la librería turn.js para la creación del flipbook (asume que hay páginas cargadas en #flipbook)
function initFlipBook() {
    var start = new Date().getTime();
    $("#flipbook").removeClass("cargando");

    $("#flipbook").css("float", "left");
    //$("#flipbook").css("margin-left", "4%");
    $("#flipbook").css("margin-left", "104px");

    $("#flipbook").turn({
        width: 1200,/*1220*/
        height: 876,
        autoCenter: true
    });

    FLIPBOOK.totalPages = $('#flipbook').turn('pages');
    $("#pages-legend").text("1 \\ " + FLIPBOOK.totalPages);

    var posicionSumario = 1;

    if (FLIPBOOK.numeroSentencias > 0) {
        if (FLIPBOOK.rangoSentencias) {
            $("#nav-sentencias").text(posicionSumario + ". " + $("#nav-sentencias").text() + ": " + FLIPBOOK.rangoSentencias);
        }
        $("a#nav-sentencias").css("display", "block");
        posicionSumario = posicionSumario + 1;
    }
    else {
        $("a#nav-sentencias").css("display", "none");
    }

    if (FLIPBOOK.numeroDeclaraciones > 0) {
        if (FLIPBOOK.rangoDeclaraciones) {
            $("#nav-declaraciones").text(posicionSumario + ". " + $("#nav-declaraciones").text() + ": " + FLIPBOOK.rangoDeclaraciones);
        }
        $("a#nav-declaraciones").css("display", "block");
        posicionSumario = posicionSumario + 1;
    }
    else {
        $("a#nav-declaraciones").css("display", "none");
    }

    if (FLIPBOOK.numeroAutos > 0) {
        if (FLIPBOOK.rangoAutos) {
            $("#nav-autos").text(posicionSumario + ". " + $("#nav-autos").text() + ": " + FLIPBOOK.rangoAutos);
        }
        $("a#nav-autos").css("display", "block");
        posicionSumario = posicionSumario + 1;
    }
    else {
        $("a#nav-autos").css("display", "none");
    }

    for (var i = 1; i <= 5; i++) {
        if (BOOKMARKS["indice" + i]) {
            if (FLIPBOOK.rangoSentencias || FLIPBOOK.rangoDeclaraciones || FLIPBOOK.rangoAutos) {
                $("a#nav-indice" + i).text(posicionSumario + ". " + $("a#nav-indice" + i).text());
            }
            $("a#nav-indice" + i).css("display", "block");
            posicionSumario = posicionSumario + 1;
        }
        else {
            $("a#nav-indice" + i).css("display", "none");
        }
    }

    if (FLIPBOOK.rangoSentencias || FLIPBOOK.rangoDeclaraciones || FLIPBOOK.rangoAutos) {
        $("a#nav-da").text(posicionSumario + ". " + $("a#nav-da").text());
    }

    $("a#nav-da").css("display", "block");
    posicionSumario = posicionSumario + 1;

    if (FLIPBOOK.rangoSentencias || FLIPBOOK.rangoDeclaraciones || FLIPBOOK.rangoAutos) {
        $("a#nav-acronimos").text(posicionSumario + ". " + $("a#nav-acronimos").text());
    }
    $("a#nav-acronimos").css("display", "block");


    var end = new Date().getTime();
    var tiempoTurn = end - start;
    //alert('Tiempo de turn.js: ' + tiempoTurn);
    //console.log("Número de páginas generadas: " + FLIPBOOK.totalPages);

    // Evento que controla el paso de páginas, si hay páginas dinámicas va cargando páginas conforme sea menester
    $("#flipbook").bind("turned", function (event, page, view) {
        //vane
        //var actual = 
        //console.log ($("#pages-legend").text());
       // var paginaAlaqueVa =
        //console.log(page);
        if ($("#pages-legend").text().indexOf('-') == -1) {
            var PA = $("#pages-legend").text().substring(0, $("#pages-legend").text().indexOf('\\'));
        }
        else
        {
            var PA = $("#pages-legend").text().substring($("#pages-legend").text().indexOf('-') + 1, $("#pages-legend").text().indexOf('\\')).trim();// $("#pages-legend").text().substring(0, $("#pages-legend").text().indexOf('-'));
        }
        //console.log(PA)
        //console.log(FLIPBOOK.totalPages)
        if (PA == page || (PA == page || PA == page + 1))//  FLIPBOOK.totalPages || page -1 >= FLIPBOOK.totalPages)// || PA - 1 == FLIPBOOK.totalPages)
        {
           // console.log("paso por aqui")
            //No poner sonido de paso de página
        }
        else if (PA== page || PA == page +1)//(PA >= page && (PA == FLIPBOOK.totalPages || PA == FLIPBOOK.totalPages + 1))// && (PA == FLIPBOOK.totalPages || PA == FLIPBOOK.totalPages-1)))
        {
           // console.log("paso por aqui2")
        }
        else if (PA > page) {
            sonidoPagina("anterior", $("#pages-legend").text());
        }
        else
        {
            sonidoPagina("siguiente", $("#pages-legend").text());
        }
        if (page == 1) {
            $("#pages-legend").text("1 \\ " + FLIPBOOK.totalPages);
        }
        else {
            if (page % 2 == 1)
                page--;

            $("#pages-legend").text(page + "-" + (page + 1) + " \\ " + FLIPBOOK.totalPages);
        }
        //console.log("dando a la función las paginas: " + $("#pages-legend").text());
        //alert (page)
        changePagesSize($("#pages-legend").text());

        if (page < FLIPBOOK.paginaSentencias) {
            resolucionVisibleIndex = -1;
        }

        /* Si estamos en el sumario y se cargó una página extra durante una navegación anterior, la quitamos*/
        if (resolucionVisibleIndex == -1 && extraPage) {
            manageExtraPage();
        }

        /* Caso especial de estar hojeando el título inicial de sentencias, hay que asegurarse de precargar la primera sentencia */
        if (FLIPBOOK.paginaSentencias - 4 <= page && page < FLIPBOOK.paginaSentencias) {
            insertResolutionsMinimumPages(0, 4);

            resolucionVisibleIndex = -1;
        }

        /* Cuando se está pasando del sumario a las sentencias hay que asegurarse de precargar la primera sentencia
        y de poner que la resolución visible es la 0 */
        if (resolucionVisibleIndex == -1 && FLIPBOOK.listaResoluciones[0].loaded) {
            var paginaPrimeraResolucion = FLIPBOOK.listaResoluciones[0].page;
            if (paginaPrimeraResolucion & 1) {
                paginaPrimeraResolucion--;
            }

            if (paginaPrimeraResolucion != page) return;

            resolucionVisibleIndex = 0;

            if (!FLIPBOOK.listaResoluciones[1].loaded) {
                insertResolutionsMinimumPages(1, 4);
            }

            return;
        }

        if (page >= FLIPBOOK.paginaTituloIndices) {
            if (!FLIPBOOK.listaResoluciones[FLIPBOOK.listaResoluciones.length - 1].loaded) {
                /* Es imposible cargar contenido antes de la página actual, así que cambiamos a la página 1,
                cargamos contenido y luego volvemos a cargar la página "equivalente" a donde estábamos */
                $('#flipbook').turn('page', 1).turn('stop');

                var numPagesLoaded = insertResolutionsMinimumPagesBackwards(FLIPBOOK.listaResoluciones.length - 1, 4);

                if (!FLIPBOOK.listaResoluciones[FLIPBOOK.listaResoluciones.length - 2].loaded) {
                    numPagesLoaded += insertResolutionsMinimumPagesBackwards(FLIPBOOK.listaResoluciones.length - 2, 4);
                }

                // Si el número de páginas generadas es impar consideramos la página extra
                var extra = 0;
                if (numPagesLoaded & 1) {
                    extra = manageExtraPage();
                }

                $('#flipbook').turn('page', page + numPagesLoaded + extra).turn('stop');
            }

            resolucionVisibleIndex = FLIPBOOK.listaResoluciones.length;
            return;
        }

        if (page < FLIPBOOK.paginaTituloIndices - 1 && resolucionVisibleIndex >= FLIPBOOK.listaResoluciones.length) {
            resolucionVisibleIndex = FLIPBOOK.listaResoluciones.length - 1;
        }

        // page señala que se están ojeando secciones que no requieren precarga
        // o el índice de resolución visualizada es absurdo (o sea, no se está visualizando una resolución)
        if (resolucionVisibleIndex < 0 || resolucionVisibleIndex >= FLIPBOOK.listaResoluciones.length
            || page < FLIPBOOK.paginaSentencias || page >= FLIPBOOK.paginaTituloIndides)
            return;

        var resolucionData = FLIPBOOK.listaResoluciones[resolucionVisibleIndex];
        if (!resolucionData.loaded) // No debería ocurrir nunca
            return;

        // Caso de que se esté ojeando hacia atrás
        if (resolucionVisibleIndex > 0 && page < resolucionData.page) {
            resolucionVisibleIndex--;
            //console.log("resolucionVisibleIndex Final: " + resolucionVisibleIndex);
            if (resolucionVisibleIndex <= 0)
                return;

            // Miramos si las resoluciones anteriores están cargadas ya
            if (!needToLoadBackwards(resolucionVisibleIndex))
                return;

            /* Es imposible cargar contenido antes de la página actual, así que cambiamos a la página 1,
            cargamos contenido y luego volvemos a cargar la página "equivalente" a donde estábamos */
            $('#flipbook').turn('page', 1).turn('stop');

            var numPagesLoaded = insertResolutionsMinimumPagesBackwards(resolucionVisibleIndex - 1, 4);

            // Si el número de páginas generadas es impar consideramos la página extra
            var extra = 0;
            if (numPagesLoaded & 1) {
                extra = manageExtraPage();
            }

            //console.log("después de inserción, page: " + page + " numPagesLoaded: " + numPagesLoaded + " extra: " + extra);
            $('#flipbook').turn('page', page + numPagesLoaded + extra).turn('stop');
        }
            // Caso de si estamos ojeando hacia adelante
        else if (page >= resolucionData.page + resolucionData.numPages) {
            resolucionVisibleIndex++;
            if (resolucionVisibleIndex >= FLIPBOOK.listaResoluciones.length - 1)
                return;
            // Miramos si las resoluciones posteriores están cargardas ya
            if (!needToLoadForwards(resolucionVisibleIndex))
                return;

            insertResolutionsMinimumPages(resolucionVisibleIndex + 1, 4);
        }
    });
}

// Evento general para elementos clickables que muestran una resolución (y sus resoluciones adyacentes si es carga dinámica)
$('body').on('click', '.link', function () {
    var destinyPage = $('#flipbook').turn('page');
    pageHistory.push($("#flipbook").turn("page"));
    $("#nav-back").attr("disabled", false);

    $('#flipbook').turn('page', 1).turn('stop');
    var linkType = $(this).attr("data-link-type");
    var link = $(this).attr("data-link");

    if (linkType == "resolucion") {
        var idResolucion = parseInt(link, 10);
        var indexResolucion = FLIPBOOK.resolucionIDToIndex[idResolucion];

        insertResolutionsMinimumPages(indexResolucion, 4);

        if (indexResolucion > 0) {
            insertResolutionsMinimumPagesBackwards(indexResolucion - 1, 4);
        }

        if (indexResolucion < FLIPBOOK.listaResoluciones.length - 1) {
            insertResolutionsMinimumPages(indexResolucion + 1, 4);
        }

        resolucionVisibleIndex = indexResolucion;
        destinyPage = FLIPBOOK.listaResoluciones[indexResolucion].page;
    }
    //else if (linkType == "descriptor") {
    //    destinyPage = FLIPBOOK.paginaDescriptores + BOOKMARKS[link];
    //}
    else if (linkType == "descriptorAlfabetico") {
        destinyPage = FLIPBOOK.paginaDescriptoresAlfabetico + BOOKMARKS[link];
    }
    else if (linkType == "abreviaturas") {
        destinyPage = FLIPBOOK.paginaAbreviaturas + BOOKMARKS[link];
    }
    else if (linkType == "indice") {
        destinyPage = FLIPBOOK.paginaTituloIndices + BOOKMARKS[link];
    }
    //else if (linkType == "voces") {
    //    destinyPage = FLIPBOOK.paginaVoces + BOOKMARKS[link];
    //}
    else if (linkType == "sumario") {
        destinyPage = FLIPBOOK.paginaSumario + BOOKMARKS[link];
    }
    else if (BOOKMARKS[link]) {
        destinyPage = BOOKMARKS[link];
    }

    $('#flipbook').turn('page', destinyPage);
})

// Tras cargar una resolución, se actualizan los números de página de los elementos del tomo
// Si indexResolucion vale -1 se actualizan todos los valores
function updatePageNumbers(indexResolucion, numPages) {
    if (indexResolucion == -1) {
        FLIPBOOK.paginaSentencias += numPages;
    }

    if (indexResolucion == -1 || FLIPBOOK.listaResoluciones[indexResolucion].tipoResolucion == "SENTENCIA") {
        FLIPBOOK.paginaDeclaraciones += numPages;
    }

    if (indexResolucion == -1 || FLIPBOOK.listaResoluciones[indexResolucion].tipoResolucion == "SENTENCIA" || FLIPBOOK.listaResoluciones[indexResolucion].tipoResolucion == "AUTO") {
        FLIPBOOK.paginaDeclaraciones += numPages;
    }

    for (var i = indexResolucion + 1; i < FLIPBOOK.listaResoluciones.length; i++) {
        if (FLIPBOOK.listaResoluciones[i].loaded) {
            FLIPBOOK.listaResoluciones[i].page += numPages;
        }
    }

    FLIPBOOK.paginaTituloIndices += numPages;
    // FLIPBOOK.paginaVoces += numPages;
    //FLIPBOOK.paginaDescriptores += numPages;
    FLIPBOOK.paginaDescriptoresAlfabetico += numPages;
    FLIPBOOK.paginaAbreviaturas += numPages;
}

// Calcula la página donde la resolución FLIPBOOK[indexResolucion] NO cargada debería ir
function calculateInsertionPoint(indexResolucion) {
    var insertionPoint = 0;
    var resolucionData = FLIPBOOK.listaResoluciones[indexResolucion];
    var i;
    for (i = indexResolucion + 1; i < FLIPBOOK.listaResoluciones.length; i++) {
        if (FLIPBOOK.listaResoluciones[i].tipoResolucion != resolucionData.tipoResolucion) {
            break;
        }
        if (FLIPBOOK.listaResoluciones[i].loaded) {
            return FLIPBOOK.listaResoluciones[i].page;
        }
    }

    for (i = indexResolucion - 1; i >= 0; i--) {
        if (FLIPBOOK.listaResoluciones[i].tipoResolucion != resolucionData.tipoResolucion) {
            break;
        }
        if (FLIPBOOK.listaResoluciones[i].loaded) {
            return FLIPBOOK.listaResoluciones[i].page + FLIPBOOK.listaResoluciones[i].numPages;
        }
    }

    return (resolucionData.tipoResolucion == "SENTENCIA" ? FLIPBOOK.paginaSentencias : FLIPBOOK.paginaAutos) + 1;
}

// Chequea si las resoluciones previas están cargadas
function needToLoadBackwards(indexResolucion) {
    var numPagesPreLoaded = 0;
    for (var i = indexResolucion - 1; i >= 0; i--) {
        var resolucionData = FLIPBOOK.listaResoluciones[i];
        if (!resolucionData.loaded)
            return true;

        numPagesPreLoaded += resolucionData.numPages;
        if (numPagesPreLoaded >= 4)
            break;
    }

    return false;
}

// Chequea si las resoluciones posteriores están cargadas
function needToLoadForwards(indexResolucion) {
    var numPagesPreLoaded = 0;
    for (var i = indexResolucion + 1; i < FLIPBOOK.listaResoluciones.length; i++) {
        var resolucionData = FLIPBOOK.listaResoluciones[i];
        if (!resolucionData.loaded)
            return true;

        numPagesPreLoaded += resolucionData.numPages;
        if (numPagesPreLoaded >= 4)
            break;
    }

    return false;
}

// Inserta una resolución en el tomo
function insertResolutionPreload(resolucionIndex, resolutionData, page) {
    var numPages = generateFlipBook(resolutionData, "#flipbook");

    resolutionData.page = page;
    resolutionData.numPages = numPages;
    resolutionData.loaded = true;

    return numPages;
}

// Inserta una resolución en el tomo de forma dinámica y actualiza las páginas del resto de elementos
function insertResolution(resolucionIndex, resolutionData, page) {
    var numPages = insertContent(resolutionData, page);

    resolutionData.page = page;
    resolutionData.numPages = numPages;
    resolutionData.loaded = true;

    updatePageNumbers(resolucionIndex, numPages);

    return numPages;
}

// Se asegura de insertar resoluciones hasta que se cumpla un mínimo de páginas insertadas
function insertResolutionsMinimumPages(indexToLoad, minimumPages) {
    var resolucionDataNext = FLIPBOOK.listaResoluciones[indexToLoad];
    var numPagesLoaded = 0;
    var numPagesPreLoaded = 0;
    do {
        if (!resolucionDataNext.loaded) {
            numPagesLoaded += insertResolution(indexToLoad, resolucionDataNext, calculateInsertionPoint(indexToLoad));
        }
        numPagesPreLoaded += resolucionDataNext.numPages;
        indexToLoad++;
        if (indexToLoad >= FLIPBOOK.listaResoluciones.length)
            break;
        resolucionDataNext = FLIPBOOK.listaResoluciones[indexToLoad];
    } while (numPagesPreLoaded < minimumPages);

    return numPagesLoaded;
}

// Se asegura de insertar resoluciones en dirección inversa hasta que se cumpla un mínimo de páginas insertadas
function insertResolutionsMinimumPagesBackwards(indexToLoad, minimumPages) {
    var resolucionDataNext = FLIPBOOK.listaResoluciones[indexToLoad];
    var numPagesLoaded = 0;
    var numPagesPreLoaded = 0;
    do {
        if (!resolucionDataNext.loaded) {
            numPagesLoaded += insertResolution(indexToLoad, resolucionDataNext, calculateInsertionPoint(indexToLoad));
        }
        numPagesPreLoaded += resolucionDataNext.numPages;
        indexToLoad--;
        if (indexToLoad < 0)
            break;
        resolucionDataNext = FLIPBOOK.listaResoluciones[indexToLoad];
    } while (numPagesPreLoaded < minimumPages);

    return numPagesLoaded;
}

// Quita o pone la página extra que se añade en caso de que alguna carga de contenido dinámico contenga páginas impares
function manageExtraPage() {
    if (extraPage) {
        $("#flipbook").turn("removePage", FLIPBOOK.paginaSentencias - 1);
        updatePageNumbers(-1, -1);
        extraPage = false;
        return -1;
    }
    else {
        var totalPages = $('#flipbook').turn('pages');
        var paginaRaw = '<div class="pagina"></div>';
        var pagina = $(paginaRaw);
        $("#sideflipbook").append(pagina);
        $('#flipbook').turn('pages', totalPages + 1);
        $("#flipbook").turn("addPage", pagina, FLIPBOOK.paginaSentencias);
        pagina.remove();
        updatePageNumbers(-1, 1);
        extraPage = true;
        return 1;
    }
}

// Inserta un contenido cualquiera comenzando en la página indicada
// data debe tener el formato correcto y page debe ser un número de página comprendido entre 1 y el número de páginas actuales del tomo
function insertContent(data, page) {
    var totalPages = $('#flipbook').turn('pages');
    generateFlipBook(data, "#sideflipbook");
    var newPages = $("#sideflipbook .pagina").length;
    $('#flipbook').turn('pages', totalPages + newPages);
    $("#sideflipbook .pagina").each(function () {
        $("#flipbook").turn("addPage", $(this), page++);
        $(this).remove();
    });

    return newPages;
}


//var pattern = /<\/?[a-z]+>/g;
//// Chequea la presencia de marcas y añade marcas si es necesario
//function checkMarkings(dividedText) {
//    var theMatch = dividedText[0].match(pattern);
//    if (theMatch) { // Si no hay coincidencias theMatch vale null
//        var lastTag = theMatch[theMatch.length - 1];
//        if (lastTag[1] != "/") { // Aquí se testa si lastTag es una tag de apertura buscando que su segundo carácter no sea "/"
//            dividedText[0] += lastTag.substring(0, 1) + "/" + lastTag.substring(1);
//            dividedText[1] = lastTag + dividedText[1];
//        }
//    }
//    return dividedText;
//}

//function itemToSpan(flipBookItem) {
//    return $('<span class="' + flipBookItem.cssClass + '">' + flipBookItem.text + '</span>');
//}

anchoImagen = 40;//38$("#hojasDer").width();

var tomeID = $("#hfTomeID").val();
console.log(tomeID);
if (tomeID) {
    loadTome(tomeID);
    $("#flipbook").css("float", "left");
}

/**
 * turn.js 3rd release
 * www.turnjs.com
 *
 * Copyright (C) 2012, Emmanuel Garcia.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * 2. Any redistribution, use, or modification is done solely for personal 
 * benefit and not for any commercial purpose or for monetary gain.
 * 
 **/

(function ($) {

    'use strict';

    var has3d,

	vendor = '',

	PI = Math.PI,

	A90 = PI / 2,

	isTouch = 'ontouchstart' in window,

	events = (isTouch) ? { start: 'touchstart', move: 'touchmove', end: 'touchend' }
			: { start: 'mousedown', move: 'mousemove', end: 'mouseup' },

    // Contansts used for each corner
    // tl * tr
    // *     *
    // bl * br

	corners = {
	    backward: ['bl', 'tl'],
	    forward: ['br', 'tr'],
	    all: ['tl', 'bl', 'tr', 'br']
	},

	displays = ['single', 'double'],

    // Default options

	turnOptions = {

	    // First page

	    page: 1,

	    // Enables gradients

	    gradients: true,

	    // Duration of transition in milliseconds

	    duration: 600,

	    // Enables hardware acceleration

	    acceleration: true,

	    // Display

	    display: 'double',

	    // Events

	    when: null
	},

	flipOptions = {

	    // Back page

	    folding: null,

	    // Corners
	    // backward: Activates both tl and bl corners
	    // forward: Activates both tr and br corners
	    // all: Activates all the corners

	    corners: 'forward',

	    // Size of the active zone of each corner

	    cornerSize: 100,

	    // Enables gradients

	    gradients: true,

	    // Duration of transition in milliseconds

	    duration: 600,

	    // Enables hardware acceleration

	    acceleration: true
	},

    // Number of pages in the DOM, minimum value: 6

	pagesInDOM = 6,

	pagePosition = {
	    0: { top: 0, left: 0, right: 'auto', bottom: 'auto' },
	    1: { top: 0, right: 0, left: 'auto', bottom: 'auto' }
	},

    // Gets basic attributes for a layer

	divAtt = function (top, left, zIndex, overf) {
	    return {
	        'css': {
	            position: 'absolute',
	            top: top,
	            left: left,
	            'overflow': overf || 'hidden',
	            'z-index': zIndex || 'auto'
	        }
	    };
	},

    // Gets a 2D point from a bezier curve of four points

	bezier = function (p1, p2, p3, p4, t) {
	    var mum1 = 1 - t,
			mum13 = mum1 * mum1 * mum1,
			mu3 = t * t * t;

	    return point2D(Math.round(mum13 * p1.x + 3 * t * mum1 * mum1 * p2.x + 3 * t * t * mum1 * p3.x + mu3 * p4.x),
						Math.round(mum13 * p1.y + 3 * t * mum1 * mum1 * p2.y + 3 * t * t * mum1 * p3.y + mu3 * p4.y));
	},

    // Converts an angle from degrees to radians

	rad = function (degrees) {
	    return degrees / 180 * PI;
	},

    // Converts an angle from radians to degrees

	deg = function (radians) {
	    return radians / PI * 180;
	},

    // Gets a 2D point

	point2D = function (x, y) {
	    return { x: x, y: y };
	},

    // Returns the traslate value

	translate = function (x, y, use3d) {
	    return (has3d && use3d) ? ' translate3d(' + x + 'px,' + y + 'px, 0px) ' : ' translate(' + x + 'px, ' + y + 'px) ';
	},

    // Returns the rotation value

	rotate = function (degrees) {
	    return ' rotate(' + degrees + 'deg) ';
	},

    // Checks if a property belongs to an object

	has = function (property, object) {
	    return Object.prototype.hasOwnProperty.call(object, property);
	},

    // Gets the CSS3 vendor prefix

	getPrefix = function () {
	    var vendorPrefixes = ['Moz', 'Webkit', 'Khtml', 'O', 'ms'],
			len = vendorPrefixes.length,
			vendor = '';

	    while (len--)
	        if ((vendorPrefixes[len] + 'Transform') in document.body.style)
	            vendor = '-' + vendorPrefixes[len].toLowerCase() + '-';

	    return vendor;
	},

    // Adds gradients

	gradient = function (obj, p0, p1, colors, numColors) {

	    var j, cols = [];

	    if (vendor == '-webkit-') {

	        for (j = 0; j < numColors; j++)
	            cols.push('color-stop(' + colors[j][0] + ', ' + colors[j][1] + ')');

	        obj.css({ 'background-image': '-webkit-gradient(linear, ' + p0.x + '% ' + p0.y + '%,  ' + p1.x + '% ' + p1.y + '%, ' + cols.join(',') + ' )' });

	    } else {

	        // This procedure makes the gradients for non-webkit browsers
	        // It will be reduced to one unique way for gradients in next versions

	        p0 = { x: p0.x / 100 * obj.width(), y: p0.y / 100 * obj.height() };
	        p1 = { x: p1.x / 100 * obj.width(), y: p1.y / 100 * obj.height() };

	        var dx = p1.x - p0.x,
				dy = p1.y - p0.y,
				angle = Math.atan2(dy, dx),
				angle2 = angle - Math.PI / 2,
				diagonal = Math.abs(obj.width() * Math.sin(angle2)) + Math.abs(obj.height() * Math.cos(angle2)),
				gradientDiagonal = Math.sqrt(dy * dy + dx * dx),
				corner = point2D((p1.x < p0.x) ? obj.width() : 0, (p1.y < p0.y) ? obj.height() : 0),
				slope = Math.tan(angle),
				inverse = -1 / slope,
				x = (inverse * corner.x - corner.y - slope * p0.x + p0.y) / (inverse - slope),
				c = { x: x, y: inverse * x - inverse * corner.x + corner.y },
				segA = (Math.sqrt(Math.pow(c.x - p0.x, 2) + Math.pow(c.y - p0.y, 2)));

	        for (j = 0; j < numColors; j++)
	            cols.push(' ' + colors[j][1] + ' ' + ((segA + gradientDiagonal * colors[j][0]) * 100 / diagonal) + '%');

	        obj.css({ 'background-image': vendor + 'linear-gradient(' + (-angle) + 'rad,' + cols.join(',') + ')' });
	    }
	},

turnMethods = {

    // Singleton constructor
    // $('#selector').turn([options]);

    init: function (opts) {

        // Define constants
        if (has3d === undefined) {
            has3d = 'WebKitCSSMatrix' in window || 'MozPerspective' in document.body.style;
            vendor = getPrefix();
        }

        var i, data = this.data(), ch = this.children();

        opts = $.extend({ width: this.width(), height: this.height() }, turnOptions, opts);
        data.opts = opts;
        data.pageObjs = {};
        data.pages = {};
        data.pageWrap = {};
        data.pagePlace = {};
        data.pageMv = [];
        data.totalPages = opts.pages || 0;

        if (opts.when)
            for (i in opts.when)
                if (has(i, opts.when))
                    this.bind(i, opts.when[i]);


        this.css({ position: 'relative', width: opts.width, height: opts.height });

        this.turn('display', opts.display);

        if (has3d && !isTouch && opts.acceleration)
            this.transform(translate(0, 0, true));

        for (i = 0; i < ch.length; i++)
            this.turn('addPage', ch[i], i + 1);

        this.turn('page', opts.page);

        // allow setting active corners as an option
        corners = $.extend({}, corners, opts.corners);

        // Event listeners

        $(this).bind(events.start, function (e) {
            for (var page in data.pages)
                if (has(page, data.pages) && flipMethods._eventStart.call(data.pages[page], e) === false)
                    return false;
        });

        $(document).bind(events.move, function (e) {
            for (var page in data.pages)
                if (has(page, data.pages))
                    flipMethods._eventMove.call(data.pages[page], e);
        }).
		bind(events.end, function (e) {
		    for (var page in data.pages)
		        if (has(page, data.pages))
		            flipMethods._eventEnd.call(data.pages[page], e);

		});

        data.done = true;

        return this;
    },

    // Adds a page from external data

    addPage: function (element, page) {

        var incPages = false,
			data = this.data(),
			lastPage = data.totalPages + 1;

        if (page) {
            if (page == lastPage) {
                page = lastPage;
                incPages = true;
            } else if (page > lastPage)
                throw new Error('It is impossible to add the page "' + page + '", the maximum value is: "' + lastPage + '"');

        } else {
            page = lastPage;
            incPages = true;
        }

        if (page >= 1 && page <= lastPage) {

            // Stop animations
            if (data.done) this.turn('stop');

            // Move pages if it's necessary
            if (page in data.pageObjs)
                turnMethods._movePages.call(this, page, 1);

            // Update number of pages
            if (incPages)
                data.totalPages = lastPage;

            // Add element
            data.pageObjs[page] = $(element).addClass('turn-page p' + page);

            // Add page
            turnMethods._addPage.call(this, page);

            // Update view
            if (data.done)
                this.turn('update');

            turnMethods._removeFromDOM.call(this);
        }

        return this;
    },

    // Adds a page from internal data

    _addPage: function (page) {

        var data = this.data(),
			element = data.pageObjs[page];

        if (element)
            if (turnMethods._necessPage.call(this, page)) {

                if (!data.pageWrap[page]) {

                    var pageWidth = (data.display == 'double') ? this.width() / 2 : this.width(),
						pageHeight = this.height();

                    element.css({ width: pageWidth, height: pageHeight });

                    // Place
                    data.pagePlace[page] = page;

                    // Wrapper
                    data.pageWrap[page] = $('<div/>', {
                        'class': 'turn-page-wrapper',
                        page: page,
                        css: {
                            position: 'absolute',
                            overflow: 'hidden',
                            width: pageWidth,
                            height: pageHeight
                        }
                    }).
													css(pagePosition[(data.display == 'double') ? page % 2 : 0]);

                    // Append to this
                    this.append(data.pageWrap[page]);

                    // Move data.pageObjs[page] (element) to wrapper
                    data.pageWrap[page].prepend(data.pageObjs[page]);
                }

                // If the page is in the current view, create the flip effect
                if (!page || turnMethods._setPageLoc.call(this, page) == 1)
                    turnMethods._makeFlip.call(this, page);

            } else {

                // Place
                data.pagePlace[page] = 0;

                // Remove element from the DOM
                if (data.pageObjs[page])
                    data.pageObjs[page].remove();

            }

    },

    // Checks if a page is in memory

    hasPage: function (page) {

        return page in this.data().pageObjs;

    },

    // Prepares the flip effect for a page

    _makeFlip: function (page) {

        var data = this.data();

        if (!data.pages[page] && data.pagePlace[page] == page) {

            var single = data.display == 'single',
				even = page % 2;

            data.pages[page] = data.pageObjs[page].
								css({ width: (single) ? this.width() : this.width() / 2, height: this.height() }).
								flip({
								    page: page,
								    next: (single && page === data.totalPages) ? page - 1 : ((even || single) ? page + 1 : page - 1),
								    turn: this,
								    duration: data.opts.duration,
								    acceleration: data.opts.acceleration,
								    corners: (single) ? 'all' : ((even) ? 'forward' : 'backward'),
								    backGradient: data.opts.gradients,
								    frontGradient: data.opts.gradients
								}).
									flip('disable', data.disabled).
									bind('pressed', turnMethods._pressed).
									bind('released', turnMethods._released).
									bind('start', turnMethods._start).
									bind('end', turnMethods._end).
									bind('flip', turnMethods._flip);
        }
        return data.pages[page];
    },

    // Makes pages within a range

    _makeRange: function () {

        var page,
			data = this.data(),
			range = this.turn('range');

        for (page = range[0]; page <= range[1]; page++)
            turnMethods._addPage.call(this, page);

    },

    // Returns a range of `pagesInDOM` pages that should be in the DOM
    // Example:
    // - page of the current view, return true
    // * page is in the range, return true
    // 0 page is not in the range, return false
    //
    // 1 2-3 4-5 6-7 8-9 10-11 12-13
    //    **  **  --   **  **

    range: function (page) {

        var remainingPages, left, right,
			data = this.data();
        page = page || data.tpage || data.page;
        var view = turnMethods._view.call(this, page);

        if (page < 1 || page > data.totalPages)
            throw new Error('"' + page + '" is not a page for range');

        view[1] = view[1] || view[0];

        if (view[0] >= 1 && view[1] <= data.totalPages) {

            remainingPages = Math.floor((pagesInDOM - 2) / 2);

            if (data.totalPages - view[1] > view[0]) {
                left = Math.min(view[0] - 1, remainingPages);
                right = 2 * remainingPages - left;
            } else {
                right = Math.min(data.totalPages - view[1], remainingPages);
                left = 2 * remainingPages - right;
            }

        } else {
            left = pagesInDOM - 1;
            right = pagesInDOM - 1;
        }

        return [Math.max(1, view[0] - left), Math.min(data.totalPages, view[1] + right)];

    },

    // Detects if a page is within the range of `pagesInDOM` from the current view

    _necessPage: function (page) {

        if (page === 0)
            return true;

        var range = this.turn('range');

        return page >= range[0] && page <= range[1];

    },

    // Releases memory by removing pages from the DOM

    _removeFromDOM: function () {

        var page, data = this.data();

        for (page in data.pageWrap)
            if (has(page, data.pageWrap) && !turnMethods._necessPage.call(this, page))
                turnMethods._removePageFromDOM.call(this, page);


    },

    // Removes a page from DOM and its internal references

    _removePageFromDOM: function (page) {

        var data = this.data();

        if (data.pages[page]) {
            var dd = data.pages[page].data();
            if (dd.f && dd.f.fwrapper)
                dd.f.fwrapper.remove();
            data.pages[page].remove();
            delete data.pages[page];
        }

        if (data.pageObjs[page])
            data.pageObjs[page].remove();

        if (data.pageWrap[page]) {
            data.pageWrap[page].remove();
            delete data.pageWrap[page];
        }

        delete data.pagePlace[page];

    },

    // Removes a page

    removePage: function (page) {

        var data = this.data();

        if (data.pageObjs[page]) {
            // Stop animations
            this.turn('stop');

            // Remove `page`
            turnMethods._removePageFromDOM.call(this, page);
            delete data.pageObjs[page];

            // Move the pages behind `page`
            turnMethods._movePages.call(this, page, -1);

            // Resize the size of this magazine
            data.totalPages = data.totalPages - 1;
            turnMethods._makeRange.call(this);

            // Check the current view
            if (data.page > data.totalPages)
                this.turn('page', data.totalPages);
        }

        return this;

    },

    // Moves pages

    _movePages: function (from, change) {

        var page,
			data = this.data(),
			single = data.display == 'single',
			move = function (page) {

			    var next = page + change,
					odd = next % 2;

			    if (data.pageObjs[page])
			        data.pageObjs[next] = data.pageObjs[page].removeClass('page' + page).addClass('page' + next);

			    if (data.pagePlace[page] && data.pageWrap[page]) {
			        data.pagePlace[next] = next;
			        data.pageWrap[next] = data.pageWrap[page].css(pagePosition[(single) ? 0 : odd]).attr('page', next);

			        if (data.pages[page])
			            data.pages[next] = data.pages[page].flip('options', {
			                page: next,
			                next: (single || odd) ? next + 1 : next - 1,
			                corners: (single) ? 'all' : ((odd) ? 'forward' : 'backward')
			            });

			        if (change) {
			            delete data.pages[page];
			            delete data.pagePlace[page];
			            delete data.pageObjs[page];
			            delete data.pageWrap[page];
			            delete data.pageObjs[page];
			        }
			    }
			};

        if (change > 0)
            for (page = data.totalPages; page >= from; page--) move(page);
        else
            for (page = from; page <= data.totalPages; page++) move(page);

    },

    // Sets or Gets the display mode

    display: function (display) {

        var data = this.data(),
			currentDisplay = data.display;

        if (display) {

            if ($.inArray(display, displays) == -1)
                throw new Error('"' + display + '" is not a value for display');

            if (display == 'single') {
                if (!data.pageObjs[0]) {
                    this.turn('stop').
						css({ 'overflow': 'hidden' });
                    data.pageObjs[0] = $('<div />', { 'class': 'turn-page p-temporal' }).
									css({ width: this.width(), height: this.height() }).
										appendTo(this);
                }
            } else {
                if (data.pageObjs[0]) {
                    this.turn('stop').
						css({ 'overflow': '' });
                    data.pageObjs[0].remove();
                    delete data.pageObjs[0];
                }
            }

            data.display = display;

            if (currentDisplay) {
                var size = this.turn('size');
                turnMethods._movePages.call(this, 1, 0);
                this.turn('size', size.width, size.height).
						turn('update');
            }

            return this;

        } else
            return currentDisplay;

    },

    // Detects if the pages are being animated

    animating: function () {

        return this.data().pageMv.length > 0;

    },

    // Disables and enables the effect

    disable: function (bool) {

        var page,
			data = this.data(),
			view = this.turn('view');

        data.disabled = bool === undefined || bool === true;

        for (page in data.pages)
            if (has(page, data.pages))
                data.pages[page].flip('disable', bool ? $.inArray(page, view) : false);

        return this;

    },

    // Gets and sets the size

    size: function (width, height) {

        if (width && height) {

            var data = this.data(), pageWidth = (data.display == 'double') ? width / 2 : width, page;

            this.css({ width: width, height: height });

            if (data.pageObjs[0])
                data.pageObjs[0].css({ width: pageWidth, height: height });

            for (page in data.pageWrap) {
                if (!has(page, data.pageWrap)) continue;
                data.pageObjs[page].css({ width: pageWidth, height: height });
                data.pageWrap[page].css({ width: pageWidth, height: height });
                if (data.pages[page])
                    data.pages[page].css({ width: pageWidth, height: height });
            }

            this.turn('resize');

            return this;

        } else {

            return { width: this.width(), height: this.height() };

        }
    },

    // Resizes each page

    resize: function () {

        var page, data = this.data();

        if (data.pages[0]) {
            data.pageWrap[0].css({ left: -this.width() });
            data.pages[0].flip('resize', true);
        }

        for (page = 1; page <= data.totalPages; page++)
            if (data.pages[page])
                data.pages[page].flip('resize', true);


    },

    // Removes an animation from the cache

    _removeMv: function (page) {

        var i, data = this.data();

        for (i = 0; i < data.pageMv.length; i++)
            if (data.pageMv[i] == page) {
                data.pageMv.splice(i, 1);
                return true;
            }

        return false;

    },

    // Adds an animation to the cache

    _addMv: function (page) {

        var data = this.data();

        turnMethods._removeMv.call(this, page);
        data.pageMv.push(page);

    },

    // Gets indexes for a view

    _view: function (page) {

        var data = this.data();
        page = page || data.page;

        if (data.display == 'double')
            return (page % 2) ? [page - 1, page] : [page, page + 1];
        else
            return [page];

    },

    // Gets a view

    view: function (page) {

        var data = this.data(), view = turnMethods._view.call(this, page);

        return (data.display == 'double') ? [(view[0] > 0) ? view[0] : 0, (view[1] <= data.totalPages) ? view[1] : 0]
				: [(view[0] > 0 && view[0] <= data.totalPages) ? view[0] : 0];

    },

    // Stops animations

    stop: function (ok) {

        var i, opts, data = this.data(), pages = data.pageMv;

        data.pageMv = [];

        if (data.tpage) {
            data.page = data.tpage;
            delete data['tpage'];
        }

        for (i in pages) {
            if (!has(i, pages)) continue;
            opts = data.pages[pages[i]].data().f.opts;
            flipMethods._moveFoldingPage.call(data.pages[pages[i]], null);
            data.pages[pages[i]].flip('hideFoldedPage');
            data.pagePlace[opts.next] = opts.next;

            if (opts.force) {
                opts.next = (opts.page % 2 === 0) ? opts.page - 1 : opts.page + 1;
                delete opts['force'];
            }

        }

        this.turn('update');

        return this;
    },

    // Gets and sets the number of pages

    pages: function (pages) {

        var data = this.data();

        if (pages) {
            if (pages < data.totalPages) {

                for (var page = pages + 1; page <= data.totalPages; page++)
                    this.turn('removePage', page);

                if (this.turn('page') > pages)
                    this.turn('page', pages);
            }

            data.totalPages = pages;

            return this;
        } else
            return data.totalPages;

    },

    // Sets a page without effect

    _fitPage: function (page, ok) {

        var data = this.data(), newView = this.turn('view', page);

        if (data.page != page) {
            this.trigger('turning', [page, newView]);
            if ($.inArray(1, newView) != -1) this.trigger('first');
            if ($.inArray(data.totalPages, newView) != -1) this.trigger('last');
        }

        if (!data.pageObjs[page])
            return;

        data.tpage = page;

        this.turn('stop', ok);
        turnMethods._removeFromDOM.call(this);
        turnMethods._makeRange.call(this);
        this.trigger('turned', [page, newView]);

    },

    // Turns to a page

    _turnPage: function (page) {

        var current, next,
			data = this.data(),
			view = this.turn('view'),
			newView = this.turn('view', page);

        if (data.page != page) {
            this.trigger('turning', [page, newView]);
            if ($.inArray(1, newView) != -1) this.trigger('first');
            if ($.inArray(data.totalPages, newView) != -1) this.trigger('last');
        }

        if (!data.pageObjs[page])
            return;

        data.tpage = page;

        this.turn('stop');

        turnMethods._makeRange.call(this);

        if (data.display == 'single') {
            current = view[0];
            next = newView[0];
        } else if (view[1] && page > view[1]) {
            current = view[1];
            next = newView[0];
        } else if (view[0] && page < view[0]) {
            current = view[0];
            next = newView[1];
        }

        if (data.pages[current]) {

            var opts = data.pages[current].data().f.opts;
            data.tpage = next;

            if (opts && opts.next != next) {
                opts.next = next;
                data.pagePlace[next] = opts.page;
                opts.force = true;
            }

            if (data.display == 'single')
                data.pages[current].flip('turnPage', (newView[0] > view[0]) ? 'br' : 'bl');
            else
                data.pages[current].flip('turnPage');
        }

    },

    // Gets and sets a page

    page: function (page) {

        page = parseInt(page, 10);

        var data = this.data();

        if (page > 0 && page <= data.totalPages) {
            if (!data.done || $.inArray(page, this.turn('view')) != -1)
                turnMethods._fitPage.call(this, page);
            else
                turnMethods._turnPage.call(this, page);

            return this;

        } else
            return data.page;

    },

    // Turns to the next view

    next: function () {

        var data = this.data();
        return this.turn('page', turnMethods._view.call(this, data.page).pop() + 1);

    },

    // Turns to the previous view

    previous: function () {

        var data = this.data();
        return this.turn('page', turnMethods._view.call(this, data.page).shift() - 1);

    },

    // Adds a motion to the internal list

    _addMotionPage: function () {

        var opts = $(this).data().f.opts,
			turn = opts.turn,
			dd = turn.data();

        opts.pageMv = opts.page;
        turnMethods._addMv.call(turn, opts.pageMv);
        dd.pagePlace[opts.next] = opts.page;
        turn.turn('update');

    },

    // This event is called in context of flip

    _start: function (e, opts, corner) {

        var data = opts.turn.data(),
				event = $.Event('start');

        e.stopPropagation();

        opts.turn.trigger(event, [opts, corner]);

        if (event.isDefaultPrevented()) {
            e.preventDefault();
            return;
        }

        if (data.display == 'single') {

            var left = corner.charAt(1) == 'l';
            if ((opts.page == 1 && left) || (opts.page == data.totalPages && !left))
                e.preventDefault();
            else {
                if (left) {
                    opts.next = (opts.next < opts.page) ? opts.next : opts.page - 1;
                    opts.force = true;
                } else
                    opts.next = (opts.next > opts.page) ? opts.next : opts.page + 1;
            }

        }

        turnMethods._addMotionPage.call(this);
    },

    // This event is called in context of flip

    _end: function (e, turned) {

        var that = $(this),
			data = that.data().f,
			opts = data.opts,
			turn = opts.turn,
			dd = turn.data();

        e.stopPropagation();

        if (turned || dd.tpage) {

            if (dd.tpage == opts.next || dd.tpage == opts.page) {
                delete dd['tpage'];
                turnMethods._fitPage.call(turn, dd.tpage || opts.next, true);
            }

        } else {
            //turnMethods._removeMv.call(turn, opts.pageMv);
            turn.turn('update');
        }

    },

    // This event is called in context of flip

    _pressed: function () {

        var page,
			that = $(this),
			data = that.data().f,
			turn = data.opts.turn,
			pages = turn.data().pages;

        for (page in pages)
            if (page != data.opts.page)
                pages[page].flip('disable', true);

        return data.time = new Date().getTime();

    },

    // This event is called in context of flip

    _released: function (e, point) {

        var that = $(this),
			data = that.data().f;

        e.stopPropagation();

        if ((new Date().getTime()) - data.time < 200 || point.x < 0 || point.x > $(this).width()) {
            e.preventDefault();
            data.opts.turn.data().tpage = data.opts.next;
            data.opts.turn.turn('update');
            $(that).flip('turnPage');
        }

    },

    // This event is called in context of flip

    _flip: function () {

        var opts = $(this).data().f.opts;

        opts.turn.trigger('turn', [opts.next]);

    },

    // Calculate the z-index value for pages during the animation

    calculateZ: function (mv) {

        var i, page, nextPage, placePage, dpage,
			that = this,
			data = this.data(),
			view = this.turn('view'),
			currentPage = view[0] || view[1],
			r = { pageZ: {}, partZ: {}, pageV: {} },

			addView = function (page) {
			    var view = that.turn('view', page);
			    if (view[0]) r.pageV[view[0]] = true;
			    if (view[1]) r.pageV[view[1]] = true;
			};

        for (i = 0; i < mv.length; i++) {
            page = mv[i];
            nextPage = data.pages[page].data().f.opts.next;
            placePage = data.pagePlace[page];
            addView(page);
            addView(nextPage);
            dpage = (data.pagePlace[nextPage] == nextPage) ? nextPage : page;
            r.pageZ[dpage] = data.totalPages - Math.abs(currentPage - dpage);
            r.partZ[placePage] = data.totalPages * 2 + Math.abs(currentPage - dpage);
        }

        return r;
    },

    // Updates the z-index and display property of every page

    update: function () {

        var page,
			data = this.data();

        if (data.pageMv.length && data.pageMv[0] !== 0) {

            // Update motion

            var apage,
				pos = this.turn('calculateZ', data.pageMv),
				view = this.turn('view', data.tpage);

            if (data.pagePlace[view[0]] == view[0]) apage = view[0];
            else if (data.pagePlace[view[1]] == view[1]) apage = view[1];

            for (page in data.pageWrap) {

                if (!has(page, data.pageWrap)) continue;

                data.pageWrap[page].css({ display: (pos.pageV[page]) ? '' : 'none', 'z-index': pos.pageZ[page] || 0 });

                if (data.pages[page]) {
                    data.pages[page].flip('z', pos.partZ[page] || null);

                    if (pos.pageV[page])
                        data.pages[page].flip('resize');

                    if (data.tpage)
                        data.pages[page].flip('disable', true); // data.disabled || page!=apage
                }
            }

        } else {

            // Update static pages

            for (page in data.pageWrap) {
                if (!has(page, data.pageWrap)) continue;
                var pageLocation = turnMethods._setPageLoc.call(this, page);
                if (data.pages[page])
                    data.pages[page].flip('disable', data.disabled || pageLocation != 1).flip('z', null);
            }
        }
    },

    // Sets the z-index and display property of a page
    // It depends on the current view

    _setPageLoc: function (page) {

        var data = this.data(),
			view = this.turn('view');

        if (page == view[0] || page == view[1]) {
            data.pageWrap[page].css({ 'z-index': data.totalPages, display: '' });
            return 1;
        } else if ((data.display == 'single' && page == view[0] + 1) || (data.display == 'double' && page == view[0] - 2 || page == view[1] + 2)) {
            data.pageWrap[page].css({ 'z-index': data.totalPages - 1, display: '' });
            return 2;
        } else {
            data.pageWrap[page].css({ 'z-index': 0, display: 'none' });
            return 0;
        }
    }
},

    // Methods and properties for the flip page effect

flipMethods = {

    // Constructor

    init: function (opts) {

        if (opts.gradients) {
            opts.frontGradient = true;
            opts.backGradient = true;
        }

        this.data({ f: {} });
        this.flip('options', opts);

        flipMethods._addPageWrapper.call(this);

        return this;
    },

    setData: function (d) {

        var data = this.data();

        data.f = $.extend(data.f, d);

        return this;
    },

    options: function (opts) {

        var data = this.data().f;

        if (!data)
            return;

        if (opts) {
            flipMethods.setData.call(this, { opts: $.extend({}, data.opts || flipOptions, opts) });
            return this;
        } else
            return data.opts;

    },

    z: function (z) {

        var data = this.data().f;

        if (!data)
            return;

        if (data.opts) {
            data.opts['z-index'] = z;
        }
        if (data.fwrapper) {
            data.fwrapper.css({ 'z-index': z || parseInt(data.parent.css('z-index'), 10) || 0 });
        }

        return this;
    },

    _cAllowed: function () {

        return corners[this.data().f.opts.corners] || this.data().f.opts.corners;

    },

    _cornerActivated: function (e) {
        if (e.originalEvent === undefined) {
            return false;
        }

        e = (isTouch) ? e.originalEvent.touches : [e];

        var data = this.data().f;

        if (!data || !data.parent) return;

        var pos = data.parent.offset(),
			width = this.width(),
			height = this.height(),
			c = { x: Math.max(0, e[0].pageX - pos.left), y: Math.max(0, e[0].pageY - pos.top) },
			csz = data.opts.cornerSize,
			allowedCorners = flipMethods._cAllowed.call(this);

        if (c.x <= 0 || c.y <= 0 || c.x >= width || c.y >= height) return false;

        if (c.y < csz) c.corner = 't';
        else if (c.y >= height - csz) c.corner = 'b';
        else return false;

        if (c.x <= csz) c.corner += 'l';
        else if (c.x >= width - csz) c.corner += 'r';
        else return false;

        return ($.inArray(c.corner, allowedCorners) == -1) ? false : c;

    },

    _c: function (corner, opts) {

        opts = opts || 0;
        return ({
            tl: point2D(opts, opts),
            tr: point2D(this.width() - opts, opts),
            bl: point2D(opts, this.height() - opts),
            br: point2D(this.width() - opts, this.height() - opts)
        })[corner];

    },

    _c2: function (corner) {

        return {
            tl: point2D(this.width() * 2, 0),
            tr: point2D(-this.width(), 0),
            bl: point2D(this.width() * 2, this.height()),
            br: point2D(-this.width(), this.height())
        }[corner];

    },

    _foldingPage: function (corner) {

        var opts = this.data().f.opts;

        if (opts.folding) return opts.folding;
        else if (opts.turn) {
            var data = opts.turn.data();
            if (data.display == 'single')
                return (data.pageObjs[opts.next]) ? data.pageObjs[0] : null;
            else
                return data.pageObjs[opts.next];
        }

    },

    _backGradient: function () {

        var data = this.data().f,
			turn = data.opts.turn,
			gradient = data.opts.backGradient &&
						(!turn || turn.data().display == 'single' || (data.opts.page != 2 && data.opts.page != turn.data().totalPages - 1));


        if (gradient && !data.bshadow)
            data.bshadow = $('<div/>', divAtt(0, 0, 1)).
				css({ 'position': '', width: this.width(), height: this.height() }).
					appendTo(data.parent);

        return gradient;

    },

    resize: function (full) {

        var data = this.data().f,
			width = this.width(),
			height = this.height(),
			size = Math.round(Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)));

        if (!data || !data.parent) return;

        if (full) {
            data.wrapper.css({ width: size, height: size });
            data.fwrapper.css({ width: size, height: size }).
				children(':first-child').
					css({ width: width, height: height });

            data.fpage.css({ width: height, height: width });

            if (data.opts.frontGradient)
                data.ashadow.css({ width: height, height: width });

            if (flipMethods._backGradient.call(this))
                data.bshadow.css({ width: width, height: height });
        }

        if (data.parent.is(':visible')) {
            data.fwrapper.css({
                top: data.parent.offset().top,
                left: data.parent.offset().left
            });

            if (data.opts.turn)
                data.fparent.css({ top: -data.opts.turn.offset().top, left: -data.opts.turn.offset().left });
        }

        this.flip('z', data.opts['z-index']);

    },

    // Prepares the page by adding a general wrapper and another objects

    _addPageWrapper: function () {

        var att,
			data = this.data().f,
			parent = this.parent();

        if (!data) return;

        if (!data.wrapper) {

            var left = this.css('left'),
				top = this.css('top'),
				width = this.width(),
				height = this.height(),
				size = Math.round(Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)));

            data.parent = parent;
            data.fparent = (data.opts.turn) ? data.opts.turn.data().fparent : $('#turn-fwrappers');

            if (!data.fparent) {
                var fparent = $('<div/>', { css: { 'pointer-events': 'none' } }).hide();
                fparent.data().flips = 0;

                if (data.opts.turn) {
                    fparent.css(divAtt(-data.opts.turn.offset().top, -data.opts.turn.offset().left, 'auto', 'visible').css).
							appendTo(data.opts.turn);

                    data.opts.turn.data().fparent = fparent;
                } else {
                    fparent.css(divAtt(0, 0, 'auto', 'visible').css).
						attr('id', 'turn-fwrappers').
							appendTo($('body'));
                }

                data.fparent = fparent;
            }

            this.css({ position: 'absolute', top: 0, left: 0, bottom: 'auto', right: 'auto' });

            data.wrapper = $('<div/>', divAtt(0, 0, this.css('z-index'))).
								appendTo(parent).
									prepend(this);

            data.fwrapper = $('<div/>', divAtt(parent.offset().top, parent.offset().left)).
								hide().
									appendTo(data.fparent);

            data.fpage = $('<div/>', { css: { cursor: 'default' } }).
					appendTo($('<div/>', divAtt(0, 0, 0, 'visible')).
								appendTo(data.fwrapper));

            if (data.opts.frontGradient)
                data.ashadow = $('<div/>', divAtt(0, 0, 1)).
					appendTo(data.fpage);

            // Save data

            flipMethods.setData.call(this, data);

            // Set size
            flipMethods.resize.call(this, true);
        }

    },

    // Takes a 2P point from the screen and applies the transformation

    _fold: function (point) {

        var that = this,
			a = 0,
			alpha = 0,
			beta,
			px,
			gradientEndPointA,
			gradientEndPointB,
			gradientStartV,
			gradientSize,
			gradientOpacity,
			mv = point2D(0, 0),
			df = point2D(0, 0),
			tr = point2D(0, 0),
			width = this.width(),
			height = this.height(),
			folding = flipMethods._foldingPage.call(this),
			tan = Math.tan(alpha),
			data = this.data().f,
			ac = data.opts.acceleration,
			h = data.wrapper.height(),
			o = flipMethods._c.call(this, point.corner),
			top = point.corner.substr(0, 1) == 't',
			left = point.corner.substr(1, 1) == 'l',

			compute = function () {
			    var rel = point2D((o.x) ? o.x - point.x : point.x, (o.y) ? o.y - point.y : point.y),
					tan = (Math.atan2(rel.y, rel.x)),
					middle;

			    alpha = A90 - tan;
			    a = deg(alpha);
			    middle = point2D((left) ? width - rel.x / 2 : point.x + rel.x / 2, rel.y / 2);

			    var gamma = alpha - Math.atan2(middle.y, middle.x),
					distance = Math.max(0, Math.sin(gamma) * Math.sqrt(Math.pow(middle.x, 2) + Math.pow(middle.y, 2)));

			    tr = point2D(distance * Math.sin(alpha), distance * Math.cos(alpha));

			    if (alpha > A90) {

			        tr.x = tr.x + Math.abs(tr.y * Math.tan(tan));
			        tr.y = 0;

			        if (Math.round(tr.x * Math.tan(PI - alpha)) < height) {

			            point.y = Math.sqrt(Math.pow(height, 2) + 2 * middle.x * rel.x);
			            if (top) point.y = height - point.y;
			            return compute();

			        }
			    }

			    if (alpha > A90) {
			        var beta = PI - alpha, dd = h - height / Math.sin(beta);
			        mv = point2D(Math.round(dd * Math.cos(beta)), Math.round(dd * Math.sin(beta)));
			        if (left) mv.x = -mv.x;
			        if (top) mv.y = -mv.y;
			    }

			    px = Math.round(tr.y / Math.tan(alpha) + tr.x);

			    var side = width - px,
					sideX = side * Math.cos(alpha * 2),
					sideY = side * Math.sin(alpha * 2);
			    df = point2D(Math.round((left ? side - sideX : px + sideX)), Math.round((top) ? sideY : height - sideY));


			    // GRADIENTS

			    gradientSize = side * Math.sin(alpha);
			    var endingPoint = flipMethods._c2.call(that, point.corner),
						far = Math.sqrt(Math.pow(endingPoint.x - point.x, 2) + Math.pow(endingPoint.y - point.y, 2));

			    gradientOpacity = (far < width) ? far / width : 1;


			    if (data.opts.frontGradient) {

			        gradientStartV = gradientSize > 100 ? (gradientSize - 100) / gradientSize : 0;
			        gradientEndPointA = point2D(gradientSize * Math.sin(A90 - alpha) / height * 100, gradientSize * Math.cos(A90 - alpha) / width * 100);

			        if (top) gradientEndPointA.y = 100 - gradientEndPointA.y;
			        if (left) gradientEndPointA.x = 100 - gradientEndPointA.x;
			    }

			    if (flipMethods._backGradient.call(that)) {

			        gradientEndPointB = point2D(gradientSize * Math.sin(alpha) / width * 100, gradientSize * Math.cos(alpha) / height * 100);
			        if (!left) gradientEndPointB.x = 100 - gradientEndPointB.x;
			        if (!top) gradientEndPointB.y = 100 - gradientEndPointB.y;
			    }
			    //

			    tr.x = Math.round(tr.x);
			    tr.y = Math.round(tr.y);

			    return true;
			},

			transform = function (tr, c, x, a) {

			    var f = ['0', 'auto'], mvW = (width - h) * x[0] / 100, mvH = (height - h) * x[1] / 100,
					v = { left: f[c[0]], top: f[c[1]], right: f[c[2]], bottom: f[c[3]] },
					aliasingFk = (a != 90 && a != -90) ? (left ? -1 : 1) : 0;

			    x = x[0] + '% ' + x[1] + '%';

			    that.css(v).transform(rotate(a) + translate(tr.x + aliasingFk, tr.y, ac), x);

			    data.fpage.parent().css(v);
			    data.wrapper.transform(translate(-tr.x + mvW - aliasingFk, -tr.y + mvH, ac) + rotate(-a), x);

			    data.fwrapper.transform(translate(-tr.x + mv.x + mvW, -tr.y + mv.y + mvH, ac) + rotate(-a), x);
			    data.fpage.parent().transform(rotate(a) + translate(tr.x + df.x - mv.x, tr.y + df.y - mv.y, ac), x);

			    if (data.opts.frontGradient)
			        gradient(data.ashadow,
							point2D(left ? 100 : 0, top ? 100 : 0),
							point2D(gradientEndPointA.x, gradientEndPointA.y),
							[[gradientStartV, 'rgba(0,0,0,0)'],
							[((1 - gradientStartV) * 0.8) + gradientStartV, 'rgba(0,0,0,' + (0.2 * gradientOpacity) + ')'],
							[1, 'rgba(255,255,255,' + (0.2 * gradientOpacity) + ')']],
							3,
							alpha);

			    if (flipMethods._backGradient.call(that))
			        gradient(data.bshadow,
							point2D(left ? 0 : 100, top ? 0 : 100),
							point2D(gradientEndPointB.x, gradientEndPointB.y),
							[[0.8, 'rgba(0,0,0,0)'],
							[1, 'rgba(0,0,0,' + (0.3 * gradientOpacity) + ')'],
							[1, 'rgba(0,0,0,0)']],
							3);

			};

        switch (point.corner) {
            case 'tl':
                point.x = Math.max(point.x, 1);
                compute();
                transform(tr, [1, 0, 0, 1], [100, 0], a);
                data.fpage.transform(translate(-height, -width, ac) + rotate(90 - a * 2), '100% 100%');
                folding.transform(rotate(90) + translate(0, -height, ac), '0% 0%');
                break;
            case 'tr':
                point.x = Math.min(point.x, width - 1);
                compute();
                transform(point2D(-tr.x, tr.y), [0, 0, 0, 1], [0, 0], -a);
                data.fpage.transform(translate(0, -width, ac) + rotate(-90 + a * 2), '0% 100%');
                folding.transform(rotate(270) + translate(-width, 0, ac), '0% 0%');
                break;
            case 'bl':
                point.x = Math.max(point.x, 1);
                compute();
                transform(point2D(tr.x, -tr.y), [1, 1, 0, 0], [100, 100], -a);
                data.fpage.transform(translate(-height, 0, ac) + rotate(-90 + a * 2), '100% 0%');
                folding.transform(rotate(270) + translate(-width, 0, ac), '0% 0%');
                break;
            case 'br':
                point.x = Math.min(point.x, width - 1);
                compute();
                transform(point2D(-tr.x, -tr.y), [0, 1, 1, 0], [0, 100], a);
                data.fpage.transform(rotate(90 - a * 2), '0% 0%');
                folding.transform(rotate(90) + translate(0, -height, ac), '0% 0%');

                break;
        }

        data.point = point;

    },

    _moveFoldingPage: function (bool) {

        var data = this.data().f,
			folding = flipMethods._foldingPage.call(this);

        if (!data) return;

        if (folding) {
            if (bool) {
                if (!data.fpage.children()[data.ashadow ? '1' : '0']) {
                    flipMethods.setData.call(this, { backParent: folding.parent() });
                    data.fpage.prepend(folding);
                }
            } else {
                if (data.backParent)
                    data.backParent.prepend(folding);

            }
        }

    },

    _showFoldedPage: function (c, animate) {

        var folding = flipMethods._foldingPage.call(this),
			dd = this.data(),
			data = dd.f;

        if (!data.point || data.point.corner != c.corner) {
            var event = $.Event('start');
            this.trigger(event, [data.opts, c.corner]);

            if (event.isDefaultPrevented())
                return false;
        }


        if (folding) {

            if (animate) {

                var that = this, point = (data.point && data.point.corner == c.corner) ? data.point : flipMethods._c.call(this, c.corner, 1);

                this.animatef({
                    from: [point.x, point.y], to: [c.x, c.y], duration: 500, frame: function (v) {
                        c.x = Math.round(v[0]);
                        c.y = Math.round(v[1]);
                        flipMethods._fold.call(that, c);
                    }
                });

            } else {

                flipMethods._fold.call(this, c);
                if (dd.effect && !dd.effect.turning)
                    this.animatef(false);

            }

            if (!data.fwrapper.is(':visible')) {
                data.fparent.show().data().flips++;
                flipMethods._moveFoldingPage.call(this, true);
                data.fwrapper.show();

                if (data.bshadow)
                    data.bshadow.show();
            }

            return true;
        }

        return false;
    },

    hide: function () {

        var data = this.data().f,
			folding = flipMethods._foldingPage.call(this);

        if (!data) return;

        if ((--data.fparent.data().flips) === 0)
            data.fparent.hide();

        this.css({ left: 0, top: 0, right: 'auto', bottom: 'auto' }).transform('', '0% 100%');

        data.wrapper.transform('', '0% 100%');

        data.fwrapper.hide();

        if (data.bshadow)
            data.bshadow.hide();

        folding.transform('', '0% 0%');

        return this;
    },

    hideFoldedPage: function (animate) {

        var data = this.data().f;

        if (!data || !data.point) return;

        var that = this,
			p1 = data.point,
			hide = function () {
			    data.point = null;
			    that.flip('hide');
			    that.trigger('end', [false]);
			};

        if (animate) {
            var p4 = flipMethods._c.call(this, p1.corner),
				top = (p1.corner.substr(0, 1) == 't'),
				delta = (top) ? Math.min(0, p1.y - p4.y) / 2 : Math.max(0, p1.y - p4.y) / 2,
				p2 = point2D(p1.x, p1.y + delta),
				p3 = point2D(p4.x, p4.y - delta);

            this.animatef({
                from: 0,
                to: 1,
                frame: function (v) {
                    var np = bezier(p1, p2, p3, p4, v);
                    p1.x = np.x;
                    p1.y = np.y;
                    flipMethods._fold.call(that, p1);
                },
                complete: hide,
                duration: 800,
                hiding: true
            });

        } else {
            this.animatef(false);
            hide();
        }
    },

    turnPage: function (corner) {

        var that = this,
			data = this.data().f;

        if (!data) return;

        corner = { corner: (data.corner) ? data.corner.corner : corner || flipMethods._cAllowed.call(this)[0] };

        var p1 = data.point || flipMethods._c.call(this, corner.corner, (data.opts.turn) ? data.opts.turn.data().opts.elevation : 0),
			p4 = flipMethods._c2.call(this, corner.corner);

        this.trigger('flip').
				animatef({
				    from: 0,
				    to: 1,
				    frame: function (v) {
				        var np = bezier(p1, p1, p4, p4, v);
				        corner.x = np.x;
				        corner.y = np.y;
				        flipMethods._showFoldedPage.call(that, corner);
				    },

				    complete: function () {
				        that.trigger('end', [true]);
				    },
				    duration: data.opts.duration,
				    turning: true
				});

        data.corner = null;
    },

    moving: function () {

        return 'effect' in this.data();

    },

    isTurning: function () {

        return this.flip('moving') && this.data().effect.turning;

    },

    _eventStart: function (e) {

        var data = this.data().f;

        if (!data)
            return;

        if (!data.disabled && !this.flip('isTurning')) {
            data.corner = flipMethods._cornerActivated.call(this, e);
            if (data.corner && flipMethods._foldingPage.call(this, data.corner)) {
                flipMethods._moveFoldingPage.call(this, true);
                this.trigger('pressed', [data.point]);
                return false;
            } else
                data.corner = null;
        }

    },

    _eventMove: function (e) {

        var data = this.data().f;

        if (!data)
            return;

        if (!data.disabled) {
            e = (isTouch) ? e.originalEvent.touches : [e];

            if (data.corner) {

                var pos = data.parent.offset();

                data.corner.x = e[0].pageX - pos.left;
                data.corner.y = e[0].pageY - pos.top;

                flipMethods._showFoldedPage.call(this, data.corner);

            } else if (!this.data().effect && this.is(':visible')) { // roll over

                var corner = flipMethods._cornerActivated.call(this, e[0]);
                if (corner) {
                    var origin = flipMethods._c.call(this, corner.corner, data.opts.cornerSize / 2);
                    corner.x = origin.x;
                    corner.y = origin.y;
                    flipMethods._showFoldedPage.call(this, corner, true);
                } else
                    flipMethods.hideFoldedPage.call(this, true);

            }
        }
    },

    _eventEnd: function () {

        var data = this.data().f;

        if (!data)
            return;

        if (!data.disabled && data.point) {
            var event = $.Event('released');
            this.trigger(event, [data.point]);
            if (!event.isDefaultPrevented())
                flipMethods.hideFoldedPage.call(this, true);
        }

        data.corner = null;

    },

    disable: function (disable) {

        flipMethods.setData.call(this, { 'disabled': disable });
        return this;

    }
},

cla = function (that, methods, args) {

    if (!args[0] || typeof (args[0]) == 'object')
        return methods.init.apply(that, args);
    else if (methods[args[0]] && args[0].toString().substr(0, 1) != '_')
        return methods[args[0]].apply(that, Array.prototype.slice.call(args, 1));
    else
        throw args[0] + ' is an invalid value';
};

    $.extend($.fn, {

        flip: function (req, opts) {
            return cla(this, flipMethods, arguments);
        },

        turn: function (req) {
            return cla(this, turnMethods, arguments);
        },

        transform: function (transform, origin) {

            var properties = {};

            if (origin)
                properties[vendor + 'transform-origin'] = origin;

            properties[vendor + 'transform'] = transform;

            return this.css(properties);

        },

        animatef: function (point) {

            var data = this.data();

            if (data.effect)
                clearInterval(data.effect.handle);

            if (point) {

                if (!point.to.length) point.to = [point.to];
                if (!point.from.length) point.from = [point.from];
                if (!point.easing) point.easing = function (x, t, b, c, data) { return c * Math.sqrt(1 - (t = t / data - 1) * t) + b; };

                var j, diff = [],
				len = point.to.length,
				that = this,
				fps = point.fps || 30,
				time = -fps,
				f = function () {
				    var j, v = [];
				    time = Math.min(point.duration, time + fps);

				    for (j = 0; j < len; j++)
				        v.push(point.easing(1, time, point.from[j], diff[j], point.duration));

				    point.frame((len == 1) ? v[0] : v);

				    if (time == point.duration) {
				        clearInterval(data.effect.handle);
				        delete data['effect'];
				        that.data(data);
				        if (point.complete)
				            point.complete();
				    }
				};

                for (j = 0; j < len; j++)
                    diff.push(point.to[j] - point.from[j]);

                data.effect = point;
                data.effect.handle = setInterval(f, fps);
                this.data(data);
                f();
            } else {
                delete data['effect'];
            }
        }
    });


    $.isTouch = isTouch;

})(jQuery);
