瀏覽代碼

[ts][player] Add SpinePlayerEditor back in for documentation page/blog.

Mario Zechner 1 年之前
父節點
當前提交
da25d821c3

+ 18 - 0
spine-ts/spine-player/example/editor.html

@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <script src="../dist/iife/spine-player.js"></script>
+    <title>Spine Player Editor</title>
+</head>
+<body style="width: 100vw; height: 100vh; display: flex; margin: 0; padding: 0;">
+    <div id="editor" style="width: 100%; height: 100%"></div>
+
+    <script>
+        var code = "<script src=\"https://unpkg.com/@esotericsoftware/[email protected].*/dist/iife/spine-player.js\"></" + "script>\n<link rel=\"stylesheet\" href=\"https://unpkg.com/@esotericsoftware/[email protected].*/dist/spine-player.css\">\n\n<div id=\"player-container\" style=\"width: 100%; height: 100vh;\"></div>\n\n<script>\nnew spine.SpinePlayer(\"player-container\", {\n	jsonUrl: \"http://esotericsoftware.com/files/examples/4.1/spineboy/export/spineboy-pro.json\",\n	atlasUrl: \"http://esotericsoftware.com/files/examples/4.1/spineboy/export/spineboy.atlas\"\n});\n</" + "script>".trim();
+        spine.SpinePlayerEditor.DEFAULT_CODE = code;
+        var player = new spine.SpinePlayerEditor(document.getElementById("editor"));
+    </script>
+</body>
+</html>

+ 0 - 177
spine-ts/spine-player/example/generator/embedding-generator.html

@@ -1,177 +0,0 @@
-<!doctype html>
-<html>
-<head>
-	<meta charset="utf-8">
-	<script src="https://esotericsoftware.com/files/spine-player/3.8/codemirror.js"></script>
-	<script src="jscolor.js"></script>
-	<script src="embedding-generator.js"></script>
-	<link rel="stylesheet" href="https://esotericsoftware.com/files/spine-player/3.8/codemirror.css">
-	<meta name="viewport" content="width=device-width, initial-scale=1.0">
-</head>
-
-<style>
-
-* {
-	box-sizing: border-box;
-}
-
-body {
-	margin: 0;
-	padding: 0;
-	font-family: sans-serif;
-}
-
-#sp_generator_drop_zone {
-	width: 100%;
-	height: 100vh;
-	background: white;
-	text-align: center;
-	vertical-align: middle;
-	line-height: 100vh;
-	border: none;
-	cursor: pointer;
-
-	-webkit-touch-callout: none;
-	-webkit-user-select: none;
-	-khtml-user-select: none;
-	-moz-user-select: none;
-	-ms-user-select: none;
-	user-select: none;
-}
-
-.sp_generator_hidden {
-	display: none !important;
-}
-
-#sp_generator_editor {
-	display: flex;
-	flex-direction: column;
-	width: 100%;
-	height: 100vh;
-}
-
-.sp_generator_tabs {
-	display: flex;
-	flex-direction: row;
-	-webkit-touch-callout: none;
-	-webkit-user-select: none;
-	-khtml-user-select: none;
-	-moz-user-select: none;
-	-ms-user-select: none;
-	user-select: none;
-	border-bottom: solid 1px #999999;
-}
-
-.sp_generator_tabs > span {
-	padding: 0.5em;
-	cursor: pointer;
-}
-
-.sp_generator_tabs > span:hover {
-	background:orangered;
-}
-
-.sp_generator_selected_tab {
-	border: solid 1px orangered;
-}
-
-.sp_generator_panel {
-	width: 100%;
-	height: 100%;
-}
-
-.sp_generator_panel TABLE TH {
-	text-align: right;
-	vertical-align: top;
-}
-
-.sp_generator_extra {
-	color: #ccc;
-	padding-left: 0.5em;
-}
-
-</style>
-
-<body>
-<div id="sp_generator_drop_zone" class="drop_zone">
-	<span>Choose .skel/.json, .atlas, and .png files, or drop them here.</span>
-	<input id="sp_generator_file_button" class="sp_generator_hidden" type="file" multiple accept=".json,.skel,.atlas,.png"/>
-</div>
-<div id="sp_generator_editor" class="sp_generator_hidden">
-	<div id="sp_generator_player">
-	</div>
-	<div id="sp_generator_config">
-		<div class="sp_generator_tabs">
-			<span class="sp_generator_selected_tab" data-tab="sp_generator_tab_general">General</span>
-			<span data-tab="sp_generator_tab_animations">Animations</span>
-			<span data-tab="sp_generator_tab_viewports">Viewports</span>
-			<span data-tab="sp_generator_tab_skins">Skins</span>
-			<span data-tab="sp_generator_tab_debug">Debug</span>
-		</div>
-		<div id="sp_generator_tab_general" class="sp_generator_panel">
-			<table>
-				<tr>
-					<th>Show controls</th>
-					<td><input id="sp_generator_show_controls" type="checkbox" checked="true"></td>
-				</tr>
-				<tr>
-					<th>Premultiplied alpha</th>
-					<td><input id="sp_generator_premultiplied_alpha" type="checkbox" checked="false"></td>
-				</tr>
-				<tr>
-					<th>Canvas alpha</th>
-					<td><input id="sp_generator_canvas_alpha" value="FF"></td>
-				</tr>
-				<tr>
-					<th>Background color</th>
-					<td><input id="sp_generator_background" class="jscolor {onFineChange:'changeBackgroundColor(this)'}'" value="000000"></td>
-				</tr>
-				<tr>
-					<th>Fullscreen background color</th>
-					<td><input id="sp_generator_background_fullscreen" class="jscolor {onFineChange:'changeFullscreenBackgroundColor(this)'}'" value="000000"></td>
-				</tr>
-				<tr style="vertical-align: top;">
-					<th>Background image</th>
-					<td>
-						<select id="sp_generator_background_image">
-						</select>
-					</td>
-					<td id="sp_generator_background_bounds" class="sp_generator_hidden">
-						<table>
-							<tr>
-								<th>X</th>
-								<td><input id="sp_generator_background_x"></td>
-							</tr>
-							<tr>
-								<th>Y</th>
-								<td><input id="sp_generator_background_y"></td>
-							</tr>
-							<tr>
-								<th>Width</th>
-								<td><input id="sp_generator_background_width"></td>
-							</tr>
-							<tr>
-								<th>Height</th>
-								<td><input id="sp_generator_background_height"></td>
-							</tr>
-						</table>
-					</td>
-				</tr>
-			</table>
-		</div>
-		<div id="sp_generator_tab_animations" class="sp_generator_panel sp_generator_hidden">
-			Animations
-		</div>
-		<div id="sp_generator_tab_viewports" class="sp_generator_panel sp_generator_hidden">
-			Viewports
-		</div>
-		<div id="sp_generator_tab_skins" class="sp_generator_panel sp_generator_hidden">
-			Skins
-		</div>
-		<div id="sp_generator_tab_debug" class="sp_generator_panel sp_generator_hidden">
-			Debug
-		</div>
-	</div>
-</div>
-</body>
-</html>

+ 0 - 435
spine-ts/spine-player/example/generator/embedding-generator.js

@@ -1,435 +0,0 @@
-window.addEventListener("load", function (event) {
-	setupDropZone();
-});
-
-if (!String.prototype.endsWith) {
-	String.prototype.endsWith = function (search, this_len) {
-		if (this_len === undefined || this_len > this.length) {
-			this_len = this.length;
-		}
-		return this.substring(this_len - search.length, this_len) === search;
-	};
-}
-
-var appState = {
-	dataUrls: null,
-	jsonFile: null,
-	skelFile: null,
-	atlasFile: null,
-	minorVersion: null,
-	majorVersion: null,
-	player: null
-}
-
-function loadFiles(files) {
-	var skels = 0;
-	var skelFile = null;
-	var jsons = 0;
-	var jsonFile = null;
-	var atlases = 0;
-	var atlasFile = null;
-	var pngs = 0;
-
-	for (var i = 0; i < files.length; i++) {
-		var file = files[i].name.toLowerCase();
-		if (file.endsWith(".skel")) {
-			skels++;
-			skelFile = file;
-		}
-		if (file.endsWith(".json")) {
-			jsons++;
-			jsonFile = file;
-		}
-		if (file.endsWith(".atlas")) {
-			atlases++;
-			atlasFile = file;
-		}
-		if (file.endsWith(".png")) pngs++;
-	}
-
-	if ((skels == 0 && jsons == 0) || (skels != 0 && jsons != 0) || skels > 1 || jsons > 1) {
-		showError("Please specify a single .skel or .json file.");
-		return;
-	}
-
-	if (atlases != 1) {
-		showError("Please specify a single .atlas file.");
-		return;
-	}
-
-	var filesToLoad = files.length;
-	var dataUrls = {};
-	for (var i = 0; i < files.length; i++) {
-		var file = files[i];
-		var reader = new FileReader();
-		reader.onload = function (file) {
-			return function (dataUrl) {
-				console.log("Loaded " + file.name);
-				dataUrls[file.name] = dataUrl.target.result;
-				filesToLoad--;
-				if (filesToLoad == 0) {
-					setupPlayer(dataUrls, jsonFile, skelFile, atlasFile);
-				}
-			};
-		}(file);
-		reader.onerror = function () {
-			showError("Sorry, couldn't load all files.");
-		}
-		reader.readAsDataURL(file);
-	}
-}
-
-function setupPlayer(dataUrls, jsonFile, skelFile, atlasFile) {
-	var version = getSkeletonVersion(dataUrls, jsonFile, skelFile);
-	var major = parseInt(version.split("\.")[0]);
-	var minor = parseInt(version.split("\.")[1]);
-
-	appState.dataUrls = dataUrls;
-	appState.jsonFile = jsonFile;
-	appState.skelFile = skelFile;
-	appState.atlasFile = atlasFile;
-	appState.majorVersion = major;
-	appState.minorVersion = minor;
-
-	if (major == 3 && minor < 8) {
-		showError("Couldn't load script for Spine version " + version + ". Only skeletons with version >= 3.8 are supported.");
-		return;
-	}
-
-	var cssUrl = "https://esotericsoftware.com/files/spine-player/" + major + "." + minor + "/spine-player.min.css";
-	spine = null;
-	loadCSS(cssUrl, function () {
-		var playerUrl = "https://esotericsoftware.com/files/spine-player/" + major + "." + minor + "/spine-player.min.js";
-		//playerUrl = "../../dist/iife/spine-player.js"; // debug
-		loadJavaScript(playerUrl, function () {
-			document.getElementById("sp_generator_editor").classList.remove("sp_generator_hidden");
-			document.getElementById("sp_generator_drop_zone").classList.add("sp_generator_hidden");
-			var player = document.getElementById("sp_generator_player");
-			player.innerHTML = "";
-
-			var config = {
-				jsonUrl: jsonFile,
-				skelUrl: skelFile,
-				atlasUrl: atlasFile,
-				rawDataURIs: dataUrls,
-				success: setupConfigUI,
-				alpha: true, // needed so we can emulate shizzle
-				viewport: { // needed so we can see viewport bounds
-					debugRender: true
-				}
-			};
-
-			appState.player = new spine.SpinePlayer(player, config);
-
-		}, function () {
-			showError("Couldn't load script for Spine version " + version + ". Only skeletons with version 3.8+ are supported.");
-		});
-	}, function () {
-		showError("Couldn't load CSS for Spine version " + version + ". Only skeletons with version 3.8+ are supported.");
-	});
-}
-
-function setupConfigUI() {
-	// Setup tabs
-	var tabs = document.getElementsByClassName("sp_generator_tabs")[0];
-	var children = tabs.getElementsByTagName("span");
-	for (var i = 0; i < children.length; i++) {
-		(function (tab) {
-			tab.onclick = function () {
-				var panelId = tab.getAttribute("data-tab");
-				var panels = document.getElementById("sp_generator_config").getElementsByClassName("sp_generator_panel");
-				for (var i = 0; i < panels.length; i++) {
-					var panel = panels[i];
-					if (panelId == panel.getAttribute("id")) {
-						tab.classList.add("sp_generator_selected_tab");
-						panel.classList.remove("sp_generator_hidden");
-					} else {
-						tab.classList.remove("sp_generator_selected_tab");
-						panel.classList.add("sp_generator_hidden");
-					}
-				}
-			}
-		})(children[i]);
-	}
-
-	// Fill general tab
-	var showControls = document.getElementById("sp_generator_show_controls");
-	showControls.onchange = function () {
-		appState.player.config.showControls = showControls.checked;
-	};
-	var canvasAlpha = document.getElementById("sp_generator_canvas_alpha");
-	canvasAlpha.onchange = function () {
-		var re = /[0-9A-Fa-f]{2}/g;
-		if (canvasAlpha.value.length > 2 || !re.test(canvasAlpha.value))
-			canvasAlpha.value = "FF";
-		else
-			canvasAlpha.value = canvasAlpha.value.toUpperCase();
-		var alpha = Number.parseInt(canvasAlpha.value, 16);
-		appState.player.config.alpha = alpha != 0xff;
-		appState.player.config.backgroundColor = document.getElementById("sp_generator_background").value + canvasAlpha.value;
-	}
-	var premultipliedAlpha = document.getElementById("sp_generator_premultiplied_alpha");
-	var premultipliedAlpha = document.getElementById("sp_generator_premultiplied_alpha");
-	premultipliedAlpha.onchange = function () {
-		appState.player.config.premultipliedAlpha = premultipliedAlpha.checked;
-	}
-	var backgroundImage = document.getElementById("sp_generator_background_image");
-	backgroundImage.innerHTML = "";
-	var noneImage = document.createElement("option");
-	noneImage.value = "none";
-	noneImage.innerText = "None";
-	noneImage.selected = true;
-	backgroundImage.append(noneImage);
-	for (var data in appState.dataUrls) {
-		if (data.toLowerCase().endsWith(".png")) {
-			var image = document.createElement("option");
-			image.value = data;
-			image.innerText = data;
-			backgroundImage.append(image);
-		}
-	}
-	backgroundImage.onchange = function () {
-		var imageUrl = backgroundImage.value;
-		if (imageUrl != "none" && !appState.player.assetManager.get(imageUrl)) {
-			appState.player.assetManager.loadTexture(imageUrl);
-		}
-
-		var boundsTable = document.getElementById("sp_generator_background_bounds");
-		if (imageUrl == "none")
-			boundsTable.classList.add("sp_generator_hidden");
-		else
-			boundsTable.classList.remove("sp_generator_hidden");
-
-		if (appState.player.config.backgroundImage) {
-			appState.player.config.backgroundImage.url = imageUrl != "none" ? imageUrl : null;
-		} else {
-			appState.player.config.backgroundImage = {
-				url: imageUrl != "none" ? imageUrl : null
-			}
-		}
-	}
-	var backgroundX = document.getElementById("sp_generator_background_x");
-	backgroundX.onkeyup = backgroundX.onchange = function () {
-		var value = Number.parseFloat(backgroundX.value);
-		if (Number.isNaN(value)) return;
-		appState.player.config.backgroundImage.x = value;
-	};
-
-	var backgroundY = document.getElementById("sp_generator_background_y");
-	backgroundY.onkeyup = backgroundY.onchange = function () {
-		var value = Number.parseFloat(backgroundY.value);
-		if (Number.isNaN(value)) return;
-		appState.player.config.backgroundImage.y = value;
-	};
-	var backgroundWidth = document.getElementById("sp_generator_background_width");
-	backgroundWidth.onkeyup = backgroundWidth.onchange = function () {
-		var value = Number.parseFloat(backgroundWidth.value);
-		if (Number.isNaN(value)) return;
-		appState.player.config.backgroundImage.width = value;
-	};
-	var backgroundHeight = document.getElementById("sp_generator_background_height");
-	backgroundHeight.onkeyup = backgroundHeight.onchange = function () {
-		var value = Number.parseFloat(backgroundHeight.value);
-		if (Number.isNaN(value)) return;
-		appState.player.config.backgroundImage.height = value;
-	};
-
-
-	// Fill animations tab
-
-	// Fill viewports tab
-
-	// Fill skins tab
-
-	// Fill debug tab
-}
-
-function changeBackgroundColor(background) {
-	appState.player.config.backgroundColor = background.valueElement.value + document.getElementById("sp_generator_canvas_alpha").value;
-}
-
-function changeFullscreenBackgroundColor(background) {
-	appState.player.config.fullScreenBackgroundColor = background.valueElement.value;
-}
-
-function getSkeletonVersion(dataUrls, jsonFile, skelFile) {
-	if (jsonFile) {
-		var json = JSON.parse(atob(dataUrls[jsonFile].split(',')[1]));
-		return json.skeleton.spine;
-	} else {
-		var bytes = atob(dataUrls[skelFile].split(',')[1]);
-		var array = new Uint8Array(new ArrayBuffer(bytes.length));
-		for (var i = 0; i < bytes.length; i++) {
-			array[i] = bytes.charCodeAt(i);
-		}
-
-		var input = new BinaryInput(array);
-		input.readString();
-		var version = input.readString();
-		return version; x
-	}
-}
-
-function loadJavaScript(url, success, error) {
-	var script = document.createElement('script');
-	script.setAttribute('src', url);
-	script.setAttribute('type', 'text/javascript');
-	script.onload = success;
-	script.onerror = error;
-	document.getElementsByTagName("head")[0].appendChild(script);
-};
-
-function loadCSS(url, success, error) {
-	var script = document.createElement('link');
-	script.setAttribute('href', url);
-	script.setAttribute('rel', 'stylesheet');
-	script.onload = success;
-	script.onerror = error;
-	document.getElementsByTagName("head")[0].appendChild(script);
-};
-
-function showError(error) {
-	alert("Error: " + error);
-}
-
-function setupDropZone() {
-	var fileButton = document.getElementById("sp_generator_file_button");
-	var dropZone = document.getElementById("sp_generator_drop_zone");
-	dropZone.onclick = function () {
-		fileButton.click();
-	};
-	dropZone.addEventListener("dragenter", function (event) {
-		event.stopPropagation();
-		event.preventDefault();
-	}, false);
-	dropZone.addEventListener("dragover", function (event) {
-		event.stopPropagation();
-		event.preventDefault();
-	}, false);
-	dropZone.addEventListener("drop", function (event) {
-		event.stopPropagation();
-		event.preventDefault();
-
-		loadFiles(event.dataTransfer.files);
-	}, false);
-
-
-	fileButton.onchange = function () {
-		loadFiles(fileButton.files);
-		fileButton.value = "";
-	};
-}
-
-function generateScript(jsonFile, skelFile, atlasFile, dataUrls) {
-	var shortVersion = major + "." + minor;
-	var scriptCode =
-		'<script src="https://esotericsoftware.com/files/spine-player/' + shortVersion + '/spine-player.min.js"><' + '/script>\n' +
-		'<link rel="stylesheet" href="https://esotericsoftware.com/files/spine-player/' + shortVersion + '/spine-player.min.css">\n\n' +
-		'<div id="player-container" style="width: 100%; height: 100vh;"></div>\n\n' +
-		'<script>\n' +
-		'new spine.SpinePlayer("player-container", {\n';
-	if (jsonFile) scriptCode +=
-		'   jsonUrl: "' + jsonFile + '",\n';
-	else scriptCode +=
-		'   skelUrl: "' + skelFile + '",\n';
-
-	scriptCode +=
-		'   atlasUrl: "' + atlasFile + '",\n' +
-		'   rawDataURIs: {\n'
-
-	for (var file in dataUrls)
-		scriptCode += '       "' + file + '": "' + dataUrls[file] + '",\n';
-
-	scriptCode +=
-		'   }\n' +
-		'});\n' +
-		'<' + '/script>';
-}
-
-var BinaryInput = (function () {
-	function BinaryInput(data, strings, index, buffer) {
-		if (strings === void 0) { strings = new Array(); }
-		if (index === void 0) { index = 0; }
-		if (buffer === void 0) { buffer = new DataView(data.buffer); }
-		this.strings = strings;
-		this.index = index;
-		this.buffer = buffer;
-	}
-	BinaryInput.prototype.readByte = function () {
-		return this.buffer.getInt8(this.index++);
-	};
-	BinaryInput.prototype.readShort = function () {
-		var value = this.buffer.getInt16(this.index);
-		this.index += 2;
-		return value;
-	};
-	BinaryInput.prototype.readInt32 = function () {
-		var value = this.buffer.getInt32(this.index);
-		this.index += 4;
-		return value;
-	};
-	BinaryInput.prototype.readInt = function (optimizePositive) {
-		var b = this.readByte();
-		var result = b & 0x7F;
-		if ((b & 0x80) != 0) {
-			b = this.readByte();
-			result |= (b & 0x7F) << 7;
-			if ((b & 0x80) != 0) {
-				b = this.readByte();
-				result |= (b & 0x7F) << 14;
-				if ((b & 0x80) != 0) {
-					b = this.readByte();
-					result |= (b & 0x7F) << 21;
-					if ((b & 0x80) != 0) {
-						b = this.readByte();
-						result |= (b & 0x7F) << 28;
-					}
-				}
-			}
-		}
-		return optimizePositive ? result : ((result >>> 1) ^ -(result & 1));
-	};
-	BinaryInput.prototype.readStringRef = function () {
-		var index = this.readInt(true);
-		return index == 0 ? null : this.strings[index - 1];
-	};
-	BinaryInput.prototype.readString = function () {
-		var byteCount = this.readInt(true);
-		switch (byteCount) {
-			case 0:
-				return null;
-			case 1:
-				return "";
-		}
-		byteCount--;
-		var chars = "";
-		var charCount = 0;
-		for (var i = 0; i < byteCount;) {
-			var b = this.readByte();
-			switch (b >> 4) {
-				case 12:
-				case 13:
-					chars += String.fromCharCode(((b & 0x1F) << 6 | this.readByte() & 0x3F));
-					i += 2;
-					break;
-				case 14:
-					chars += String.fromCharCode(((b & 0x0F) << 12 | (this.readByte() & 0x3F) << 6 | this.readByte() & 0x3F));
-					i += 3;
-					break;
-				default:
-					chars += String.fromCharCode(b);
-					i++;
-			}
-		}
-		return chars;
-	};
-	BinaryInput.prototype.readFloat = function () {
-		var value = this.buffer.getFloat32(this.index);
-		this.index += 4;
-		return value;
-	};
-	BinaryInput.prototype.readBoolean = function () {
-		return this.readByte() != 0;
-	};
-	return BinaryInput;
-}());

+ 0 - 152
spine-ts/spine-player/example/generator/generator.html

@@ -1,152 +0,0 @@
-<!doctype html>
-<html>
-<head>
-	<meta charset="utf-8">
-	<script src="jscolor.js"></script>
-	<script src="ui.js"></script>
-	<script src="loader.js"></script>
-	<meta name="viewport" content="width=device-width, initial-scale=1.0">
-</head>
-
-<style>
-* {
-	box-sizing: border-box;
-}
-
-body {
-	margin: 0;
-	padding: 0;
-	font-family: sans-serif;
-}
-
-#dropzone {
-	width: 100%;
-	height: 100vh;
-	background: #cccccc;
-	text-align: center;
-	line-height: 100vh;
-
-
-	-webkit-touch-callout: none;
-	-webkit-user-select: none;
-	-khtml-user-select: none;
-	-moz-user-select: none;
-	-ms-user-select: none;
-	user-select: none;
-
-	cursor: pointer;
-}
-
-#editor {
-	display: flex;
-	flex-direction: row-reverse;
-	width: 100%;
-	height: 100vh;
-	background: #aaaaaa;
-}
-
-#player {
-	width: 100%;
-	height: 100%;
-}
-
-#config {
-	width: 100%;
-	height: 100%;
-	padding: 1em;
-	background: #f0f0f0;
-}
-
-</style>
-
-<body>
-	<div id="dropzone">
-		Click to choose .skel/.json, .atlas, and .png files, or drop them here.
-	</div>
-
-	<div id="editor" style="display: none">
-	</div>
-
-	<script>
-		var UI;
-		var Loader;
-		var dropZone = document.getElementById("dropzone");
-		var editor = document.getElementById("editor")
-
-		function showError(errorMessage) {
-			alert("Error: " + errorMessage);
-		}
-
-		window.addEventListener("load", function(event) {
-			UI = spineGenerator.UI;
-			Loader = spineGenerator.Loader;
-			var dropZone = document.getElementById("dropzone");
-			new UI.DropZone(dropZone, true, ".json,.skel,.atlas,.png", function (files) {
-				spineGenerator.Loader.loadSkeletonFiles(files, function(data) {
-					console.log(`Loaded files ${data.jsonFile} ${data.skelFile} ${data.atlasFile}`);
-					console.log(`${data.version} ${data.majorVersion} ${data.minorVersion} ${data.patchVersion}`);
-
-					spine = null;
-					var cssUrl = `https://esotericsoftware.com/files/spine-player/${data.majorVersion}.${data.minorVersion}/spine-player.min.css`;
-					var playerUrl = `https://esotericsoftware.com/files/spine-player/${data.majorVersion}.${data.minorVersion}/spine-player.min.js`;
-
-					Loader.loadStyle(cssUrl, function () {
-						Loader.loadJavaScript(playerUrl, function () {
-							UI.hide(dropZone)
-							setupEditor(editor, data);
-						});
-					}, showError);
-				}, showError);
-			}, showError);
-		});
-
-		function setupEditor(editor, data) {
-			setupPlayer(editor, data, function(player) {
-				setupConfig(editor, player, data);
-				UI.show(editor, "flex");
-			}, showError)
-		}
-
-		function setupPlayer(editor, data, success, error) {
-			var playerElement = UI.createElement(editor, `<div id="player"></div>`);
-
-			var config = {
-				jsonUrl: data.jsonFile,
-				skelUrl: data.skelFile,
-				atlasUrl: data.atlasFile,
-				rawDataURIs: data.dataUrls,
-				success: success,
-				error: error,
-				alpha: true, // needed so we can emulate shizzle
-				viewport: { // needed so we can see viewport bounds
-					debugRender: true
-				}
-			};
-
-			return new spine.SpinePlayer(playerElement, config);
-		}
-
-		function setupConfig(editor, player, data) {
-			var cfg = UI.createElement(editor, `<div id="config"></div>`);
-
-			var topBar = UI.createElement(cfg, /*html*/`
-				<div style="display: flex; flex-direction: row;">
-					<button type="button">New</button>
-					<button type="button">Download HTML</button>
-				</div>
-			`);
-
-			var newButton = topBar.children[0];
-			newButton.onclick = function() {
-				player.stopRendering();
-				UI.show(dropZone);
-				UI.clear(editor);
-				UI.hide(editor);
-			}
-			var downloadButton = topBar.children[1];
-
-			UI.createElement(cfg, `<h3>General</h3>`);
-		}
-	</script>
-</body>
-</html>

+ 0 - 1855
spine-ts/spine-player/example/generator/jscolor.js

@@ -1,1855 +0,0 @@
-/**
- * jscolor - JavaScript Color Picker
- *
- * @link    http://jscolor.com
- * @license For open source use: GPLv3
- *          For commercial use: JSColor Commercial License
- * @author  Jan Odvarko
- * @version 2.0.5
- *
- * See usage examples at http://jscolor.com/examples/
- */
-
-
-"use strict";
-
-
-if (!window.jscolor) { window.jscolor = (function () {
-
-
-var jsc = {
-
-
-	register : function () {
-		jsc.attachDOMReadyEvent(jsc.init);
-		jsc.attachEvent(document, 'mousedown', jsc.onDocumentMouseDown);
-		jsc.attachEvent(document, 'touchstart', jsc.onDocumentTouchStart);
-		jsc.attachEvent(window, 'resize', jsc.onWindowResize);
-	},
-
-
-	init : function () {
-		if (jsc.jscolor.lookupClass) {
-			jsc.jscolor.installByClassName(jsc.jscolor.lookupClass);
-		}
-	},
-
-
-	tryInstallOnElements : function (elms, className) {
-		var matchClass = new RegExp('(^|\\s)(' + className + ')(\\s*(\\{[^}]*\\})|\\s|$)', 'i');
-
-		for (var i = 0; i < elms.length; i += 1) {
-			if (elms[i].type !== undefined && elms[i].type.toLowerCase() == 'color') {
-				if (jsc.isColorAttrSupported) {
-					// skip inputs of type 'color' if supported by the browser
-					continue;
-				}
-			}
-			var m;
-			if (!elms[i].jscolor && elms[i].className && (m = elms[i].className.match(matchClass))) {
-				var targetElm = elms[i];
-				var optsStr = null;
-
-				var dataOptions = jsc.getDataAttr(targetElm, 'jscolor');
-				if (dataOptions !== null) {
-					optsStr = dataOptions;
-				} else if (m[4]) {
-					optsStr = m[4];
-				}
-
-				var opts = {};
-				if (optsStr) {
-					try {
-						opts = (new Function ('return (' + optsStr + ')'))();
-					} catch(eParseError) {
-						jsc.warn('Error parsing jscolor options: ' + eParseError + ':\n' + optsStr);
-					}
-				}
-				targetElm.jscolor = new jsc.jscolor(targetElm, opts);
-			}
-		}
-	},
-
-
-	isColorAttrSupported : (function () {
-		var elm = document.createElement('input');
-		if (elm.setAttribute) {
-			elm.setAttribute('type', 'color');
-			if (elm.type.toLowerCase() == 'color') {
-				return true;
-			}
-		}
-		return false;
-	})(),
-
-
-	isCanvasSupported : (function () {
-		var elm = document.createElement('canvas');
-		return !!(elm.getContext && elm.getContext('2d'));
-	})(),
-
-
-	fetchElement : function (mixed) {
-		return typeof mixed === 'string' ? document.getElementById(mixed) : mixed;
-	},
-
-
-	isElementType : function (elm, type) {
-		return elm.nodeName.toLowerCase() === type.toLowerCase();
-	},
-
-
-	getDataAttr : function (el, name) {
-		var attrName = 'data-' + name;
-		var attrValue = el.getAttribute(attrName);
-		if (attrValue !== null) {
-			return attrValue;
-		}
-		return null;
-	},
-
-
-	attachEvent : function (el, evnt, func) {
-		if (el.addEventListener) {
-			el.addEventListener(evnt, func, false);
-		} else if (el.attachEvent) {
-			el.attachEvent('on' + evnt, func);
-		}
-	},
-
-
-	detachEvent : function (el, evnt, func) {
-		if (el.removeEventListener) {
-			el.removeEventListener(evnt, func, false);
-		} else if (el.detachEvent) {
-			el.detachEvent('on' + evnt, func);
-		}
-	},
-
-
-	_attachedGroupEvents : {},
-
-
-	attachGroupEvent : function (groupName, el, evnt, func) {
-		if (!jsc._attachedGroupEvents.hasOwnProperty(groupName)) {
-			jsc._attachedGroupEvents[groupName] = [];
-		}
-		jsc._attachedGroupEvents[groupName].push([el, evnt, func]);
-		jsc.attachEvent(el, evnt, func);
-	},
-
-
-	detachGroupEvents : function (groupName) {
-		if (jsc._attachedGroupEvents.hasOwnProperty(groupName)) {
-			for (var i = 0; i < jsc._attachedGroupEvents[groupName].length; i += 1) {
-				var evt = jsc._attachedGroupEvents[groupName][i];
-				jsc.detachEvent(evt[0], evt[1], evt[2]);
-			}
-			delete jsc._attachedGroupEvents[groupName];
-		}
-	},
-
-
-	attachDOMReadyEvent : function (func) {
-		var fired = false;
-		var fireOnce = function () {
-			if (!fired) {
-				fired = true;
-				func();
-			}
-		};
-
-		if (document.readyState === 'complete') {
-			setTimeout(fireOnce, 1); // async
-			return;
-		}
-
-		if (document.addEventListener) {
-			document.addEventListener('DOMContentLoaded', fireOnce, false);
-
-			// Fallback
-			window.addEventListener('load', fireOnce, false);
-
-		} else if (document.attachEvent) {
-			// IE
-			document.attachEvent('onreadystatechange', function () {
-				if (document.readyState === 'complete') {
-					document.detachEvent('onreadystatechange', arguments.callee);
-					fireOnce();
-				}
-			})
-
-			// Fallback
-			window.attachEvent('onload', fireOnce);
-
-			// IE7/8
-			if (document.documentElement.doScroll && window == window.top) {
-				var tryScroll = function () {
-					if (!document.body) { return; }
-					try {
-						document.documentElement.doScroll('left');
-						fireOnce();
-					} catch (e) {
-						setTimeout(tryScroll, 1);
-					}
-				};
-				tryScroll();
-			}
-		}
-	},
-
-
-	warn : function (msg) {
-		if (window.console && window.console.warn) {
-			window.console.warn(msg);
-		}
-	},
-
-
-	preventDefault : function (e) {
-		if (e.preventDefault) { e.preventDefault(); }
-		e.returnValue = false;
-	},
-
-
-	captureTarget : function (target) {
-		// IE
-		if (target.setCapture) {
-			jsc._capturedTarget = target;
-			jsc._capturedTarget.setCapture();
-		}
-	},
-
-
-	releaseTarget : function () {
-		// IE
-		if (jsc._capturedTarget) {
-			jsc._capturedTarget.releaseCapture();
-			jsc._capturedTarget = null;
-		}
-	},
-
-
-	fireEvent : function (el, evnt) {
-		if (!el) {
-			return;
-		}
-		if (document.createEvent) {
-			var ev = document.createEvent('HTMLEvents');
-			ev.initEvent(evnt, true, true);
-			el.dispatchEvent(ev);
-		} else if (document.createEventObject) {
-			var ev = document.createEventObject();
-			el.fireEvent('on' + evnt, ev);
-		} else if (el['on' + evnt]) { // alternatively use the traditional event model
-			el['on' + evnt]();
-		}
-	},
-
-
-	classNameToList : function (className) {
-		return className.replace(/^\s+|\s+$/g, '').split(/\s+/);
-	},
-
-
-	// The className parameter (str) can only contain a single class name
-	hasClass : function (elm, className) {
-		if (!className) {
-			return false;
-		}
-		return -1 != (' ' + elm.className.replace(/\s+/g, ' ') + ' ').indexOf(' ' + className + ' ');
-	},
-
-
-	// The className parameter (str) can contain multiple class names separated by whitespace
-	setClass : function (elm, className) {
-		var classList = jsc.classNameToList(className);
-		for (var i = 0; i < classList.length; i += 1) {
-			if (!jsc.hasClass(elm, classList[i])) {
-				elm.className += (elm.className ? ' ' : '') + classList[i];
-			}
-		}
-	},
-
-
-	// The className parameter (str) can contain multiple class names separated by whitespace
-	unsetClass : function (elm, className) {
-		var classList = jsc.classNameToList(className);
-		for (var i = 0; i < classList.length; i += 1) {
-			var repl = new RegExp(
-				'^\\s*' + classList[i] + '\\s*|' +
-				'\\s*' + classList[i] + '\\s*$|' +
-				'\\s+' + classList[i] + '(\\s+)',
-				'g'
-			);
-			elm.className = elm.className.replace(repl, '$1');
-		}
-	},
-
-
-	getStyle : function (elm) {
-		return window.getComputedStyle ? window.getComputedStyle(elm) : elm.currentStyle;
-	},
-
-
-	setStyle : (function () {
-		var helper = document.createElement('div');
-		var getSupportedProp = function (names) {
-			for (var i = 0; i < names.length; i += 1) {
-				if (names[i] in helper.style) {
-					return names[i];
-				}
-			}
-		};
-		var props = {
-			borderRadius: getSupportedProp(['borderRadius', 'MozBorderRadius', 'webkitBorderRadius']),
-			boxShadow: getSupportedProp(['boxShadow', 'MozBoxShadow', 'webkitBoxShadow'])
-		};
-		return function (elm, prop, value) {
-			switch (prop.toLowerCase()) {
-			case 'opacity':
-				var alphaOpacity = Math.round(parseFloat(value) * 100);
-				elm.style.opacity = value;
-				elm.style.filter = 'alpha(opacity=' + alphaOpacity + ')';
-				break;
-			default:
-				elm.style[props[prop]] = value;
-				break;
-			}
-		};
-	})(),
-
-
-	setBorderRadius : function (elm, value) {
-		jsc.setStyle(elm, 'borderRadius', value || '0');
-	},
-
-
-	setBoxShadow : function (elm, value) {
-		jsc.setStyle(elm, 'boxShadow', value || 'none');
-	},
-
-
-	getElementPos : function (e, relativeToViewport) {
-		var x=0, y=0;
-		var rect = e.getBoundingClientRect();
-		x = rect.left;
-		y = rect.top;
-		if (!relativeToViewport) {
-			var viewPos = jsc.getViewPos();
-			x += viewPos[0];
-			y += viewPos[1];
-		}
-		return [x, y];
-	},
-
-
-	getElementSize : function (e) {
-		return [e.offsetWidth, e.offsetHeight];
-	},
-
-
-	// get pointer's X/Y coordinates relative to viewport
-	getAbsPointerPos : function (e) {
-		if (!e) { e = window.event; }
-		var x = 0, y = 0;
-		if (typeof e.changedTouches !== 'undefined' && e.changedTouches.length) {
-			// touch devices
-			x = e.changedTouches[0].clientX;
-			y = e.changedTouches[0].clientY;
-		} else if (typeof e.clientX === 'number') {
-			x = e.clientX;
-			y = e.clientY;
-		}
-		return { x: x, y: y };
-	},
-
-
-	// get pointer's X/Y coordinates relative to target element
-	getRelPointerPos : function (e) {
-		if (!e) { e = window.event; }
-		var target = e.target || e.srcElement;
-		var targetRect = target.getBoundingClientRect();
-
-		var x = 0, y = 0;
-
-		var clientX = 0, clientY = 0;
-		if (typeof e.changedTouches !== 'undefined' && e.changedTouches.length) {
-			// touch devices
-			clientX = e.changedTouches[0].clientX;
-			clientY = e.changedTouches[0].clientY;
-		} else if (typeof e.clientX === 'number') {
-			clientX = e.clientX;
-			clientY = e.clientY;
-		}
-
-		x = clientX - targetRect.left;
-		y = clientY - targetRect.top;
-		return { x: x, y: y };
-	},
-
-
-	getViewPos : function () {
-		var doc = document.documentElement;
-		return [
-			(window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0),
-			(window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)
-		];
-	},
-
-
-	getViewSize : function () {
-		var doc = document.documentElement;
-		return [
-			(window.innerWidth || doc.clientWidth),
-			(window.innerHeight || doc.clientHeight),
-		];
-	},
-
-
-	redrawPosition : function () {
-
-		if (jsc.picker && jsc.picker.owner) {
-			var thisObj = jsc.picker.owner;
-
-			var tp, vp;
-
-			if (thisObj.fixed) {
-				// Fixed elements are positioned relative to viewport,
-				// therefore we can ignore the scroll offset
-				tp = jsc.getElementPos(thisObj.targetElement, true); // target pos
-				vp = [0, 0]; // view pos
-			} else {
-				tp = jsc.getElementPos(thisObj.targetElement); // target pos
-				vp = jsc.getViewPos(); // view pos
-			}
-
-			var ts = jsc.getElementSize(thisObj.targetElement); // target size
-			var vs = jsc.getViewSize(); // view size
-			var ps = jsc.getPickerOuterDims(thisObj); // picker size
-			var a, b, c;
-			switch (thisObj.position.toLowerCase()) {
-				case 'left': a=1; b=0; c=-1; break;
-				case 'right':a=1; b=0; c=1; break;
-				case 'top':  a=0; b=1; c=-1; break;
-				default:     a=0; b=1; c=1; break;
-			}
-			var l = (ts[b]+ps[b])/2;
-
-			// compute picker position
-			if (!thisObj.smartPosition) {
-				var pp = [
-					tp[a],
-					tp[b]+ts[b]-l+l*c
-				];
-			} else {
-				var pp = [
-					-vp[a]+tp[a]+ps[a] > vs[a] ?
-						(-vp[a]+tp[a]+ts[a]/2 > vs[a]/2 && tp[a]+ts[a]-ps[a] >= 0 ? tp[a]+ts[a]-ps[a] : tp[a]) :
-						tp[a],
-					-vp[b]+tp[b]+ts[b]+ps[b]-l+l*c > vs[b] ?
-						(-vp[b]+tp[b]+ts[b]/2 > vs[b]/2 && tp[b]+ts[b]-l-l*c >= 0 ? tp[b]+ts[b]-l-l*c : tp[b]+ts[b]-l+l*c) :
-						(tp[b]+ts[b]-l+l*c >= 0 ? tp[b]+ts[b]-l+l*c : tp[b]+ts[b]-l-l*c)
-				];
-			}
-
-			var x = pp[a];
-			var y = pp[b];
-			var positionValue = thisObj.fixed ? 'fixed' : 'absolute';
-			var contractShadow =
-				(pp[0] + ps[0] > tp[0] || pp[0] < tp[0] + ts[0]) &&
-				(pp[1] + ps[1] < tp[1] + ts[1]);
-
-			jsc._drawPosition(thisObj, x, y, positionValue, contractShadow);
-		}
-	},
-
-
-	_drawPosition : function (thisObj, x, y, positionValue, contractShadow) {
-		var vShadow = contractShadow ? 0 : thisObj.shadowBlur; // px
-
-		jsc.picker.wrap.style.position = positionValue;
-		jsc.picker.wrap.style.left = x + 'px';
-		jsc.picker.wrap.style.top = y + 'px';
-
-		jsc.setBoxShadow(
-			jsc.picker.boxS,
-			thisObj.shadow ?
-				new jsc.BoxShadow(0, vShadow, thisObj.shadowBlur, 0, thisObj.shadowColor) :
-				null);
-	},
-
-
-	getPickerDims : function (thisObj) {
-		var displaySlider = !!jsc.getSliderComponent(thisObj);
-		var dims = [
-			2 * thisObj.insetWidth + 2 * thisObj.padding + thisObj.width +
-				(displaySlider ? 2 * thisObj.insetWidth + jsc.getPadToSliderPadding(thisObj) + thisObj.sliderSize : 0),
-			2 * thisObj.insetWidth + 2 * thisObj.padding + thisObj.height +
-				(thisObj.closable ? 2 * thisObj.insetWidth + thisObj.padding + thisObj.buttonHeight : 0)
-		];
-		return dims;
-	},
-
-
-	getPickerOuterDims : function (thisObj) {
-		var dims = jsc.getPickerDims(thisObj);
-		return [
-			dims[0] + 2 * thisObj.borderWidth,
-			dims[1] + 2 * thisObj.borderWidth
-		];
-	},
-
-
-	getPadToSliderPadding : function (thisObj) {
-		return Math.max(thisObj.padding, 1.5 * (2 * thisObj.pointerBorderWidth + thisObj.pointerThickness));
-	},
-
-
-	getPadYComponent : function (thisObj) {
-		switch (thisObj.mode.charAt(1).toLowerCase()) {
-			case 'v': return 'v'; break;
-		}
-		return 's';
-	},
-
-
-	getSliderComponent : function (thisObj) {
-		if (thisObj.mode.length > 2) {
-			switch (thisObj.mode.charAt(2).toLowerCase()) {
-				case 's': return 's'; break;
-				case 'v': return 'v'; break;
-			}
-		}
-		return null;
-	},
-
-
-	onDocumentMouseDown : function (e) {
-		if (!e) { e = window.event; }
-		var target = e.target || e.srcElement;
-
-		if (target._jscLinkedInstance) {
-			if (target._jscLinkedInstance.showOnClick) {
-				target._jscLinkedInstance.show();
-			}
-		} else if (target._jscControlName) {
-			jsc.onControlPointerStart(e, target, target._jscControlName, 'mouse');
-		} else {
-			// Mouse is outside the picker controls -> hide the color picker!
-			if (jsc.picker && jsc.picker.owner) {
-				jsc.picker.owner.hide();
-			}
-		}
-	},
-
-
-	onDocumentTouchStart : function (e) {
-		if (!e) { e = window.event; }
-		var target = e.target || e.srcElement;
-
-		if (target._jscLinkedInstance) {
-			if (target._jscLinkedInstance.showOnClick) {
-				target._jscLinkedInstance.show();
-			}
-		} else if (target._jscControlName) {
-			jsc.onControlPointerStart(e, target, target._jscControlName, 'touch');
-		} else {
-			if (jsc.picker && jsc.picker.owner) {
-				jsc.picker.owner.hide();
-			}
-		}
-	},
-
-
-	onWindowResize : function (e) {
-		jsc.redrawPosition();
-	},
-
-
-	onParentScroll : function (e) {
-		// hide the picker when one of the parent elements is scrolled
-		if (jsc.picker && jsc.picker.owner) {
-			jsc.picker.owner.hide();
-		}
-	},
-
-
-	_pointerMoveEvent : {
-		mouse: 'mousemove',
-		touch: 'touchmove'
-	},
-	_pointerEndEvent : {
-		mouse: 'mouseup',
-		touch: 'touchend'
-	},
-
-
-	_pointerOrigin : null,
-	_capturedTarget : null,
-
-
-	onControlPointerStart : function (e, target, controlName, pointerType) {
-		var thisObj = target._jscInstance;
-
-		jsc.preventDefault(e);
-		jsc.captureTarget(target);
-
-		var registerDragEvents = function (doc, offset) {
-			jsc.attachGroupEvent('drag', doc, jsc._pointerMoveEvent[pointerType],
-				jsc.onDocumentPointerMove(e, target, controlName, pointerType, offset));
-			jsc.attachGroupEvent('drag', doc, jsc._pointerEndEvent[pointerType],
-				jsc.onDocumentPointerEnd(e, target, controlName, pointerType));
-		};
-
-		registerDragEvents(document, [0, 0]);
-
-		if (window.parent && window.frameElement) {
-			var rect = window.frameElement.getBoundingClientRect();
-			var ofs = [-rect.left, -rect.top];
-			registerDragEvents(window.parent.window.document, ofs);
-		}
-
-		var abs = jsc.getAbsPointerPos(e);
-		var rel = jsc.getRelPointerPos(e);
-		jsc._pointerOrigin = {
-			x: abs.x - rel.x,
-			y: abs.y - rel.y
-		};
-
-		switch (controlName) {
-		case 'pad':
-			// if the slider is at the bottom, move it up
-			switch (jsc.getSliderComponent(thisObj)) {
-			case 's': if (thisObj.hsv[1] === 0) { thisObj.fromHSV(null, 100, null); }; break;
-			case 'v': if (thisObj.hsv[2] === 0) { thisObj.fromHSV(null, null, 100); }; break;
-			}
-			jsc.setPad(thisObj, e, 0, 0);
-			break;
-
-		case 'sld':
-			jsc.setSld(thisObj, e, 0);
-			break;
-		}
-
-		jsc.dispatchFineChange(thisObj);
-	},
-
-
-	onDocumentPointerMove : function (e, target, controlName, pointerType, offset) {
-		return function (e) {
-			var thisObj = target._jscInstance;
-			switch (controlName) {
-			case 'pad':
-				if (!e) { e = window.event; }
-				jsc.setPad(thisObj, e, offset[0], offset[1]);
-				jsc.dispatchFineChange(thisObj);
-				break;
-
-			case 'sld':
-				if (!e) { e = window.event; }
-				jsc.setSld(thisObj, e, offset[1]);
-				jsc.dispatchFineChange(thisObj);
-				break;
-			}
-		}
-	},
-
-
-	onDocumentPointerEnd : function (e, target, controlName, pointerType) {
-		return function (e) {
-			var thisObj = target._jscInstance;
-			jsc.detachGroupEvents('drag');
-			jsc.releaseTarget();
-			// Always dispatch changes after detaching outstanding mouse handlers,
-			// in case some user interaction will occur in user's onchange callback
-			// that would intrude with current mouse events
-			jsc.dispatchChange(thisObj);
-		};
-	},
-
-
-	dispatchChange : function (thisObj) {
-		if (thisObj.valueElement) {
-			if (jsc.isElementType(thisObj.valueElement, 'input')) {
-				jsc.fireEvent(thisObj.valueElement, 'change');
-			}
-		}
-	},
-
-
-	dispatchFineChange : function (thisObj) {
-		if (thisObj.onFineChange) {
-			var callback;
-			if (typeof thisObj.onFineChange === 'string') {
-				callback = new Function (thisObj.onFineChange);
-			} else {
-				callback = thisObj.onFineChange;
-			}
-			callback.call(thisObj);
-		}
-	},
-
-
-	setPad : function (thisObj, e, ofsX, ofsY) {
-		var pointerAbs = jsc.getAbsPointerPos(e);
-		var x = ofsX + pointerAbs.x - jsc._pointerOrigin.x - thisObj.padding - thisObj.insetWidth;
-		var y = ofsY + pointerAbs.y - jsc._pointerOrigin.y - thisObj.padding - thisObj.insetWidth;
-
-		var xVal = x * (360 / (thisObj.width - 1));
-		var yVal = 100 - (y * (100 / (thisObj.height - 1)));
-
-		switch (jsc.getPadYComponent(thisObj)) {
-		case 's': thisObj.fromHSV(xVal, yVal, null, jsc.leaveSld); break;
-		case 'v': thisObj.fromHSV(xVal, null, yVal, jsc.leaveSld); break;
-		}
-	},
-
-
-	setSld : function (thisObj, e, ofsY) {
-		var pointerAbs = jsc.getAbsPointerPos(e);
-		var y = ofsY + pointerAbs.y - jsc._pointerOrigin.y - thisObj.padding - thisObj.insetWidth;
-
-		var yVal = 100 - (y * (100 / (thisObj.height - 1)));
-
-		switch (jsc.getSliderComponent(thisObj)) {
-		case 's': thisObj.fromHSV(null, yVal, null, jsc.leavePad); break;
-		case 'v': thisObj.fromHSV(null, null, yVal, jsc.leavePad); break;
-		}
-	},
-
-
-	_vmlNS : 'jsc_vml_',
-	_vmlCSS : 'jsc_vml_css_',
-	_vmlReady : false,
-
-
-	initVML : function () {
-		if (!jsc._vmlReady) {
-			// init VML namespace
-			var doc = document;
-			if (!doc.namespaces[jsc._vmlNS]) {
-				doc.namespaces.add(jsc._vmlNS, 'urn:schemas-microsoft-com:vml');
-			}
-			if (!doc.styleSheets[jsc._vmlCSS]) {
-				var tags = ['shape', 'shapetype', 'group', 'background', 'path', 'formulas', 'handles', 'fill', 'stroke', 'shadow', 'textbox', 'textpath', 'imagedata', 'line', 'polyline', 'curve', 'rect', 'roundrect', 'oval', 'arc', 'image'];
-				var ss = doc.createStyleSheet();
-				ss.owningElement.id = jsc._vmlCSS;
-				for (var i = 0; i < tags.length; i += 1) {
-					ss.addRule(jsc._vmlNS + '\\:' + tags[i], 'behavior:url(#default#VML);');
-				}
-			}
-			jsc._vmlReady = true;
-		}
-	},
-
-
-	createPalette : function () {
-
-		var paletteObj = {
-			elm: null,
-			draw: null
-		};
-
-		if (jsc.isCanvasSupported) {
-			// Canvas implementation for modern browsers
-
-			var canvas = document.createElement('canvas');
-			var ctx = canvas.getContext('2d');
-
-			var drawFunc = function (width, height, type) {
-				canvas.width = width;
-				canvas.height = height;
-
-				ctx.clearRect(0, 0, canvas.width, canvas.height);
-
-				var hGrad = ctx.createLinearGradient(0, 0, canvas.width, 0);
-				hGrad.addColorStop(0 / 6, '#F00');
-				hGrad.addColorStop(1 / 6, '#FF0');
-				hGrad.addColorStop(2 / 6, '#0F0');
-				hGrad.addColorStop(3 / 6, '#0FF');
-				hGrad.addColorStop(4 / 6, '#00F');
-				hGrad.addColorStop(5 / 6, '#F0F');
-				hGrad.addColorStop(6 / 6, '#F00');
-
-				ctx.fillStyle = hGrad;
-				ctx.fillRect(0, 0, canvas.width, canvas.height);
-
-				var vGrad = ctx.createLinearGradient(0, 0, 0, canvas.height);
-				switch (type.toLowerCase()) {
-				case 's':
-					vGrad.addColorStop(0, 'rgba(255,255,255,0)');
-					vGrad.addColorStop(1, 'rgba(255,255,255,1)');
-					break;
-				case 'v':
-					vGrad.addColorStop(0, 'rgba(0,0,0,0)');
-					vGrad.addColorStop(1, 'rgba(0,0,0,1)');
-					break;
-				}
-				ctx.fillStyle = vGrad;
-				ctx.fillRect(0, 0, canvas.width, canvas.height);
-			};
-
-			paletteObj.elm = canvas;
-			paletteObj.draw = drawFunc;
-
-		} else {
-			// VML fallback for IE 7 and 8
-
-			jsc.initVML();
-
-			var vmlContainer = document.createElement('div');
-			vmlContainer.style.position = 'relative';
-			vmlContainer.style.overflow = 'hidden';
-
-			var hGrad = document.createElement(jsc._vmlNS + ':fill');
-			hGrad.type = 'gradient';
-			hGrad.method = 'linear';
-			hGrad.angle = '90';
-			hGrad.colors = '16.67% #F0F, 33.33% #00F, 50% #0FF, 66.67% #0F0, 83.33% #FF0'
-
-			var hRect = document.createElement(jsc._vmlNS + ':rect');
-			hRect.style.position = 'absolute';
-			hRect.style.left = -1 + 'px';
-			hRect.style.top = -1 + 'px';
-			hRect.stroked = false;
-			hRect.appendChild(hGrad);
-			vmlContainer.appendChild(hRect);
-
-			var vGrad = document.createElement(jsc._vmlNS + ':fill');
-			vGrad.type = 'gradient';
-			vGrad.method = 'linear';
-			vGrad.angle = '180';
-			vGrad.opacity = '0';
-
-			var vRect = document.createElement(jsc._vmlNS + ':rect');
-			vRect.style.position = 'absolute';
-			vRect.style.left = -1 + 'px';
-			vRect.style.top = -1 + 'px';
-			vRect.stroked = false;
-			vRect.appendChild(vGrad);
-			vmlContainer.appendChild(vRect);
-
-			var drawFunc = function (width, height, type) {
-				vmlContainer.style.width = width + 'px';
-				vmlContainer.style.height = height + 'px';
-
-				hRect.style.width =
-				vRect.style.width =
-					(width + 1) + 'px';
-				hRect.style.height =
-				vRect.style.height =
-					(height + 1) + 'px';
-
-				// Colors must be specified during every redraw, otherwise IE won't display
-				// a full gradient during a subsequential redraw
-				hGrad.color = '#F00';
-				hGrad.color2 = '#F00';
-
-				switch (type.toLowerCase()) {
-				case 's':
-					vGrad.color = vGrad.color2 = '#FFF';
-					break;
-				case 'v':
-					vGrad.color = vGrad.color2 = '#000';
-					break;
-				}
-			};
-			
-			paletteObj.elm = vmlContainer;
-			paletteObj.draw = drawFunc;
-		}
-
-		return paletteObj;
-	},
-
-
-	createSliderGradient : function () {
-
-		var sliderObj = {
-			elm: null,
-			draw: null
-		};
-
-		if (jsc.isCanvasSupported) {
-			// Canvas implementation for modern browsers
-
-			var canvas = document.createElement('canvas');
-			var ctx = canvas.getContext('2d');
-
-			var drawFunc = function (width, height, color1, color2) {
-				canvas.width = width;
-				canvas.height = height;
-
-				ctx.clearRect(0, 0, canvas.width, canvas.height);
-
-				var grad = ctx.createLinearGradient(0, 0, 0, canvas.height);
-				grad.addColorStop(0, color1);
-				grad.addColorStop(1, color2);
-
-				ctx.fillStyle = grad;
-				ctx.fillRect(0, 0, canvas.width, canvas.height);
-			};
-
-			sliderObj.elm = canvas;
-			sliderObj.draw = drawFunc;
-
-		} else {
-			// VML fallback for IE 7 and 8
-
-			jsc.initVML();
-
-			var vmlContainer = document.createElement('div');
-			vmlContainer.style.position = 'relative';
-			vmlContainer.style.overflow = 'hidden';
-
-			var grad = document.createElement(jsc._vmlNS + ':fill');
-			grad.type = 'gradient';
-			grad.method = 'linear';
-			grad.angle = '180';
-
-			var rect = document.createElement(jsc._vmlNS + ':rect');
-			rect.style.position = 'absolute';
-			rect.style.left = -1 + 'px';
-			rect.style.top = -1 + 'px';
-			rect.stroked = false;
-			rect.appendChild(grad);
-			vmlContainer.appendChild(rect);
-
-			var drawFunc = function (width, height, color1, color2) {
-				vmlContainer.style.width = width + 'px';
-				vmlContainer.style.height = height + 'px';
-
-				rect.style.width = (width + 1) + 'px';
-				rect.style.height = (height + 1) + 'px';
-
-				grad.color = color1;
-				grad.color2 = color2;
-			};
-			
-			sliderObj.elm = vmlContainer;
-			sliderObj.draw = drawFunc;
-		}
-
-		return sliderObj;
-	},
-
-
-	leaveValue : 1<<0,
-	leaveStyle : 1<<1,
-	leavePad : 1<<2,
-	leaveSld : 1<<3,
-
-
-	BoxShadow : (function () {
-		var BoxShadow = function (hShadow, vShadow, blur, spread, color, inset) {
-			this.hShadow = hShadow;
-			this.vShadow = vShadow;
-			this.blur = blur;
-			this.spread = spread;
-			this.color = color;
-			this.inset = !!inset;
-		};
-
-		BoxShadow.prototype.toString = function () {
-			var vals = [
-				Math.round(this.hShadow) + 'px',
-				Math.round(this.vShadow) + 'px',
-				Math.round(this.blur) + 'px',
-				Math.round(this.spread) + 'px',
-				this.color
-			];
-			if (this.inset) {
-				vals.push('inset');
-			}
-			return vals.join(' ');
-		};
-
-		return BoxShadow;
-	})(),
-
-
-	//
-	// Usage:
-	// var myColor = new jscolor(<targetElement> [, <options>])
-	//
-
-	jscolor : function (targetElement, options) {
-
-		// General options
-		//
-		this.value = null; // initial HEX color. To change it later, use methods fromString(), fromHSV() and fromRGB()
-		this.valueElement = targetElement; // element that will be used to display and input the color code
-		this.styleElement = targetElement; // element that will preview the picked color using CSS backgroundColor
-		this.required = true; // whether the associated text <input> can be left empty
-		this.refine = true; // whether to refine the entered color code (e.g. uppercase it and remove whitespace)
-		this.hash = false; // whether to prefix the HEX color code with # symbol
-		this.uppercase = true; // whether to show the color code in upper case
-		this.onFineChange = null; // called instantly every time the color changes (value can be either a function or a string with javascript code)
-		this.activeClass = 'jscolor-active'; // class to be set to the target element when a picker window is open on it
-		this.overwriteImportant = false; // whether to overwrite colors of styleElement using !important
-		this.minS = 0; // min allowed saturation (0 - 100)
-		this.maxS = 100; // max allowed saturation (0 - 100)
-		this.minV = 0; // min allowed value (brightness) (0 - 100)
-		this.maxV = 100; // max allowed value (brightness) (0 - 100)
-
-		// Accessing the picked color
-		//
-		this.hsv = [0, 0, 100]; // read-only  [0-360, 0-100, 0-100]
-		this.rgb = [255, 255, 255]; // read-only  [0-255, 0-255, 0-255]
-
-		// Color Picker options
-		//
-		this.width = 181; // width of color palette (in px)
-		this.height = 101; // height of color palette (in px)
-		this.showOnClick = true; // whether to display the color picker when user clicks on its target element
-		this.mode = 'HSV'; // HSV | HVS | HS | HV - layout of the color picker controls
-		this.position = 'bottom'; // left | right | top | bottom - position relative to the target element
-		this.smartPosition = true; // automatically change picker position when there is not enough space for it
-		this.sliderSize = 16; // px
-		this.crossSize = 8; // px
-		this.closable = false; // whether to display the Close button
-		this.closeText = 'Close';
-		this.buttonColor = '#000000'; // CSS color
-		this.buttonHeight = 18; // px
-		this.padding = 12; // px
-		this.backgroundColor = '#FFFFFF'; // CSS color
-		this.borderWidth = 1; // px
-		this.borderColor = '#BBBBBB'; // CSS color
-		this.borderRadius = 8; // px
-		this.insetWidth = 1; // px
-		this.insetColor = '#BBBBBB'; // CSS color
-		this.shadow = true; // whether to display shadow
-		this.shadowBlur = 15; // px
-		this.shadowColor = 'rgba(0,0,0,0.2)'; // CSS color
-		this.pointerColor = '#4C4C4C'; // px
-		this.pointerBorderColor = '#FFFFFF'; // px
-        this.pointerBorderWidth = 1; // px
-        this.pointerThickness = 2; // px
-		this.zIndex = 1000;
-		this.container = null; // where to append the color picker (BODY element by default)
-
-
-		for (var opt in options) {
-			if (options.hasOwnProperty(opt)) {
-				this[opt] = options[opt];
-			}
-		}
-
-
-		this.hide = function () {
-			if (isPickerOwner()) {
-				detachPicker();
-			}
-		};
-
-
-		this.show = function () {
-			drawPicker();
-		};
-
-
-		this.redraw = function () {
-			if (isPickerOwner()) {
-				drawPicker();
-			}
-		};
-
-
-		this.importColor = function () {
-			if (!this.valueElement) {
-				this.exportColor();
-			} else {
-				if (jsc.isElementType(this.valueElement, 'input')) {
-					if (!this.refine) {
-						if (!this.fromString(this.valueElement.value, jsc.leaveValue)) {
-							if (this.styleElement) {
-								this.styleElement.style.backgroundImage = this.styleElement._jscOrigStyle.backgroundImage;
-								this.styleElement.style.backgroundColor = this.styleElement._jscOrigStyle.backgroundColor;
-								this.styleElement.style.color = this.styleElement._jscOrigStyle.color;
-							}
-							this.exportColor(jsc.leaveValue | jsc.leaveStyle);
-						}
-					} else if (!this.required && /^\s*$/.test(this.valueElement.value)) {
-						this.valueElement.value = '';
-						if (this.styleElement) {
-							this.styleElement.style.backgroundImage = this.styleElement._jscOrigStyle.backgroundImage;
-							this.styleElement.style.backgroundColor = this.styleElement._jscOrigStyle.backgroundColor;
-							this.styleElement.style.color = this.styleElement._jscOrigStyle.color;
-						}
-						this.exportColor(jsc.leaveValue | jsc.leaveStyle);
-
-					} else if (this.fromString(this.valueElement.value)) {
-						// managed to import color successfully from the value -> OK, don't do anything
-					} else {
-						this.exportColor();
-					}
-				} else {
-					// not an input element -> doesn't have any value
-					this.exportColor();
-				}
-			}
-		};
-
-
-		this.exportColor = function (flags) {
-			if (!(flags & jsc.leaveValue) && this.valueElement) {
-				var value = this.toString();
-				if (this.uppercase) { value = value.toUpperCase(); }
-				if (this.hash) { value = '#' + value; }
-
-				if (jsc.isElementType(this.valueElement, 'input')) {
-					this.valueElement.value = value;
-				} else {
-					this.valueElement.innerHTML = value;
-				}
-			}
-			if (!(flags & jsc.leaveStyle)) {
-				if (this.styleElement) {
-					var bgColor = '#' + this.toString();
-					var fgColor = this.isLight() ? '#000' : '#FFF';
-
-					this.styleElement.style.backgroundImage = 'none';
-					this.styleElement.style.backgroundColor = bgColor;
-					this.styleElement.style.color = fgColor;
-
-					if (this.overwriteImportant) {
-						this.styleElement.setAttribute('style',
-							'background: ' + bgColor + ' !important; ' +
-							'color: ' + fgColor + ' !important;'
-						);
-					}
-				}
-			}
-			if (!(flags & jsc.leavePad) && isPickerOwner()) {
-				redrawPad();
-			}
-			if (!(flags & jsc.leaveSld) && isPickerOwner()) {
-				redrawSld();
-			}
-		};
-
-
-		// h: 0-360
-		// s: 0-100
-		// v: 0-100
-		//
-		this.fromHSV = function (h, s, v, flags) { // null = don't change
-			if (h !== null) {
-				if (isNaN(h)) { return false; }
-				h = Math.max(0, Math.min(360, h));
-			}
-			if (s !== null) {
-				if (isNaN(s)) { return false; }
-				s = Math.max(0, Math.min(100, this.maxS, s), this.minS);
-			}
-			if (v !== null) {
-				if (isNaN(v)) { return false; }
-				v = Math.max(0, Math.min(100, this.maxV, v), this.minV);
-			}
-
-			this.rgb = HSV_RGB(
-				h===null ? this.hsv[0] : (this.hsv[0]=h),
-				s===null ? this.hsv[1] : (this.hsv[1]=s),
-				v===null ? this.hsv[2] : (this.hsv[2]=v)
-			);
-
-			this.exportColor(flags);
-		};
-
-
-		// r: 0-255
-		// g: 0-255
-		// b: 0-255
-		//
-		this.fromRGB = function (r, g, b, flags) { // null = don't change
-			if (r !== null) {
-				if (isNaN(r)) { return false; }
-				r = Math.max(0, Math.min(255, r));
-			}
-			if (g !== null) {
-				if (isNaN(g)) { return false; }
-				g = Math.max(0, Math.min(255, g));
-			}
-			if (b !== null) {
-				if (isNaN(b)) { return false; }
-				b = Math.max(0, Math.min(255, b));
-			}
-
-			var hsv = RGB_HSV(
-				r===null ? this.rgb[0] : r,
-				g===null ? this.rgb[1] : g,
-				b===null ? this.rgb[2] : b
-			);
-			if (hsv[0] !== null) {
-				this.hsv[0] = Math.max(0, Math.min(360, hsv[0]));
-			}
-			if (hsv[2] !== 0) {
-				this.hsv[1] = hsv[1]===null ? null : Math.max(0, this.minS, Math.min(100, this.maxS, hsv[1]));
-			}
-			this.hsv[2] = hsv[2]===null ? null : Math.max(0, this.minV, Math.min(100, this.maxV, hsv[2]));
-
-			// update RGB according to final HSV, as some values might be trimmed
-			var rgb = HSV_RGB(this.hsv[0], this.hsv[1], this.hsv[2]);
-			this.rgb[0] = rgb[0];
-			this.rgb[1] = rgb[1];
-			this.rgb[2] = rgb[2];
-
-			this.exportColor(flags);
-		};
-
-
-		this.fromString = function (str, flags) {
-			var m;
-			if (m = str.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i)) {
-				// HEX notation
-				//
-
-				if (m[1].length === 6) {
-					// 6-char notation
-					this.fromRGB(
-						parseInt(m[1].substr(0,2),16),
-						parseInt(m[1].substr(2,2),16),
-						parseInt(m[1].substr(4,2),16),
-						flags
-					);
-				} else {
-					// 3-char notation
-					this.fromRGB(
-						parseInt(m[1].charAt(0) + m[1].charAt(0),16),
-						parseInt(m[1].charAt(1) + m[1].charAt(1),16),
-						parseInt(m[1].charAt(2) + m[1].charAt(2),16),
-						flags
-					);
-				}
-				return true;
-
-			} else if (m = str.match(/^\W*rgba?\(([^)]*)\)\W*$/i)) {
-				var params = m[1].split(',');
-				var re = /^\s*(\d*)(\.\d+)?\s*$/;
-				var mR, mG, mB;
-				if (
-					params.length >= 3 &&
-					(mR = params[0].match(re)) &&
-					(mG = params[1].match(re)) &&
-					(mB = params[2].match(re))
-				) {
-					var r = parseFloat((mR[1] || '0') + (mR[2] || ''));
-					var g = parseFloat((mG[1] || '0') + (mG[2] || ''));
-					var b = parseFloat((mB[1] || '0') + (mB[2] || ''));
-					this.fromRGB(r, g, b, flags);
-					return true;
-				}
-			}
-			return false;
-		};
-
-
-		this.toString = function () {
-			return (
-				(0x100 | Math.round(this.rgb[0])).toString(16).substr(1) +
-				(0x100 | Math.round(this.rgb[1])).toString(16).substr(1) +
-				(0x100 | Math.round(this.rgb[2])).toString(16).substr(1)
-			);
-		};
-
-
-		this.toHEXString = function () {
-			return '#' + this.toString().toUpperCase();
-		};
-
-
-		this.toRGBString = function () {
-			return ('rgb(' +
-				Math.round(this.rgb[0]) + ',' +
-				Math.round(this.rgb[1]) + ',' +
-				Math.round(this.rgb[2]) + ')'
-			);
-		};
-
-
-		this.isLight = function () {
-			return (
-				0.213 * this.rgb[0] +
-				0.715 * this.rgb[1] +
-				0.072 * this.rgb[2] >
-				255 / 2
-			);
-		};
-
-
-		this._processParentElementsInDOM = function () {
-			if (this._linkedElementsProcessed) { return; }
-			this._linkedElementsProcessed = true;
-
-			var elm = this.targetElement;
-			do {
-				// If the target element or one of its parent nodes has fixed position,
-				// then use fixed positioning instead
-				//
-				// Note: In Firefox, getComputedStyle returns null in a hidden iframe,
-				// that's why we need to check if the returned style object is non-empty
-				var currStyle = jsc.getStyle(elm);
-				if (currStyle && currStyle.position.toLowerCase() === 'fixed') {
-					this.fixed = true;
-				}
-
-				if (elm !== this.targetElement) {
-					// Ensure to attach onParentScroll only once to each parent element
-					// (multiple targetElements can share the same parent nodes)
-					//
-					// Note: It's not just offsetParents that can be scrollable,
-					// that's why we loop through all parent nodes
-					if (!elm._jscEventsAttached) {
-						jsc.attachEvent(elm, 'scroll', jsc.onParentScroll);
-						elm._jscEventsAttached = true;
-					}
-				}
-			} while ((elm = elm.parentNode) && !jsc.isElementType(elm, 'body'));
-		};
-
-
-		// r: 0-255
-		// g: 0-255
-		// b: 0-255
-		//
-		// returns: [ 0-360, 0-100, 0-100 ]
-		//
-		function RGB_HSV (r, g, b) {
-			r /= 255;
-			g /= 255;
-			b /= 255;
-			var n = Math.min(Math.min(r,g),b);
-			var v = Math.max(Math.max(r,g),b);
-			var m = v - n;
-			if (m === 0) { return [ null, 0, 100 * v ]; }
-			var h = r===n ? 3+(b-g)/m : (g===n ? 5+(r-b)/m : 1+(g-r)/m);
-			return [
-				60 * (h===6?0:h),
-				100 * (m/v),
-				100 * v
-			];
-		}
-
-
-		// h: 0-360
-		// s: 0-100
-		// v: 0-100
-		//
-		// returns: [ 0-255, 0-255, 0-255 ]
-		//
-		function HSV_RGB (h, s, v) {
-			var u = 255 * (v / 100);
-
-			if (h === null) {
-				return [ u, u, u ];
-			}
-
-			h /= 60;
-			s /= 100;
-
-			var i = Math.floor(h);
-			var f = i%2 ? h-i : 1-(h-i);
-			var m = u * (1 - s);
-			var n = u * (1 - s * f);
-			switch (i) {
-				case 6:
-				case 0: return [u,n,m];
-				case 1: return [n,u,m];
-				case 2: return [m,u,n];
-				case 3: return [m,n,u];
-				case 4: return [n,m,u];
-				case 5: return [u,m,n];
-			}
-		}
-
-
-		function detachPicker () {
-			jsc.unsetClass(THIS.targetElement, THIS.activeClass);
-			jsc.picker.wrap.parentNode.removeChild(jsc.picker.wrap);
-			delete jsc.picker.owner;
-		}
-
-
-		function drawPicker () {
-
-			// At this point, when drawing the picker, we know what the parent elements are
-			// and we can do all related DOM operations, such as registering events on them
-			// or checking their positioning
-			THIS._processParentElementsInDOM();
-
-			if (!jsc.picker) {
-				jsc.picker = {
-					owner: null,
-					wrap : document.createElement('div'),
-					box : document.createElement('div'),
-					boxS : document.createElement('div'), // shadow area
-					boxB : document.createElement('div'), // border
-					pad : document.createElement('div'),
-					padB : document.createElement('div'), // border
-					padM : document.createElement('div'), // mouse/touch area
-					padPal : jsc.createPalette(),
-					cross : document.createElement('div'),
-					crossBY : document.createElement('div'), // border Y
-					crossBX : document.createElement('div'), // border X
-					crossLY : document.createElement('div'), // line Y
-					crossLX : document.createElement('div'), // line X
-					sld : document.createElement('div'),
-					sldB : document.createElement('div'), // border
-					sldM : document.createElement('div'), // mouse/touch area
-					sldGrad : jsc.createSliderGradient(),
-					sldPtrS : document.createElement('div'), // slider pointer spacer
-					sldPtrIB : document.createElement('div'), // slider pointer inner border
-					sldPtrMB : document.createElement('div'), // slider pointer middle border
-					sldPtrOB : document.createElement('div'), // slider pointer outer border
-					btn : document.createElement('div'),
-					btnT : document.createElement('span') // text
-				};
-
-				jsc.picker.pad.appendChild(jsc.picker.padPal.elm);
-				jsc.picker.padB.appendChild(jsc.picker.pad);
-				jsc.picker.cross.appendChild(jsc.picker.crossBY);
-				jsc.picker.cross.appendChild(jsc.picker.crossBX);
-				jsc.picker.cross.appendChild(jsc.picker.crossLY);
-				jsc.picker.cross.appendChild(jsc.picker.crossLX);
-				jsc.picker.padB.appendChild(jsc.picker.cross);
-				jsc.picker.box.appendChild(jsc.picker.padB);
-				jsc.picker.box.appendChild(jsc.picker.padM);
-
-				jsc.picker.sld.appendChild(jsc.picker.sldGrad.elm);
-				jsc.picker.sldB.appendChild(jsc.picker.sld);
-				jsc.picker.sldB.appendChild(jsc.picker.sldPtrOB);
-				jsc.picker.sldPtrOB.appendChild(jsc.picker.sldPtrMB);
-				jsc.picker.sldPtrMB.appendChild(jsc.picker.sldPtrIB);
-				jsc.picker.sldPtrIB.appendChild(jsc.picker.sldPtrS);
-				jsc.picker.box.appendChild(jsc.picker.sldB);
-				jsc.picker.box.appendChild(jsc.picker.sldM);
-
-				jsc.picker.btn.appendChild(jsc.picker.btnT);
-				jsc.picker.box.appendChild(jsc.picker.btn);
-
-				jsc.picker.boxB.appendChild(jsc.picker.box);
-				jsc.picker.wrap.appendChild(jsc.picker.boxS);
-				jsc.picker.wrap.appendChild(jsc.picker.boxB);
-			}
-
-			var p = jsc.picker;
-
-			var displaySlider = !!jsc.getSliderComponent(THIS);
-			var dims = jsc.getPickerDims(THIS);
-			var crossOuterSize = (2 * THIS.pointerBorderWidth + THIS.pointerThickness + 2 * THIS.crossSize);
-			var padToSliderPadding = jsc.getPadToSliderPadding(THIS);
-			var borderRadius = Math.min(
-				THIS.borderRadius,
-				Math.round(THIS.padding * Math.PI)); // px
-			var padCursor = 'crosshair';
-
-			// wrap
-			p.wrap.style.clear = 'both';
-			p.wrap.style.width = (dims[0] + 2 * THIS.borderWidth) + 'px';
-			p.wrap.style.height = (dims[1] + 2 * THIS.borderWidth) + 'px';
-			p.wrap.style.zIndex = THIS.zIndex;
-
-			// picker
-			p.box.style.width = dims[0] + 'px';
-			p.box.style.height = dims[1] + 'px';
-
-			p.boxS.style.position = 'absolute';
-			p.boxS.style.left = '0';
-			p.boxS.style.top = '0';
-			p.boxS.style.width = '100%';
-			p.boxS.style.height = '100%';
-			jsc.setBorderRadius(p.boxS, borderRadius + 'px');
-
-			// picker border
-			p.boxB.style.position = 'relative';
-			p.boxB.style.border = THIS.borderWidth + 'px solid';
-			p.boxB.style.borderColor = THIS.borderColor;
-			p.boxB.style.background = THIS.backgroundColor;
-			jsc.setBorderRadius(p.boxB, borderRadius + 'px');
-
-			// IE hack:
-			// If the element is transparent, IE will trigger the event on the elements under it,
-			// e.g. on Canvas or on elements with border
-			p.padM.style.background =
-			p.sldM.style.background =
-				'#FFF';
-			jsc.setStyle(p.padM, 'opacity', '0');
-			jsc.setStyle(p.sldM, 'opacity', '0');
-
-			// pad
-			p.pad.style.position = 'relative';
-			p.pad.style.width = THIS.width + 'px';
-			p.pad.style.height = THIS.height + 'px';
-
-			// pad palettes (HSV and HVS)
-			p.padPal.draw(THIS.width, THIS.height, jsc.getPadYComponent(THIS));
-
-			// pad border
-			p.padB.style.position = 'absolute';
-			p.padB.style.left = THIS.padding + 'px';
-			p.padB.style.top = THIS.padding + 'px';
-			p.padB.style.border = THIS.insetWidth + 'px solid';
-			p.padB.style.borderColor = THIS.insetColor;
-
-			// pad mouse area
-			p.padM._jscInstance = THIS;
-			p.padM._jscControlName = 'pad';
-			p.padM.style.position = 'absolute';
-			p.padM.style.left = '0';
-			p.padM.style.top = '0';
-			p.padM.style.width = (THIS.padding + 2 * THIS.insetWidth + THIS.width + padToSliderPadding / 2) + 'px';
-			p.padM.style.height = dims[1] + 'px';
-			p.padM.style.cursor = padCursor;
-
-			// pad cross
-			p.cross.style.position = 'absolute';
-			p.cross.style.left =
-			p.cross.style.top =
-				'0';
-			p.cross.style.width =
-			p.cross.style.height =
-				crossOuterSize + 'px';
-
-			// pad cross border Y and X
-			p.crossBY.style.position =
-			p.crossBX.style.position =
-				'absolute';
-			p.crossBY.style.background =
-			p.crossBX.style.background =
-				THIS.pointerBorderColor;
-			p.crossBY.style.width =
-			p.crossBX.style.height =
-				(2 * THIS.pointerBorderWidth + THIS.pointerThickness) + 'px';
-			p.crossBY.style.height =
-			p.crossBX.style.width =
-				crossOuterSize + 'px';
-			p.crossBY.style.left =
-			p.crossBX.style.top =
-				(Math.floor(crossOuterSize / 2) - Math.floor(THIS.pointerThickness / 2) - THIS.pointerBorderWidth) + 'px';
-			p.crossBY.style.top =
-			p.crossBX.style.left =
-				'0';
-
-			// pad cross line Y and X
-			p.crossLY.style.position =
-			p.crossLX.style.position =
-				'absolute';
-			p.crossLY.style.background =
-			p.crossLX.style.background =
-				THIS.pointerColor;
-			p.crossLY.style.height =
-			p.crossLX.style.width =
-				(crossOuterSize - 2 * THIS.pointerBorderWidth) + 'px';
-			p.crossLY.style.width =
-			p.crossLX.style.height =
-				THIS.pointerThickness + 'px';
-			p.crossLY.style.left =
-			p.crossLX.style.top =
-				(Math.floor(crossOuterSize / 2) - Math.floor(THIS.pointerThickness / 2)) + 'px';
-			p.crossLY.style.top =
-			p.crossLX.style.left =
-				THIS.pointerBorderWidth + 'px';
-
-			// slider
-			p.sld.style.overflow = 'hidden';
-			p.sld.style.width = THIS.sliderSize + 'px';
-			p.sld.style.height = THIS.height + 'px';
-
-			// slider gradient
-			p.sldGrad.draw(THIS.sliderSize, THIS.height, '#000', '#000');
-
-			// slider border
-			p.sldB.style.display = displaySlider ? 'block' : 'none';
-			p.sldB.style.position = 'absolute';
-			p.sldB.style.right = THIS.padding + 'px';
-			p.sldB.style.top = THIS.padding + 'px';
-			p.sldB.style.border = THIS.insetWidth + 'px solid';
-			p.sldB.style.borderColor = THIS.insetColor;
-
-			// slider mouse area
-			p.sldM._jscInstance = THIS;
-			p.sldM._jscControlName = 'sld';
-			p.sldM.style.display = displaySlider ? 'block' : 'none';
-			p.sldM.style.position = 'absolute';
-			p.sldM.style.right = '0';
-			p.sldM.style.top = '0';
-			p.sldM.style.width = (THIS.sliderSize + padToSliderPadding / 2 + THIS.padding + 2 * THIS.insetWidth) + 'px';
-			p.sldM.style.height = dims[1] + 'px';
-			p.sldM.style.cursor = 'default';
-
-			// slider pointer inner and outer border
-			p.sldPtrIB.style.border =
-			p.sldPtrOB.style.border =
-				THIS.pointerBorderWidth + 'px solid ' + THIS.pointerBorderColor;
-
-			// slider pointer outer border
-			p.sldPtrOB.style.position = 'absolute';
-			p.sldPtrOB.style.left = -(2 * THIS.pointerBorderWidth + THIS.pointerThickness) + 'px';
-			p.sldPtrOB.style.top = '0';
-
-			// slider pointer middle border
-			p.sldPtrMB.style.border = THIS.pointerThickness + 'px solid ' + THIS.pointerColor;
-
-			// slider pointer spacer
-			p.sldPtrS.style.width = THIS.sliderSize + 'px';
-			p.sldPtrS.style.height = sliderPtrSpace + 'px';
-
-			// the Close button
-			function setBtnBorder () {
-				var insetColors = THIS.insetColor.split(/\s+/);
-				var outsetColor = insetColors.length < 2 ? insetColors[0] : insetColors[1] + ' ' + insetColors[0] + ' ' + insetColors[0] + ' ' + insetColors[1];
-				p.btn.style.borderColor = outsetColor;
-			}
-			p.btn.style.display = THIS.closable ? 'block' : 'none';
-			p.btn.style.position = 'absolute';
-			p.btn.style.left = THIS.padding + 'px';
-			p.btn.style.bottom = THIS.padding + 'px';
-			p.btn.style.padding = '0 15px';
-			p.btn.style.height = THIS.buttonHeight + 'px';
-			p.btn.style.border = THIS.insetWidth + 'px solid';
-			setBtnBorder();
-			p.btn.style.color = THIS.buttonColor;
-			p.btn.style.font = '12px sans-serif';
-			p.btn.style.textAlign = 'center';
-			try {
-				p.btn.style.cursor = 'pointer';
-			} catch(eOldIE) {
-				p.btn.style.cursor = 'hand';
-			}
-			p.btn.onmousedown = function () {
-				THIS.hide();
-			};
-			p.btnT.style.lineHeight = THIS.buttonHeight + 'px';
-			p.btnT.innerHTML = '';
-			p.btnT.appendChild(document.createTextNode(THIS.closeText));
-
-			// place pointers
-			redrawPad();
-			redrawSld();
-
-			// If we are changing the owner without first closing the picker,
-			// make sure to first deal with the old owner
-			if (jsc.picker.owner && jsc.picker.owner !== THIS) {
-				jsc.unsetClass(jsc.picker.owner.targetElement, THIS.activeClass);
-			}
-
-			// Set the new picker owner
-			jsc.picker.owner = THIS;
-
-			// The redrawPosition() method needs picker.owner to be set, that's why we call it here,
-			// after setting the owner
-			if (jsc.isElementType(container, 'body')) {
-				jsc.redrawPosition();
-			} else {
-				jsc._drawPosition(THIS, 0, 0, 'relative', false);
-			}
-
-			if (p.wrap.parentNode != container) {
-				container.appendChild(p.wrap);
-			}
-
-			jsc.setClass(THIS.targetElement, THIS.activeClass);
-		}
-
-
-		function redrawPad () {
-			// redraw the pad pointer
-			switch (jsc.getPadYComponent(THIS)) {
-			case 's': var yComponent = 1; break;
-			case 'v': var yComponent = 2; break;
-			}
-			var x = Math.round((THIS.hsv[0] / 360) * (THIS.width - 1));
-			var y = Math.round((1 - THIS.hsv[yComponent] / 100) * (THIS.height - 1));
-			var crossOuterSize = (2 * THIS.pointerBorderWidth + THIS.pointerThickness + 2 * THIS.crossSize);
-			var ofs = -Math.floor(crossOuterSize / 2);
-			jsc.picker.cross.style.left = (x + ofs) + 'px';
-			jsc.picker.cross.style.top = (y + ofs) + 'px';
-
-			// redraw the slider
-			switch (jsc.getSliderComponent(THIS)) {
-			case 's':
-				var rgb1 = HSV_RGB(THIS.hsv[0], 100, THIS.hsv[2]);
-				var rgb2 = HSV_RGB(THIS.hsv[0], 0, THIS.hsv[2]);
-				var color1 = 'rgb(' +
-					Math.round(rgb1[0]) + ',' +
-					Math.round(rgb1[1]) + ',' +
-					Math.round(rgb1[2]) + ')';
-				var color2 = 'rgb(' +
-					Math.round(rgb2[0]) + ',' +
-					Math.round(rgb2[1]) + ',' +
-					Math.round(rgb2[2]) + ')';
-				jsc.picker.sldGrad.draw(THIS.sliderSize, THIS.height, color1, color2);
-				break;
-			case 'v':
-				var rgb = HSV_RGB(THIS.hsv[0], THIS.hsv[1], 100);
-				var color1 = 'rgb(' +
-					Math.round(rgb[0]) + ',' +
-					Math.round(rgb[1]) + ',' +
-					Math.round(rgb[2]) + ')';
-				var color2 = '#000';
-				jsc.picker.sldGrad.draw(THIS.sliderSize, THIS.height, color1, color2);
-				break;
-			}
-		}
-
-
-		function redrawSld () {
-			var sldComponent = jsc.getSliderComponent(THIS);
-			if (sldComponent) {
-				// redraw the slider pointer
-				switch (sldComponent) {
-				case 's': var yComponent = 1; break;
-				case 'v': var yComponent = 2; break;
-				}
-				var y = Math.round((1 - THIS.hsv[yComponent] / 100) * (THIS.height - 1));
-				jsc.picker.sldPtrOB.style.top = (y - (2 * THIS.pointerBorderWidth + THIS.pointerThickness) - Math.floor(sliderPtrSpace / 2)) + 'px';
-			}
-		}
-
-
-		function isPickerOwner () {
-			return jsc.picker && jsc.picker.owner === THIS;
-		}
-
-
-		function blurValue () {
-			THIS.importColor();
-		}
-
-
-		// Find the target element
-		if (typeof targetElement === 'string') {
-			var id = targetElement;
-			var elm = document.getElementById(id);
-			if (elm) {
-				this.targetElement = elm;
-			} else {
-				jsc.warn('Could not find target element with ID \'' + id + '\'');
-			}
-		} else if (targetElement) {
-			this.targetElement = targetElement;
-		} else {
-			jsc.warn('Invalid target element: \'' + targetElement + '\'');
-		}
-
-		if (this.targetElement._jscLinkedInstance) {
-			jsc.warn('Cannot link jscolor twice to the same element. Skipping.');
-			return;
-		}
-		this.targetElement._jscLinkedInstance = this;
-
-		// Find the value element
-		this.valueElement = jsc.fetchElement(this.valueElement);
-		// Find the style element
-		this.styleElement = jsc.fetchElement(this.styleElement);
-
-		var THIS = this;
-		var container =
-			this.container ?
-			jsc.fetchElement(this.container) :
-			document.getElementsByTagName('body')[0];
-		var sliderPtrSpace = 3; // px
-
-		// For BUTTON elements it's important to stop them from sending the form when clicked
-		// (e.g. in Safari)
-		if (jsc.isElementType(this.targetElement, 'button')) {
-			if (this.targetElement.onclick) {
-				var origCallback = this.targetElement.onclick;
-				this.targetElement.onclick = function (evt) {
-					origCallback.call(this, evt);
-					return false;
-				};
-			} else {
-				this.targetElement.onclick = function () { return false; };
-			}
-		}
-
-		/*
-		var elm = this.targetElement;
-		do {
-			// If the target element or one of its offsetParents has fixed position,
-			// then use fixed positioning instead
-			//
-			// Note: In Firefox, getComputedStyle returns null in a hidden iframe,
-			// that's why we need to check if the returned style object is non-empty
-			var currStyle = jsc.getStyle(elm);
-			if (currStyle && currStyle.position.toLowerCase() === 'fixed') {
-				this.fixed = true;
-			}
-
-			if (elm !== this.targetElement) {
-				// attach onParentScroll so that we can recompute the picker position
-				// when one of the offsetParents is scrolled
-				if (!elm._jscEventsAttached) {
-					jsc.attachEvent(elm, 'scroll', jsc.onParentScroll);
-					elm._jscEventsAttached = true;
-				}
-			}
-		} while ((elm = elm.offsetParent) && !jsc.isElementType(elm, 'body'));
-		*/
-
-		// valueElement
-		if (this.valueElement) {
-			if (jsc.isElementType(this.valueElement, 'input')) {
-				var updateField = function () {
-					THIS.fromString(THIS.valueElement.value, jsc.leaveValue);
-					jsc.dispatchFineChange(THIS);
-				};
-				jsc.attachEvent(this.valueElement, 'keyup', updateField);
-				jsc.attachEvent(this.valueElement, 'input', updateField);
-				jsc.attachEvent(this.valueElement, 'blur', blurValue);
-				this.valueElement.setAttribute('autocomplete', 'off');
-			}
-		}
-
-		// styleElement
-		if (this.styleElement) {
-			this.styleElement._jscOrigStyle = {
-				backgroundImage : this.styleElement.style.backgroundImage,
-				backgroundColor : this.styleElement.style.backgroundColor,
-				color : this.styleElement.style.color
-			};
-		}
-
-		if (this.value) {
-			// Try to set the color from the .value option and if unsuccessful,
-			// export the current color
-			this.fromString(this.value) || this.exportColor();
-		} else {
-			this.importColor();
-		}
-	}
-
-};
-
-
-//================================
-// Public properties and methods
-//================================
-
-
-// By default, search for all elements with class="jscolor" and install a color picker on them.
-//
-// You can change what class name will be looked for by setting the property jscolor.lookupClass
-// anywhere in your HTML document. To completely disable the automatic lookup, set it to null.
-//
-jsc.jscolor.lookupClass = 'jscolor';
-
-
-jsc.jscolor.installByClassName = function (className) {
-	var inputElms = document.getElementsByTagName('input');
-	var buttonElms = document.getElementsByTagName('button');
-
-	jsc.tryInstallOnElements(inputElms, className);
-	jsc.tryInstallOnElements(buttonElms, className);
-};
-
-
-jsc.register();
-
-
-return jsc.jscolor;
-
-
-})(); }

+ 0 - 186
spine-ts/spine-player/example/generator/loader.js

@@ -1,186 +0,0 @@
-var spineGenerator;
-
-(function (spineGenerator) {
-	var Loader = (function () {
-		function Loader() {
-		}
-
-		Loader.loadSkeletonFiles = function(files, success, error) {
-			var skels = 0;
-			var skelFile = null;
-			var jsons = 0;
-			var jsonFile = null;
-			var atlases = 0;
-			var atlasFile = null;
-			var pngs = 0;
-
-			for (var i = 0; i < files.length; i++) {
-				var file = files[i].name.toLowerCase();
-				if (file.endsWith(".skel")) {
-					skels++;
-					skelFile = file;
-				}
-				if (file.endsWith(".json")) {
-					jsons++;
-					jsonFile = file;
-				}
-				if (file.endsWith(".atlas")) {
-					atlases++;
-					atlasFile = file;
-				}
-				if (file.endsWith(".png")) pngs++;
-			}
-
-			if ((skels == 0 && jsons == 0) || (skels != 0 && jsons != 0) || skels > 1 || jsons > 1) {
-				error("Please specify a single .skel or .json file.");
-				return;
-			}
-
-			if (atlases != 1) {
-				error("Please specify a single .atlas file.");
-				return;
-			}
-
-			var filesToLoad = files.length;
-			var dataUrls = {};
-			for (var i = 0; i < files.length; i++) {
-				var file = files[i];
-				var reader = new FileReader();
-				reader.onload = function(file) {
-					return function(dataUrl) {
-						console.log("Loaded " + file.name);
-						dataUrls[file.name] = dataUrl.target.result;
-						filesToLoad--;
-						if (filesToLoad == 0) {
-							var data = {
-								dataUrls: dataUrls,
-								jsonFile: jsonFile,
-								skelFile: skelFile,
-								atlasFile: atlasFile
-							};
-							var version = data.version = Loader.getSkeletonVersion(data);
-							data.majorVersion = parseInt(version.split("\.")[0]);
-							data.minorVersion = parseInt(version.split("\.")[1]);
-							data.patchVersion = parseInt(version.split("\.")[2]);
-							success(data);
-						}
-					};
-				}(file);
-				reader.onerror = function () {
-					error("Sorry, couldn't load all files.");
-				}
-				reader.readAsDataURL(file);
-			}
-		}
-
-		Loader.getSkeletonVersion = function (data) {
-			var jsonFile = data.jsonFile;
-			var skelFile = data.skelFile;
-			var dataUrls = data.dataUrls;
-			if (jsonFile) {
-				var json = JSON.parse(atob(dataUrls[jsonFile].split(',')[1]));
-				return json.skeleton.spine;
-			} else {
-				var bytes = atob(dataUrls[skelFile].split(',')[1]);
-				var array = new Uint8Array(new ArrayBuffer(bytes.length));
-				for (var i = 0; i < bytes.length; i++) {
-					array[i] = bytes.charCodeAt(i);
-				}
-
-				var input = new BinaryInput(array);
-				input.readString();
-				var version = input.readString();
-				return version;
-			}
-		}
-
-		Loader.loadJavaScript = function (url, success, error) {
-			var script = document.createElement('script');
-			script.setAttribute('src', url);
-			script.setAttribute('type', 'text/javascript');
-			script.onload = success;
-			script.onerror = error;
-			document.getElementsByTagName("head")[0].appendChild(script);
-		};
-
-		Loader.loadStyle = function(url, success, error) {
-			var style = document.createElement('link');
-			style.setAttribute('href', url);
-			style.setAttribute('rel', 'stylesheet');
-			style.onload = success;
-			style.onerror = error;
-			document.getElementsByTagName("head")[0].appendChild(style);
-		};
-
-		var BinaryInput = (function () {
-			function BinaryInput(data, strings, index, buffer) {
-				if (strings === void 0) { strings = new Array(); }
-				if (index === void 0) { index = 0; }
-				if (buffer === void 0) { buffer = new DataView(data.buffer); }
-				this.index = index;
-				this.buffer = buffer;
-			}
-
-			BinaryInput.prototype.readByte = function () {
-				return this.buffer.getInt8(this.index++);
-			};
-
-			BinaryInput.prototype.readInt = function (optimizePositive) {
-				var b = this.readByte();
-				var result = b & 0x7F;
-				if ((b & 0x80) != 0) {
-					b = this.readByte();
-					result |= (b & 0x7F) << 7;
-					if ((b & 0x80) != 0) {
-						b = this.readByte();
-						result |= (b & 0x7F) << 14;
-						if ((b & 0x80) != 0) {
-							b = this.readByte();
-							result |= (b & 0x7F) << 21;
-							if ((b & 0x80) != 0) {
-								b = this.readByte();
-								result |= (b & 0x7F) << 28;
-							}
-						}
-					}
-				}
-				return optimizePositive ? result : ((result >>> 1) ^ -(result & 1));
-			};
-
-			BinaryInput.prototype.readString = function () {
-				var byteCount = this.readInt(true);
-				switch (byteCount) {
-					case 0:
-						return null;
-					case 1:
-						return "";
-				}
-				byteCount--;
-				var chars = "";
-				var charCount = 0;
-				for (var i = 0; i < byteCount;) {
-					var b = this.readByte();
-					switch (b >> 4) {
-						case 12:
-						case 13:
-							chars += String.fromCharCode(((b & 0x1F) << 6 | this.readByte() & 0x3F));
-							i += 2;
-							break;
-						case 14:
-							chars += String.fromCharCode(((b & 0x0F) << 12 | (this.readByte() & 0x3F) << 6 | this.readByte() & 0x3F));
-							i += 3;
-							break;
-						default:
-							chars += String.fromCharCode(b);
-							i++;
-					}
-				}
-				return chars;
-			};
-			return BinaryInput;
-		}());
-
-		return Loader;
-	}());
-	spineGenerator.Loader = Loader;
-}(spineGenerator || (spineGenerator = {})));

+ 0 - 66
spine-ts/spine-player/example/generator/ui.js

@@ -1,66 +0,0 @@
-var spineGenerator;
-
-(function (spineGenerator) {
-	var UI = (function () {
-		function UI(dropZone, multiple, acceptedExtensions, callback) {
-		}
-
-		UI.createElement = function (parent, html) {
-			parent.insertAdjacentHTML("beforeend", html);
-			return parent.lastElementChild;
-		}
-
-		UI.clear = function(element) {
-			element.innerHTML = "";
-		}
-
-		UI.hide = function(element) {
-			element.__oldDisplay = element.style.display;
-			element.style.display = "none";
-		}
-
-		UI.show = function(element, display) {
-			if (display) element.style.display = display;
-			else if (element.__oldDisplay) element.style.display = element.__oldDisplay;
-			else element.style.display = "block";
-		}
-
-		return UI;
-	}());
-	spineGenerator.UI = UI;
-}(spineGenerator || (spineGenerator = {})));
-
-(function (spineGenerator) {
-	var UI = spineGenerator.UI;
-	var DropZone = (function () {
-		function DropZone(dropZone, multiple, acceptedExtensions, callback) {
-			var fileButton = this.fileButton = UI.createElement(dropZone,
-				`<input style="display:none;" type="file" ${multiple?"multiple":""} accept="${acceptedExtensions}"/>`);
-
-			dropZone.onclick = function() {
-				fileButton.click();
-			};
-			dropZone.addEventListener("dragenter", function  (event) {
-				event.stopPropagation();
-				event.preventDefault();
-			}, false);
-			dropZone.addEventListener("dragover", function  (event) {
-				event.stopPropagation();
-				event.preventDefault();
-			}, false);
-			dropZone.addEventListener("drop", function  (event) {
-				event.stopPropagation();
-				event.preventDefault();
-
-				loadFiles(event.dataTransfer.files);
-			}, false);
-
-			fileButton.onchange = function () {
-				callback(fileButton.files);
-				fileButton.value = "";
-			};
-		}
-		return DropZone;
-	}());
-	spineGenerator.UI.DropZone = DropZone;
-}(spineGenerator || (spineGenerator = {})));

+ 141 - 0
spine-ts/spine-player/src/PlayerEditor.ts

@@ -0,0 +1,141 @@
+/******************************************************************************
+ * Spine Runtimes License Agreement
+ * Last updated January 1, 2020. Replaces all prior versions.
+ *
+ * Copyright (c) 2013-2020, Esoteric Software LLC
+ *
+ * Integration of the Spine Runtimes into software or otherwise creating
+ * derivative works of the Spine Runtimes is permitted under the terms and
+ * conditions of Section 2 of the Spine Editor License Agreement:
+ * http://esotericsoftware.com/spine-editor-license
+ *
+ * Otherwise, it is permitted to integrate the Spine Runtimes into software
+ * or otherwise create derivative works of the Spine Runtimes (collectively,
+ * "Products"), provided that each user of the Products must obtain their own
+ * Spine Editor license and redistribution of the Products in any form must
+ * include this license and copyright notice.
+ *
+ * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
+ * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *****************************************************************************/
+
+declare function CodeMirror (el: Element, config: any): void;
+
+function loadScript(url: string): Promise<void> {
+    return new Promise((resolve, reject) => {
+        const script = document.createElement('script');
+        script.src = url;
+        script.onload = () => resolve();
+        script.onerror = () => reject(new Error(`Script load error for ${url}`));
+        document.head.appendChild(script);
+    });
+}
+
+function loadCss(url: string): Promise<void> {
+    return new Promise((resolve, reject) => {
+        const link = document.createElement('link');
+        link.href = url;
+        link.rel = 'stylesheet';
+        link.onload = () => resolve();
+        link.onerror = () => reject(new Error(`CSS load error for ${url}`));
+        document.head.appendChild(link);
+    });
+}
+
+export class SpinePlayerEditor {
+	private static DEFAULT_CODE =
+		`
+<script src="https://esotericsoftware.com/files/spine-player/4.1/spine-player.js"></script>
+<link rel="stylesheet" href="https://esotericsoftware.com/files/spine-player/4.1/spine-player.css">
+
+<div id="player-container" style="width: 100vw; height: 100vh;"></div>
+
+<script>
+new spine.SpinePlayer("player-container", {
+	jsonUrl: "https://esotericsoftware.com/files/examples/4.1/spineboy/export/spineboy-pro.json",
+	atlasUrl: "https://esotericsoftware.com/files/examples/4.1/spineboy/export/spineboy-pma.atlas"
+});
+</script>
+		`.trim();
+
+	private prefix: string =
+		`<html>
+<head>
+<style>
+body { margin: 0px; }
+</style>
+</head>
+<body>`.trim()
+	private postfix: string = `</body>`;
+	private code: any;
+	private player?: HTMLIFrameElement;
+
+	constructor (private readonly parent: HTMLElement) {
+		this.load();
+	}
+
+	private async load() {
+		await Promise.all([loadScript("https://www.unpkg.com/[email protected]/lib/codemirror.js"), loadCss("https://www.unpkg.com/[email protected]/lib/codemirror.css")]);
+		this.render(this.parent);
+	}
+
+	private render (parent: HTMLElement) {
+		let dom = /*html*/`
+				<div style="display: flex; flex-direction: column; width: 100%; height: 100%;">
+					<div style="width: 100%; height: 50%;"></div>
+					<iframe style="width: 100%; height: 50%; outline: none; border: none;"></iframe>
+				</div>
+			`;
+		parent.innerHTML = dom;
+		let codeElement = parent.children[0].children[0];
+		this.player = parent.children[0].children[1] as HTMLIFrameElement;
+
+		requestAnimationFrame(() => {
+			this.code = CodeMirror(codeElement, {
+				lineNumbers: true,
+				tabSize: 3,
+				indentUnit: 3,
+				indentWithTabs: true,
+				scrollBarStyle: "native",
+				mode: "htmlmixed",
+				theme: "monokai"
+			});
+			this.code.on("change", () => {
+				this.startPlayer();
+			});
+
+			this.setCode(SpinePlayerEditor.DEFAULT_CODE);
+		})
+	}
+
+	setPreAndPostfix (prefix: string, postfix: string) {
+		this.prefix = prefix;
+		this.postfix = postfix;
+		this.startPlayer()
+	}
+
+	setCode (code: string) {
+		this.code.setValue(code);
+		this.startPlayer();
+	}
+
+	private timerId = 0;
+	startPlayer () {
+		clearTimeout(this.timerId);
+		this.timerId = setTimeout(() => {
+			let code = this.code.getDoc().getValue();
+			code = this.prefix + code + this.postfix;
+			code = window.btoa(code);
+			this.player!.src = "";
+			this.player!.src = "data:text/html;base64," + code;
+		}, 500);
+	}
+}

+ 1 - 0
spine-ts/spine-player/src/index.ts

@@ -1,3 +1,4 @@
 export * from './Player.js';
+export * from './PlayerEditor.js';
 export * from "@esotericsoftware/spine-core";
 export * from "@esotericsoftware/spine-webgl";