1/* Minification failed. Returning unminified contents. 2(27,20-21): run-time error JS1195: Expected expression: ) 3(27,23-24): run-time error JS1195: Expected expression: > 4(28,27-28): run-time error JS1195: Expected expression: > 5(34,30-31): run-time error JS1195: Expected expression: ) 6(34,33-34): run-time error JS1195: Expected expression: > 7(39,1-2): run-time error JS1002: Syntax error: } 8(40,23-24): run-time error JS1195: Expected expression: > 9(42,1-2): run-time error JS1002: Syntax error: } 10(43,56-57): run-time error JS1195: Expected expression: > 11(48,27-37): run-time error JS1004: Expected ';': readAsText 12(54,65-66): run-time error JS1003: Expected ':': } 13(54,69-70): run-time error JS1195: Expected expression: > 14(55,53-54): run-time error JS1195: Expected expression: > 15(55,76-77): run-time error JS1004: Expected ';': ) 16(58,1-2): run-time error JS1002: Syntax error: } 17(86,11-12): run-time error JS1195: Expected expression: ) 18(86,13-14): run-time error JS1004: Expected ';': { 19(1810,2-3): run-time error JS1195: Expected expression: ) 20(1825,22-23): run-time error JS1004: Expected ';': { 21(5078,3-4): run-time error JS1004: Expected ';': ) 22(5080,2-8): run-time error JS1197: Too many errors. The file might not be a JavaScript file: jQuery 23(57,5-77): run-time error JS1018: 'return' statement outside of function: return disallowedSvgElements.length === 0 && !hasScriptAttr ? svg : null 24(47,9-19): run-time error JS1018: 'return' statement outside of function: return svg 25(41,5-34): run-time error JS1018: 'return' statement outside of function: return obj.size !== undefined 26 */ 27const svgDisallowed = [ 28 'a', 29 'animate', 30 'color-profile', 31 'cursor', 32 'discard', 33 'fedropshadow', 34 'font-face', 35 'font-face-format', 36 'font-face-name', 37 'font-face-src', 38 'font-face-uri', 39 'foreignobject', 40 'hatch', 41 'hatchpath', 42 'mesh', 43 'meshgradient', 44 'meshpatch', 45 'meshrow', 46 'missing-glyph', 47 'script', 48 'set', 49 'solidcolor', 50 'unknown', 51 'use' 52]; 53const getWindow = () => (typeof window === 'undefined' ? null : window); 54const readAsText = (svg) => new Promise((resolve) => { 55 if (!isFile(svg)) { 56 resolve(svg.toString('utf-8')); 57 } 58 else { 59 const fileReader = new FileReader(); 60 fileReader.onload = () => { 61 resolve(fileReader.result); 62 }; 63 fileReader.readAsText(svg); 64 } 65}); 66const isFile = (obj) => { 67 return obj.size !== undefined; 68}; 69const sanitizeSVG = async (svg, window = getWindow()) => { 70 if (!window) 71 throw new Error('DOM window required'); 72 if (isFile(svg) && svg.type !== 'image/svg+xml') 73 return svg; 74 const svgText = await readAsText(svg); 75 if (!svgText) 76 throw new Error('Image corrupt'); 77 const playground = window.document.createElement('template'); 78 playground.innerHTML = svgText; 79 const svgEl = playground.content.firstElementChild; 80 const attributes = Array.from(svgEl.attributes).map(({ name }) => name); 81 const hasScriptAttr = !!attributes.find((attr) => attr.startsWith('on')); 82 const disallowedSvgElements = svgEl.querySelectorAll(svgDisallowed.join(',')); 83 return disallowedSvgElements.length === 0 && !hasScriptAttr ? svg : null; 84};; 85 86/* 87 * 88 * More info at [www.dropzonejs.com](http://www.dropzonejs.com) 89 * 90 * Copyright (c) 2012, Matias Meno 91 * 92 * Permission is hereby granted, free of charge, to any person obtaining a copy 93 * of this software and associated documentation files (the "Software"), to deal 94 * in the Software without restriction, including without limitation the rights 95 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 96 * copies of the Software, and to permit persons to whom the Software is 97 * furnished to do so, subject to the following conditions: 98 * 99 * The above copyright notice and this permission notice shall be included in 100 * all copies or substantial portions of the Software. 101 * 102 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 103 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 104 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 105 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 106 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 107 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 108 * THE SOFTWARE. 109 * 110 */ 111 112(function() { 113 var Dropzone, Emitter, camelize, contentLoaded, detectVerticalSquash, drawImageIOSFix, noop, without, 114 __slice = [].slice, 115 __hasProp = {}.hasOwnProperty, 116 __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; 117 118 noop = function() {}; 119 120 Emitter = (function() { 121 function Emitter() {} 122 123 Emitter.prototype.addEventListener = Emitter.prototype.on; 124 125 Emitter.prototype.on = function(event, fn) { 126 this._callbacks = this._callbacks || {}; 127 if (!this._callbacks[event]) { 128 this._callbacks[event] = []; 129 } 130 this._callbacks[event].push(fn); 131 return this; 132 }; 133 134 Emitter.prototype.emit = function() { 135 var args, callback, callbacks, event, _i, _len; 136 event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; 137 this._callbacks = this._callbacks || {}; 138 callbacks = this._callbacks[event]; 139 if (callbacks) { 140 for (_i = 0, _len = callbacks.length; _i < _len; _i++) { 141 callback = callbacks[_i]; 142 callback.apply(this, args); 143 } 144 } 145 return this; 146 }; 147 148 Emitter.prototype.removeListener = Emitter.prototype.off; 149 150 Emitter.prototype.removeAllListeners = Emitter.prototype.off; 151 152 Emitter.prototype.removeEventListener = Emitter.prototype.off; 153 154 Emitter.prototype.off = function(event, fn) { 155 var callback, callbacks, i, _i, _len; 156 if (!this._callbacks || arguments.length === 0) { 157 this._callbacks = {}; 158 return this; 159 } 160 callbacks = this._callbacks[event]; 161 if (!callbacks) { 162 return this; 163 } 164 if (arguments.length === 1) { 165 delete this._callbacks[event]; 166 return this; 167 } 168 for (i = _i = 0, _len = callbacks.length; _i < _len; i = ++_i) { 169 callback = callbacks[i]; 170 if (callback === fn) { 171 callbacks.splice(i, 1); 172 break; 173 } 174 } 175 return this; 176 }; 177 178 return Emitter; 179 180 })();
181 182 Dropzone = (function(_super) { 183 var extend, resolveOption; 184 185 __extends(Dropzone, _super); 186 187 Dropzone.prototype.Emitter = Emitter; 188 189 190 /* 191 This is a list of all available events you can register on a dropzone object. 192 193 You can register an event handler like this: 194 195 dropzone.on("dragEnter", function() { }); 196 */ 197 198 Dropzone.prototype.events = ["drop", "dragstart", "dragend", "dragenter", "dragover", "dragleave", "addedfile", "addedfiles", "removedfile", "thumbnail", "error", "errormultiple", "processing", "processingmultiple", "uploadprogress", "totaluploadprogress", "sending", "sendingmultiple", "success", "successmultiple", "canceled", "canceledmultiple", "complete", "completemultiple", "reset", "maxfilesexceeded", "maxfilesreached", "queuecomplete"]; 199 200 Dropzone.prototype.defaultOptions = { 201 url: null, 202 method: "post", 203 withCredentials: false, 204 parallelUploads: 2, 205 uploadMultiple: false, 206 maxFilesize: 256, 207 paramName: "file", 208 createImageThumbnails: true, 209 maxThumbnailFilesize: 10, 210 thumbnailWidth: 120, 211 thumbnailHeight: 120, 212 filesizeBase: 1000, 213 maxFiles: null, 214 params: {}, 215 clickable: true, 216 ignoreHiddenFiles: true, 217 acceptedFiles: null, 218 acceptedMimeTypes: null, 219 autoProcessQueue: true, 220 autoQueue: true, 221 addRemoveLinks: false, 222 previewsContainer: null, 223 hiddenInputContainer: "body", 224 capture: null, 225 dictDefaultMessage: "Drop files here to upload", 226 dictFallbackMessage: "Your browser does not support drag'n'drop file uploads.", 227 dictFallbackText: "Please use the fallback form below to upload your files like in the olden days.", 228 dictFileTooBig: "File is too big ({{filesize}}MiB). Max filesize: {{maxFilesize}}MiB.", 229 dictInvalidFileType: "You can't upload files of this type.", 230 dictResponseError: "Server responded with {{statusCode}} code.", 231 dictCancelUpload: "Cancel upload", 232 dictCancelUploadConfirmation: "Are you sure you want to cancel this upload?", 233 dictRemoveFile: "Remove file", 234 dictRemoveFileConfirmation: null, 235 dictMaxFilesExceeded: "You can not upload any more files.", 236 accept: function(file, done) { 237 return done(); 238 }, 239 init: function() { 240 return noop; 241 }, 242 forceFallback: false, 243 fallback: function() { 244 var child, messageElement, span, _i, _len, _ref; 245 this.element.className = "" + this.element.className + " dz-browser-not-supported"; 246 _ref = this.element.getElementsByTagName("div"); 247 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 248 child = _ref[_i]; 249 if (/(^| )dz-message($| )/.test(child.className)) { 250 messageElement = child; 251 child.className = "dz-message"; 252 continue; 253 } 254 } 255 if (!messageElement) { 256 messageElement = Dropzone.createElement("<div class=\"dz-message\"><span></span></div>"); 257 this.element.appendChild(messageElement); 258 } 259 span = messageElement.getElementsByTagName("span")[0]; 260 if (span) { 261 if (span.textContent != null) { 262 span.textContent = this.options.dictFallbackMessage; 263 } else if (span.innerText != null) { 264 span.innerText = this.options.dictFallbackMessage; 265 } 266 } 267 return this.element.appendChild(this.getFallbackForm()); 268 }, 269 resize: function(file) { 270 var info, srcRatio, trgRatio; 271 info = { 272 srcX: 0, 273 srcY: 0, 274 srcWidth: file.width, 275 srcHeight: file.height 276 }; 277 srcRatio = file.width / file.height; 278 info.optWidth = this.options.thumbnailWidth; 279 info.optHeight = this.options.thumbnailHeight; 280 if ((info.optWidth == null) && (info.optHeight == null)) { 281 info.optWidth = info.srcWidth; 282 info.optHeight = info.srcHeight; 283 } else if (info.optWidth == null) { 284 info.optWidth = srcRatio * info.optHeight; 285 } else if (info.optHeight == null) { 286 info.optHeight = (1 / srcRatio) * info.optWidth; 287 } 288 trgRatio = info.optWidth / info.optHeight; 289 if (file.height < info.optHeight || file.width < info.optWidth) { 290 info.trgHeight = info.srcHeight; 291 info.trgWidth = info.srcWidth; 292 } else { 293 if (srcRatio > trgRatio) { 294 info.srcHeight = file.height; 295 info.srcWidth = info.srcHeight * trgRatio; 296 } else { 297 info.srcWidth = file.width; 298 info.srcHeight = info.srcWidth / trgRatio; 299 } 300 } 301 info.srcX = (file.width - info.srcWidth) / 2; 302 info.srcY = (file.height - info.srcHeight) / 2; 303 return info; 304 }, 305 306 /* 307 Those functions register themselves to the events on init and handle all 308 the user interface specific stuff. Overwriting them won't break the upload 309 but can break the way it's displayed. 310 You can overwrite them if you don't like the default behavior. If you just 311 want to add an additional event handler, register it on the dropzone object 312 and don't overwrite those options. 313 */ 314 drop: function(e) { 315 return this.element.classList.remove("dz-drag-hover"); 316 }, 317 dragstart: noop, 318 dragend: function(e) { 319 return this.element.classList.remove("dz-drag-hover"); 320 }, 321 dragenter: function(e) { 322 return this.element.classList.add("dz-drag-hover"); 323 }, 324 dragover: function(e) { 325 return this.element.classList.add("dz-drag-hover"); 326 }, 327 dragleave: function(e) { 328 return this.element.classList.remove("dz-drag-hover"); 329 }, 330 paste: noop, 331 reset: function() { 332 return this.element.classList.remove("dz-started"); 333 }, 334 addedfile: function(file) { 335 var node, removeFileEvent, removeLink, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results; 336 if (this.element === this.previewsContainer) { 337 this.element.classList.add("dz-started"); 338 } 339 if (this.previewsContainer) { 340 file.previewElement = Dropzone.createElement(this.options.previewTemplate.trim()); 341 file.previewTemplate = file.previewElement; 342 this.previewsContainer.appendChild(file.previewElement); 343 _ref = file.previewElement.querySelectorAll("[data-dz-name]"); 344 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 345 node = _ref[_i]; 346 node.textContent = file.name; 347 } 348 _ref1 = file.previewElement.querySelectorAll("[data-dz-size]"); 349 for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { 350 node = _ref1[_j]; 351 node.innerHTML = this.filesize(file.size); 352 } 353 if (this.options.addRemoveLinks) { 354 file._removeLink = Dropzone.createElement("<a class=\"dz-remove\" href=\"javascript:undefined;\" data-dz-remove>" + this.options.dictRemoveFile + "</a>"); 355 file.previewElement.appendChild(file._removeLink); 356 } 357 removeFileEvent = (function(_this) { 358 return function(e) { 359 e.preventDefault(); 360 e.stopPropagation(); 361 if (file.status === Dropzone.UPLOADING) { 362 return Dropzone.confirm(_this.options.dictCancelUploadConfirmation, function() { 363 return _this.removeFile(file); 364 }); 365 } else { 366 if (_this.options.dictRemoveFileConfirmation) { 367 return Dropzone.confirm(_this.options.dictRemoveFileConfirmation, function() { 368 return _this.removeFile(file); 369 }); 370 } else { 371 return _this.removeFile(file); 372 } 373 } 374 }; 375 })(this); 376 _ref2 = file.previewElement.querySelectorAll("[data-dz-remove]"); 377 _results = []; 378 for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { 379 removeLink = _ref2[_k]; 380 _results.push(removeLink.addEventListener("click", removeFileEvent)); 381 } 382 return _results; 383 } 384 }, 385 removedfile: function(file) { 386 var _ref; 387 if (file.previewElement) { 388 if ((_ref = file.previewElement) != null) { 389 _ref.parentNode.removeChild(file.previewElement); 390 } 391 } 392 return this._updateMaxFilesReachedClass(); 393 }, 394 thumbnail: function(file, dataUrl) { 395 var thumbnailElement, _i, _len, _ref; 396 if (file.previewElement) { 397 file.previewElement.classList.remove("dz-file-preview"); 398 _ref = file.previewElement.querySelectorAll("[data-dz-thumbnail]"); 399 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 400 thumbnailElement = _ref[_i]; 401 thumbnailElement.alt = file.name; 402 thumbnailElement.src = dataUrl; 403 } 404 return setTimeout(((function(_this) { 405 return function() { 406 return file.previewElement.classList.add("dz-image-preview"); 407 }; 408 })(this)), 1); 409 } 410 }, 411 error: function(file, message) { 412 var node, _i, _len, _ref, _results; 413 if (file.previewElement) { 414 file.previewElement.classList.add("dz-error"); 415 if (typeof message !== "String" && message.error) { 416 message = message.error; 417 } 418 _ref = file.previewElement.querySelectorAll("[data-dz-errormessage]"); 419 _results = []; 420 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 421 node = _ref[_i]; 422 _results.push(node.textContent = message); 423 } 424 return _results; 425 } 426 }, 427 errormultiple: noop, 428 processing: function(file) { 429 if (file.previewElement) { 430 file.previewElement.classList.add("dz-processing"); 431 if (file._removeLink) { 432 return file._removeLink.textContent = this.options.dictCancelUpload; 433 } 434 } 435 }, 436 processingmultiple: noop, 437 uploadprogress: function(file, progress, bytesSent) { 438 var node, _i, _len, _ref, _results; 439 if (file.previewElement) { 440 _ref = file.previewElement.querySelectorAll("[data-dz-uploadprogress]"); 441 _results = []; 442 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 443 node = _ref[_i]; 444 if (node.nodeName === 'PROGRESS') { 445 _results.push(node.value = progress); 446 } else { 447 _results.push(node.style.width = "" + progress + "%"); 448 } 449 } 450 return _results; 451 } 452 }, 453 totaluploadprogress: noop, 454 sending: noop, 455 sendingmultiple: noop, 456 success: function(file) { 457 if (file.previewElement) { 458 return file.previewElement.classList.add("dz-success"); 459 } 460 }, 461 successmultiple: noop, 462 canceled: function(file) {
463 return this.emit("error", file, "Upload canceled."); 464 }, 465 canceledmultiple: noop, 466 complete: function(file) { 467 if (file._removeLink) { 468 file._removeLink.textContent = this.options.dictRemoveFile; 469 } 470 if (file.previewElement) { 471 return file.previewElement.classList.add("dz-complete"); 472 } 473 }, 474 completemultiple: noop, 475 maxfilesexceeded: noop, 476 maxfilesreached: noop, 477 queuecomplete: noop, 478 addedfiles: noop, 479 previewTemplate: "<div class=\"dz-preview dz-file-preview\">\n <div class=\"dz-image\"><img data-dz-thumbnail /></div>\n <div class=\"dz-details\">\n <div class=\"dz-size\"><span data-dz-size></span></div>\n <div class=\"dz-filename\"><span data-dz-name></span></div>\n </div>\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress></span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n <div class=\"dz-success-mark\">\n <svg width=\"54px\" height=\"54px\" viewBox=\"0 0 54 54\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n <title>Check</title>\n <defs></defs>\n <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n <path d=\"M23.5,31.8431458 L17.5852419,25.9283877 C16.0248253,24.3679711 13.4910294,24.366835 11.9289322,25.9289322 C10.3700136,27.4878508 10.3665912,30.0234455 11.9283877,31.5852419 L20.4147581,40.0716123 C20.5133999,40.1702541 20.6159315,40.2626649 20.7218615,40.3488435 C22.2835669,41.8725651 24.794234,41.8626202 26.3461564,40.3106978 L43.3106978,23.3461564 C44.8771021,21.7797521 44.8758057,19.2483887 43.3137085,17.6862915 C41.7547899,16.1273729 39.2176035,16.1255422 37.6538436,17.6893022 L23.5,31.8431458 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\" id=\"Oval-2\" stroke-opacity=\"0.198794158\" stroke=\"#747474\" fill-opacity=\"0.816519475\" fill=\"#FFFFFF\" sketch:type=\"MSShapeGroup\"></path>\n </g>\n </svg>\n </div>\n <div class=\"dz-error-mark\">\n <svg width=\"54px\" height=\"54px\" viewBox=\"0 0 54 54\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sketch=\"http://www.bohemiancoding.com/sketch/ns\">\n <title>Error</title>\n <defs></defs>\n <g id=\"Page-1\" stroke=\"none\" stroke-width=\"1\" fill=\"none\" fill-rule=\"evenodd\" sketch:type=\"MSPage\">\n <g id=\"Check-+-Oval-2\" sketch:type=\"MSLayerGroup\" stroke=\"#747474\" stroke-opacity=\"0.198794158\" fill=\"#FFFFFF\" fill-opacity=\"0.816519475\">\n <path d=\"M32.6568542,29 L38.3106978,23.3461564 C39.8771021,21.7797521 39.8758057,19.2483887 38.3137085,17.6862915 C36.7547899,16.1273729 34.2176035,16.1255422 32.6538436,17.6893022 L27,23.3431458 L21.3461564,17.6893022 C19.7823965,16.1255422 17.2452101,16.1273729 15.6862915,17.6862915 C14.1241943,19.2483887 14.1228979,21.7797521 15.6893022,23.3461564 L21.3431458,29 L15.6893022,34.6538436 C14.1228979,36.2202479 14.1241943,38.7516113 15.6862915,40.3137085 C17.2452101,41.8726271 19.7823965,41.8744578 21.3461564,40.3106978 L27,34.6568542 L32.6538436,40.3106978 C34.2176035,41.8744578 36.7547899,41.8726271 38.3137085,40.3137085 C39.8758057,38.7516113 39.8771021,36.2202479 38.3106978,34.6538436 L32.6568542,29 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z\" id=\"Oval-2\" sketch:type=\"MSShapeGroup\"></path>\n </g>\n </g>\n </svg>\n </div>\n</div>" 480 }; 481 482 extend = function() { 483 var key, object, objects, target, val, _i, _len; 484 target = arguments[0], objects = 2 <= arguments.length ? __slice.call(arguments, 1) : []; 485 for (_i = 0, _len = objects.length; _i < _len; _i++) { 486 object = objects[_i]; 487 for (key in object) { 488 val = object[key]; 489 target[key] = val; 490 } 491 } 492 return target; 493 }; 494 495 function Dropzone(element, options) { 496 var elementOptions, fallback, _ref; 497 this.element = element; 498 this.version = Dropzone.version; 499 this.defaultOptions.previewTemplate = this.defaultOptions.previewTemplate.replace(/\n*/g, ""); 500 this.clickableElements = []; 501 this.listeners = []; 502 this.files = []; 503 if (typeof this.element === "string") { 504 this.element = document.querySelector(this.element); 505 } 506 if (!(this.element && (this.element.nodeType != null))) { 507 throw new Error("Invalid dropzone element."); 508 } 509 if (this.element.dropzone) { 510 throw new Error("Dropzone already attached."); 511 } 512 Dropzone.instances.push(this); 513 this.element.dropzone = this; 514 elementOptions = (_ref = Dropzone.optionsForElement(this.element)) != null ? _ref : {}; 515 this.options = extend({}, this.defaultOptions, elementOptions, options != null ? options : {}); 516 if (this.options.forceFallback || !Dropzone.isBrowserSupported()) { 517 return this.options.fallback.call(this); 518 } 519 if (this.options.url == null) { 520 this.options.url = this.element.getAttribute("action"); 521 } 522 if (!this.options.url) { 523 throw new Error("No URL provided."); 524 } 525 if (this.options.acceptedFiles && this.options.acceptedMimeTypes) { 526 throw new Error("You can't provide both 'acceptedFiles' and 'acceptedMimeTypes'. 'acceptedMimeTypes' is deprecated."); 527 } 528 if (this.options.acceptedMimeTypes) { 529 this.options.acceptedFiles = this.options.acceptedMimeTypes; 530 delete this.options.acceptedMimeTypes; 531 } 532 this.options.method = this.options.method.toUpperCase(); 533 if ((fallback = this.getExistingFallback()) && fallback.parentNode) { 534 fallback.parentNode.removeChild(fallback); 535 } 536 if (this.options.previewsContainer !== false) { 537 if (this.options.previewsContainer) { 538 this.previewsContainer = Dropzone.getElement(this.options.previewsContainer, "previewsContainer"); 539 } else { 540 this.previewsContainer = this.element; 541 } 542 } 543 if (this.options.clickable) { 544 if (this.options.clickable === true) { 545 this.clickableElements = [this.element]; 546 } else { 547 this.clickableElements = Dropzone.getElements(this.options.clickable, "clickable"); 548 } 549 } 550 this.init(); 551 } 552 553 Dropzone.prototype.getAcceptedFiles = function() { 554 var file, _i, _len, _ref, _results; 555 _ref = this.files; 556 _results = []; 557 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 558 file = _ref[_i]; 559 if (file.accepted) { 560 _results.push(file); 561 } 562 } 563 return _results; 564 }; 565 566 Dropzone.prototype.getRejectedFiles = function() { 567 var file, _i, _len, _ref, _results; 568 _ref = this.files; 569 _results = []; 570 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 571 file = _ref[_i]; 572 if (!file.accepted) { 573 _results.push(file); 574 } 575 } 576 return _results; 577 }; 578 579 Dropzone.prototype.getFilesWithStatus = function(status) { 580 var file, _i, _len, _ref, _results; 581 _ref = this.files; 582 _results = []; 583 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 584 file = _ref[_i]; 585 if (file.status === status) { 586 _results.push(file); 587 } 588 } 589 return _results; 590 }; 591 592 Dropzone.prototype.getQueuedFiles = function() { 593 return this.getFilesWithStatus(Dropzone.QUEUED); 594 }; 595 596 Dropzone.prototype.getUploadingFiles = function() { 597 return this.getFilesWithStatus(Dropzone.UPLOADING); 598 }; 599 600 Dropzone.prototype.getAddedFiles = function() { 601 return this.getFilesWithStatus(Dropzone.ADDED); 602 }; 603 604 Dropzone.prototype.getActiveFiles = function() { 605 var file, _i, _len, _ref, _results; 606 _ref = this.files; 607 _results = []; 608 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 609 file = _ref[_i]; 610 if (file.status === Dropzone.UPLOADING || file.status === Dropzone.QUEUED) { 611 _results.push(file); 612 } 613 } 614 return _results; 615 }; 616 617 Dropzone.prototype.init = function() { 618 var eventName, noPropagation, setupHiddenFileInput, _i, _len, _ref, _ref1; 619 if (this.element.tagName === "form") { 620 this.element.setAttribute("enctype", "multipart/form-data"); 621 } 622 if (this.element.classList.contains("dropzone") && !this.element.querySelector(".dz-message")) { 623 this.element.appendChild(Dropzone.createElement("<div class=\"dz-default dz-message\"><span>" + this.options.dictDefaultMessage + "</span></div>")); 624 } 625 if (this.clickableElements.length) { 626 setupHiddenFileInput = (function(_this) { 627 return function() { 628 if (_this.hiddenFileInput) { 629 _this.hiddenFileInput.parentNode.removeChild(_this.hiddenFileInput); 630 } 631 _this.hiddenFileInput = document.createElement("input"); 632 _this.hiddenFileInput.setAttribute("type", "file"); 633 if ((_this.options.maxFiles == null) || _this.options.maxFiles > 1) { 634 _this.hiddenFileInput.setAttribute("multiple", "multiple"); 635 } 636 _this.hiddenFileInput.className = "dz-hidden-input"; 637 if (_this.options.acceptedFiles != null) { 638 _this.hiddenFileInput.setAttribute("accept", _this.options.acceptedFiles); 639 } 640 if (_this.options.capture != null) { 641 _this.hiddenFileInput.setAttribute("capture", _this.options.capture); 642 } 643 _this.hiddenFileInput.style.visibility = "hidden"; 644 _this.hiddenFileInput.style.position = "absolute"; 645 _this.hiddenFileInput.style.top = "0"; 646 _this.hiddenFileInput.style.left = "0"; 647 _this.hiddenFileInput.style.height = "0"; 648 _this.hiddenFileInput.style.width = "0"; 649 document.querySelector(_this.options.hiddenInputContainer).appendChild(_this.hiddenFileInput); 650 return _this.hiddenFileInput.addEventListener("change", function() { 651 var file, files, _i, _len; 652 files = _this.hiddenFileInput.files; 653 if (files.length) { 654 for (_i = 0, _len = files.length; _i < _len; _i++) { 655 file = files[_i]; 656 _this.addFile(file); 657 } 658 }
659 _this.emit("addedfiles", files); 660 return setupHiddenFileInput(); 661 }); 662 }; 663 })(this); 664 setupHiddenFileInput(); 665 } 666 this.URL = (_ref = window.URL) != null ? _ref : window.webkitURL; 667 _ref1 = this.events; 668 for (_i = 0, _len = _ref1.length; _i < _len; _i++) { 669 eventName = _ref1[_i]; 670 this.on(eventName, this.options[eventName]); 671 } 672 this.on("uploadprogress", (function(_this) { 673 return function() { 674 return _this.updateTotalUploadProgress(); 675 }; 676 })(this)); 677 this.on("removedfile", (function(_this) { 678 return function() { 679 return _this.updateTotalUploadProgress(); 680 }; 681 })(this)); 682 this.on("canceled", (function(_this) { 683 return function(file) { 684 return _this.emit("complete", file); 685 }; 686 })(this)); 687 this.on("complete", (function(_this) { 688 return function(file) { 689 if (_this.getAddedFiles().length === 0 && _this.getUploadingFiles().length === 0 && _this.getQueuedFiles().length === 0) { 690 return setTimeout((function() { 691 return _this.emit("queuecomplete"); 692 }), 0); 693 } 694 }; 695 })(this)); 696 noPropagation = function(e) { 697 e.stopPropagation(); 698 if (e.preventDefault) { 699 return e.preventDefault(); 700 } else { 701 return e.returnValue = false; 702 } 703 }; 704 this.listeners = [ 705 { 706 element: this.element, 707 events: { 708 "dragstart": (function(_this) { 709 return function(e) { 710 return _this.emit("dragstart", e); 711 }; 712 })(this), 713 "dragenter": (function(_this) { 714 return function(e) { 715 noPropagation(e); 716 return _this.emit("dragenter", e); 717 }; 718 })(this), 719 "dragover": (function(_this) { 720 return function(e) { 721 var efct; 722 try { 723 efct = e.dataTransfer.effectAllowed; 724 } catch (_error) {} 725 e.dataTransfer.dropEffect = 'move' === efct || 'linkMove' === efct ? 'move' : 'copy'; 726 noPropagation(e); 727 return _this.emit("dragover", e); 728 }; 729 })(this), 730 "dragleave": (function(_this) { 731 return function(e) { 732 return _this.emit("dragleave", e); 733 }; 734 })(this), 735 "drop": (function(_this) { 736 return function(e) { 737 noPropagation(e); 738 return _this.drop(e); 739 }; 740 })(this), 741 "dragend": (function(_this) { 742 return function(e) { 743 return _this.emit("dragend", e); 744 }; 745 })(this) 746 } 747 } 748 ]; 749 this.clickableElements.forEach((function(_this) { 750 return function(clickableElement) { 751 return _this.listeners.push({ 752 element: clickableElement, 753 events: { 754 "click": function(evt) { 755 if ((clickableElement !== _this.element) || (evt.target === _this.element || Dropzone.elementInside(evt.target, _this.element.querySelector(".dz-message")))) { 756 _this.hiddenFileInput.click(); 757 } 758 return true; 759 } 760 } 761 }); 762 }; 763 })(this)); 764 this.enable(); 765 return this.options.init.call(this); 766 }; 767 768 Dropzone.prototype.destroy = function() { 769 var _ref; 770 this.disable(); 771 this.removeAllFiles(true); 772 if ((_ref = this.hiddenFileInput) != null ? _ref.parentNode : void 0) { 773 this.hiddenFileInput.parentNode.removeChild(this.hiddenFileInput); 774 this.hiddenFileInput = null; 775 } 776 delete this.element.dropzone; 777 return Dropzone.instances.splice(Dropzone.instances.indexOf(this), 1); 778 }; 779 780 Dropzone.prototype.updateTotalUploadProgress = function() { 781 var activeFiles, file, totalBytes, totalBytesSent, totalUploadProgress, _i, _len, _ref; 782 totalBytesSent = 0; 783 totalBytes = 0; 784 activeFiles = this.getActiveFiles(); 785 if (activeFiles.length) { 786 _ref = this.getActiveFiles(); 787 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 788 file = _ref[_i];
789 totalBytesSent += file.upload.bytesSent; 790 totalBytes += file.upload.total; 791 } 792 totalUploadProgress = 100 * totalBytesSent / totalBytes; 793 } else { 794 totalUploadProgress = 100; 795 } 796 return this.emit("totaluploadprogress", totalUploadProgress, totalBytes, totalBytesSent); 797 }; 798 799 Dropzone.prototype._getParamName = function(n) { 800 if (typeof this.options.paramName === "function") { 801 return this.options.paramName(n); 802 } else { 803 return "" + this.options.paramName + (this.options.uploadMultiple ? "[" + n + "]" : ""); 804 } 805 }; 806 807 Dropzone.prototype.getFallbackForm = function() { 808 var existingFallback, fields, fieldsString, form; 809 if (existingFallback = this.getExistingFallback()) { 810 return existingFallback; 811 } 812 fieldsString = "<div class=\"dz-fallback\">"; 813 if (this.options.dictFallbackText) { 814 fieldsString += "<p>" + this.options.dictFallbackText + "</p>"; 815 } 816 fieldsString += "<input type=\"file\" name=\"" + (this._getParamName(0)) + "\" " + (this.options.uploadMultiple ? 'multiple="multiple"' : void 0) + " /><input type=\"submit\" value=\"Upload!\"></div>"; 817 fields = Dropzone.createElement(fieldsString); 818 if (this.element.tagName !== "FORM") { 819 form = Dropzone.createElement("<form action=\"" + this.options.url + "\" enctype=\"multipart/form-data\" method=\"" + this.options.method + "\"></form>"); 820 form.appendChild(fields); 821 } else { 822 this.element.setAttribute("enctype", "multipart/form-data"); 823 this.element.setAttribute("method", this.options.method); 824 } 825 return form != null ? form : fields; 826 }; 827 828 Dropzone.prototype.getExistingFallback = function() { 829 var fallback, getFallback, tagName, _i, _len, _ref; 830 getFallback = function(elements) { 831 var el, _i, _len; 832 for (_i = 0, _len = elements.length; _i < _len; _i++) { 833 el = elements[_i]; 834 if (/(^| )fallback($| )/.test(el.className)) { 835 return el; 836 } 837 } 838 }; 839 _ref = ["div", "form"]; 840 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 841 tagName = _ref[_i]; 842 if (fallback = getFallback(this.element.getElementsByTagName(tagName))) { 843 return fallback; 844 } 845 } 846 }; 847 848 Dropzone.prototype.setupEventListeners = function() { 849 var elementListeners, event, listener, _i, _len, _ref, _results; 850 _ref = this.listeners; 851 _results = []; 852 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 853 elementListeners = _ref[_i]; 854 _results.push((function() { 855 var _ref1, _results1; 856 _ref1 = elementListeners.events; 857 _results1 = []; 858 for (event in _ref1) { 859 listener = _ref1[event]; 860 _results1.push(elementListeners.element.addEventListener(event, listener, false)); 861 } 862 return _results1; 863 })()); 864 } 865 return _results; 866 }; 867 868 Dropzone.prototype.removeEventListeners = function() { 869 var elementListeners, event, listener, _i, _len, _ref, _results; 870 _ref = this.listeners; 871 _results = []; 872 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 873 elementListeners = _ref[_i]; 874 _results.push((function() { 875 var _ref1, _results1; 876 _ref1 = elementListeners.events; 877 _results1 = []; 878 for (event in _ref1) { 879 listener = _ref1[event]; 880 _results1.push(elementListeners.element.removeEventListener(event, listener, false)); 881 } 882 return _results1; 883 })()); 884 } 885 return _results; 886 }; 887 888 Dropzone.prototype.disable = function() { 889 var file, _i, _len, _ref, _results; 890 this.clickableElements.forEach(function(element) { 891 return element.classList.remove("dz-clickable"); 892 }); 893 this.removeEventListeners(); 894 _ref = this.files; 895 _results = []; 896 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 897 file = _ref[_i]; 898 _results.push(this.cancelUpload(file)); 899 } 900 return _results; 901 }; 902 903 Dropzone.prototype.enable = function() {
904 this.clickableElements.forEach(function(element) { 905 return element.classList.add("dz-clickable"); 906 }); 907 return this.setupEventListeners(); 908 }; 909 910 Dropzone.prototype.filesize = function(size) { 911 var cutoff, i, selectedSize, selectedUnit, unit, units, _i, _len; 912 selectedSize = 0; 913 selectedUnit = "b"; 914 if (size > 0) { 915 units = ['TB', 'GB', 'MB', 'KB', 'b']; 916 for (i = _i = 0, _len = units.length; _i < _len; i = ++_i) { 917 unit = units[i]; 918 cutoff = Math.pow(this.options.filesizeBase, 4 - i) / 10; 919 if (size >= cutoff) { 920 selectedSize = size / Math.pow(this.options.filesizeBase, 4 - i); 921 selectedUnit = unit; 922 break; 923 } 924 } 925 selectedSize = Math.round(10 * selectedSize) / 10; 926 } 927 return "<strong>" + selectedSize + "</strong> " + selectedUnit; 928 }; 929 930 Dropzone.prototype._updateMaxFilesReachedClass = function() { 931 if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) { 932 if (this.getAcceptedFiles().length === this.options.maxFiles) { 933 this.emit('maxfilesreached', this.files); 934 } 935 return this.element.classList.add("dz-max-files-reached"); 936 } else { 937 return this.element.classList.remove("dz-max-files-reached"); 938 } 939 }; 940 941 Dropzone.prototype.drop = function(e) { 942 var files, items; 943 if (!e.dataTransfer) { 944 return; 945 } 946 this.emit("drop", e); 947 files = e.dataTransfer.files; 948 this.emit("addedfiles", files); 949 if (files.length) { 950 items = e.dataTransfer.items; 951 if (items && items.length && (items[0].webkitGetAsEntry != null)) { 952 this._addFilesFromItems(items); 953 } else { 954 this.handleFiles(files); 955 } 956 } 957 }; 958 959 Dropzone.prototype.paste = function(e) { 960 var items, _ref; 961 if ((e != null ? (_ref = e.clipboardData) != null ? _ref.items : void 0 : void 0) == null) { 962 return; 963 } 964 this.emit("paste", e); 965 items = e.clipboardData.items; 966 if (items.length) { 967 return this._addFilesFromItems(items); 968 } 969 }; 970 971 Dropzone.prototype.handleFiles = function(files) { 972 var file, _i, _len, _results; 973 _results = []; 974 for (_i = 0, _len = files.length; _i < _len; _i++) { 975 file = files[_i]; 976 _results.push(this.addFile(file)); 977 } 978 return _results; 979 }; 980 981 Dropzone.prototype._addFilesFromItems = function(items) { 982 var entry, item, _i, _len, _results; 983 _results = []; 984 for (_i = 0, _len = items.length; _i < _len; _i++) { 985 item = items[_i]; 986 if ((item.webkitGetAsEntry != null) && (entry = item.webkitGetAsEntry())) { 987 if (entry.isFile) { 988 _results.push(this.addFile(item.getAsFile())); 989 } else if (entry.isDirectory) { 990 _results.push(this._addFilesFromDirectory(entry, entry.name)); 991 } else { 992 _results.push(void 0); 993 } 994 } else if (item.getAsFile != null) { 995 if ((item.kind == null) || item.kind === "file") { 996 _results.push(this.addFile(item.getAsFile())); 997 } else { 998 _results.push(void 0); 999 } 1000 } else { 1001 _results.push(void 0); 1002 } 1003 } 1004 return _results; 1005 }; 1006 1007 Dropzone.prototype._addFilesFromDirectory = function(directory, path) { 1008 var dirReader, entriesReader; 1009 dirReader = directory.createReader(); 1010 entriesReader = (function(_this) { 1011 return function(entries) { 1012 var entry, _i, _len; 1013 for (_i = 0, _len = entries.length; _i < _len; _i++) { 1014 entry = entries[_i]; 1015 if (entry.isFile) { 1016 entry.file(function(file) { 1017 if (_this.options.ignoreHiddenFiles && file.name.substring(0, 1) === '.') { 1018 return; 1019 } 1020 file.fullPath = "" + path + "/" + file.name; 1021 return _this.addFile(file); 1022 }); 1023 } else if (entry.isDirectory) { 1024 _this._addFilesFromDirectory(entry, "" + path + "/" + entry.name); 1025 } 1026 } 1027 }; 1028 })(this); 1029 return dirReader.readEntries(entriesReader, function(error) { 1030 return typeof console !== "undefined" && console !== null ? typeof console.log === "function" ? console.log(error) : void 0 : void 0; 1031 }); 1032 }; 1033 1034 Dropzone.prototype.accept = function(file, done) { 1035 if (file.size > this.options.maxFilesize * 1024 * 1024) { 1036 return done(this.options.dictFileTooBig.replace("{{filesize}}", Math.round(file.size / 1024 / 10.24) / 100).replace("{{maxFilesize}}", this.options.maxFilesize)); 1037 } else if (!Dropzone.isValidFile(file, this.options.acceptedFiles)) { 1038 return done(this.options.dictInvalidFileType); 1039 } else if ((this.options.maxFiles != null) && this.getAcceptedFiles().length >= this.options.maxFiles) { 1040 done(this.options.dictMaxFilesExceeded.replace("{{maxFiles}}", this.options.maxFiles));
1041 return this.emit("maxfilesexceeded", file); 1042 } else { 1043 return this.options.accept.call(this, file, done); 1044 } 1045 }; 1046 1047 Dropzone.prototype.addFile = function(file) { 1048 file.upload = { 1049 progress: 0, 1050 total: file.size, 1051 bytesSent: 0 1052 }; 1053 this.files.push(file); 1054 file.status = Dropzone.ADDED; 1055 this.emit("addedfile", file); 1056 this._enqueueThumbnail(file); 1057 return this.accept(file, (function(_this) { 1058 return function(error) { 1059 if (error) { 1060 file.accepted = false; 1061 _this._errorProcessing([file], error); 1062 } else { 1063 file.accepted = true; 1064 if (_this.options.autoQueue) { 1065 _this.enqueueFile(file); 1066 } 1067 } 1068 return _this._updateMaxFilesReachedClass(); 1069 }; 1070 })(this)); 1071 }; 1072 1073 Dropzone.prototype.enqueueFiles = function(files) { 1074 var file, _i, _len; 1075 for (_i = 0, _len = files.length; _i < _len; _i++) { 1076 file = files[_i]; 1077 this.enqueueFile(file); 1078 } 1079 return null; 1080 }; 1081 1082 Dropzone.prototype.enqueueFile = function(file) { 1083 if (file.status === Dropzone.ADDED && file.accepted === true) { 1084 file.status = Dropzone.QUEUED; 1085 if (this.options.autoProcessQueue) { 1086 return setTimeout(((function(_this) { 1087 return function() { 1088 return _this.processQueue(); 1089 }; 1090 })(this)), 0); 1091 } 1092 } else { 1093 throw new Error("This file can't be queued because it has already been processed or was rejected."); 1094 } 1095 }; 1096 1097 Dropzone.prototype._thumbnailQueue = []; 1098 1099 Dropzone.prototype._processingThumbnail = false; 1100 1101 Dropzone.prototype._enqueueThumbnail = function(file) { 1102 if (this.options.createImageThumbnails && file.type.match(/image.*/) && file.size <= this.options.maxThumbnailFilesize * 1024 * 1024) { 1103 this._thumbnailQueue.push(file); 1104 return setTimeout(((function(_this) { 1105 return function() { 1106 return _this._processThumbnailQueue(); 1107 }; 1108 })(this)), 0); 1109 } 1110 }; 1111 1112 Dropzone.prototype._processThumbnailQueue = function() { 1113 if (this._processingThumbnail || this._thumbnailQueue.length === 0) { 1114 return; 1115 } 1116 this._processingThumbnail = true; 1117 return this.createThumbnail(this._thumbnailQueue.shift(), (function(_this) { 1118 return function() { 1119 _this._processingThumbnail = false; 1120 return _this._processThumbnailQueue(); 1121 }; 1122 })(this)); 1123 }; 1124 1125 Dropzone.prototype.removeFile = function(file) { 1126 if (file.status === Dropzone.UPLOADING) { 1127 this.cancelUpload(file); 1128 } 1129 this.files = without(this.files, file); 1130 this.emit("removedfile", file); 1131 if (this.files.length === 0) { 1132 return this.emit("reset"); 1133 } 1134 }; 1135 1136 Dropzone.prototype.removeAllFiles = function(cancelIfNecessary) { 1137 var file, _i, _len, _ref; 1138 if (cancelIfNecessary == null) { 1139 cancelIfNecessary = false; 1140 } 1141 _ref = this.files.slice(); 1142 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 1143 file = _ref[_i]; 1144 if (file.status !== Dropzone.UPLOADING || cancelIfNecessary) { 1145 this.removeFile(file); 1146 } 1147 } 1148 return null; 1149 }; 1150 1151 Dropzone.prototype.createThumbnail = function(file, callback) { 1152 var fileReader; 1153 fileReader = new FileReader; 1154 fileReader.onload = (function(_this) { 1155 return function() { 1156 if (file.type === "image/svg+xml") { 1157 _this.emit("thumbnail", file, fileReader.result); 1158 if (callback != null) { 1159 callback(); 1160 } 1161 return; 1162 } 1163 return _this.createThumbnailFromUrl(file, fileReader.result, callback); 1164 }; 1165 })(this); 1166 return fileReader.readAsDataURL(file); 1167 }; 1168 1169 Dropzone.prototype.createThumbnailFromUrl = function(file, imageUrl, callback, crossOrigin) { 1170 var img; 1171 img = document.createElement("img"); 1172 if (crossOrigin) { 1173 img.crossOrigin = crossOrigin; 1174 } 1175 img.onload = (function(_this) { 1176 return function() { 1177 var canvas, ctx, resizeInfo, thumbnail, _ref, _ref1, _ref2, _ref3; 1178 file.width = img.width;
1179 file.height = img.height; 1180 resizeInfo = _this.options.resize.call(_this, file); 1181 if (resizeInfo.trgWidth == null) { 1182 resizeInfo.trgWidth = resizeInfo.optWidth; 1183 } 1184 if (resizeInfo.trgHeight == null) { 1185 resizeInfo.trgHeight = resizeInfo.optHeight; 1186 } 1187 canvas = document.createElement("canvas"); 1188 ctx = canvas.getContext("2d"); 1189 canvas.width = resizeInfo.trgWidth; 1190 canvas.height = resizeInfo.trgHeight; 1191 drawImageIOSFix(ctx, img, (_ref = resizeInfo.srcX) != null ? _ref : 0, (_ref1 = resizeInfo.srcY) != null ? _ref1 : 0, resizeInfo.srcWidth, resizeInfo.srcHeight, (_ref2 = resizeInfo.trgX) != null ? _ref2 : 0, (_ref3 = resizeInfo.trgY) != null ? _ref3 : 0, resizeInfo.trgWidth, resizeInfo.trgHeight); 1192 thumbnail = canvas.toDataURL("image/png"); 1193 _this.emit("thumbnail", file, thumbnail); 1194 if (callback != null) { 1195 return callback(); 1196 } 1197 }; 1198 })(this); 1199 if (callback != null) { 1200 img.onerror = callback; 1201 } 1202 return img.src = imageUrl; 1203 }; 1204 1205 Dropzone.prototype.processQueue = function() { 1206 var i, parallelUploads, processingLength, queuedFiles; 1207 parallelUploads = this.options.parallelUploads; 1208 processingLength = this.getUploadingFiles().length; 1209 i = processingLength; 1210 if (processingLength >= parallelUploads) { 1211 return; 1212 } 1213 queuedFiles = this.getQueuedFiles(); 1214 if (!(queuedFiles.length > 0)) { 1215 return; 1216 } 1217 if (this.options.uploadMultiple) { 1218 return this.processFiles(queuedFiles.slice(0, parallelUploads - processingLength)); 1219 } else { 1220 while (i < parallelUploads) { 1221 if (!queuedFiles.length) { 1222 return; 1223 } 1224 this.processFile(queuedFiles.shift()); 1225 i++; 1226 } 1227 } 1228 }; 1229 1230 Dropzone.prototype.processFile = function(file) { 1231 return this.processFiles([file]); 1232 }; 1233 1234 Dropzone.prototype.processFiles = function(files) { 1235 var file, _i, _len; 1236 for (_i = 0, _len = files.length; _i < _len; _i++) { 1237 file = files[_i]; 1238 file.processing = true; 1239 file.status = Dropzone.UPLOADING; 1240 this.emit("processing", file); 1241 } 1242 if (this.options.uploadMultiple) { 1243 this.emit("processingmultiple", files); 1244 } 1245 return this.uploadFiles(files); 1246 }; 1247 1248 Dropzone.prototype._getFilesWithXhr = function(xhr) { 1249 var file, files; 1250 return files = (function() { 1251 var _i, _len, _ref, _results; 1252 _ref = this.files; 1253 _results = []; 1254 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 1255 file = _ref[_i]; 1256 if (file.xhr === xhr) { 1257 _results.push(file); 1258 } 1259 } 1260 return _results; 1261 }).call(this); 1262 }; 1263 1264 Dropzone.prototype.cancelUpload = function(file) { 1265 var groupedFile, groupedFiles, _i, _j, _len, _len1, _ref; 1266 if (file.status === Dropzone.UPLOADING) { 1267 groupedFiles = this._getFilesWithXhr(file.xhr); 1268 for (_i = 0, _len = groupedFiles.length; _i < _len; _i++) { 1269 groupedFile = groupedFiles[_i]; 1270 groupedFile.status = Dropzone.CANCELED; 1271 } 1272 file.xhr.abort(); 1273 for (_j = 0, _len1 = groupedFiles.length; _j < _len1; _j++) { 1274 groupedFile = groupedFiles[_j]; 1275 this.emit("canceled", groupedFile); 1276 } 1277 if (this.options.uploadMultiple) { 1278 this.emit("canceledmultiple", groupedFiles); 1279 } 1280 } else if ((_ref = file.status) === Dropzone.ADDED || _ref === Dropzone.QUEUED) { 1281 file.status = Dropzone.CANCELED; 1282 this.emit("canceled", file); 1283 if (this.options.uploadMultiple) { 1284 this.emit("canceledmultiple", [file]); 1285 } 1286 } 1287 if (this.options.autoProcessQueue) { 1288 return this.processQueue(); 1289 } 1290 }; 1291 1292 resolveOption = function() { 1293 var args, option; 1294 option = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : []; 1295 if (typeof option === 'function') { 1296 return option.apply(this, args); 1297 } 1298 return option; 1299 }; 1300 1301 Dropzone.prototype.uploadFile = function(file) { 1302 return this.uploadFiles([file]); 1303 }; 1304 1305 Dropzone.prototype.uploadFiles = function(files) { 1306 var file, formData, handleError, headerName, headerValue, headers, i, input, inputName, inputType, key, method, option, progressObj, response, updateProgress, url, value, xhr, _i, _j, _k, _l, _len, _len1, _len2, _len3, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5; 1307 xhr = new XMLHttpRequest(); 1308 for (_i = 0, _len = files.length; _i < _len; _i++) { 1309 file = files[_i]; 1310 file.xhr = xhr; 1311 } 1312 method = resolveOption(this.options.method, files); 1313 url = resolveOption(this.options.url, files); 1314 xhr.open(method, url, true); 1315 xhr.withCredentials = !!this.options.withCredentials; 1316 response = null; 1317 handleError = (function(_this) { 1318 return function() { 1319 var _j, _len1, _results; 1320 _results = []; 1321 for (_j = 0, _len1 = files.length; _j < _len1; _j++) { 1322 file = files[_j]; 1323 _results.push(_this._errorProcessing(files, response || _this.options.dictResponseError.replace("{{statusCode}}", xhr.status), xhr)); 1324 } 1325 return _results; 1326 }; 1327 })(this); 1328 updateProgress = (function(_this) { 1329 return function(e) { 1330 var allFilesFinished, progress, _j, _k, _l, _len1, _len2, _len3, _results; 1331 if (e != null) { 1332 progress = 100 * e.loaded / e.total; 1333 for (_j = 0, _len1 = files.length; _j < _len1; _j++) { 1334 file = files[_j]; 1335 file.upload = { 1336 progress: progress, 1337 total: e.total, 1338 bytesSent: e.loaded 1339 }; 1340 } 1341 } else { 1342 allFilesFinished = true; 1343 progress = 100; 1344 for (_k = 0, _len2 = files.length; _k < _len2; _k++) { 1345 file = files[_k]; 1346 if (!(file.upload.progress === 100 && file.upload.b
1346ytesSent === file.upload.total)) { 1347 allFilesFinished = false; 1348 } 1349 file.upload.progress = progress; 1350 file.upload.bytesSent = file.upload.total; 1351 } 1352 if (allFilesFinished) { 1353 return; 1354 } 1355 } 1356 _results = []; 1357 for (_l = 0, _len3 = files.length; _l < _len3; _l++) { 1358 file = files[_l]; 1359 _results.push(_this.emit("uploadprogress", file, progress, file.upload.bytesSent)); 1360 } 1361 return _results; 1362 }; 1363 })(this); 1364 xhr.onload = (function(_this) { 1365 return function(e) { 1366 var _ref; 1367 if (files[0].status === Dropzone.CANCELED) { 1368 return; 1369 } 1370 if (xhr.readyState !== 4) { 1371 return; 1372 } 1373 response = xhr.responseText; 1374 if (xhr.getResponseHeader("content-type") && ~xhr.getResponseHeader("content-type").indexOf("application/json")) { 1375 try { 1376 response = JSON.parse(response); 1377 } catch (_error) { 1378 e = _error; 1379 response = "Invalid JSON response from server."; 1380 } 1381 } 1382 updateProgress(); 1383 if (!((200 <= (_ref = xhr.status) && _ref < 300))) { 1384 return handleError(); 1385 } else { 1386 return _this._finished(files, response, e); 1387 } 1388 }; 1389 })(this); 1390 xhr.onerror = (function(_this) { 1391 return function() { 1392 if (files[0].status === Dropzone.CANCELED) { 1393 return; 1394 } 1395 return handleError(); 1396 }; 1397 })(this); 1398 progressObj = (_ref = xhr.upload) != null ? _ref : xhr; 1399 progressObj.onprogress = updateProgress; 1400 headers = { 1401 "Accept": "application/json", 1402 "Cache-Control": "no-cache", 1403 "X-Requested-With": "XMLHttpRequest" 1404 }; 1405 if (this.options.headers) { 1406 extend(headers, this.options.headers); 1407 } 1408 for (headerName in headers) { 1409 headerValue = headers[headerName]; 1410 if (headerValue) { 1411 xhr.setRequestHeader(headerName, headerValue); 1412 } 1413 } 1414 formData = new FormData(); 1415 if (this.options.params) { 1416 _ref1 = this.options.params; 1417 for (key in _ref1) { 1418 value = _ref1[key]; 1419 formData.append(key, value); 1420 } 1421 } 1422 for (_j = 0, _len1 = files.length; _j < _len1; _j++) { 1423 file = files[_j]; 1424 this.emit("sending", file, xhr, formData); 1425 } 1426 if (this.options.uploadMultiple) { 1427 this.emit("sendingmultiple", files, xhr, formData); 1428 } 1429 if (this.element.tagName === "FORM") { 1430 _ref2 = this.element.querySelectorAll("input, textarea, select, button"); 1431 for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) { 1432 input = _ref2[_k]; 1433 inputName = input.getAttribute("name"); 1434 inputType = input.getAttribute("type"); 1435 if (input.tagName === "SELECT" && input.hasAttribute("multiple")) { 1436 _ref3 = input.options; 1437 for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) { 1438 option = _ref3[_l]; 1439 if (option.selected) { 1440 formData.append(inputName, option.value); 1441 } 1442 } 1443 } else if (!inputType || ((_ref4 = inputType.toLowerCase()) !== "checkbox" && _ref4 !== "radio") || input.checked) { 1444 formData.append(inputName, input.value); 1445 } 1446 } 1447 } 1448 for (i = _m = 0, _ref5 = files.length - 1; 0 <= _ref5 ? _m <= _ref5 : _m >= _ref5; i = 0 <= _ref5 ? ++_m : --_m) { 1449 formData.append(this._getParamName(i), files[i], files[i].name); 1450 } 1451 return this.submitRequest(xhr, formData, files); 1452 }; 1453 1454 Dropzone.prototype.submitRequest = function(xhr, formData, files) { 1455 return xhr.send(formData); 1456 }; 1457 1458 Dropzone.prototype._finished = function(files, responseText, e) { 1459 var file, _i, _len; 1460 for (_i = 0, _len = files.length; _i < _len; _i++) { 1461 file = files[_i]; 1462 file.status = Dropzone.SUCCESS;
1463 this.emit("success", file, responseText, e); 1464 this.emit("complete", file); 1465 } 1466 if (this.options.uploadMultiple) { 1467 this.emit("successmultiple", files, responseText, e); 1468 this.emit("completemultiple", files); 1469 } 1470 if (this.options.autoProcessQueue) { 1471 return this.processQueue(); 1472 } 1473 }; 1474 1475 Dropzone.prototype._errorProcessing = function(files, message, xhr) { 1476 var file, _i, _len; 1477 for (_i = 0, _len = files.length; _i < _len; _i++) { 1478 file = files[_i]; 1479 file.status = Dropzone.ERROR; 1480 this.emit("error", file, message, xhr); 1481 this.emit("complete", file); 1482 } 1483 if (this.options.uploadMultiple) { 1484 this.emit("errormultiple", files, message, xhr); 1485 this.emit("completemultiple", files); 1486 } 1487 if (this.options.autoProcessQueue) { 1488 return this.processQueue(); 1489 } 1490 }; 1491 1492 return Dropzone; 1493 1494 })(Emitter); 1495 1496 Dropzone.version = "4.2.0"; 1497 1498 Dropzone.options = {}; 1499 1500 Dropzone.optionsForElement = function(element) { 1501 if (element.getAttribute("id")) { 1502 return Dropzone.options[camelize(element.getAttribute("id"))]; 1503 } else { 1504 return void 0; 1505 } 1506 }; 1507 1508 Dropzone.instances = []; 1509 1510 Dropzone.forElement = function(element) { 1511 if (typeof element === "string") { 1512 element = document.querySelector(element); 1513 } 1514 if ((element != null ? element.dropzone : void 0) == null) { 1515 throw new Error("No Dropzone found for given element. This is probably because you're trying to access it before Dropzone had the time to initialize. Use the `init` option to setup any additional observers on your Dropzone."); 1516 } 1517 return element.dropzone; 1518 }; 1519 1520 Dropzone.autoDiscover = true; 1521 1522 Dropzone.discover = function() { 1523 var checkElements, dropzone, dropzones, _i, _len, _results; 1524 if (document.querySelectorAll) { 1525 dropzones = document.querySelectorAll(".dropzone"); 1526 } else { 1527 dropzones = []; 1528 checkElements = function(elements) { 1529 var el, _i, _len, _results; 1530 _results = []; 1531 for (_i = 0, _len = elements.length; _i < _len; _i++) { 1532 el = elements[_i]; 1533 if (/(^| )dropzone($| )/.test(el.className)) { 1534 _results.push(dropzones.push(el)); 1535 } else { 1536 _results.push(void 0); 1537 } 1538 } 1539 return _results; 1540 }; 1541 checkElements(document.getElementsByTagName("div")); 1542 checkElements(document.getElementsByTagName("form")); 1543 } 1544 _results = []; 1545 for (_i = 0, _len = dropzones.length; _i < _len; _i++) { 1546 dropzone = dropzones[_i]; 1547 if (Dropzone.optionsForElement(dropzone) !== false) { 1548 _results.push(new Dropzone(dropzone)); 1549 } else { 1550 _results.push(void 0); 1551 } 1552 } 1553 return _results; 1554 }; 1555 1556 Dropzone.blacklistedBrowsers = [/opera.*Macintosh.*version\/12/i]; 1557 1558 Dropzone.isBrowserSupported = function() { 1559 var capableBrowser, regex, _i, _len, _ref; 1560 capableBrowser = true; 1561 if (window.File && window.FileReader && window.FileList && window.Blob && window.FormData && document.querySelector) { 1562 if (!("classList" in document.createElement("a"))) { 1563 capableBrowser = false; 1564 } else { 1565 _ref = Dropzone.blacklistedBrowsers; 1566 for (_i = 0, _len = _ref.length; _i < _len; _i++) { 1567 regex = _ref[_i]; 1568 if (regex.test(navigator.userAgent)) { 1569 capableBrowser = false; 1570 continue; 1571 } 1572 } 1573 } 1574 } else { 1575 capableBrowser = false; 1576 } 1577 return capableBrowser; 1578 }; 1579 1580 without = function(list, rejectedItem) { 1581 var item, _i, _len, _results; 1582 _results = []; 1583 for (_i = 0, _len = list.length; _i < _len; _i++) { 1584 item = list[_i]; 1585 if (item !== rejectedItem) { 1586 _results.push(item); 1587 } 1588 } 1589 return _results; 1590 }; 1591 1592 camelize = function(str) { 1593 return str.replace(/[\-_](\w)/g, function(match) { 1594 return match.charAt(1).toUpperCase(); 1595 });
1596 }; 1597 1598 Dropzone.createElement = function(string) { 1599 var div; 1600 div = document.createElement("div"); 1601 div.innerHTML = string; 1602 return div.childNodes[0]; 1603 }; 1604 1605 Dropzone.elementInside = function(element, container) { 1606 if (element === container) { 1607 return true; 1608 } 1609 while (element = element.parentNode) { 1610 if (element === container) { 1611 return true; 1612 } 1613 } 1614 return false; 1615 }; 1616 1617 Dropzone.getElement = function(el, name) { 1618 var element; 1619 if (typeof el === "string") { 1620 element = document.querySelector(el); 1621 } else if (el.nodeType != null) { 1622 element = el; 1623 } 1624 if (element == null) { 1625 throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector or a plain HTML element."); 1626 } 1627 return element; 1628 }; 1629 1630 Dropzone.getElements = function(els, name) { 1631 var e, el, elements, _i, _j, _len, _len1, _ref; 1632 if (els instanceof Array) { 1633 elements = []; 1634 try { 1635 for (_i = 0, _len = els.length; _i < _len; _i++) { 1636 el = els[_i]; 1637 elements.push(this.getElement(el, name)); 1638 } 1639 } catch (_error) { 1640 e = _error; 1641 elements = null; 1642 } 1643 } else if (typeof els === "string") { 1644 elements = []; 1645 _ref = document.querySelectorAll(els); 1646 for (_j = 0, _len1 = _ref.length; _j < _len1; _j++) { 1647 el = _ref[_j]; 1648 elements.push(el); 1649 } 1650 } else if (els.nodeType != null) { 1651 elements = [els]; 1652 } 1653 if (!((elements != null) && elements.length)) { 1654 throw new Error("Invalid `" + name + "` option provided. Please provide a CSS selector, a plain HTML element or a list of those."); 1655 } 1656 return elements; 1657 }; 1658 1659 Dropzone.confirm = function(question, accepted, rejected) { 1660 if (window.confirm(question)) { 1661 return accepted(); 1662 } else if (rejected != null) { 1663 return rejected(); 1664 } 1665 }; 1666 1667 Dropzone.isValidFile = function(file, acceptedFiles) { 1668 var baseMimeType, mimeType, validType, _i, _len; 1669 if (!acceptedFiles) { 1670 return true; 1671 } 1672 acceptedFiles = acceptedFiles.split(","); 1673 mimeType = file.type; 1674 baseMimeType = mimeType.replace(/\/.*$/, ""); 1675 for (_i = 0, _len = acceptedFiles.length; _i < _len; _i++) { 1676 validType = acceptedFiles[_i]; 1677 validType = validType.trim(); 1678 if (validType.charAt(0) === ".") { 1679 if (file.name.toLowerCase().indexOf(validType.toLowerCase(), file.name.length - validType.length) !== -1) { 1680 return true; 1681 } 1682 } else if (/\/\*$/.test(validType)) { 1683 if (baseMimeType === validType.replace(/\/.*$/, "")) { 1684 return true; 1685 } 1686 } else { 1687 if (mimeType === validType) { 1688 return true; 1689 } 1690 } 1691 } 1692 return false; 1693 }; 1694 1695 if (typeof jQuery !== "undefined" && jQuery !== null) { 1696 jQuery.fn.dropzone = function(options) { 1697 return this.each(function() { 1698 return new Dropzone(this, options); 1699 }); 1700 }; 1701 } 1702 1703 if (typeof module !== "undefined" && module !== null) { 1704 module.exports = Dropzone; 1705 } else { 1706 window.Dropzone = Dropzone; 1707 } 1708 1709 Dropzone.ADDED = "added"; 1710 1711 Dropzone.QUEUED = "queued"; 1712 1713 Dropzone.ACCEPTED = Dropzone.QUEUED; 1714 1715 Dropzone.UPLOADING = "uploading"; 1716 1717 Dropzone.PROCESSING = Dropzone.UPLOADING; 1718 1719 Dropzone.CANCELED = "canceled"; 1720 1721 Dropzone.ERROR = "error"; 1722 1723 Dropzone.SUCCESS = "success"; 1724 1725 1726 /* 1727 1728 Bugfix for iOS 6 and 7 1729 Source: http://stackoverflow.com/questions/11929099/html5-canvas-drawimage-ratio-bug-ios 1730 based on the work of https://github.com/stomita/ios-imagefile-megapixel 1731 */ 1732 1733 detectVerticalSquash = function(img) { 1734 var alpha, canvas, ctx, data, ey, ih, iw, py, ratio, sy; 1735 iw = img.naturalWidth; 1736 ih = img.naturalHeight; 1737 canvas = document.createElement("canvas"); 1738 canvas.width = 1; 1739 canvas.height = ih; 1740 ctx = canvas.getContext("2d"); 1741 ctx.drawImage(img, 0, 0); 1742 data = ctx.getImageData(0, 0, 1, ih).data; 1743 sy = 0; 1744 ey = ih; 1745 py = ih; 1746 while (py > sy) { 1747 alpha = data[(py - 1) * 4 + 3]; 1748 if (alpha === 0) { 1749 ey = py; 1750 } else { 1751 sy = py; 1752 } 1753 py = (ey + sy) >> 1; 1754 } 1755 ratio = py / ih; 1756 if (ratio === 0) { 1757 return 1; 1758 } else { 1759 return ratio; 1760 } 1761 }; 1762 1763 drawImageIOSFix = function(ctx, img, sx, sy, sw, sh, dx, dy, dw, dh) { 1764 var vertSquashRatio; 1765 vertSquashRatio = detectVerticalSquash(img); 1766 return ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh / vertSquashRatio); 1767 }; 1768 1769 1770 /* 1771 * contentloaded.js 1772 * 1773 * Author: Diego Perini (diego.perini at gmail.com) 1774 * Summary: cross-browser wrapper for DOMContentLoaded 1775 * Updated: 20101020 1776 * License: MIT 1777 * Version: 1.2 1778 * 1779 * URL: 1780 * http://javascript.nwbox.com/ContentLoaded/ 1781 * http://javascript.nwbox.com/ContentLoaded/MIT-LICENSE 1782 */ 1783 1784 contentLoaded = function(win, fn) { 1785 var add, doc, done, init, poll, pre, rem, root, top; 1786 done = false; 1787 top = true; 1788 doc = win.document; 1789 root = doc.documentElement; 1790 add = (doc.addEventListener ? "addEventListener" : "attachEvent"); 1791 rem = (doc.addEventListener ? "removeEventListener" : "detachEvent"); 1792 pre = (doc.addEventListener ? "" : "on"); 1793 init = function(e) { 1794 if (e.type === "readystatechange" && doc.readyState !== "complete") { 1795 return; 1796 } 1797 (e.type === "load" ? win : doc)[rem](pre + e.type, init, false); 1798 if (!done && (done = true)) {
1799 return fn.call(win, e.type || e); 1800 } 1801 }; 1802 poll = function() { 1803 var e; 1804 try { 1805 root.doScroll("left"); 1806 } catch (_error) { 1807 e = _error; 1808 setTimeout(poll, 50); 1809 return; 1810 } 1811 return init("poll"); 1812 }; 1813 if (doc.readyState !== "complete") { 1814 if (doc.createEventObject && root.doScroll) { 1815 try { 1816 top = !win.frameElement; 1817 } catch (_error) {} 1818 if (top) { 1819 poll(); 1820 } 1821 } 1822 doc[add](pre + "DOMContentLoaded", init, false); 1823 doc[add](pre + "readystatechange", init, false); 1824 return win[add](pre + "load", init, false); 1825 } 1826 }; 1827 1828 Dropzone._autoDiscoverFunction = function() { 1829 if (Dropzone.autoDiscover) { 1830 return Dropzone.discover(); 1831 } 1832 }; 1833 1834 contentLoaded(window, Dropzone._autoDiscoverFunction); 1835 1836}).call(this); 1837; 1838/*jslint devel: true, bitwise: true, regexp: true, browser: true, confusion: true, unparam: true, eqeq: true, white: true, nomen: true, plusplus: true, maxerr: 50, indent: 4 */ 1839/*globals jQuery,Color,define */ 1840 1841/*! 1842 * ColorPicker 1843 * 1844 * Copyright (c) 2011-2016 Martijn W. van der Lee 1845 * Licensed under the MIT. 1846 */ 1847/* Full-featured colorpicker for jQueryUI with full theming support. 1848 * Most images from jPicker by Christopher T. Tillman. 1849 * Sourcecode created from scratch by Martijn W. van der Lee. 1850 */ 1851(function( factory ) { 1852 if ( typeof define === "function" && define.amd ) { 1853 1854 // AMD. Register as an anonymous module. 1855 define([ 1856 "jquery" 1857 ], factory ); 1858 } else { 1859 1860 // Browser globals 1861 factory( jQuery ); 1862 } 1863} (function ($) { 1864 "use strict"; 1865 1866 var _colorpicker_index = 0, 1867 1868 _container_popup = '<div class="ui-colorpicker ui-colorpicker-dialog ui-dialog ui-widget ui-widget-content ui-corner-all" style="display: none;"></div>', 1869 _container_inlineFrame = '<div class="ui-colorpicker ui-colorpicker-inline ui-dialog ui-widget ui-widget-content ui-corner-all"></div>', 1870 _container_inline = '<div class="ui-colorpicker ui-colorpicker-inline"></div>', 1871 1872 _intToHex = function (dec) { 1873 var result = Math.round(dec).toString(16); 1874 if (result.length === 1) { 1875 result = ('0' + result); 1876 } 1877 return result.toLowerCase(); 1878 }, 1879 1880 _keycode = { 1881 isPrint: function(keycode) { 1882 return keycode == 32 // spacebar 1883 || (keycode >= 48 && keycode <= 57) // number keys 1884 || (keycode >= 65 && keycode <= 90) // letter keys 1885 || (keycode >= 96 && keycode <= 111) // numpad keys 1886 || (keycode >= 186 && keycode < 192) // ;=,-./` (in order) 1887 || (keycode >= 219 && keycode < 222); // [\]' (in order) 1888 }, 1889 isHex: function(keycode) { 1890 return (keycode >= 48 && keycode <= 57) // number keys 1891 || (keycode >= 65 && keycode <= 70); // a-f 1892 } 1893 }, 1894 1895 _layoutTable = function(layout, callback) { 1896 var bitmap, 1897 x, y, 1898 width, height, 1899 columns, rows, 1900 index, 1901 cell, 1902 html, 1903 w, h, 1904 colspan, 1905 walked; 1906 1907 layout.sort(function(a, b) { 1908 if (a.pos[1] === b.pos[1]) { 1909 return a.pos[0] - b.pos[0]; 1910 } 1911 return a.pos[1] - b.pos[1]; 1912 }); 1913 1914 // Determine dimensions of the table 1915 width = 0; 1916 height = 0; 1917 $.each (layout, function(index, part) { 1918 width = Math.max(width, part.pos[0] + part.pos[2]); 1919 height = Math.max(height, part.pos[1] + part.pos[3]); 1920 }); 1921 1922 // Initialize bitmap 1923 bitmap = []; 1924 for (x = 0; x < width; ++x) { 1925 bitmap.push([]); 1926 } 1927 1928 // Mark rows and columns which have layout assigned 1929 rows = []; 1930 columns = []; 1931 $.each(layout, function(index, part) { 1932 // mark columns 1933 for (x = 0; x < part.pos[2]; x += 1) { 1934 columns[part.pos[0] + x] = true; 1935 } 1936 for (y = 0; y < part.pos[3]; y += 1) { 1937 rows[part.pos[1] + y] = true; 1938 } 1939 }); 1940 1941 // Generate the table 1942 html = ''; 1943 cell = layout[index = 0]; 1944 for (y = 0; y < height; ++y) { 1945 html += '<tr>'; 1946 x = 0; 1947 while (x < width) { 1948 if (typeof cell !== 'undefined' && x === cell.pos[0] && y === cell.pos[1]) { 1949 // Create a "real" cell 1950 html += callback(cell, x, y); 1951 1952 for (h = 0; h < cell.pos[3]; h +=1) { 1953 for (w = 0; w < cell.pos[2]; w +=1) { 1954 bitmap[x + w][y + h] = true; 1955 } 1956 } 1957 1958 x += cell.pos[2]; 1959 cell = layout[++index]; 1960 } else { 1961 // Fill in the gaps 1962 colspan = 0; 1963 walked = false; 1964 1965 while (x < width && bitmap[x][y] === undefined && (cell === undefined || y < cell.pos[1] || (y === cell.pos[1] && x < cell.pos[0]))) { 1966 if (columns[x] === true) { 1967 colspan += 1;
1968 } 1969 walked = true; 1970 x += 1; 1971 } 1972 1973 if (colspan > 0) { 1974 html += '<td colspan="'+colspan+'"></td>'; 1975 } else if (!walked) { 1976 x += 1; 1977 } 1978 } 1979 } 1980 html += '</tr>'; 1981 } 1982 1983 return '<table cellspacing="0" cellpadding="0" border="0"><tbody>' + html + '</tbody></table>'; 1984 }; 1985 1986 $.colorpicker = new function() { 1987 this.regional = { 1988 '': { 1989 ok: 'OK', 1990 cancel: 'Cancel', 1991 none: 'None', 1992 button: 'Color', 1993 title: 'Pick a color', 1994 transparent: 'Transparent', 1995 hsvH: 'H', 1996 hsvS: 'S', 1997 hsvV: 'V', 1998 rgbR: 'R', 1999 rgbG: 'G', 2000 rgbB: 'B', 2001 labL: 'L', 2002 labA: 'a', 2003 labB: 'b', 2004 hslH: 'H', 2005 hslS: 'S', 2006 hslL: 'L', 2007 cmykC: 'C', 2008 cmykM: 'M', 2009 cmykY: 'Y', 2010 cmykK: 'K', 2011 alphaA: 'A' 2012 } 2013 }; 2014 2015 this.swatchesNames = { 2016 'html': 'HTML' 2017 }; 2018 2019 this.swatches = { 2020 'html': [ 2021 {name: 'black', r: 0, g: 0, b: 0}, 2022 {name: 'dimgray', r: 0.4117647058823529, g: 0.4117647058823529, b: 0.4117647058823529}, 2023 {name: 'gray', r: 0.5019607843137255, g: 0.5019607843137255, b: 0.5019607843137255}, 2024 {name: 'darkgray', r: 0.6627450980392157, g: 0.6627450980392157, b: 0.6627450980392157}, 2025 {name: 'silver', r: 0.7529411764705882, g: 0.7529411764705882, b: 0.7529411764705882}, 2026 {name: 'lightgrey', r: 0.8274509803921568, g: 0.8274509803921568, b: 0.8274509803921568}, 2027 {name: 'gainsboro', r: 0.8627450980392157, g: 0.8627450980392157, b: 0.8627450980392157},
2028 {name: 'whitesmoke', r: 0.9607843137254902, g: 0.9607843137254902, b: 0.9607843137254902}, 2029 {name: 'white', r: 1, g: 1, b: 1}, 2030 {name: 'rosybrown', r: 0.7372549019607844, g: 0.5607843137254902, b: 0.5607843137254902}, 2031 {name: 'indianred', r: 0.803921568627451, g: 0.3607843137254902, b: 0.3607843137254902}, 2032 {name: 'brown', r: 0.6470588235294118, g: 0.16470588235294117, b: 0.16470588235294117}, 2033 {name: 'firebrick', r: 0.6980392156862745, g: 0.13333333333333333, b: 0.13333333333333333}, 2034 {name: 'lightcoral', r: 0.9411764705882353, g: 0.5019607843137255, b: 0.5019607843137255}, 2035 {name: 'maroon', r: 0.5019607843137255, g: 0, b: 0}, 2036 {name: 'darkred', r: 0.5450980392156862, g: 0, b: 0}, 2037 {name: 'red', r: 1, g: 0, b: 0}, 2038 {name: 'snow', r: 1, g: 0.9803921568627451, b: 0.9803921568627451}, 2039 {name: 'salmon', r: 0.9803921568627451, g: 0.5019607843137255, b: 0.4470588235294118}, 2040 {name: 'mistyrose', r: 1, g: 0.8941176470588236, b: 0.8823529411764706}, 2041 {name: 'tomato', r: 1, g: 0.38823529411764707, b: 0.2784313725490196}, 2042 {name: 'darksalmon', r: 0.9137254901960784, g: 0.5882352941176471, b: 0.47843137254901963}, 2043 {name: 'orangered', r: 1, g: 0.27058823529411763, b: 0}, 2044 {name: 'coral', r: 1, g: 0.4980392156862745, b: 0.3137254901960784}, 2045 {name: 'lightsalmon', r: 1, g: 0.6274509803921569, b: 0.47843137254901963}, 2046 {name: 'sienna', r: 0.6274509803921569, g: 0.3215686274509804, b: 0.17647058823529413}, 2047 {name: 'seashell', r: 1, g: 0.9607843137254902, b: 0.9333333333333333}, 2048 {name: 'chocolate', r: 0.8235294117647058, g: 0.4117647058823529, b: 0.11764705882352941}, 2049 {name: 'saddlebrown', r: 0.5450980392156862, g: 0.27058823529411763, b: 0.07450980392156863}, 2050 {name: 'sandybrown', r: 0.9568627450980393, g: 0.6431372549019608, b: 0.3764705882352941}, 2051 {name: 'peachpuff', r: 1, g: 0.8549019607843137, b: 0.7254901960784313}, 2052 {name: 'peru', r: 0.803921568627451, g: 0.5215686274509804, b: 0.24705882352941178}, 2053 {name: 'linen', r: 0.9803921568627451, g: 0.9411764705882353, b: 0.9019607843137255}, 2054 {name: 'darkorange', r: 1, g: 0.5490196078431373, b: 0}, 2055 {name: 'bisque', r: 1, g: 0.8941176470588236, b: 0.7686274509803922}, 2056 {name: 'burlywood', r: 0.8705882352941177, g: 0.7215686274509804, b: 0.5294117647058824}, 2057 {name: 'tan', r: 0.8235294117647058, g: 0.7058823529411765, b: 0.5490196078431373}, 2058 {name: 'antiquewhite', r: 0.9803921568627451, g: 0.9215686274509803, b: 0.8431372549019608}, 2059 {name: 'navajowhite', r: 1, g: 0.8705882352941177, b: 0.6784313725490196}, 2060 {name: 'blanchedalmond', r: 1, g: 0.9215686274509803, b: 0.803921568627451}, 2061 {name: 'papayawhip', r: 1, g: 0.9372549019607843, b: 0.8352941176470589}, 2062 {name: 'orange', r: 1, g: 0.6470588235294118, b: 0}, 2063 {name: 'moccasin', r: 1, g: 0.8941176470588236, b: 0.7098039215686275}, 2064 {name: 'wheat', r: 0.9607843137254902, g: 0.8705882352941177, b: 0.7019607843137254}, 2065 {name: 'oldlace', r: 0.9921568627450981, g: 0.9607843137254902, b: 0.9019607843137255}, 2066 {name: 'floralwhite', r: 1, g: 0.9803921568627451, b: 0.9411764705882353}, 2067 {name: 'goldenrod', r: 0.8549019607843137, g: 0.6470588235294118, b: 0.12549019607843137}, 2068 {name: 'darkgoldenrod', r: 0.7215686274509804, g: 0.5254901960784314, b: 0.043137254901960784}, 2069 {name: 'cornsilk', r: 1, g: 0.9725490196078431, b: 0.8627450980392157}, 2070 {name: 'gold', r: 1, g: 0.8431372549019608, b: 0}, 2071 {name: 'palegoldenrod', r: 0.9333333333333333, g: 0.9098039215686274, b: 0.6666666666666666}, 2072 {name: 'khaki', r: 0.9411764705882353, g: 0.9019607843137255, b: 0.5490196078431373}, 2073 {name: 'lemonchiffon', r: 1, g: 0.9803921568627451, b: 0.803921568627451}, 2074 {name: 'darkkhaki', r: 0.7411764705882353, g: 0.7176470588235294, b: 0.4196078431372549}, 2075 {name: 'beige', r: 0.9607843137254902, g: 0.9607843137254902, b: 0.8627450980392157}, 2076 {name: 'lightgoldenrodyellow', r: 0.9803921568627451, g: 0.9803921568627451, b: 0.82352941176470
207658}, 2077 {name: 'olive', r: 0.5019607843137255, g: 0.5019607843137255, b: 0}, 2078 {name: 'yellow', r: 1, g: 1, b: 0}, 2079 {name: 'lightyellow', r: 1, g: 1, b: 0.8784313725490196}, 2080 {name: 'ivory', r: 1, g: 1, b: 0.9411764705882353}, 2081 {name: 'olivedrab', r: 0.4196078431372549, g: 0.5568627450980392, b: 0.13725490196078433}, 2082 {name: 'yellowgreen', r: 0.6039215686274509, g: 0.803921568627451, b: 0.19607843137254902}, 2083 {name: 'darkolivegreen', r: 0.3333333333333333, g: 0.4196078431372549, b: 0.1843137254901961}, 2084 {name: 'greenyellow', r: 0.6784313725490196, g: 1, b: 0.1843137254901961}, 2085 {name: 'lawngreen', r: 0.48627450980392156, g: 0.9882352941176471, b: 0}, 2086 {name: 'chartreuse', r: 0.4980392156862745, g: 1, b: 0}, 2087 {name: 'darkseagreen', r: 0.5607843137254902, g: 0.7372549019607844, b: 0.5607843137254902}, 2088 {name: 'forestgreen', r: 0.13333333333333333, g: 0.5450980392156862, b: 0.13333333333333333}, 2089 {name: 'limegreen', r: 0.19607843137254902, g: 0.803921568627451, b: 0.19607843137254902}, 2090 {name: 'lightgreen', r: 0.5647058823529412, g: 0.9333333333333333, b: 0.5647058823529412}, 2091 {name: 'palegreen', r: 0.596078431372549, g: 0.984313725490196, b: 0.596078431372549}, 2092 {name: 'darkgreen', r: 0, g: 0.39215686274509803, b: 0}, 2093 {name: 'green', r: 0, g: 0.5019607843137255, b: 0}, 2094 {name: 'lime', r: 0, g: 1, b: 0}, 2095 {name: 'honeydew', r: 0.9411764705882353, g: 1, b: 0.9411764705882353}, 2096 {name: 'mediumseagreen', r: 0.23529411764705882, g: 0.7019607843137254, b: 0.44313725490196076}, 2097 {name: 'seagreen', r: 0.1803921568627451, g: 0.5450980392156862, b: 0.3411764705882353}, 2098 {name: 'springgreen', r: 0, g: 1, b: 0.4980392156862745}, 2099 {name: 'mintcream', r: 0.9607843137254902, g: 1, b: 0.9803921568627451}, 2100 {name: 'mediumspringgreen', r: 0, g: 0.9803921568627451, b: 0.6039215686274509}, 2101 {name: 'mediumaquamarine', r: 0.4, g: 0.803921568627451, b: 0.6666666666666666}, 2102 {name: 'aquamarine', r: 0.4980392156862745, g: 1, b: 0.8313725490196079}, 2103 {name: 'turquoise', r: 0.25098039215686274, g: 0.8784313725490196, b: 0.8156862745098039}, 2104 {name: 'lightseagreen', r: 0.12549019607843137, g: 0.6980392156862745, b: 0.6666666666666666}, 2105 {name: 'mediumturquoise', r: 0.2823529411764706, g: 0.8196078431372549, b: 0.8}, 2106 {name: 'darkslategray', r: 0.1843137254901961, g: 0.30980392156862746, b: 0.30980392156862746}, 2107 {name: 'paleturquoise', r: 0.6862745098039216, g: 0.9333333333333333, b: 0.9333333333333333}, 2108 {name: 'teal', r: 0, g: 0.5019607843137255, b: 0.5019607843137255}, 2109 {name: 'darkcyan', r: 0, g: 0.5450980392156862, b: 0.5450980392156862}, 2110 {name: 'darkturquoise', r: 0, g: 0.807843137254902, b: 0.8196078431372549}, 2111 {name: 'aqua', r: 0, g: 1, b: 1}, 2112 {name: 'cyan', r: 0, g: 1, b: 1}, 2113 {name: 'lightcyan', r: 0.8784313725490196, g: 1, b: 1}, 2114 {name: 'azure', r: 0.9411764705882353, g: 1, b: 1}, 2115 {name: 'cadetblue', r: 0.37254901960784315, g: 0.6196078431372549, b: 0.6274509803921569}, 2116 {name: 'powderblue', r: 0.6901960784313725, g: 0.8784313725490196, b: 0.9019607843137255}, 2117 {name: 'lightblue', r: 0.6784313725490196, g: 0.8470588235294118, b: 0.9019607843137255}, 2118 {name: 'deepskyblue', r: 0, g: 0.7490196078431373, b: 1}, 2119 {name: 'skyblue', r: 0.5294117647058824, g: 0.807843137254902, b: 0.9215686274509803}, 2120 {name: 'lightskyblue', r: 0.5294117647058824, g: 0.807843137254902, b: 0.9803921568627451}, 2121 {name: 'steelblue', r: 0.27450980392156865, g: 0.5098039215686274, b: 0.7058823529411765}, 2122 {name: 'aliceblue', r: 0.9411764705882353, g: 0.9725490196078431, b: 1}, 2123 {name: 'dodgerblue', r: 0.11764705882352941, g: 0.5647058823529412, b: 1}, 2124 {name: 'slategray', r: 0.4392156862745098, g: 0.5019607843137255, b: 0.5647058823529412}, 2125 {name: 'lightslategray', r: 0.4666666666666667, g: 0.5333333333333333, b: 0.6}, 2126 {name: 'lightsteelblue', r: 0.6901960784313725, g: 0.7686274509803922, b: 0.8705882352941177}, 2127 {name: 'cornflowerblue', r: 0.39215686274509803, g: 0.5843137254901961, b: 0.92941176470
212758824}, 2128 {name: 'royalblue', r: 0.2549019607843137, g: 0.4117647058823529, b: 0.8823529411764706}, 2129 {name: 'midnightblue', r: 0.09803921568627451, g: 0.09803921568627451, b: 0.4392156862745098}, 2130 {name: 'lavender', r: 0.9019607843137255, g: 0.9019607843137255, b: 0.9803921568627451}, 2131 {name: 'navy', r: 0, g: 0, b: 0.5019607843137255}, 2132 {name: 'darkblue', r: 0, g: 0, b: 0.5450980392156862}, 2133 {name: 'mediumblue', r: 0, g: 0, b: 0.803921568627451}, 2134 {name: 'blue', r: 0, g: 0, b: 1}, 2135 {name: 'ghostwhite', r: 0.9725490196078431, g: 0.9725490196078431, b: 1}, 2136 {name: 'darkslateblue', r: 0.2823529411764706, g: 0.23921568627450981, b: 0.5450980392156862}, 2137 {name: 'slateblue', r: 0.41568627450980394, g: 0.35294117647058826, b: 0.803921568627451}, 2138 {name: 'mediumslateblue', r: 0.4823529411764706, g: 0.40784313725490196, b: 0.9333333333333333}, 2139 {name: 'mediumpurple', r: 0.5764705882352941, g: 0.4392156862745098, b: 0.8588235294117647}, 2140 {name: 'blueviolet', r: 0.5411764705882353, g: 0.16862745098039217, b: 0.8862745098039215}, 2141 {name: 'indigo', r: 0.29411764705882354, g: 0, b: 0.5098039215686274}, 2142 {name: 'darkorchid', r: 0.6, g: 0.19607843137254902, b: 0.8}, 2143 {name: 'darkviolet', r: 0.5803921568627451, g: 0, b: 0.8274509803921568}, 2144 {name: 'mediumorchid', r: 0.7294117647058823, g: 0.3333333333333333, b: 0.8274509803921568}, 2145 {name: 'thistle', r: 0.8470588235294118, g: 0.7490196078431373, b: 0.8470588235294118}, 2146 {name: 'plum', r: 0.8666666666666667, g: 0.6274509803921569, b: 0.8666666666666667}, 2147 {name: 'violet', r: 0.9333333333333333, g: 0.5098039215686274, b: 0.9333333333333333}, 2148 {name: 'purple', r: 0.5019607843137255, g: 0, b: 0.5019607843137255}, 2149 {name: 'darkmagenta', r: 0.5450980392156862, g: 0, b: 0.5450980392156862}, 2150 {name: 'magenta', r: 1, g: 0, b: 1}, 2151 {name: 'fuchsia', r: 1, g: 0, b: 1}, 2152 {name: 'orchid', r: 0.8549019607843137, g: 0.4392156862745098, b: 0.8392156862745098}, 2153 {name: 'mediumvioletred', r: 0.7803921568627451, g: 0.08235294117647059, b: 0.5215686274509804}, 2154 {name: 'deeppink', r: 1, g: 0.0784313725490196, b: 0.5764705882352941}, 2155 {name: 'hotpink', r: 1, g: 0.4117647058823529, b: 0.7058823529411765}, 2156 {name: 'palevioletred', r: 0.8588235294117647, g: 0.4392156862745098, b: 0.5764705882352941}, 2157 {name: 'lavenderblush', r: 1, g: 0.9411764705882353, b: 0.9607843137254902}, 2158 {name: 'crimson', r: 0.8627450980392157, g: 0.0784313725490196, b: 0.23529411764705882}, 2159 {name: 'pink', r: 1, g: 0.7529411764705882, b: 0.796078431372549}, 2160 {name: 'lightpink', r: 1, g: 0.7137254901960784, b: 0.7568627450980392} 2161 ] 2162 }; 2163 2164 this.writers = { 2165 '#HEX': function(color, that) { 2166 return that._formatColor('#rxgxbx', color); 2167 } 2168 , '#HEX3': function(color, that) { 2169 var hex3 = $.colorpicker.writers.HEX3(color); 2170 return hex3 === false? false : '#'+hex3; 2171 } 2172 , 'HEX': function(color, that) { 2173 return that._formatColor('rxgxbx', color); 2174 } 2175 , 'HEX3': function(color, that) { 2176 var rgb = color.getRGB(), 2177 r = Math.round(rgb.r * 255), 2178 g = Math.round(rgb.g * 255), 2179 b = Math.round(rgb.b * 255); 2180 2181 if (((r >>> 4) === (r &= 0xf)) 2182 && ((g >>> 4) === (g &= 0xf)) 2183 && ((b >>> 4) === (b &= 0xf))) { 2184 return r.toString(16)+g.toString(16)+b.toString(16); 2185 } 2186 return false; 2187 } 2188 , '#HEXA': function(color, that) { 2189 return that._formatColor('#rxgxbxax', color); 2190 } 2191 , '#HEXA4': function(color, that) { 2192 var hexa4 = $.colorpicker.writers.HEXA4(color, that); 2193 return hexa4 === false? false : '#'+hexa4; 2194 } 2195 , 'HEXA': function(color, that) { 2196 return that._formatColor('rxgxbxax', color); 2197 } 2198 , 'HEXA4': function(color, that) { 2199 var a = Math.round(color.getAlpha() * 255); 2200 2201 if ((a >>> 4) === (a &= 0xf)) { 2202 return $.colorpicker.writers.HEX3(color, that)+a.toString(16); 2203 } 2204 return false; 2205 } 2206 , 'RGB': function(color, that) { 2207 return color.getAlpha() >= 1 2208 ? that._formatColor('rgb(rd,gd,bd)', color) 2209 : false; 2210 } 2211 , 'RGBA': function(color, that) { 2212 return that._formatColor('rgba(rd,gd,bd,af)', color); 2213 } 2214 , 'RGB%': function(color, that) { 2215 return color.getAlpha() >= 1 2216 ? that._formatColor('rgb(rp%,gp%,bp%)', color) 2217 : false; 2218 } 2219 , 'RGBA%': function(color, that) { 2220 return that._formatColor('rgba(rp%,gp%,bp%,af)', color); 2221 } 2222 , 'HSL': function(color, that) { 2223 return color.getAlpha() >= 1 2224 ? that._formatColor('hsl(hd,sd,vd)', color) 2225 : false; 2226 } 2227 , 'HSLA': function(color, that) { 2228 return that._formatColor('hsla(hd,sd,vd,af)', color); 2229 } 2230 , 'HSL%': function(color, that) { 2231 return color.getAlpha() >= 1 2232 ? that._formatColor('hsl(hp%,sp%,vp%)', color) 2233 : false; 2234 } 2235 , 'HSLA%': function(color, that) { 2236 return that._formatColor('hsla(hp%,sp%,vp%,af)', color); 2237 } 2238 , 'NAME': function(color, that) { 2239 return that._closestName(color); 2240 } 2241 , 'EXACT': function(color, that) { 2242 return that._exactName(color); 2243 } 2244 }; 2245 2246 this.parsers = { 2247 '': function(color) { 2248 if (color === '') { 2249 return new $.colorpicker.Color(); 2250 } 2251 } 2252 , 'NAME': function(color, that) { 2253 var c = that._getSwatch($.trim(color)); 2254 if (c) { 2255 return new $.colorpicker.Color(c.r, c.g, c.b); 2256 } 2257 } 2258 , 'RGBA': function(color) { 2259 var m = /^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)$/.exec(color); 2260 if (m) { 2261 return new $.colorpicker.Color(
2262 m[1] / 255, 2263 m[2] / 255, 2264 m[3] / 255, 2265 parseFloat(m[4]) 2266 ); 2267 } 2268 } 2269 , 'RGBA%': function(color) { 2270 var m = /^rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)$/.exec(color); 2271 if (m) { 2272 return new $.colorpicker.Color( 2273 m[1] / 100, 2274 m[2] / 100, 2275 m[3] / 100, 2276 m[4] / 100 2277 ); 2278 } 2279 } 2280 , 'HSLA': function(color) { 2281 var m = /^hsla?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)$/.exec(color); 2282 if (m) { 2283 return (new $.colorpicker.Color()).setHSL( 2284 m[1] / 255, 2285 m[2] / 255, 2286 m[3] / 255).setAlpha(parseFloat(m[4])); 2287 } 2288 } 2289 , 'HSLA%': function(color) { 2290 var m = /^hsla?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)$/.exec(color); 2291 if (m) { 2292 return (new $.colorpicker.Color()).setHSL( 2293 m[1] / 100, 2294 m[2] / 100, 2295 m[3] / 100).setAlpha(m[4] / 100); 2296 } 2297 } 2298 , '#HEX': function(color) { 2299 var m = /^#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$/.exec(color); 2300 if (m) { 2301 return new $.colorpicker.Color( 2302 parseInt(m[1], 16) / 255, 2303 parseInt(m[2], 16) / 255, 2304 parseInt(m[3], 16) / 255 2305 ); 2306 } 2307 } 2308 , '#HEX3': function(color) { 2309 var m = /^#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])$/.exec(color); 2310 if (m) { 2311 return new $.colorpicker.Color( 2312 parseInt(String(m[1]) + m[1], 16) / 255, 2313 parseInt(String(m[2]) + m[2], 16) / 255, 2314 parseInt(String(m[3]) + m[3], 16) / 255 2315 ); 2316 } 2317 } 2318 , 'HEX': function(color) { 2319 var m = /^([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$/.exec(color); 2320 if (m) { 2321 return new $.colorpicker.Color( 2322 parseInt(m[1], 16) / 255, 2323 parseInt(m[2], 16) / 255, 2324 parseInt(m[3], 16) / 255 2325 ); 2326 } 2327 } 2328 , 'HEX3': function(color) { 2329 var m = /^([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])$/.exec(color); 2330 if (m) { 2331 return new $.colorpicker.Color( 2332 parseInt(String(m[1]) + m[1], 16) / 255, 2333 parseInt(String(m[2]) + m[2], 16) / 255, 2334 parseInt(String(m[3]) + m[3], 16) / 255 2335 ); 2336 } 2337 } 2338 , '#HEXA': function(color) { 2339 var m = /^#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$/.exec(color); 2340 if (m) { 2341 return new $.colorpicker.Color( 2342 parseInt(m[1], 16) / 255, 2343 parseInt(m[2], 16) / 255, 2344 parseInt(m[3], 16) / 255, 2345 parseInt(m[4], 16) / 255 2346 ); 2347 } 2348 } 2349 , '#HEXA4': function(color) { 2350 var m = /^#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])$/.exec(color); 2351 if (m) { 2352 return new $.colorpicker.Color( 2353 parseInt(String(m[1]) + m[1], 16) / 255, 2354 parseInt(String(m[2]) + m[2], 16) / 255, 2355 parseInt(String(m[3]) + m[3], 16) / 255, 2356 parseInt(String(m[4]) + m[4], 16) / 255 2357 ); 2358 } 2359 } 2360 , 'HEXA': function(color) { 2361 var m = /^([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})$/.exec(color); 2362 if (m) { 2363 return new $.colorpicker.Color( 2364 parseInt(m[1], 16) / 255, 2365 parseInt(m[2], 16) / 255, 2366 parseInt(m[3], 16) / 255, 2367 parseInt(m[4], 16) / 255 2368 ); 2369 } 2370 } 2371 , 'HEXA4': function(color) { 2372 var m = /^([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])$/.exec(color); 2373 if (m) { 2374 return new $.colorpicker.Color( 2375 parseInt(String(m[1]) + m[1], 16) / 255, 2376 parseInt(String(m[2]) + m[2], 16) / 255, 2377 parseInt(String(m[3]) + m[3], 16) / 255, 2378 parseInt(String(m[4]) + m[4], 16) / 255 2379 ); 2380 } 2381 } 2382 }; 2383 2384 this.partslists = { 2385 'full': ['header', 'map', 'bar', 'hex', 'hsv', 'rgb', 'alpha', 'lab', 'cmyk', 'preview', 'swatches', 'footer'], 2386 'popup': ['map', 'bar', 'hex', 'hsv', 'rgb', 'alpha', 'preview', 'footer'], 2387 'draggable': ['header', 'map', 'bar', 'hex', 'hsv', 'rgb', 'alpha', 'preview', 'footer'], 2388 'inline': ['map', 'bar', 'hex', 'hsv', 'rgb', 'alpha', 'preview'] 2389 }; 2390 2391 this.limits = { 2392 'websafe': function(color) { 2393 color.limit(6); 2394 }, 2395 'nibble': function(color) { 2396 color.limit(16); 2397 }, 2398 'binary': function(color) { 2399 color.limit(2); 2400 }, 2401 'name': function(color, that) { 2402 var swatch = that._getSwatch(that._closestName(color)); 2403 color.setRGB(swatch.r, swatch.g, swatch.b); 2404 } 2405 }; 2406 2407 this.parts = { 2408 header: function (inst) { 2409 var that = this, 2410 part = null, 2411 _html = function() { 2412 var title = inst.options.title || inst._getRegional('title'), 2413 html = '<span class="ui-dialog-title">' + title + '</span>'; 2414 2415 if (!inst.inline && inst.options.showCloseButton) { 2416 html += '<a href="#" class="ui-dialog-titlebar-close ui-corner-all" role="button">' 2417 + '<span class="ui-icon ui-icon-closethick">close</span></a>'; 2418 } 2419 2420 return '<div class="ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix">' + html + '</div>'; 2421 }, 2422 _onclick = function(event) { 2423 event.preventDefault(); 2424 inst.close(inst.options.revert); 2425 }; 2426 2427 this.init = function() { 2428 part = $(_html()).prependTo(inst.dialog); 2429 2430 var close = $('.ui-dialog-titlebar-close', part); 2431 inst._hoverable(close); 2432 inst._focusable(close); 2433 close.bind('click', _onclick); 2434 2435 if (!inst.inline && inst.options.draggable) { 2436 var draggableOptions = { 2437 handle: part, 2438 } 2439 if (inst.options.containment) { 2440 draggableOptions.containment = inst.options.containment; 2441 } 2442 inst.dialog.draggable(draggableOptions); 2443 } 2444 }; 2445 2446 this.disable = function (disable) { 2447 $('.ui-dialog-titlebar-close', part)[disable ? 'unbind' : 'bind']('click', _onclick); 2448 }; 2449 }, 2450 2451 map: function (inst) { 2452 var that = this, 2453 part = null, 2454 pointer, width, height, layers = {}, 2455 _mousedown, _mouseup, _mousemove, _keydown, _html; 2456 2457 _mousedown = function (event) { 2458 if (!inst.opened) { 2459 return; 2460 } 2461 2462 var offset = layers.p.offset(), 2463 x = event.pageX - offset.left, 2464 y = event.pageY - offset.top; 2465 2466 if (x >= 0 && x < width && y >= 0 && y < height) { 2467 event.stopImmediatePropagation(); 2468 event.preventDefault(); 2469 part.unbind('mousedown', _mousedown).focus(); 2470 $(document).bind('mouseup', _mouseup); 2471 $(document).bind('mousemove', _mousemove); 2472 _mousemove(event); 2473 } 2474 }; 2475 2476 _mouseup = function (event) { 2477 event.stopImmediatePropagation(); 2478 event.preventDefault(); 2479 $(document).unbind('mouseup', _mouseup); 2480 $(document).unbind('mousemove', _mousemove); 2481 part.bind('mousedown', _mousedown);
2482 2483 inst._callback('stop'); 2484 }; 2485 2486 _mousemove = function (event) { 2487 event.stopImmediatePropagation(); 2488 event.preventDefault(); 2489 2490 if (event.pageX === that.x && event.pageY === that.y) { 2491 return; 2492 } 2493 that.x = event.pageX; 2494 that.y = event.pageY; 2495 2496 var offset = layers.p.offset(), 2497 x = event.pageX - offset.left, 2498 y = event.pageY - offset.top; 2499 2500 x = Math.max(0, Math.min(x / width, 1)); 2501 y = Math.max(0, Math.min(y / height, 1)); 2502 2503 // interpret values 2504 switch (inst.mode) { 2505 case 'h': 2506 inst.color.setHSV(null, x, 1 - y); 2507 break; 2508 2509 case 's': 2510 case 'a': 2511 inst.color.setHSV(x, null, 1 - y); 2512 break; 2513 2514 case 'v': 2515 inst.color.setHSV(x, 1 - y, null); 2516 break; 2517 2518 case 'r': 2519 inst.color.setRGB(null, 1 - y, x); 2520 break; 2521 2522 case 'g': 2523 inst.color.setRGB(1 - y, null, x); 2524 break; 2525 2526 case 'b': 2527 inst.color.setRGB(x, 1 - y, null); 2528 break; 2529 } 2530 2531 inst._change(false); 2532 }; 2533 2534 _keydown = function(event) { 2535 var x_channel_map = { 2536 'h': 's', 2537 's': 'h', 2538 'v': 'h', 2539 'r': 'b', 2540 'g': 'b', 2541 'b': 'r', 2542 'a': 'h' 2543 }, 2544 x_change = { 2545 37: -1, 2546 39: 1, 2547 }, 2548 y_channel_map = { 2549 'h': 'v', 2550 's': 'v', 2551 'v': 's', 2552 'r': 'g', 2553 'g': 'r', 2554 'b': 'g', 2555 'a': 'v' 2556 }, 2557 y_change = { 2558 38: 1, 2559 40: -1 2560 }, 2561 set = { 2562 35: 0, 2563 36: 1 2564 }, 2565 change, value; 2566 2567 if (typeof x_change[event.which] !== 'undefined') { 2568 value = inst.color.getChannel(x_channel_map[inst.mode]) * width; 2569 change = x_change[event.which]; 2570 if (event.shiftKey) { 2571 change *= 10; 2572 } else if (event.ctrlKey) { 2573 change *= width; 2574 } 2575 inst.color.setChannel(x_channel_map[inst.mode], (value + change) / width); 2576 inst._change(false); 2577 } else if (typeof y_change[event.which] !== 'undefined') { 2578 value = inst.color.getChannel(y_channel_map[inst.mode]) * height; 2579 change = y_change[event.which]; 2580 if (event.shiftKey) { 2581 change *= 10; 2582 } else if (event.ctrlKey) { 2583 change *= height; 2584 } 2585 inst.color.setChannel(y_channel_map[inst.mode], (value + change) / height); 2586 inst._change(false); 2587 } else if (typeof set[event.which] !== 'undefined') { 2588 inst.color.setChannel(x_channel_map[inst.mode], 1 - set[event.which]); 2589 inst.color.setChannel(y_channel_map[inst.mode], set[event.which]); 2590 inst._change(false); 2591 } 2592 }; 2593 2594 _html = function () { 2595 var html = '<div class="ui-colorpicker-map ui-colorpicker-map-'+(inst.options.part.map.size || 256)+' ui-colorpicker-border" tabindex="0">' 2596 + '<span class="ui-colorpicker-map-layer-1"> </span>' 2597 + '<span class="ui-colorpicker-map-layer-2"> </span>' 2598 + (inst.options.alpha ? '<span class="ui-colorpicker-map-layer-alpha"> </span>' : '') 2599 + '<span class="ui-colorpicker-map-layer-pointer"><span class="ui-colorpicker-map-pointer"></span></span></div>'; 2600 return html; 2601 }; 2602 2603 this.init = function () { 2604 part = $(_html()).appendTo($('.ui-colorpicker-map-container', inst.dialog)); 2605 2606 part.bind('mousedown', _mousedown); 2607 part.bind('keydown', _keydown); 2608 2609 // cache 2610 layers[1] = $('.ui-colorpicker-map-layer-1', part); 2611 layers[2] = $('.ui-colorpicker-map-layer-2', part); 2612 layers.a = $('.ui-colorpicker-map-layer-alpha', part); 2613 layers.p = $('.ui-colorpicker-map-layer-pointer', part); 2614 width = layers.p.width(); 2615 height = layers.p.height(); 2616 2617 pointer = $('.ui-colorpicker-map-pointer', part); 2618 }; 2619 2620 this.update = function () { 2621 var step = ((inst.options.part.map.size || 256) * 65 / 64); 2622 2623 switch (inst.mode) { 2624 case 'h': 2625 layers[1].css({'background-position': '0 0', 'opacity': ''}).show(); 2626 layers[2].hide(); 2627 break; 2628 2629 case 's': 2630 case 'a': 2631 layers[1].css({'background-position': '0 ' + (-step) + 'px', 'opacity': ''}).show(); 2632 layers[2].css({'background-position': '0 ' + (-step * 2) + 'px', 'opacity': ''}).show(); 2633 break; 2634 2635 case 'v': 2636 part.css('background-color', 'black'); 2637 layers[1].css({'background-position': '0 ' + (-step * 3) + 'px', 'opacity': ''}).show(); 2638 layers[2].hide(); 2639 break; 2640 2641 case 'r': 2642 layers[1].css({'background-position': '0 ' + (-step * 4) + 'px', 'opacity': ''}).show(); 2643 layers[2].css({'background-position': '0 ' + (-step * 5) + 'px', 'opacity': ''}).show(); 2644 break; 2645 2646 case 'g': 2647 layers[1].css({'background-position': '0 ' + (-step * 6) + 'px', 'opacity': ''}).show(); 2648 layers[2].css({'background-position': '0 ' + (-step * 7) + 'px', 'opacity': ''}).show(); 2649 break; 2650 2651 case 'b': 2652 layers[1].css({'background-position': '0 ' + (-step * 8) + 'px', 'opacity': ''}).show(); 2653 layers[2].css({'background-position': '0 ' + (-step * 9) + 'px', 'opacity': ''}).show(); 2654 break; 2655 } 2656 2657 that.repaint(); 2658 }; 2659 2660 this.repaint = function () { 2661 var x = 0, 2662 y = 0; 2663 2664 switch (inst.mode) { 2665 case 'h': 2666 var hsv = inst.color.getHSV(); 2667 x = hsv.s * width; 2668 y = (1 - hsv.v) * width; 2669 part.css('background-color', inst.color.copy().setHSV(null, 1, 1).toCSS()); 2670 break; 2671 2672 case 's': 2673 case 'a': 2674 var hsv = inst.color.getHSV(); 2675 x = hsv.h * width; 2676 y = (1 - hsv.v) * width; 2677 layers[2].css('opacity', 1 - hsv.s); 2678 break; 2679 2680 case 'v': 2681 var hsv = inst.color.getHSV(); 2682 x = hsv.h * width; 2683 y = (1 - hsv.s) * width; 2684 layers[1].css('opacity', hsv.v); 2685 break; 2686 2687 case 'r': 2688 var rgb = inst.color.getRGB()
2689 x = rgb.b * width; 2690 y = (1 - rgb.g) * width; 2691 layers[2].css('opacity', rgb.r); 2692 break; 2693 2694 case 'g': 2695 var rgb = inst.color.getRGB(); 2696 x = rgb.b * width; 2697 y = (1 - rgb.r) * width; 2698 layers[2].css('opacity', rgb.g); 2699 break; 2700 2701 case 'b': 2702 var rgb = inst.color.getRGB() 2703 x = rgb.r * width; 2704 y = (1 - rgb.g) * width; 2705 layers[2].css('opacity', rgb.b); 2706 break; 2707 } 2708 2709 if (inst.options.alpha) { 2710 layers.a.css('opacity', 1 - inst.color.getAlpha()); 2711 } 2712 2713 pointer.css({ 2714 'left': x - 7, 2715 'top': y - 7 2716 }); 2717 }; 2718 2719 this.disable = function (disable) { 2720 part[disable ? 'unbind' : 'bind']('mousedown', _mousedown); 2721 part[disable ? 'unbind' : 'bind']('keydown', _keydown); 2722 }; 2723 }, 2724 2725 bar: function (inst) { 2726 var that = this, 2727 part = null, 2728 pointer, width, height, layers = {}, 2729 _mousedown, _mouseup, _mousemove, _keydown, _html; 2730 2731 _mousedown = function (event) { 2732 if (!inst.opened) { 2733 return; 2734 } 2735 2736 var offset = layers.p.offset(), 2737 x = event.pageX - offset.left, 2738 y = event.pageY - offset.top; 2739 2740 if (x >= 0 && x < width && y >= 0 && y < height) { 2741 event.stopImmediatePropagation(); 2742 event.preventDefault(); 2743 part.unbind('mousedown', _mousedown).focus(); 2744 $(document).bind('mouseup', _mouseup); 2745 $(document).bind('mousemove', _mousemove); 2746 _mousemove(event); 2747 } 2748 }; 2749 2750 _mouseup = function (event) { 2751 event.stopImmediatePropagation(); 2752 event.preventDefault(); 2753 $(document).unbind('mouseup', _mouseup); 2754 $(document).unbind('mousemove', _mousemove); 2755 part.bind('mousedown', _mousedown); 2756 2757 inst._callback('stop'); 2758 }; 2759 2760 _mousemove = function (event) { 2761 event.stopImmediatePropagation(); 2762 event.preventDefault(); 2763 2764 if (event.pageY === that.y) { 2765 return; 2766 } 2767 that.y = event.pageY; 2768 2769 var offset = layers.p.offset(), 2770 y = event.pageY - offset.top; 2771 2772 y = Math.max(0, Math.min(y / height, 1)); 2773 2774 // interpret values 2775 switch (inst.mode) { 2776 case 'h': 2777 inst.color.setHSV(1 - y, null, null); 2778 break; 2779 2780 case 's': 2781 inst.color.setHSV(null, 1 - y, null); 2782 break; 2783 2784 case 'v': 2785 inst.color.setHSV(null, null, 1 - y); 2786 break; 2787 2788 case 'r': 2789 inst.color.setRGB(1 - y, null, null); 2790 break; 2791 2792 case 'g': 2793 inst.color.setRGB(null, 1 - y, null); 2794 break; 2795 2796 case 'b': 2797 inst.color.setRGB(null, null, 1 - y); 2798 break; 2799 2800 case 'a': 2801 inst.color.setAlpha(1 - y); 2802 break; 2803 } 2804 2805 inst._change(false); 2806 }; 2807 2808 _keydown = function(event) { 2809 var change = { 2810 38: 1, 2811 40: -1, 2812 33: 10, 2813 34: -10 2814 }, 2815 set = { 2816 35: 0, 2817 36: 1 2818 }, 2819 change, value; 2820 2821 if (typeof change[event.which] !== 'undefined') { 2822 value = inst.color.getChannel(inst.mode) * height; 2823 change = change[event.which]; 2824 if (event.shiftKey) { 2825 change *= 10; 2826 } else if (event.ctrlKey) { 2827 change *= height; 2828 } 2829 inst.color.setChannel(inst.mode, (value + change) / height); 2830 inst._change(false); 2831 } else if (typeof set[event.which] !== 'undefined') { 2832 inst.color.setChannel(inst.mode, set[event.which]); 2833 inst._change(false); 2834 } 2835 }; 2836 2837 _html = function () { 2838 var html = '<div class="ui-colorpicker-bar ui-colorpicker-bar-'+(inst.options.part.bar.size || 256)+' ui-colorpicker-border" tabindex="0">' 2839 + '<span class="ui-colorpicker-bar-layer-1"> </span>' 2840 + '<span class="ui-colorpicker-bar-layer-2"> </span>' 2841 + '<span class="ui-colorpicker-bar-layer-3"> </span>' 2842 + '<span class="ui-colorpicker-bar-layer-4"> </span>'; 2843 2844 if (inst.options.alpha) {
2845 html += '<span class="ui-colorpicker-bar-layer-alpha"> </span>' 2846 + '<span class="ui-colorpicker-bar-layer-alphabar"> </span>'; 2847 } 2848 2849 html += '<span class="ui-colorpicker-bar-layer-pointer"><span class="ui-colorpicker-bar-pointer"></span></span></div>'; 2850 2851 return html; 2852 }; 2853 2854 this.init = function () { 2855 part = $(_html()).appendTo($('.ui-colorpicker-bar-container', inst.dialog)); 2856 2857 part.bind('mousedown', _mousedown); 2858 part.bind('keydown', _keydown); 2859 2860 // cache 2861 layers[1] = $('.ui-colorpicker-bar-layer-1', part); 2862 layers[2] = $('.ui-colorpicker-bar-layer-2', part); 2863 layers[3] = $('.ui-colorpicker-bar-layer-3', part); 2864 layers[4] = $('.ui-colorpicker-bar-layer-4', part); 2865 layers.a = $('.ui-colorpicker-bar-layer-alpha', part); 2866 layers.ab = $('.ui-colorpicker-bar-layer-alphabar', part); 2867 layers.p = $('.ui-colorpicker-bar-layer-pointer', part); 2868 width = layers.p.width(); 2869 height = layers.p.height(); 2870 2871 pointer = $('.ui-colorpicker-bar-pointer', part); 2872 }; 2873 2874 this.update = function () { 2875 var step = ((inst.options.part.bar.size || 256) * 65 / 64); 2876 2877 switch (inst.mode) { 2878 case 'h': 2879 case 's': 2880 case 'v': 2881 case 'r': 2882 case 'g': 2883 case 'b': 2884 layers.a.show(); 2885 layers.ab.hide(); 2886 break; 2887 2888 case 'a': 2889 layers.a.hide(); 2890 layers.ab.show(); 2891 break; 2892 } 2893 2894 switch (inst.mode) { 2895 case 'h': 2896 layers[1].css({'background-position': '0 0', 'opacity': ''}).show(); 2897 layers[2].hide(); 2898 layers[3].hide(); 2899 layers[4].hide(); 2900 break; 2901 2902 case 's': 2903 layers[1].css({'background-position': '0 ' + (-step) + 'px', 'opacity': ''}).show(); 2904 layers[2].css({'background-position': '0 ' + (-step * 2) + 'px', 'opacity': ''}).show(); 2905 layers[3].hide(); 2906 layers[4].hide(); 2907 break; 2908 2909 case 'v': 2910 layers[1].css({'background-position': '0 ' + (-step * 2) + 'px', 'opacity': ''}).show(); 2911 layers[2].hide(); 2912 layers[3].hide(); 2913 layers[4].hide(); 2914 break; 2915 2916 case 'r': 2917 layers[1].css({'background-position': '0 ' + (-step * 6) + 'px', 'opacity': ''}).show(); 2918 layers[2].css({'background-position': '0 ' + (-step * 5) + 'px', 'opacity': ''}).show(); 2919 layers[3].css({'background-position': '0 ' + (-step * 3) + 'px', 'opacity': ''}).show(); 2920 layers[4].css({'background-position': '0 ' + (-step * 4) + 'px', 'opacity': ''}).show(); 2921 break; 2922 2923 case 'g': 2924 layers[1].css({'background-position': '0 ' + (-step * 10) + 'px', 'opacity': ''}).show(); 2925 layers[2].css({'background-position': '0 ' + (-step * 9) + 'px', 'opacity': ''}).show(); 2926 layers[3].css({'background-position': '0 ' + (-step * 7) + 'px', 'opacity': ''}).show(); 2927 layers[4].css({'background-position': '0 ' + (-step * 8) + 'px', 'opacity': ''}).show(); 2928 break; 2929 2930 case 'b': 2931 layers[1].css({'background-position': '0 ' + (-step * 14) + 'px', 'opacity': ''}).show(); 2932 layers[2].css({'background-position': '0 ' + (-step * 13) + 'px', 'opacity': ''}).show(); 2933 layers[3].css({'background-position': '0 ' + (-step * 11) + 'px', 'opacity': ''}).show(); 2934 layers[4].css({'background-position': '0 ' + (-step * 12) + 'px', 'opacity': ''}).show(); 2935 break; 2936 2937 case 'a': 2938 layers[1].hide(); 2939 layers[2].hide(); 2940 layers[3].hide(); 2941 layers[4].hide(); 2942 break; 2943 } 2944 2945 that.repaint(); 2946 }; 2947 2948 this.repaint = function () { 2949 var y = 0; 2950 2951 switch (inst.mode) { 2952 case 'h': 2953 y = (1 - inst.color.getHSV().h) * height; 2954 break; 2955 2956 case 's': 2957 var hsv = inst.color.getHSV(); 2958 y = (1 - hsv.s) * height; 2959 layers[2].css('opacity', 1 - hsv.v); 2960 part.css('background-color', inst.color.copy().setHSV(null, 1, null).toCSS()); 2961 break; 2962 2963 case 'v': 2964 y = (1 - inst.color.getHSV().v) * height; 2965 part.css('background-color', inst.color.copy().setHSV(null, null, 1).toCSS()); 2966 break; 2967 2968 case 'r': 2969 var rgb = inst.color.getRGB(); 2970 y = (1 - rgb.r) * height; 2971 layers[2].css('opacity', Math.max(0, (rgb.b - rgb.g))); 2972 layers[3].css('opacity', Math.max(0, (rgb.g - rgb.b))); 2973 layers[4].css('opacity', Math.min(rgb.b, rgb.g)); 2974 break; 2975 2976 case 'g': 2977 var rgb = inst.color.getRGB(); 2978 y = (1 - rgb.g) * height; 2979 layers[2].css('opacity', Math.max(0, (rgb.b - rgb.r))); 2980 layers[3].css('opacity', Math.max(0, (rgb.r - rgb.b))); 2981 layers[4].css('opacity', Math.min(rgb.r, rgb.b)); 2982 break; 2983 2984 case 'b': 2985 var rgb = inst.color.getRGB(); 2986 y = (1 - rgb.b) * height; 2987 layers[2].css('opacity', Math.max(0, (rgb.r - rgb.g))); 2988 layers[3].css('opacity', Math.max(0, (rgb.g - rgb.r))); 2989 layers[4].css('opacity', Math.min(rgb.r, rgb.g)); 2990 break; 2991 2992 case 'a': 2993 y = (1 - inst.color.getAlpha()) * height; 2994 part.css('background-color', inst.color.copy().toCSS()); 2995 break; 2996 } 2997 2998 if (inst.mode !== 'a') { 2999 layers.a.css('opacity', 1 - inst.color.getAlpha()); 3000 } 3001 3002 pointer.css('top', y - 3); 3003 }; 3004 3005 this.disable = function (disable) { 3006 part[disable ? 'unbind' : 'bind']('mousedown', _mousedown);
3007 part[disable ? 'unbind' : 'bind']('keydown', _keydown); 3008 }; 3009 }, 3010 3011 preview: function (inst) { 3012 var that = this, 3013 part = null, 3014 both, 3015 initial, initial_alpha, 3016 current, current_alpha, 3017 _html, 3018 onclick = function () { 3019 inst.color = inst.currentColor.copy(); 3020 inst._change(); 3021 }; 3022 3023 _html = function () { 3024 return '<div class="ui-colorpicker-preview ui-colorpicker-border">' 3025 + '<div class="ui-colorpicker-preview-initial"><div class="ui-colorpicker-preview-initial-alpha"></div></div>' 3026 + '<div class="ui-colorpicker-preview-current"><div class="ui-colorpicker-preview-current-alpha"></div></div>' 3027 + '</div>'; 3028 }; 3029 3030 this.init = function () { 3031 part = $(_html()).appendTo($('.ui-colorpicker-preview-container', inst.dialog)); 3032 3033 $('.ui-colorpicker-preview-initial', part).bind('click', onclick); 3034 3035 // cache 3036 initial = $('.ui-colorpicker-preview-initial', part); 3037 initial_alpha = $('.ui-colorpicker-preview-initial-alpha', part); 3038 current = $('.ui-colorpicker-preview-current', part); 3039 current_alpha = $('.ui-colorpicker-preview-current-alpha', part); 3040 both = $('.ui-colorpicker-preview-initial-alpha, .ui-colorpicker-preview-current-alpha', part); 3041 }; 3042 3043 this.update = function () { 3044 both[inst.options.alpha ? 'show' : 'hide'](); 3045 3046 this.repaint(); 3047 }; 3048 3049 this.repaint = function () { 3050 initial.css('background-color', inst.currentColor.set ? inst.currentColor.toCSS() : '').attr('title', inst.currentColor.set ? inst.currentColor.toCSS() : ''); 3051 initial_alpha.css('opacity', 1 - inst.currentColor.getAlpha()); 3052 current.css('background-color', inst.color.set ? inst.color.toCSS() : '').attr('title', inst.color.set ? inst.color.toCSS() : ''); 3053 current_alpha.css('opacity', 1 - inst.color.getAlpha()); 3054 }; 3055 3056 this.disable = function (disable) { 3057 $('.ui-colorpicker-preview-initial', part)[disable ? 'unbind' : 'bind']('click', onclick); 3058 }; 3059 }, 3060 3061 hsv: function (inst) { 3062 var that = this, 3063 part = null, 3064 inputs = {}, 3065 _html; 3066 3067 _html = function () { 3068 var html = ''; 3069 3070 if (inst.options.hsv) { 3071 html += '<div class="ui-colorpicker-hsv-h"><input class="ui-colorpicker-mode" type="radio" value="h"/><label>' + inst._getRegional('hsvH') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="360" size="10"/><span class="ui-colorpicker-unit">°</span></div>' 3072 + '<div class="ui-colorpicker-hsv-s"><input class="ui-colorpicker-mode" type="radio" value="s"/><label>' + inst._getRegional('hsvS') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="100" size="10"/><span class="ui-colorpicker-unit">%</span></div>' 3073 + '<div class="ui-colorpicker-hsv-v"><input class="ui-colorpicker-mode" type="radio" value="v"/><label>' + inst._getRegional('hsvV') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="100" size="10"/><span class="ui-colorpicker-unit">%</span></div>'; 3074 } 3075 3076 return '<div class="ui-colorpicker-hsv">' + html + '</div>'; 3077 }; 3078 3079 this.init = function () { 3080 part = $(_html()).appendTo($('.ui-colorpicker-hsv-container', inst.dialog)); 3081 3082 $('.ui-colorpicker-mode', part).click(function () { 3083 inst.mode = $(this).val(); 3084 inst._updateAllParts(); 3085 }); 3086 3087 inputs.h = $('.ui-colorpicker-hsv-h .ui-colorpicker-number', part); 3088 inputs.s = $('.ui-colorpicker-hsv-s .ui-colorpicker-number', part); 3089 inputs.v = $('.ui-colorpicker-hsv-v .ui-colorpicker-number', part); 3090 3091 $('.ui-colorpicker-number', part).bind('change keyup', function () { 3092 inst.color.setHSV( 3093 inputs.h.val() / 360, 3094 inputs.s.val() / 100, 3095 inputs.v.val() / 100 3096 ); 3097 inst._change(); 3098 }); 3099 }; 3100 3101 this.repaint = function () { 3102 var hsv = inst.color.getHSV(); 3103 inputs.h.val(Math.round(hsv.h * 360)); 3104 inputs.s.val(Math.round(hsv.s * 100)); 3105 inputs.v.val(Math.round(hsv.v * 100)); 3106 }; 3107 3108 this.update = function () { 3109 $('.ui-colorpicker-mode', part).each(function () { 3110 var $this = $(this); 3111 $this.attr('checked', $this.val() === inst.mode); 3112 });
3113 this.repaint(); 3114 }; 3115 3116 this.disable = function (disable) { 3117 $(':input', part).prop('disabled', disable); 3118 }; 3119 }, 3120 3121 rgb: function (inst) { 3122 var that = this, 3123 part = null, 3124 inputs = {}, 3125 _html; 3126 3127 _html = function () { 3128 var html = ''; 3129 3130 if (inst.options.rgb) { 3131 html += '<div class="ui-colorpicker-rgb-r"><input class="ui-colorpicker-mode" type="radio" value="r"/><label>' + inst._getRegional('rgbR') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="255"/></div>' 3132 + '<div class="ui-colorpicker-rgb-g"><input class="ui-colorpicker-mode" type="radio" value="g"/><label>' + inst._getRegional('rgbG') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="255"/></div>' 3133 + '<div class="ui-colorpicker-rgb-b"><input class="ui-colorpicker-mode" type="radio" value="b"/><label>' + inst._getRegional('rgbB') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="255"/></div>'; 3134 } 3135 3136 return '<div class="ui-colorpicker-rgb">' + html + '</div>'; 3137 }; 3138 3139 this.init = function () { 3140 part = $(_html()).appendTo($('.ui-colorpicker-rgb-container', inst.dialog)); 3141 3142 $('.ui-colorpicker-mode', part).click(function () { 3143 inst.mode = $(this).val(); 3144 inst._updateAllParts(); 3145 }); 3146 3147 inputs.r = $('.ui-colorpicker-rgb-r .ui-colorpicker-number', part); 3148 inputs.g = $('.ui-colorpicker-rgb-g .ui-colorpicker-number', part); 3149 inputs.b = $('.ui-colorpicker-rgb-b .ui-colorpicker-number', part); 3150 3151 $('.ui-colorpicker-number', part).bind('change keyup', function () { 3152 var r = $('.ui-colorpicker-rgb-r .ui-colorpicker-number', part).val(); 3153 inst.color.setRGB( 3154 inputs.r.val() / 255, 3155 inputs.g.val() / 255, 3156 inputs.b.val() / 255 3157 ); 3158 3159 inst._change(); 3160 }); 3161 }; 3162 3163 this.repaint = function () { 3164 var rgb = inst.color.getRGB(); 3165 inputs.r.val(Math.round(rgb.r * 255)); 3166 inputs.g.val(Math.round(rgb.g * 255)); 3167 inputs.b.val(Math.round(rgb.b * 255)); 3168 }; 3169 3170 this.update = function () { 3171 $('.ui-colorpicker-mode', part).each(function () { 3172 var $this = $(this); 3173 $this.attr('checked', $this.val() === inst.mode); 3174 }); 3175 this.repaint(); 3176 }; 3177 3178 this.disable = function (disable) { 3179 $(':input', part).prop('disabled', disable); 3180 }; 3181 }, 3182 3183 lab: function (inst) { 3184 var that = this, 3185 part = null, 3186 inputs = {}, 3187 html = function () { 3188 var html = ''; 3189 3190 if (inst.options.hsv) { 3191 html += '<div class="ui-colorpicker-lab-l"><label>' + inst._getRegional('labL') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="100"/></div>' 3192 + '<div class="ui-colorpicker-lab-a"><label>' + inst._getRegional('labA') + '</label><input class="ui-colorpicker-number" type="number" min="-128" max="127"/></div>' 3193 + '<div class="ui-colorpicker-lab-b"><label>' + inst._getRegional('labB') + '</label><input class="ui-colorpicker-number" type="number" min="-128" max="127"/></div>'; 3194 } 3195 3196 return '<div class="ui-colorpicker-lab">' + html + '</div>'; 3197 }; 3198 3199 this.init = function () { 3200 var data = 0; 3201 3202 part = $(html()).appendTo($('.ui-colorpicker-lab-container', inst.dialog)); 3203 3204 inputs.l = $('.ui-colorpicker-lab-l .ui-colorpicker-number', part); 3205 inputs.a = $('.ui-colorpicker-lab-a .ui-colorpicker-number', part); 3206 inputs.b = $('.ui-colorpicker-lab-b .ui-colorpicker-number', part); 3207 3208 $('.ui-colorpicker-number', part).bind('change keyup', function (event) { 3209 inst.color.setLAB( 3210 parseInt(inputs.l.val(), 10) / 100, 3211 (parseInt(inputs.a.val(), 10) + 128) / 255, 3212 (parseInt(inputs.b.val(), 10) + 128) / 255 3213 ); 3214 inst._change(); 3215 }); 3216 }; 3217 3218 this.repaint = function () { 3219 var lab = inst.color.getLAB(); 3220 inputs.l.val(Math.round(lab.l * 100)); 3221 inputs.a.val(Math.round(lab.a * 255) - 128); 3222 inputs.b.val(Math.round(lab.b * 255) - 128); 3223 }; 3224 3225 this.update = this.repaint; 3226 3227 this.disable = function (disable) { 3228 $(':input', part).prop('disabled', disable); 3229 }; 3230 }, 3231 3232 cmyk: function (inst) { 3233 var that = this, 3234 part = null, 3235 inputs = {}, 3236 html = function () { 3237 var html = ''; 3238 3239 if (inst.options.hsv) { 3240 html += '<div class="ui-colorpicker-cmyk-c"><label>' + inst._getRegional('cmykC') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="100"/>
3240<span class="ui-colorpicker-unit">%</span></div>' 3241 + '<div class="ui-colorpicker-cmyk-m"><label>' + inst._getRegional('cmykM') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="100"/><span class="ui-colorpicker-unit">%</span></div>' 3242 + '<div class="ui-colorpicker-cmyk-y"><label>' + inst._getRegional('cmykY') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="100"/><span class="ui-colorpicker-unit">%</span></div>' 3243 + '<div class="ui-colorpicker-cmyk-k"><label>' + inst._getRegional('cmykK') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="100"/><span class="ui-colorpicker-unit">%</span></div>'; 3244 } 3245 3246 return '<div class="ui-colorpicker-cmyk">' + html + '</div>'; 3247 }; 3248 3249 this.init = function () { 3250 part = $(html()).appendTo($('.ui-colorpicker-cmyk-container', inst.dialog)); 3251 3252 inputs.c = $('.ui-colorpicker-cmyk-c .ui-colorpicker-number', part); 3253 inputs.m = $('.ui-colorpicker-cmyk-m .ui-colorpicker-number', part); 3254 inputs.y = $('.ui-colorpicker-cmyk-y .ui-colorpicker-number', part); 3255 inputs.k = $('.ui-colorpicker-cmyk-k .ui-colorpicker-number', part); 3256 3257 $('.ui-colorpicker-number', part).bind('change keyup', function (event) { 3258 inst.color.setCMYK( 3259 parseInt(inputs.c.val(), 10) / 100, 3260 parseInt(inputs.m.val(), 10) / 100, 3261 parseInt(inputs.y.val(), 10) / 100, 3262 parseInt(inputs.k.val(), 10) / 100 3263 ); 3264 inst._change(); 3265 }); 3266 }; 3267 3268 this.repaint = function () { 3269 var cmyk = inst.color.getCMYK(); 3270 inputs.c.val(Math.round(cmyk.c * 100)); 3271 inputs.m.val(Math.round(cmyk.m * 100)); 3272 inputs.y.val(Math.round(cmyk.y * 100)); 3273 inputs.k.val(Math.round(cmyk.k * 100)); 3274 }; 3275 3276 this.update = this.repaint; 3277 3278 this.disable = function (disable) { 3279 $(':input', part).prop('disabled', disable); 3280 }; 3281 }, 3282 3283 alpha: function (inst) { 3284 var that = this, 3285 part = null, 3286 input, 3287 html = function () { 3288 var html = ''; 3289 3290 if (inst.options.alpha) { 3291 html += '<div class="ui-colorpicker-a"><input class="ui-colorpicker-mode" name="mode" type="radio" value="a"/><label>' + inst._getRegional('alphaA') + '</label><input class="ui-colorpicker-number" type="number" min="0" max="100"/><span class="ui-colorpicker-unit">%</span></div>'; 3292 } 3293 3294 return '<div class="ui-colorpicker-alpha">' + html + '</div>'; 3295 }; 3296 3297 this.init = function () { 3298 part = $(html()).appendTo($('.ui-colorpicker-alpha-container', inst.dialog)); 3299 3300 $('.ui-colorpicker-mode', part).click(function () { 3301 inst.mode = $(this).val(); 3302 inst._updateAllParts(); 3303 }); 3304 3305 input = $('.ui-colorpicker-a .ui-colorpicker-number', part); 3306 3307 $('.ui-colorpicker-number', part).bind('change keyup', function () { 3308 inst.color.setAlpha(input.val() / 100); 3309 inst._change(); 3310 }); 3311 }; 3312 3313 this.update = function () { 3314 $('.ui-colorpicker-mode', part).each(function () { 3315 $(this).attr('checked', $(this).val() === inst.mode); 3316 }); 3317 this.repaint(); 3318 }; 3319 3320 this.repaint = function () { 3321 input.val(Math.round(inst.color.getAlpha() * 100)); 3322 }; 3323 3324 this.disable = function (disable) { 3325 $(':input', part).prop('disabled', disable); 3326 }; 3327 }, 3328 3329 hex: function (inst) { 3330 var that = this, 3331 part = null, 3332 inputs = {}, 3333 parseHex = function(color) { 3334 var c, 3335 m; 3336 3337 // {#}rgb 3338 m = /^#?([a-fA-F0-9]{1,3})$/.exec(color); 3339 if (m) { 3340 c = parseInt(m[1], 16); 3341 return new $.colorpicker.Color( 3342 ((c >> 8) & 0xF) / 15, 3343 ((c >> 4) & 0xF) / 15, 3344 (c & 0xF) / 15 3345 ); 3346 } 3347 3348 // {#}rrggbb 3349 m = /^#?([a-fA-F0-9]{1,6})$/.exec(color); 3350 if (m) { 3351 c = parseInt(m[1], 16); 3352 return new $.colorpicker.Color( 3353 ((c >> 16) & 0xFF) / 255, 3354 ((c >> 8) & 0xFF) / 255, 3355 (c & 0xFF) / 255 3356 ); 3357 } 3358 3359 return new $.colorpicker.Color(); 3360 }, 3361 html = function () { 3362 var html = ''; 3363 3364 if (inst.options.alpha) { 3365 html += '<input class="ui-colorpicker-hex-alpha" type="text" maxlength="2" size="2"/>'; 3366 } 3367 3368 html += '<input class="ui-colorpicker-hex-input" type="text" maxlength="6" size="6"/>'; 3369 3370 return '<div class="ui-colorpicker-hex"><label>#</label>' + html + '</div>'; 3371 }; 3372 3373 this.init = function () { 3374 part = $(html()).appendTo($('.ui-colorpicker-hex-container', inst.dialog)); 3375 3376 inputs.color = $('.ui-colorpicker-hex-input', part); 3377 inputs.alpha = $('.ui-colorpicker-hex-alpha', part); 3378 3379 inputs.color.bind('keydown keyup', function(e) { 3380 return e.ctrlKey || _keycode.isHex(e.which) || !_keycode.isPrint(e.which); 3381 });
3382 3383 // repeat here makes the invalid input disappear faster 3384 inputs.color.bind('change', function () { 3385 if (/[^a-fA-F0-9]/.test(inputs.color.val())) { 3386 inputs.color.val(inputs.color.val().replace(/[^a-fA-F0-9]/, '')); 3387 } 3388 }); 3389 3390 inputs.color.bind('change keyup', function () { 3391 // repeat here makes sure that the invalid input doesn't get parsed 3392 inst.color = parseHex(inputs.color.val()).setAlpha(inst.color.getAlpha()); 3393 inst._change(); 3394 }); 3395 3396 inputs.alpha.bind('keydown keyup', function(e) { 3397 return e.ctrlKey || _keycode.isHex(e.which) || !_keycode.isPrint(e.which); 3398 }); 3399 3400 inputs.alpha.bind('change', function () { 3401 if (/[^a-fA-F0-9]/.test(inputs.alpha)) { 3402 inputs.alpha.val(inputs.alpha.val().replace(/[^a-fA-F0-9]/, '')); 3403 } 3404 }); 3405 3406 inputs.alpha.bind('change keyup', function () { 3407 inst.color.setAlpha(parseInt(inputs.alpha.val(), 16) / 255); 3408 inst._change(); 3409 }); 3410 }; 3411 3412 this.repaint = function () { 3413 if (!inputs.color.is(':focus')) { 3414 inputs.color.val(inst.color.toHex(true)); 3415 } 3416 3417 if (!inputs.alpha.is(':focus')) { 3418 inputs.alpha.val(_intToHex(inst.color.getAlpha() * 255)); 3419 } 3420 }; 3421 3422 this.update = this.repaint; 3423 3424 this.disable = function (disable) { 3425 $(':input', part).prop('disabled', disable); 3426 }; 3427 }, 3428 3429 swatches: function (inst) { 3430 var that = this, 3431 part = null, 3432 html = function () { 3433 var html = ''; 3434 3435 inst._eachSwatch(function (name, color) { 3436 var c = new $.colorpicker.Color(color.r, color.g, color.b), 3437 css = c.toCSS(); 3438 html += '<div class="ui-colorpicker-swatch" style="background-color:' + css + '" title="' + name + '"></div>'; 3439 }); 3440 3441 return '<div class="ui-colorpicker-swatches ui-colorpicker-border" style="width:' + inst.options.swatchesWidth + 'px">' + html + '</div>'; 3442 }, 3443 onclick = function () { 3444 inst.color = inst._parseColor($(this).css('background-color')) || new $.colorpicker.Color(); 3445 inst._change(); 3446 }; 3447 3448 this.init = function () { 3449 part = $(html()); 3450 $('.ui-colorpicker-swatches-container', inst.dialog).html(part); 3451 $('.ui-colorpicker-swatch', part).bind('click', onclick); 3452 }; 3453 3454 this.disable = function (disable) { 3455 $('.ui-colorpicker-swatch', part)[disable ? 'unbind' : 'bind']('click', onclick); 3456 }; 3457 }, 3458 3459 footer: function (inst) { 3460 var that = this, 3461 part = null, 3462 id_transparent = 'ui-colorpicker-special-transparent-' + inst.colorpicker_index, 3463 id_none = 'ui-colorpicker-special-none-' + inst.colorpicker_index, 3464 html = function () { 3465 var html = ''; 3466 3467 if (inst.options.alpha || (!inst.inline && inst.options.showNoneButton)) { 3468 html += '<div class="ui-colorpicker-buttonset">'; 3469 3470 if (inst.options.alpha) { 3471 html += '<input type="radio" name="ui-colorpicker-special" id="'+id_transparent+'" class="ui-colorpicker-special-transparent"/><label for="'+id_transparent+'">' + inst._getRegional('transparent') + '</label>'; 3472 } 3473 if (!inst.inline && inst.options.showNoneButton) { 3474 html += '<input type="radio" name="ui-colorpicker-special" id="'+id_none+'" class="ui-colorpicker-special-none"><label for="'+id_none+'">' + inst._getRegional('none') + '</label>'; 3475 } 3476 html += '</div>'; 3477 } 3478 3479 if (!inst.inline) { 3480 html += '<div class="ui-dialog-buttonset">'; 3481 if (inst.options.showCancelButton) { 3482 html += '<button class="btn btn-custom btn-custom-secondary ui-colorpicker-cancel">' + inst._getRegional('cancel') + '</button>'; 3483 } 3484 html += '<button class="btn btn-custom btn-custom-secondary ui-colorpicker-ok">' + inst._getRegional('ok') + '</button>'; 3485 html += '</div>'; 3486 } 3487 3488 return '<div class="ui-dialog-buttonpane ui-widget-content">' + html + '</div>'; 3489 }; 3490 3491 this.init = function () { 3492 part = $(html()).appendTo(inst.dialog); 3493 3494 $('.ui-colorpicker-ok', part).button().click(function () { 3495 inst.close(); 3496 });
3497 3498 $('.ui-colorpicker-cancel', part).button().click(function () { 3499 inst.close(true); //cancel 3500 }); 3501 3502 $('.ui-colorpicker-buttonset', part)[$.fn.controlgroup ? 'controlgroup' : 'buttonset'](); 3503 3504 $('.ui-colorpicker-special-color', part).click(function () { 3505 inst._change(); 3506 }); 3507 3508 $('#'+id_none, part).click(function () { 3509 inst.color.set = false; 3510 inst._change(); 3511 }); 3512 3513 $('#'+id_transparent, part).click(function () { 3514 inst.color.setAlpha(0); 3515 inst._change(); 3516 }); 3517 }; 3518 3519 this.repaint = function () { 3520 $('.ui-colorpicker-special-none', part).prop('checked', !inst.color.set).button('refresh'); 3521 $('.ui-colorpicker-special-transparent', part).prop('checked', inst.color.set && inst.color.getAlpha() === 0).button('refresh'); 3522 $('.ui-colorpicker-ok', part).button(inst.changed ? 'enable' : 'disable'); 3523 }; 3524 3525 this.update = function () {}; 3526 3527 this.disable = function (disabled) { 3528 $(':input, :button', part).button(disabled ? 'disable' : 'enable'); 3529 if (!disabled) { 3530 $('.ui-colorpicker-ok', part).button(inst.changed ? 'enable' : 'disable'); 3531 } 3532 }; 3533 } 3534 }; 3535 3536 this.Color = function () { 3537 var spaces = { rgb: {r: 0, g: 0, b: 0}, 3538 hsv: {h: 0, s: 0, v: 0}, 3539 hsl: {h: 0, s: 0, l: 0}, 3540 lab: {l: 0, a: 0, b: 0}, 3541 cmyk: {c: 0, m: 0, y: 0, k: 1} 3542 }, 3543 a = 1, 3544 illuminant = [0.9504285, 1, 1.0889], // CIE-L*ab D65/2' 1931 3545 args = arguments, 3546 _clip = function(v) { 3547 if (isNaN(v) || v === null) { 3548 return 0; 3549 } 3550 if (typeof v == 'string') { 3551 v = parseInt(v, 10); 3552 } 3553 return Math.max(0, Math.min(v, 1)); 3554 }, 3555 _hexify = function (number) { 3556 var number = Math.round(number), 3557 digits = '0123456789abcdef', 3558 lsd = number % 16, 3559 msd = (number - lsd) / 16, 3560 hexified = digits.charAt(msd) + digits.charAt(lsd); 3561 return hexified; 3562 }, 3563 _rgb_to_xyz = function(rgb) { 3564 var r = (rgb.r > 0.04045) ? Math.pow((rgb.r + 0.055) / 1.055, 2.4) : rgb.r / 12.92, 3565 g = (rgb.g > 0.04045) ? Math.pow((rgb.g + 0.055) / 1.055, 2.4) : rgb.g / 12.92, 3566 b = (rgb.b > 0.04045) ? Math.pow((rgb.b + 0.055) / 1.055, 2.4) : rgb.b / 12.92; 3567 3568 return { 3569 x: r * 0.4124 + g * 0.3576 + b * 0.1805, 3570 y: r * 0.2126 + g * 0.7152 + b * 0.0722, 3571 z: r * 0.0193 + g * 0.1192 + b * 0.9505 3572 }; 3573 }, 3574 _xyz_to_rgb = function(xyz) { 3575 var rgb = { 3576 r: xyz.x * 3.2406 + xyz.y * -1.5372 + xyz.z * -0.4986, 3577 g: xyz.x * -0.9689 + xyz.y * 1.8758 + xyz.z * 0.0415, 3578 b: xyz.x * 0.0557 + xyz.y * -0.2040 + xyz.z * 1.0570 3579 }; 3580 3581 rgb.r = (rgb.r > 0.0031308) ? 1.055 * Math.pow(rgb.r, (1 / 2.4)) - 0.055 : 12.92 * rgb.r; 3582 rgb.g = (rgb.g > 0.0031308) ? 1.055 * Math.pow(rgb.g, (1 / 2.4)) - 0.055 : 12.92 * rgb.g; 3583 rgb.b = (rgb.b > 0.0031308) ? 1.055 * Math.pow(rgb.b, (1 / 2.4)) - 0.055 : 12.92 * rgb.b; 3584 3585 return rgb; 3586 }, 3587 _rgb_to_hsv = function(rgb) { 3588 var minVal = Math.min(rgb.r, rgb.g, rgb.b), 3589 maxVal = Math.max(rgb.r, rgb.g, rgb.b), 3590 delta = maxVal - minVal, 3591 del_R, del_G, del_B, 3592 hsv = { 3593 h: 0, 3594 s: 0, 3595 v: maxVal 3596 }; 3597 3598 if (delta === 0) { 3599 hsv.h = 0; 3600 hsv.s = 0; 3601 } else { 3602 hsv.s = delta / maxVal; 3603 3604 del_R = (((maxVal - rgb.r) / 6) + (delta / 2)) / delta; 3605 del_G = (((maxVal - rgb.g) / 6) + (delta / 2)) / delta; 3606 del_B = (((maxVal - rgb.b) / 6) + (delta / 2)) / delta; 3607 3608 if (rgb.r === maxVal) { 3609 hsv.h = del_B - del_G; 3610 } else if (rgb.g === maxVal) { 3611 hsv.h = (1 / 3) + del_R - del_B; 3612 } else if (rgb.b === maxVal) { 3613 hsv.h = (2 / 3) + del_G - del_R; 3614 } 3615 3616 if (hsv.h < 0) { 3617 hsv.h += 1; 3618 } else if (hsv.h > 1) { 3619 hsv.h -= 1; 3620 } 3621 } 3622 3623 return hsv; 3624 }, 3625 _hsv_to_rgb = function(hsv) { 3626 var rgb = { 3627 r: 0, 3628 g: 0, 3629 b: 0 3630 }, 3631 var_h, 3632 var_i, 3633 var_1, 3634 var_2, 3635 var_3; 3636 3637 if (hsv.s === 0) { 3638 rgb.r = rgb.g = rgb.b = hsv.v; 3639 } else { 3640 var_h = hsv.h === 1 ? 0 : hsv.h * 6; 3641 var_i = Math.floor(var_h); 3642 var_1 = hsv.v * (1 - hsv.s); 3643 var_2 = hsv.v * (1 - hsv.s * (var_h - var_i)); 3644 var_3 = hsv.v * (1 - hsv.s * (1 - (var_h - var_i))); 3645 3646 if (var_i === 0) { 3647 rgb.r = hsv.v; 3648 rgb.g = var_3; 3649 rgb.b = var_1; 3650 } else if (var_i === 1) { 3651 rgb.r = var_2; 3652 rgb.g = hsv.v; 3653 rgb.b = var_1; 3654 } else if (var_i === 2) { 3655 rgb.r = var_1; 3656 rgb.g = hsv.v; 3657 rgb.b = var_3; 3658 } else if (var_i === 3) { 3659 rgb.r = var_1; 3660 rgb.g = var_2; 3661 rgb.b = hsv.v; 3662 } else if (var_i === 4) { 3663 rgb.r = var_3; 3664 rgb.g = var_1; 3665 rgb.b = hsv.v; 3666 } else { 3667 rgb.r = hsv.v; 3668 rgb.g = var_1; 3669 rgb.b = var_2; 3670 } 3671 } 3672 3673 return rgb; 3674 }, 3675 _rgb_to_hsl = function(rgb) { 3676 var minVal = Math.min(rgb.r, rgb.g, rgb.b), 3677 maxVal = Math.max(rgb.r, rgb.g, rgb.b), 3678 delta = maxVal - minVal, 3679 del_R, del_G, del_B, 3680 hsl = { 3681 h: 0, 3682 s: 0, 3683 l: (maxVal + minVal) / 2 3684 }; 3685 3686 if (delta === 0) { 3687 hsl.h = 0; 3688 hsl.s = 0; 3689 } else { 3690 hsl.s = hsl.l < 0.5 ? delta / (maxVal + minVal) : delta / (2 - maxVal - minVal); 3691 3692 del_R = (((maxVal - rgb.r) / 6) + (delta / 2)) / delta; 3693 del_G = (((maxVal - rgb.g) / 6) + (delta / 2)) / delta; 3694 del_B = (((maxVal - rgb.b) / 6) + (delta / 2)) / delta; 3695 3696 if (rgb.r === maxVal) { 3697 hsl.h = del_B - del_G; 3698 } else if (rgb.g === maxVal) { 3699 hsl.h = (1 / 3) + del_R - del_B; 3700 } else if (rgb.b === maxVal) { 3701 hsl.h = (2 / 3) + del_G - del_R; 3702 } 3703 3704 if (hsl.h < 0) { 3705 hsl.h += 1;
3706 } else if (hsl.h > 1) { 3707 hsl.h -= 1; 3708 } 3709 } 3710 3711 return hsl; 3712 }, 3713 _hsl_to_rgb = function(hsl) { 3714 var var_1, 3715 var_2, 3716 hue_to_rgb = function(v1, v2, vH) { 3717 if (vH < 0) { 3718 vH += 1; 3719 } 3720 if (vH > 1) { 3721 vH -= 1; 3722 } 3723 if ((6 * vH) < 1) { 3724 return v1 + (v2 - v1) * 6 * vH; 3725 } 3726 if ((2 * vH) < 1) { 3727 return v2; 3728 } 3729 if ((3 * vH) < 2) { 3730 return v1 + (v2 - v1) * ((2 / 3) - vH) * 6; 3731 } 3732 return v1; 3733 }; 3734 3735 if (hsl.s === 0) { 3736 return { 3737 r: hsl.l, 3738 g: hsl.l, 3739 b: hsl.l 3740 }; 3741 } 3742 3743 var_2 = (hsl.l < 0.5) ? hsl.l * (1 + hsl.s) : (hsl.l + hsl.s) - (hsl.s * hsl.l); 3744 var_1 = 2 * hsl.l - var_2; 3745 3746 return { 3747 r: hue_to_rgb(var_1, var_2, hsl.h + (1 / 3)), 3748 g: hue_to_rgb(var_1, var_2, hsl.h), 3749 b: hue_to_rgb(var_1, var_2, hsl.h - (1 / 3)) 3750 }; 3751 }, 3752 _xyz_to_lab = function(xyz) { 3753 var x = xyz.x / illuminant[0], 3754 y = xyz.y / illuminant[1], 3755 z = xyz.z / illuminant[2]; 3756 3757 x = (x > 0.008856) ? Math.pow(x, (1/3)) : (7.787 * x) + (16/116); 3758 y = (y > 0.008856) ? Math.pow(y, (1/3)) : (7.787 * y) + (16/116); 3759 z = (z > 0.008856) ? Math.pow(z, (1/3)) : (7.787 * z) + (16/116); 3760 3761 return { 3762 l: ((116 * y) - 16) / 100, // [0,100] 3763 a: ((500 * (x - y)) + 128) / 255, // [-128,127] 3764 b: ((200 * (y - z)) + 128) / 255 // [-128,127] 3765 }; 3766 }, 3767 _lab_to_xyz = function(lab) { 3768 var lab2 = { 3769 l: lab.l * 100, 3770 a: (lab.a * 255) - 128, 3771 b: (lab.b * 255) - 128 3772 }, 3773 xyz = { 3774 x: 0, 3775 y: (lab2.l + 16) / 116, 3776 z: 0 3777 }; 3778 3779 xyz.x = lab2.a / 500 + xyz.y; 3780 xyz.z = xyz.y - lab2.b / 200; 3781 3782 xyz.x = (Math.pow(xyz.x, 3) > 0.008856) ? Math.pow(xyz.x, 3) : (xyz.x - 16 / 116) / 7.787; 3783 xyz.y = (Math.pow(xyz.y, 3) > 0.008856) ? Math.pow(xyz.y, 3) : (xyz.y - 16 / 116) / 7.787; 3784 xyz.z = (Math.pow(xyz.z, 3) > 0.008856) ? Math.pow(xyz.z, 3) : (xyz.z - 16 / 116) / 7.787; 3785 3786 xyz.x *= illuminant[0]; 3787 xyz.y *= illuminant[1]; 3788 xyz.z *= illuminant[2]; 3789 3790 return xyz; 3791 }, 3792 _rgb_to_cmy = function(rgb) { 3793 return { 3794 c: 1 - (rgb.r), 3795 m: 1 - (rgb.g), 3796 y: 1 - (rgb.b) 3797 }; 3798 }, 3799 _cmy_to_rgb = function(cmy) { 3800 return { 3801 r: 1 - (cmy.c), 3802 g: 1 - (cmy.m), 3803 b: 1 - (cmy.y) 3804 }; 3805 }, 3806 _cmy_to_cmyk = function(cmy) { 3807 var K = 1; 3808 3809 if (cmy.c < K) { 3810 K = cmy.c; 3811 } 3812 if (cmy.m < K) { 3813 K = cmy.m; 3814 } 3815 if (cmy.y < K) { 3816 K = cmy.y; 3817 } 3818 3819 if (K === 1) { 3820 return { 3821 c: 0, 3822 m: 0, 3823 y: 0, 3824 k: 1 3825 }; 3826 } 3827 3828 return { 3829 c: (cmy.c - K) / (1 - K), 3830 m: (cmy.m - K) / (1 - K), 3831 y: (cmy.y - K) / (1 - K), 3832 k: K 3833 }; 3834 }, 3835 _cmyk_to_cmy = function(cmyk) { 3836 return { 3837 c: cmyk.c * (1 - cmyk.k) + cmyk.k, 3838 m: cmyk.m * (1 - cmyk.k) + cmyk.k, 3839 y: cmyk.y * (1 - cmyk.k) + cmyk.k 3840 }; 3841 }; 3842 3843 this.set = false; 3844 3845 this.setAlpha = function(_a) { 3846 if (_a !== null) { 3847 a = _clip(_a); 3848 } 3849 this.set = true; 3850 3851 return this; 3852 }; 3853 3854 this.getAlpha = function() { 3855 return a; 3856 }; 3857 3858 this.setRGB = function(r, g, b) { 3859 spaces = { rgb: this.getRGB() }; 3860 if (r !== null) { 3861 spaces.rgb.r = _clip(r); 3862 } 3863 if (g !== null) { 3864 spaces.rgb.g = _clip(g); 3865 } 3866 if (b !== null) { 3867 spaces.rgb.b = _clip(b); 3868 } 3869 this.set = true; 3870 3871 return this; 3872 }; 3873 3874 this.getChannel = function(channel) { 3875 switch (channel) { 3876 case 'h': 3877 case 's': 3878 case 'v': 3879 return this.getHSV()[channel]; 3880 3881 case 'r': 3882 case 'g': 3883 case 'b': 3884 return this.getRGB()[channel]; 3885 3886 case 'a': 3887 return this.getAlpha(); 3888 } 3889 3890 return null; 3891 }; 3892
3893 this.setChannel = function(channel, value) { 3894 switch (channel) { 3895 case 'h': 3896 return this.setHSV(value, null, null); 3897 3898 case 's': 3899 return this.setHSV(null, value, null); 3900 3901 case 'v': 3902 return this.setHSV(null, null, value); 3903 3904 case 'r': 3905 return this.setRGB(value, null, null); 3906 3907 case 'g': 3908 return this.setRGB(null, value, null); 3909 3910 case 'b': 3911 return this.setRGB(null, null, value); 3912 3913 case 'a': 3914 return this.setAlpha(value); 3915 } 3916 3917 return this; 3918 }; 3919 3920 this.setHSV = function(h, s, v) { 3921 spaces = {hsv: this.getHSV()}; 3922 if (h !== null) { 3923 spaces.hsv.h = _clip(h); 3924 } 3925 if (s !== null) { 3926 spaces.hsv.s = _clip(s); 3927 } 3928 if (v !== null) { 3929 spaces.hsv.v = _clip(v); 3930 } 3931 this.set = true; 3932 3933 return this; 3934 }; 3935 3936 this.setHSL = function(h, s, l) { 3937 spaces = {hsl: this.getHSL()}; 3938 if (h !== null) { 3939 spaces.hsl.h = _clip(h); 3940 } 3941 if (s !== null) { 3942 spaces.hsl.s = _clip(s); 3943 } 3944 if (l !== null) { 3945 spaces.hsl.l = _clip(l); 3946 } 3947 this.set = true; 3948 3949 return this; 3950 }; 3951 3952 this.setLAB = function(l, a, b) { 3953 spaces = {lab: this.getLAB()}; 3954 if (l !== null) { 3955 spaces.lab.l = _clip(l); 3956 } 3957 if (a !== null) { 3958 spaces.lab.a = _clip(a); 3959 } 3960 if (b !== null) { 3961 spaces.lab.b = _clip(b); 3962 } 3963 this.set = true; 3964 3965 return this; 3966 }; 3967 3968 this.setCMYK = function(c, m, y, k) { 3969 spaces = {cmyk: this.getCMYK()}; 3970 if (c !== null) { 3971 spaces.cmyk.c = _clip(c); 3972 } 3973 if (m !== null) { 3974 spaces.cmyk.m = _clip(m); 3975 } 3976 if (y !== null) { 3977 spaces.cmyk.y = _clip(y); 3978 } 3979 if (k !== null) {
3980 spaces.cmyk.k = _clip(k); 3981 } 3982 this.set = true; 3983 3984 return this; 3985 }; 3986 3987 this.getRGB = function() { 3988 if (!spaces.rgb) { 3989 spaces.rgb = spaces.lab ? _xyz_to_rgb(_lab_to_xyz(spaces.lab)) 3990 : spaces.hsv ? _hsv_to_rgb(spaces.hsv) 3991 : spaces.hsl ? _hsl_to_rgb(spaces.hsl) 3992 : spaces.cmyk ? _cmy_to_rgb(_cmyk_to_cmy(spaces.cmyk)) 3993 : {r: 0, g: 0, b: 0}; 3994 spaces.rgb.r = _clip(spaces.rgb.r); 3995 spaces.rgb.g = _clip(spaces.rgb.g); 3996 spaces.rgb.b = _clip(spaces.rgb.b); 3997 } 3998 return $.extend({}, spaces.rgb); 3999 }; 4000 4001 this.getHSV = function() { 4002 if (!spaces.hsv) { 4003 spaces.hsv = spaces.lab ? _rgb_to_hsv(this.getRGB()) 4004 : spaces.rgb ? _rgb_to_hsv(spaces.rgb) 4005 : spaces.hsl ? _rgb_to_hsv(this.getRGB()) 4006 : spaces.cmyk ? _rgb_to_hsv(this.getRGB()) 4007 : {h: 0, s: 0, v: 0}; 4008 spaces.hsv.h = _clip(spaces.hsv.h); 4009 spaces.hsv.s = _clip(spaces.hsv.s); 4010 spaces.hsv.v = _clip(spaces.hsv.v); 4011 } 4012 return $.extend({}, spaces.hsv); 4013 }; 4014 4015 this.getHSL = function() { 4016 if (!spaces.hsl) { 4017 spaces.hsl = spaces.rgb ? _rgb_to_hsl(spaces.rgb) 4018 : spaces.hsv ? _rgb_to_hsl(this.getRGB()) 4019 : spaces.cmyk ? _rgb_to_hsl(this.getRGB()) 4020 : spaces.hsv ? _rgb_to_hsl(this.getRGB()) 4021 : {h: 0, s: 0, l: 0}; 4022 spaces.hsl.h = _clip(spaces.hsl.h); 4023 spaces.hsl.s = _clip(spaces.hsl.s); 4024 spaces.hsl.l = _clip(spaces.hsl.l); 4025 } 4026 return $.extend({}, spaces.hsl); 4027 }; 4028 4029 this.getCMYK = function() { 4030 if (!spaces.cmyk) { 4031 spaces.cmyk = spaces.rgb ? _cmy_to_cmyk(_rgb_to_cmy(spaces.rgb)) 4032 : spaces.hsv ? _cmy_to_cmyk(_rgb_to_cmy(this.getRGB())) 4033 : spaces.hsl ? _cmy_to_cmyk(_rgb_to_cmy(this.getRGB())) 4034 : spaces.lab ? _cmy_to_cmyk(_rgb_to_cmy(this.getRGB())) 4035 : {c: 0, m: 0, y: 0, k: 1}; 4036 spaces.cmyk.c = _clip(spaces.cmyk.c); 4037 spaces.cmyk.m = _clip(spaces.cmyk.m); 4038 spaces.cmyk.y = _clip(spaces.cmyk.y);
4039 spaces.cmyk.k = _clip(spaces.cmyk.k); 4040 } 4041 return $.extend({}, spaces.cmyk); 4042 }; 4043 4044 this.getLAB = function() { 4045 if (!spaces.lab) { 4046 spaces.lab = spaces.rgb ? _xyz_to_lab(_rgb_to_xyz(spaces.rgb)) 4047 : spaces.hsv ? _xyz_to_lab(_rgb_to_xyz(this.getRGB())) 4048 : spaces.hsl ? _xyz_to_lab(_rgb_to_xyz(this.getRGB())) 4049 : spaces.cmyk ? _xyz_to_lab(_rgb_to_xyz(this.getRGB())) 4050 : {l: 0, a: 0, b: 0}; 4051 spaces.lab.l = _clip(spaces.lab.l); 4052 spaces.lab.a = _clip(spaces.lab.a); 4053 spaces.lab.b = _clip(spaces.lab.b); 4054 } 4055 return $.extend({}, spaces.lab); 4056 }; 4057 4058 this.getChannels = function() { 4059 return { 4060 r: this.getRGB().r, 4061 g: this.getRGB().g, 4062 b: this.getRGB().b, 4063 a: this.getAlpha(), 4064 h: this.getHSV().h, 4065 s: this.getHSV().s, 4066 v: this.getHSV().v, 4067 c: this.getCMYK().c, 4068 m: this.getCMYK().m, 4069 y: this.getCMYK().y, 4070 k: this.getCMYK().k, 4071 L: this.getLAB().l, 4072 A: this.getLAB().a, 4073 B: this.getLAB().b 4074 }; 4075 }; 4076 4077 this.getSpaces = function() { 4078 return $.extend(true, {}, spaces); 4079 }; 4080 4081 this.distance = function(color) { 4082 var space = 'lab', 4083 getter = 'get'+space.toUpperCase(), 4084 a = this[getter](), 4085 b = color[getter](), 4086 distance = 0, 4087 channel; 4088 4089 for (channel in a) { 4090 distance += Math.pow(a[channel] - b[channel], 2); 4091 } 4092 4093 return distance; 4094 }; 4095 4096 this.equals = function(color) { 4097 if (color) { 4098 var a = this.getRGB(), 4099 b = color.getRGB(); 4100 4101 return this.set === color.set 4102 && this.getAlpha() === color.getAlpha() 4103 && a.r === b.r 4104 && a.g === b.g 4105 && a.b === b.b; 4106 } 4107 return false; 4108 }; 4109 4110 this.limit = function(steps) { 4111 steps -= 1; 4112 var rgb = this.getRGB(); 4113 this.setRGB( 4114 Math.round(rgb.r * steps) / steps, 4115 Math.round(rgb.g * steps) / steps, 4116 Math.round(rgb.b * steps) / steps 4117 ); 4118 }; 4119 4120 this.toHex = function() { 4121 var rgb = this.getRGB(); 4122 return _hexify(rgb.r * 255) + _hexify(rgb.g * 255) + _hexify(rgb.b * 255); 4123 }; 4124 4125 this.toCSS = function() { 4126 return '#' + this.toHex(); 4127 }; 4128 4129 this.copy = function() { 4130 var color = new $.colorpicker.Color(this.getSpaces(), this.getAlpha()); 4131 color.set = this.set; 4132 return color; 4133 }; 4134 4135 // Construct 4136 if (args.length === 2) { 4137 spaces = args[0]; 4138 this.setAlpha(args[1] === 0 ? 0 : args[1] || 1); 4139 this.set = true; 4140 } 4141 if (args.length > 2) { 4142 this.setRGB(args[0], args[1], args[2]); 4143 this.setAlpha(args[3] === 0 ? 0 : args[3] || 1); 4144 this.set = true; 4145 } 4146 }; 4147 }(); 4148 4149 $.widget("vanderlee.colorpicker", { 4150 options: { 4151 alpha: false, // Show alpha controls and mode 4152 altAlpha: true, // change opacity of altField as well? 4153 altField: '', // selector for DOM elements which change background color on change. 4154 altOnChange: true, // true to update on each change, false to update only on close. 4155 altProperties: 'background-color', // comma separated list of any of 'background-color', 'color', 'border-color', 'outline-color' 4156 autoOpen: false, // Open dialog automatically upon creation 4157 buttonClass: null, // If set, the button will get this/these classname(s). 4158 buttonColorize: false, 4159 buttonImage: '/Content/images/ui-colorpicker.png', 4160 buttonImageOnly: false, 4161 buttonText: null, // Text on the button and/or title of button image. 4162 closeOnEscape: true, // Close the dialog when the escape key is pressed. 4163 closeOnOutside: true, // Close the dialog when clicking outside the dialog (not for inline) 4164 color: '#00FF00', // Initial color (for inline only) 4165 colorFormat: 'HEX', // Format string for output color format 4166 disabled: false, // Disable or enable the colorpicker initially 4167 draggable: true, // Make popup dialog draggable if header is visible. 4168 containment: null, // Constrains dragging to within the bounds of the specified element or region. 4169 duration: 'fast', 4170 hideOn: 'button', // 'focus', 'click', 'button', 'alt', 'all' 4171 hsv: true, // Show HSV controls and modes 4172 inline: true, // Show any divs as inline by default 4173 inlineFrame: true, // Show a border and background when inline. 4174 layout: { 4175 map: [0, 0, 1, 5], // Left, Top, Width, Height (in table cells). 4176 bar: [1, 0, 1, 5], 4177 preview: [2, 0, 1, 1], 4178 hsv: [2, 1, 1, 1], 4179 rgb: [2, 2, 1, 1], 4180 alpha: [2, 3, 1, 1], 4181 hex: [2, 4, 1, 1], 4182 lab: [3, 1, 1, 1], 4183 cmyk: [3, 2, 1, 2], 4184 swatches: [4, 0, 1, 5] 4185 }, 4186 limit: '', // Limit color "resolution": '', 'websafe', 'nibble', 'binary', 'name' 4187 modal: false, // Modal dialog? 4188 mode: 'h', // Initial editing mode, h, s, v, r, g, b or a 4189 okOnEnter: false, // Close (with OK) when pressing the enter key 4190 parts: '', // leave empty for automatic selection 4191 part: { 4192 map: { size: 256 }, 4193 bar: { size: 256 } 4194 }, // options per part 4195 position: null, 4196 regional: '', 4197 revert: false, // Revert color upon non 4198 rgb: true, // Show RGB controls and modes
4199 showAnim: 'fadeIn', 4200 showCancelButton: true, 4201 showNoneButton: false, 4202 showCloseButton: true, 4203 showOn: 'focus click alt', // 'focus', 'click', 'button', 'alt', 'all' 4204 showOptions: {}, 4205 swatches: null, // null for default or kv-object or names swatches set 4206 swatchesWidth: 84, // width (in number of pixels) of swatches box. 4207 title: null, 4208 4209 cancel: null, 4210 close: null, 4211 init: null, 4212 ok: null, 4213 open: null, 4214 select: null, 4215 stop: null 4216 }, 4217 4218 _create: function () { 4219 var that = this, 4220 text; 4221 4222 that.colorpicker_index = _colorpicker_index++; 4223 4224 that.widgetEventPrefix = 'colorpicker'; 4225 4226 that.opened = false; 4227 that.generated = false; 4228 that.inline = false; 4229 that.changed = false; 4230 4231 that.dialog = null; 4232 that.button = null; 4233 that.image = null; 4234 that.overlay = null; 4235 4236 that.events = { 4237 window_resize: null, 4238 document_keydown: null, 4239 document_click_html: null 4240 }; 4241 4242 that.mode = that.options.mode; 4243 4244 if (that.element.is('input') || that.options.inline === false) { 4245 // Initial color 4246 that._setColor(that.element.is('input') ? that.element.val() : that.options.color); 4247 that._callback('init'); 4248 4249 // showOn focus 4250 if (/\bfocus|all|both\b/.test(that.options.showOn)) { 4251 that.element.bind('focus', function () { 4252 that.open(); 4253 }); 4254 } 4255 if (/\bfocus|all|both\b/.test(that.options.hideOn)) { 4256 that.element.bind('focusout', function (e) { 4257 that.close(); 4258 }); 4259 } 4260 4261 // showOn click 4262 if (/\bclick|all|both\b/.test(that.options.showOn)) { 4263 that.element.bind('click', function (e) { 4264 if (that.opened && /\bclick|all|both\b/.test(that.options.hideOn)) { 4265 that.close(); 4266 } else { 4267 that.open(); 4268 } 4269 }); 4270 } 4271 4272 // showOn button 4273 if (/\bbutton|all|both\b/.test(that.options.showOn)) { 4274 if (that.options.buttonImage !== '') { 4275 text = that.options.buttonText || that._getRegional('button'); 4276 4277 that.image = $('<img/>').attr({ 4278 'src': that.options.buttonImage, 4279 'alt': text, 4280 'title': text 4281 }); 4282 if (that.options.buttonClass) { 4283 that.image.attr('class', that.options.buttonClass); 4284 } 4285 4286 that._setImageBackground(); 4287 } 4288 4289 if (that.options.buttonImageOnly && that.image) { 4290 that.button = that.image; 4291 } else { 4292 that.button = $('<button type="button"></button>').html(that.image || that.options.buttonText).button(); 4293 that.image = that.image ? $('img', that.button).first() : null; 4294 } 4295 that.button.insertAfter(that.element).click(function () { 4296 if (that.opened && /\bbutton|all|both\b/.test(that.options.hideOn)) { 4297 that.close(); 4298 } else { 4299 that.open(); 4300 } 4301 }); 4302 } 4303 4304 // showOn alt 4305 if (/\balt|all|both\b/.test(that.options.showOn)) { 4306 $(that.options.altField).bind('click', function () { 4307 if (that.opened && /\balt|all|both\b/.test(that.options.hideOn)) { 4308 that.close(); 4309 } else { 4310 that.open(); 4311 } 4312 }); 4313 } 4314 4315 if (that.options.autoOpen) { 4316 that.open(); 4317 } 4318 4319 } else { 4320 that.inline = true; 4321 4322 that._generate(); 4323 that.opened = true; 4324 } 4325 4326 // Disable Widget-style 4327 (that.element.is(':disabled') || that.options.disabled) && that.disable(); 4328 4329 return this; 4330 }, 4331 4332 _setOption: function(key, value) { 4333 switch (key) { 4334 case 'disabled': 4335 this[value ? 'disable' : 'enable'](); 4336 break; 4337 4338 case 'swatches': 4339 this.options.swatches = value; 4340 this.parts.swatches.init(); 4341 break; 4342 } 4343 4344 $.Widget.prototype._setOption.apply(this, arguments); 4345 }, 4346 4347 enable: function () { 4348 //$.Widget.prototype.enable.call(this); 4349 this.element && this.element.prop('disabled', false); 4350 this.button && this.button.prop('disabled', false); 4351 this.dialog && this.dialog.removeClass('ui-colorpicker-disabled'); 4352 this.options.disabled = false; 4353 4354 this.parts && $.each(this.parts, function (index, part) { 4355 part.disable && part.disable(false); 4356 }); 4357 }, 4358 4359 disable: function () { 4360 //$.Widget.prototype.disable.call(this); 4361 this.element && this.element.prop('disabled', true); 4362 this.button && this.button.prop('disabled', true); 4363 this.dialog && this.dialog.addClass('ui-colorpicker-disabled'); 4364 this.options.disabled = true; 4365 4366 this.parts && $.each(this.parts, function (index, part) { 4367 part.disable && part.disable(true); 4368 }); 4369 }, 4370
4371 _setImageBackground: function() { 4372 if (this.image && this.options.buttonColorize) { 4373 this.image.css('background-color', this.color.set? this._formatColor('RGBA', this.color) : ''); 4374 } 4375 }, 4376 4377 /** 4378 * If an alternate field is specified, set it according to the current color. 4379 */ 4380 _setAltField: function () { 4381 if (this.options.altOnChange && this.options.altField && this.options.altProperties) { 4382 var index, 4383 property, 4384 properties = this.options.altProperties.split(','); 4385 4386 for (index = 0; index <= properties.length; ++index) { 4387 property = $.trim(properties[index]); 4388 switch (property) { 4389 case 'color': 4390 case 'fill': 4391 case 'stroke': 4392 case 'background-color': 4393 case 'backgroundColor': 4394 case 'outline-color': 4395 case 'border-color': 4396 $(this.options.altField).css(property, this.color.set? this.color.toCSS() : ''); 4397 break; 4398 } 4399 } 4400 4401 this.options.altAlpha && 4402 $(this.options.altField).css('opacity', this.color.set? this.color.getAlpha() : ''); 4403 } 4404 }, 4405 4406 _setColor: function (text) { 4407 this.color = this._parseColor(text) || new $.colorpicker.Color(); 4408 this.currentColor = this.color.copy(); 4409 4410 this._setImageBackground(); 4411 this._setAltField(); 4412 }, 4413 4414 setColor: function(text) { 4415 this._setColor(text); 4416 this._change(); 4417 }, 4418 4419 getColor: function (format) { 4420 if (!this.color.set) 4421 return null 4422 else 4423 return this._formatColor(format || this.options.colorFormat, this.color); 4424 }, 4425 4426 _generateInline: function() { 4427 var that = this; 4428 4429 $(that.element).html(that.options.inlineFrame ? _container_inlineFrame : _container_inline); 4430 4431 that.dialog = $('.ui-colorpicker', that.element); 4432 }, 4433 4434 _generatePopup: function() { 4435 var that = this; 4436 4437 that.dialog = $(_container_popup).appendTo('body'); 4438 4439 // Close on clicking outside window and controls 4440 if (that.events.document_click_html === null) { 4441 $(document).delegate('html', 'touchstart click', that.events.document_click_html = function (event) { 4442 if (!that.opened || event.target === that.element[0] || that.overlay) { 4443 return; 4444 } 4445 4446 // Check if clicked on any part of dialog 4447 if (that.dialog.is(event.target) || that.dialog.has(event.target).length > 0) { 4448 that.element.blur(); // inside window! 4449 return; 4450 } 4451 4452 // Check if clicked on known external elements 4453 var p, 4454 parents = $(event.target).parents(); 4455 // add the event.target in case of buttonImageOnly and closeOnOutside both are set to true 4456 parents.push(event.target); 4457 for (p = 0; p <= parents.length; ++p) { 4458 // button 4459 if (that.button !== null && parents[p] === that.button[0]) { 4460 return; 4461 } 4462 // showOn alt 4463 if (/\balt|all|both\b/.test(that.options.showOn) && $(that.options.altField).is(parents[p])) { 4464 return; 4465 } 4466 } 4467 4468 // no closeOnOutside 4469 if (!that.options.closeOnOutside) { 4470 return; 4471 } 4472 4473 that.close(that.options.revert); 4474 }); 4475 } 4476 4477 if (that.events.document_keydown === null) { 4478 $(document).bind('keydown', that.events.document_keydown = function (event) { 4479 // close on ESC key 4480 if (that.opened && event.keyCode === 27 && that.options.closeOnEscape) { 4481 that.close(that.options.revert); 4482 } 4483 4484 // OK on Enter key 4485 if (that.opened && event.keyCode === 13 && that.options.okOnEnter) { 4486 that.close(); 4487 } 4488 }); 4489 } 4490 4491 // Close (with OK) on tab key in element 4492 that.element.keydown(function (event) { 4493 if (event.keyCode === 9) { 4494 that.close(); 4495 } 4496 }).keyup(function (event) { 4497 var color = that._parseColor(that.element.val()); 4498 if (color && !that.color.equals(color)) { 4499 that.color = color; 4500 that._change(); 4501 } 4502 }); 4503 }, 4504 4505 _generate: function () { 4506 var that = this, 4507 index, 4508 part, 4509 parts_list, 4510 layout_parts, 4511 table, 4512 classes; 4513 4514 that._setColor(that.inline || !that.element.is('input') ? that.options.color : that.element.val()); 4515 4516 that[that.inline ? '_generateInline' : '_generatePopup'](); 4517 4518 // Determine the parts to include in this colorpicker 4519 if (typeof that.options.parts === 'string') { 4520 if ($.colorpicker.partslists[that.options.parts]) { 4521 parts_list = $.colorpicker.partslists[that.options.parts]; 4522 } else { 4523 // automatic 4524 parts_list = $.colorpicker.partslists[that.inline ? 'inline' : 'popup']; 4525 } 4526 } else { 4527 parts_list = that.options.parts; 4528 } 4529 4530 // Add any parts to the internal parts list 4531 that.parts = {}; 4532 $.each(parts_list, function(index, part) { 4533 if ($.colorpicker.parts[part]) { 4534 that.parts[part] = new $.colorpicker.parts[part](that); 4535 } 4536 }); 4537 4538 if (!that.generated) { 4539 layout_parts = []; 4540 4541 $.each(that.options.layout, function(part, pos) { 4542 if (that.parts[part]) { 4543 layout_parts.push({ 4544 'part': part, 4545 'pos': pos 4546 });
4547 } 4548 }); 4549 4550 table = $(_layoutTable(layout_parts, function(cell, x, y) { 4551 classes = ['ui-colorpicker-' + cell.part + '-container']; 4552 4553 if (x > 0) { 4554 classes.push('ui-colorpicker-padding-left'); 4555 } 4556 4557 if (y > 0) { 4558 classes.push('ui-colorpicker-padding-top'); 4559 } 4560 4561 return '<td class="' + classes.join(' ') + '"' 4562 + (cell.pos[2] > 1 ? ' colspan="' + cell.pos[2] + '"' : '') 4563 + (cell.pos[3] > 1 ? ' rowspan="' + cell.pos[3] + '"' : '') 4564 + ' valign="top"></td>'; 4565 })).appendTo(that.dialog); 4566 if (that.options.inlineFrame) { 4567 table.addClass('ui-dialog-content ui-widget-content'); 4568 } 4569 4570 that._initAllParts(); 4571 that._updateAllParts(); 4572 that.generated = true; 4573 } 4574 }, 4575 4576 _effectGeneric: function (element, show, slide, fade, callback) { 4577 var that = this; 4578 4579 if ($.effects && $.effects[that.options.showAnim]) { 4580 element[show](that.options.showAnim, that.options.showOptions, that.options.duration, callback); 4581 } else { 4582 element[(that.options.showAnim === 'slideDown' ? 4583 slide 4584 : (that.options.showAnim === 'fadeIn' ? 4585 fade 4586 : show))]((that.options.showAnim ? that.options.duration : null), callback); 4587 if (!that.options.showAnim || !that.options.duration) { 4588 callback(); 4589 } 4590 } 4591 }, 4592 4593 _effectShow: function(element, callback) { 4594 this._effectGeneric(element, 'show', 'slideDown', 'fadeIn', callback); 4595 }, 4596 4597 _effectHide: function(element, callback) { 4598 this._effectGeneric(element, 'hide', 'slideUp', 'fadeOut', callback); 4599 }, 4600 4601 open: function() { 4602 var that = this, 4603 offset, 4604 bottom, right, 4605 height, width, 4606 x, y, 4607 zIndex, 4608 element, 4609 position; 4610 4611 if (!that.opened) { 4612 that._generate(); 4613 4614 if (that.element.is(':hidden')) { 4615 element = $('<div/>').insertBefore(that.element); 4616 } else { 4617 element = that.element; 4618 } 4619 4620 if (that.element.is(':hidden')) { 4621 element.remove(); 4622 } 4623 4624 // Automatically find highest z-index. 4625 zIndex = 0; 4626 $(that.element[0]).parents().each(function() { 4627 var z = $(this).css('z-index'); 4628 if ((typeof(z) === 'number' || typeof(z) === 'string') && z !== '' && !isNaN(z)) { 4629 if (z > zIndex) { 4630 zIndex = parseInt(z, 10); 4631 return false; 4632 } 4633 } 4634 else { 4635 $(this).siblings().each(function() { 4636 var z = $(this).css('z-index'); 4637 if ((typeof(z) === 'number' || typeof(z) === 'string') && z !== '' && !isNaN(z)) { 4638 if (z > zIndex) { 4639 zIndex = parseInt(z, 10); 4640 } 4641 } 4642 }); 4643 } 4644 }); 4645 4646 zIndex += 2; 4647 that.dialog.css('z-index', zIndex); 4648 4649 if (that.options.modal) { 4650 that.overlay = $('<div class="ui-widget-overlay"></div>').appendTo('body').css('z-index', zIndex - 1); 4651 4652 if (that.events.window_resize !== null) { 4653 $(window).unbind('resize', that.events.window_resize); 4654 } 4655 4656 that.events.window_resize = function() { 4657 if (that.overlay) { 4658 that.overlay.width($(document).width()); 4659 that.overlay.height($(document).height()); 4660 } 4661 }, 4662 4663 $(window).bind('resize', that.events.window_resize); 4664 that.events.window_resize(); 4665 } 4666 4667 that._effectShow(this.dialog); 4668 4669 if (that.options.position) { 4670 position = $.extend({}, that.options.position); 4671 if (position.of === 'element') { 4672 position.of = element; 4673 } 4674 } else { 4675 position = { 4676 my: 'left top', 4677 at: 'left bottom', 4678 of: element, 4679 collision: 'flip' 4680 }; 4681 } 4682 that.dialog.position(position); 4683 4684 that.opened = true; 4685 that._callback('open', true); 4686 4687 // Without waiting for domready the width of the map is 0 and we 4688 // wind up with the cursor stuck in the upper left corner 4689 $(function() { 4690 that._repaintAllParts(); 4691 }); 4692 } 4693 }, 4694 4695 close: function (cancel) { 4696 var that = this; 4697 4698 if (!that.opened) { 4699 return; 4700 } 4701 4702 if (cancel) { 4703 that.color = that.currentColor.copy(); 4704 that._change();
4705 that._callback('cancel', true); 4706 } else { 4707 that.currentColor = that.color.copy(); 4708 that._callback('ok', true); 4709 } 4710 that.changed = false; 4711 4712 if (that.overlay) { 4713 $(window).unbind('resize', that.events.window_resize); 4714 that.overlay.remove(); 4715 } 4716 4717 // tear down the interface 4718 that._effectHide(that.dialog, function () { 4719 that.dialog.remove(); 4720 that.dialog = null; 4721 that.generated = false; 4722 4723 that.opened = false; 4724 that._callback('close', true); 4725 }); 4726 }, 4727 4728 destroy: function() { 4729 var that = this; 4730 if (that.events.document_click_html !== null) { 4731 $(document).undelegate('html', 'touchstart click', that.events.document_click_html); 4732 } 4733 4734 if (that.events.document_keydown !== null) { 4735 $(document).unbind('keydown', that.events.document_keydown); 4736 } 4737 4738 if (that.events.resizeOverlay !== null) { 4739 $(window).unbind('resize', that.events.resizeOverlay); 4740 } 4741 4742 this.element.unbind(); 4743 4744 if (this.overlay) { 4745 this.overlay.remove(); 4746 } 4747 4748 if (this.dialog !== null) { 4749 this.dialog.remove(); 4750 } 4751 4752 if (this.image !== null) { 4753 this.image.remove(); 4754 } 4755 4756 if (this.button !== null) { 4757 this.button.remove(); 4758 } 4759 }, 4760 4761 _callback: function (callback, spaces) { 4762 var that = this, 4763 data, 4764 lab; 4765 4766 if (that.color.set) { 4767 data = { 4768 formatted: that._formatColor(that.options.colorFormat, that.color), 4769 colorPicker: that 4770 }; 4771 4772 lab = that.color.getLAB(); 4773 lab.a = (lab.a * 2) - 1; 4774 lab.b = (lab.b * 2) - 1; 4775 4776 if (spaces === true) { 4777 data.a = that.color.getAlpha(); 4778 data.rgb = that.color.getRGB(); 4779 data.hsv = that.color.getHSV(); 4780 data.cmyk = that.color.getCMYK(); 4781 data.hsl = that.color.getHSL(); 4782 data.lab = lab; 4783 } 4784 4785 return that._trigger(callback, null, data); 4786 } else { 4787 return that._trigger(callback, null, { 4788 formatted: '', 4789 colorPicker: that 4790 }); 4791 } 4792 }, 4793 4794 _initAllParts: function () { 4795 $.each(this.parts, function (index, part) { 4796 if (part.init) { 4797 part.init(); 4798 } 4799 }); 4800 }, 4801 4802 _updateAllParts: function () { 4803 $.each(this.parts, function (index, part) { 4804 if (part.update) { 4805 part.update(); 4806 } 4807 }); 4808 }, 4809 4810 _repaintAllParts: function () { 4811 $.each(this.parts, function (index, part) { 4812 if (part.repaint) { 4813 part.repaint(); 4814 } 4815 }); 4816 }, 4817 4818 _change: function (stoppedChanging /* = true */) { 4819 // Limit color palette 4820 if (this.color.set && this.options.limit && $.colorpicker.limits[this.options.limit]) { 4821 $.colorpicker.limits[this.options.limit](this.color, this); 4822 } 4823 4824 // Set changed if different from starting color 4825 this.changed = !this.color.equals(this.currentColor); 4826 4827 // update input element content
4828 if (!this.inline) { 4829 if (!this.color.set) { 4830 if (this.element.val() !== '') { 4831 this.element.val('').change(); 4832 } 4833 } else if (!this.color.equals(this._parseColor(this.element.val()))) { 4834 this.element.val(this._formatColor(this.options.colorFormat, this.color)).change(); 4835 } 4836 4837 this._setImageBackground(); 4838 } 4839 4840 // Set the alt field 4841 this._setAltField(); 4842 4843 // update color option 4844 this.options.color = this.color.set ? this.color.toCSS() : ''; 4845 4846 if (this.opened) { 4847 this._repaintAllParts(); 4848 } 4849 4850 // callbacks 4851 this._callback('select'); 4852 4853 if (typeof stoppedChanging === 'undefined' ? true : !!stoppedChanging) { 4854 this._callback('stop'); 4855 } 4856 }, 4857 4858 // This will be deprecated by jQueryUI 1.9 widget 4859 _hoverable: function (e) { 4860 e.hover(function () { 4861 e.addClass("ui-state-hover"); 4862 }, function () { 4863 e.removeClass("ui-state-hover"); 4864 }); 4865 }, 4866 4867 // This will be deprecated by jQueryUI 1.9 widget 4868 _focusable: function (e) { 4869 e.focus(function () { 4870 e.addClass("ui-state-focus"); 4871 }).blur(function () { 4872 e.removeClass("ui-state-focus"); 4873 }); 4874 }, 4875 4876 _getRegional: function(name) { 4877 return $.colorpicker.regional[this.options.regional][name] !== undefined ? 4878 $.colorpicker.regional[this.options.regional][name] : $.colorpicker.regional[''][name]; 4879 }, 4880 4881 _getSwatches: function() { 4882 if (typeof(this.options.swatches) === 'string') { 4883 return $.colorpicker.swatches[this.options.swatches]; 4884 } 4885 4886 if ($.isPlainObject(this.options.swatches)) { 4887 return this.options.swatches; 4888 } 4889 4890 return $.colorpicker.swatches.html; 4891 }, 4892 4893 _eachSwatch: function (callback) { 4894 var currentSwatches = this._getSwatches(), 4895 name; 4896 $.each(currentSwatches, function (nameOrIndex, swatch) { 4897 name = $.isArray(currentSwatches) ? swatch.name : nameOrIndex; 4898 return callback(name, swatch); 4899 }); 4900 }, 4901 4902 _getSwatch: function(name) { 4903 var swatch = false; 4904 4905 this._eachSwatch(function(swatchName, current) { 4906 if (swatchName.toLowerCase() == name.toLowerCase()) { 4907 swatch = current; 4908 return false; 4909 } 4910 }); 4911 4912 return swatch; 4913 }, 4914 4915 _parseFormat: function(format, text) { 4916 var that = this, 4917 typeRegexps = { 4918 x: function() {return '([0-9a-fA-F]{2})';} 4919 , d: function() {return '([12]?[0-9]{1,2})';} 4920 , f: function() {return '([0-9]*\\.?[0-9]*)';} 4921 , p: function() {return '([0-9]*\\.?[0-9]*)';} 4922 }, 4923 typeConverters = { 4924 x: function(v) {return parseInt(v, 16) / 255.;} 4925 , d: function(v) {return v / 255.;} 4926 , f: function(v) {return v;} 4927 , p: function(v) {return v * 0.01;} 4928 }, 4929 setters = { 4930 r: 'setRGB' 4931 , g: 'setRGB' 4932 , b: 'setRGB' 4933 , h: 'setHSV' 4934 , s: 'setHSV' 4935 , v: 'setHSV' 4936 , c: 'setCMYK' 4937 , m: 'setCMYK' 4938 , y: 'setCMYK' 4939 , k: 'setCMYK' 4940 , L: 'setLAB' 4941 , A: 'setLAB' 4942 , B: 'setLAB' 4943 }, 4944 setterChannels = { 4945 setRGB: [ 'r', 'g', 'b'] 4946 , setHSV: [ 'h', 's', 'v' ] 4947 , setCMYK: [ 'c', 'm', 'y', 'k' ] 4948 , setLAB: [ 'L', 'A', 'B' ] 4949 }, 4950 channels = [], 4951 converters = [], 4952 setter = null, 4953 color, 4954 pattern; 4955 4956 // Construct pattern 4957 pattern = format.replace(/[()\\^$.|?*+[\]]/g, function(m) { 4958 return '\\'+m; 4959 }); 4960 4961 4962 pattern = pattern.replace(/\\?[argbhsvcmykLAB][xdfp]/g, function(variable) { 4963 if (variable.match(/^\\/)) { 4964 return variable.slice(1); 4965 } 4966 4967 var channel = variable.charAt(0), 4968 type = variable.charAt(1); 4969 4970 channels.push(channel); 4971 converters.push(typeConverters[type]); 4972 if (setters[channel]) { 4973 setter = setters[channel]; 4974 } 4975 4976 return typeRegexps[type](); 4977 }); 4978 4979 if (setter) { 4980 var values = text.match(new RegExp(pattern)); 4981 if (values) { 4982 var args = [], 4983 channelIndex; 4984 4985 values.shift(); 4986 4987 $.each(setterChannels[setter], function(index, channel) { 4988 channelIndex = $.inArray(channel, channels); 4989 args[index] = converters[channelIndex](values[channelIndex]); 4990 });
4991 4992 color = new $.colorpicker.Color(); 4993 color[setter].apply(color, args); 4994 } 4995 } 4996 4997 return color; 4998 }, 4999 5000 _parseColor: function(text) { 5001 var that = this, 5002 color; 5003 5004 var formats = $.isArray(that.options.colorFormat) 5005 ? that.options.colorFormat 5006 : [ that.options.colorFormat ]; 5007 5008 $.each(formats, function(index, format) { 5009 if ($.colorpicker.parsers[format]) { 5010 color = $.colorpicker.parsers[format](text, that); 5011 } else { 5012 color = that._parseFormat(format, text); 5013 } 5014 5015 if (color) { 5016 return false; 5017 } 5018 }); 5019 5020 if (!color) { 5021 // fallback; check all registered parsers 5022 $.each($.colorpicker.parsers, function(name, parser) { 5023 color = parser(text, that); 5024 if (color) { 5025 return false; 5026 } 5027 }); 5028 } 5029 5030 if (color) { 5031 return color; 5032 } 5033 5034 return false; 5035 }, 5036 5037 _exactName: function(color) { 5038 var name = false; 5039 5040 this._eachSwatch(function(n, swatch) { 5041 if (color.equals(new $.colorpicker.Color(swatch.r, swatch.g, swatch.b))) { 5042 name = n; 5043 return false; 5044 } 5045 }); 5046 5047 return name; 5048 }, 5049 5050 _closestName: function(color) { 5051 var rgb = color.getRGB(), 5052 distance = null, 5053 name = false, 5054 d; 5055 5056 this._eachSwatch(function(n, swatch) { 5057 d = color.distance(new $.colorpicker.Color(swatch.r, swatch.g, swatch.b)); 5058 if (d < distance || distance === null) { 5059 name = n; 5060 if (d <= 1e-20) { // effectively 0 by maximum rounding error 5061 return false; // can't get much closer than 0 5062 } 5063 distance = d; // safety net 5064 } 5065 }); 5066 5067 return name; 5068 }, 5069 5070 _formatColor: function (formats, color) { 5071 var that = this, 5072 text = null, 5073 types = { 'x': function(v) {return _intToHex(v * 255);} 5074 , 'd': function(v) {return Math.round(v * 255);} 5075 , 'f': function(v) {return v;} 5076 , 'p': function(v) {return v * 100.;} 5077 }, 5078 channels = color.getChannels(); 5079 5080 if (!$.isArray(formats)) { 5081 formats = [formats]; 5082 } 5083 5084 $.each(formats, function(index, format) { 5085 if ($.colorpicker.writers[format]) { 5086 text = $.colorpicker.writers[format](color, that); 5087 return (text === false); 5088 } else { 5089 text = format.replace(/\\?[argbhsvcmykLAB][xdfp]/g, function(m) { 5090 if (m.match(/^\\/)) { 5091 return m.slice(1); 5092 } 5093 return types[m.charAt(1)](channels[m.charAt(0)]); 5094 }); 5095 return false; 5096 } 5097 }); 5098 5099 return text; 5100 } 5101 }); 5102 5103 return $.vanderlee.colorpicker; 5104})); 5105; 5106;jQuery(function($) { 5107 $.colorpicker.swatchesNames['pantone'] = 'Pantone'; 5108 $.colorpicker.swatches['pantone'] = [ 5109 {name: '100', r: 0.956862745098039, g: 0.929411764705882, b: 0.486274509803922}, 5110 {name: '101', r: 0.956862745098039, g: 0.929411764705882, b: 0.27843137254902}, 5111 {name: '102', r: 0.976470588235294, g: 0.909803921568627, b: 0.0784313725490196}, 5112 {name: '103', r: 0.776470588235294, g: 0.67843137254902, b: 0.0588235294117647}, 5113 {name: '104', r: 0.67843137254902, g: 0.607843137254902, b: 0.0470588235294118}, 5114 {name: '105', r: 0.509803921568627, g: 0.458823529411765, b: 0.0588235294117647}, 5115 {name: '106', r: 0.968627450980392, g: 0.909803921568627, b: 0.349019607843137}, 5116 {name: '107', r: 0.976470588235294, g: 0.898039215686275, b: 0.149019607843137}, 5117 {name: '108', r: 0.976470588235294, g: 0.866666666666667, b: 0.0862745098039216}, 5118 {name: '109', r: 0.976470588235294, g: 0.83921568627451, b: 0.0862745098039216}, 5119 {name: '110', r: 0.847058823529412, g: 0.709803921568627, b: 0.0666666666666667}, 5120 {name: '111', r: 0.666666666666667, g: 0.576470588235294, b: 0.0392156862745098}, 5121 {name: '112', r: 0.6, g: 0.517647058823529, b: 0.0392156862745098}, 5122 {name: '113', r: 0.976470588235294, g: 0.898039215686275, b: 0.356862745098039}, 5123 {name: '114', r: 0.976470588235294, g: 0.886274509803922, b: 0.298039215686275}, 5124 {name: '115', r: 0.976470588235294, g: 0.87843137254902, b: 0.298039215686275}, 5125 {name: '116', r: 0.988235294117647, g: 0.819607843137255, b: 0.0862745098039216}, 5126 {name: '116 2X', r: 0.968627450980392, g: 0.709803921568627, b: 0.0470588235294118}, 5127 {name: '117', r: 0.776470588235294, g: 0.627450980392157, b: 0.0470588235294118}, 5128 {name: '118', r: 0.666666666666667, g: 0.556862745098039, b: 0.0392156862745098}, 5129 {name: '119', r: 0.537254901960784, g: 0.466666666666667, b: 0.0980392156862745}, 5130 {name: '120', r: 0.976470588235294, g: 0.886274509803922, b: 0.498039215686275}, 5131 {name: '1205', r: 0.968627450980392, g: 0.909803921568627, b: 0.666666666666667}, 5132 {name: '121', r: 0.976470588235294, g: 0.87843137254902, b: 0.43921568627451}, 5133 {name: '1215', r: 0.976470588235294, g: 0.87843137254902, b: 0.549019607843137}, 5134 {name: '122', r: 0.988235294117647, g: 0.847058823529412, b: 0.337254901960784}, 5135 {name: '1225', r: 1, g: 0.8, b: 0.286274509803922}, 5136 {name: '123', r: 1, g: 0.776470588235294, b: 0.117647058823529}, 5137 {name: '1235', r: 0.988235294117647, g: 0.709803921568627, b: 0.0784313725490196}, 5138 {name: '124', r: 0.87843137254902, g: 0.666666666666667, b: 0.0588235294117647},
5139 {name: '1245', r: 0.749019607843137, g: 0.568627450980392, b: 0.0470588235294118}, 5140 {name: '125', r: 0.709803921568627, g: 0.549019607843137, b: 0.0392156862745098}, 5141 {name: '1255', r: 0.63921568627451, g: 0.498039215686275, b: 0.0784313725490196}, 5142 {name: '126', r: 0.63921568627451, g: 0.509803921568627, b: 0.0196078431372549}, 5143 {name: '1265', r: 0.486274509803922, g: 0.388235294117647, b: 0.0862745098039216}, 5144 {name: '127', r: 0.956862745098039, g: 0.886274509803922, b: 0.529411764705882}, 5145 {name: '128', r: 0.956862745098039, g: 0.858823529411765, b: 0.376470588235294}, 5146 {name: '129', r: 0.949019607843137, g: 0.819607843137255, b: 0.23921568627451}, 5147 {name: '130', r: 0.917647058823529, g: 0.686274509803922, b: 0.0588235294117647}, 5148 {name: '130 2X', r: 0.886274509803922, g: 0.568627450980392, b: 0}, 5149 {name: '131', r: 0.776470588235294, g: 0.576470588235294, b: 0.0392156862745098}, 5150 {name: '132', r: 0.619607843137255, g: 0.486274509803922, b: 0.0392156862745098}, 5151 {name: '133', r: 0.43921568627451, g: 0.356862745098039, b: 0.0392156862745098}, 5152 {name: '134', r: 1, g: 0.847058823529412, b: 0.498039215686275}, 5153 {name: '1345', r: 1, g: 0.83921568627451, b: 0.568627450980392}, 5154 {name: '135', r: 0.988235294117647, g: 0.788235294117647, b: 0.388235294117647}, 5155 {name: '1355', r: 0.988235294117647, g: 0.807843137254902, b: 0.529411764705882}, 5156 {name: '136', r: 0.988235294117647, g: 0.749019607843137, b: 0.286274509803922}, 5157 {name: '1365', r: 0.988235294117647, g: 0.729411764705882, b: 0.368627450980392}, 5158 {name: '137', r: 0.988235294117647, g: 0.63921568627451, b: 0.0666666666666667}, 5159 {name: '1375', r: 0.976470588235294, g: 0.607843137254902, b: 0.0470588235294118}, 5160 {name: '138', r: 0.847058823529412, g: 0.549019607843137, b: 0.00784313725490196}, 5161 {name: '1385', r: 0.8, g: 0.47843137254902, b: 0.00784313725490196}, 5162 {name: '139', r: 0.686274509803922, g: 0.458823529411765, b: 0.0196078431372549}, 5163 {name: '1395', r: 0.6, g: 0.376470588235294, b: 0.0274509803921569}, 5164 {name: '140', r: 0.47843137254902, g: 0.356862745098039, b: 0.0666666666666667}, 5165 {name: '1405', r: 0.419607843137255, g: 0.27843137254902, b: 0.0784313725490196}, 5166 {name: '141', r: 0.949019607843137, g: 0.807843137254902, b: 0.407843137254902}, 5167 {name: '142', r: 0.949019607843137, g: 0.749019607843137, b: 0.286274509803922}, 5168 {name: '143', r: 0.937254901960784, g: 0.698039215686274, b: 0.176470588235294}, 5169 {name: '144', r: 0.886274509803922, g: 0.549019607843137, b: 0.0196078431372549}, 5170 {name: '145', r: 0.776470588235294, g: 0.498039215686275, b: 0.0274509803921569}, 5171 {name: '146', r: 0.619607843137255, g: 0.419607843137255, b: 0.0196078431372549}, 5172 {name: '147', r: 0.447058823529412, g: 0.368627450980392, b: 0.149019607843137}, 5173 {name: '148', r: 1, g: 0.83921568627451, b: 0.607843137254902}, 5174 {name: '1485', r: 1, g: 0.717647058823529, b: 0.466666666666667}, 5175 {name: '149', r: 0.988235294117647, g: 0.8, b: 0.576470588235294}, 5176 {name: '1495', r: 1, g: 0.6, b: 0.247058823529412}, 5177 {name: '150', r: 0.988235294117647, g: 0.67843137254902, b: 0.337254901960784}, 5178 {name: '1505', r: 0.956862745098039, g: 0.486274509803922, b: 0}, 5179 {name: '151', r: 0.968627450980392, g: 0.498039215686275, b: 0}, 5180 {name: '152', r: 0.866666666666667, g: 0.458823529411765, b: 0}, 5181 {name: '1525', r: 0.709803921568627, g: 0.329411764705882, b: 0}, 5182 {name: '153', r: 0.737254901960784, g: 0.427450980392157, b: 0.0392156862745098}, 5183 {name: '1535', r: 0.549019607843137, g: 0.266666666666667, b: 0}, 5184 {name: '154', r: 0.6, g: 0.349019607843137, b: 0.0196078431372549}, 5185 {name: '1545', r: 0.27843137254902, g: 0.133333333333333, b: 0}, 5186 {name: '155', r: 0.956862745098039, g: 0.858823529411765, b: 0.666666666666667}, 5187 {name: '1555', r: 0.976470588235294, g: 0.749019607843137, b: 0.619607843137255}, 5188 {name: '156', r: 0.949019607843137, g: 0.776470588235294, b: 0.549019607843137}, 5189 {name: '1565', r: 0.988235294117647, g: 0.647058823529412, b: 0.466666666666667}, 5190 {name: '157', r: 0.929411764705882, g: 0.627450980392157, b: 0.309803921568627},
5191 {name: '1575', r: 0.988235294117647, g: 0.529411764705882, b: 0.266666666666667}, 5192 {name: '158', r: 0.909803921568627, g: 0.458823529411765, b: 0.0666666666666667}, 5193 {name: '1585', r: 0.976470588235294, g: 0.419607843137255, b: 0.0274509803921569}, 5194 {name: '159', r: 0.776470588235294, g: 0.376470588235294, b: 0.0196078431372549}, 5195 {name: '1595', r: 0.819607843137255, g: 0.356862745098039, b: 0.0196078431372549}, 5196 {name: '160', r: 0.619607843137255, g: 0.329411764705882, b: 0.0392156862745098}, 5197 {name: '1605', r: 0.627450980392157, g: 0.309803921568627, b: 0.0666666666666667}, 5198 {name: '161', r: 0.388235294117647, g: 0.227450980392157, b: 0.0666666666666667}, 5199 {name: '1615', r: 0.517647058823529, g: 0.247058823529412, b: 0.0588235294117647}, 5200 {name: '162', r: 0.976470588235294, g: 0.776470588235294, b: 0.666666666666667}, 5201 {name: '1625', r: 0.976470588235294, g: 0.647058823529412, b: 0.549019607843137}, 5202 {name: '163', r: 0.988235294117647, g: 0.619607843137255, b: 0.43921568627451}, 5203 {name: '1635', r: 0.976470588235294, g: 0.556862745098039, b: 0.427450980392157}, 5204 {name: '164', r: 0.988235294117647, g: 0.498039215686275, b: 0.247058823529412}, 5205 {name: '1645', r: 0.976470588235294, g: 0.447058823529412, b: 0.258823529411765}, 5206 {name: '165', r: 0.976470588235294, g: 0.388235294117647, b: 0.00784313725490196}, 5207 {name: '165 2X', r: 0.917647058823529, g: 0.309803921568627, b: 0}, 5208 {name: '1655', r: 0.976470588235294, g: 0.337254901960784, b: 0.00784313725490196}, 5209 {name: '166', r: 0.866666666666667, g: 0.349019607843137, b: 0}, 5210 {name: '1665', r: 0.866666666666667, g: 0.309803921568627, b: 0.0196078431372549}, 5211 {name: '167', r: 0.737254901960784, g: 0.309803921568627, b: 0.0274509803921569}, 5212 {name: '1675', r: 0.647058823529412, g: 0.247058823529412, b: 0.0588235294117647}, 5213 {name: '168', r: 0.427450980392157, g: 0.188235294117647, b: 0.0666666666666667}, 5214 {name: '1685', r: 0.517647058823529, g: 0.207843137254902, b: 0.0666666666666667}, 5215 {name: '169', r: 0.976470588235294, g: 0.729411764705882, b: 0.666666666666667}, 5216 {name: '170', r: 0.976470588235294, g: 0.537254901960784, b: 0.447058823529412}, 5217 {name: '171', r: 0.976470588235294, g: 0.376470588235294, b: 0.227450980392157}, 5218 {name: '172', r: 0.968627450980392, g: 0.286274509803922, b: 0.00784313725490196}, 5219 {name: '173', r: 0.819607843137255, g: 0.266666666666667, b: 0.0784313725490196}, 5220 {name: '174', r: 0.576470588235294, g: 0.2, b: 0.0666666666666667}, 5221 {name: '175', r: 0.427450980392157, g: 0.2, b: 0.129411764705882}, 5222 {name: '176', r: 0.976470588235294, g: 0.686274509803922, b: 0.67843137254902}, 5223 {name: '1765', r: 0.976470588235294, g: 0.619607843137255, b: 0.63921568627451}, 5224 {name: '1767', r: 0.976470588235294, g: 0.698039215686274, b: 0.717647058823529}, 5225 {name: '177', r: 0.976470588235294, g: 0.509803921568627, b: 0.498039215686275}, 5226 {name: '1775', r: 0.976470588235294, g: 0.517647058823529, b: 0.556862745098039}, 5227 {name: '1777', r: 0.988235294117647, g: 0.4, b: 0.458823529411765}, 5228 {name: '178', r: 0.976470588235294, g: 0.368627450980392, b: 0.349019607843137}, 5229 {name: '1785', r: 0.988235294117647, g: 0.309803921568627, b: 0.349019607843137}, 5230 {name: '1787', r: 0.956862745098039, g: 0.247058823529412, b: 0.309803921568627}, 5231 {name: '1788', r: 0.937254901960784, g: 0.168627450980392, b: 0.176470588235294}, 5232 {name: '1788 2X', r: 0.83921568627451, g: 0.129411764705882, b: 0}, 5233 {name: '179', r: 0.886274509803922, g: 0.23921568627451, b: 0.156862745098039}, 5234 {name: '1795', r: 0.83921568627451, g: 0.156862745098039, b: 0.156862745098039}, 5235 {name: '1797', r: 0.8, g: 0.176470588235294, b: 0.188235294117647}, 5236 {name: '180', r: 0.756862745098039, g: 0.219607843137255, b: 0.156862745098039}, 5237 {name: '1805', r: 0.686274509803922, g: 0.149019607843137, b: 0.149019607843137}, 5238 {name: '1807', r: 0.627450980392157, g: 0.188235294117647, b: 0.2}, 5239 {name: '181', r: 0.486274509803922, g: 0.176470588235294, b: 0.137254901960784},
5240 {name: '1810', r: 0.486274509803922, g: 0.129411764705882, b: 0.117647058823529}, 5241 {name: '1817', r: 0.356862745098039, g: 0.176470588235294, b: 0.156862745098039}, 5242 {name: '182', r: 0.976470588235294, g: 0.749019607843137, b: 0.756862745098039}, 5243 {name: '183', r: 0.988235294117647, g: 0.549019607843137, b: 0.6}, 5244 {name: '184', r: 0.988235294117647, g: 0.368627450980392, b: 0.447058823529412}, 5245 {name: '185', r: 0.909803921568627, g: 0.0666666666666667, b: 0.176470588235294}, 5246 {name: '185 2X', r: 0.819607843137255, g: 0.0862745098039216, b: 0}, 5247 {name: '186', r: 0.807843137254902, g: 0.0666666666666667, b: 0.149019607843137}, 5248 {name: '187', r: 0.686274509803922, g: 0.117647058823529, b: 0.176470588235294}, 5249 {name: '188', r: 0.486274509803922, g: 0.129411764705882, b: 0.156862745098039}, 5250 {name: '189', r: 1, g: 0.63921568627451, b: 0.698039215686274}, 5251 {name: '1895', r: 0.988235294117647, g: 0.749019607843137, b: 0.788235294117647}, 5252 {name: '190', r: 0.988235294117647, g: 0.458823529411765, b: 0.556862745098039}, 5253 {name: '1905', r: 0.988235294117647, g: 0.607843137254902, b: 0.698039215686274}, 5254 {name: '191', r: 0.956862745098039, g: 0.27843137254902, b: 0.419607843137255}, 5255 {name: '1915', r: 0.956862745098039, g: 0.329411764705882, b: 0.486274509803922}, 5256 {name: '192', r: 0.898039215686275, g: 0.0196078431372549, b: 0.227450980392157}, 5257 {name: '1925', r: 0.87843137254902, g: 0.0274509803921569, b: 0.27843137254902}, 5258 {name: '193', r: 0.768627450980392, g: 0, b: 0.262745098039216}, 5259 {name: '1935', r: 0.756862745098039, g: 0.0196078431372549, b: 0.219607843137255}, 5260 {name: '194', r: 0.6, g: 0.129411764705882, b: 0.207843137254902}, 5261 {name: '1945', r: 0.658823529411765, g: 0.0470588235294118, b: 0.207843137254902}, 5262 {name: '1955', r: 0.576470588235294, g: 0.0862745098039216, b: 0.219607843137255}, 5263 {name: '196', r: 0.980392156862745, g: 0.835294117647059, b: 0.882352941176471}, 5264 {name: '197', r: 0.964705882352941, g: 0.647058823529412, b: 0.745098039215686}, 5265 {name: '198', r: 0.937254901960784, g: 0.356862745098039, b: 0.517647058823529}, 5266 {name: '199', r: 0.627450980392157, g: 0.152941176470588, b: 0.294117647058824}, 5267 {name: '200', r: 0.768627450980392, g: 0.117647058823529, b: 0.227450980392157}, 5268 {name: '201', r: 0.63921568627451, g: 0.149019607843137, b: 0.219607843137255}, 5269 {name: '202', r: 0.549019607843137, g: 0.149019607843137, b: 0.2}, 5270 {name: '203', r: 0.949019607843137, g: 0.686274509803922, b: 0.756862745098039}, 5271 {name: '204', r: 0.929411764705882, g: 0.47843137254902, b: 0.619607843137255}, 5272 {name: '205', r: 0.898039215686275, g: 0.298039215686275, b: 0.486274509803922}, 5273 {name: '206', r: 0.827450980392157, g: 0.0196078431372549, b: 0.27843137254902}, 5274 {name: '207', r: 0.752941176470588, g: 0, b: 0.305882352941176}, 5275 {name: '208', r: 0.556862745098039, g: 0.137254901960784, b: 0.266666666666667}, 5276 {name: '209', r: 0.458823529411765, g: 0.149019607843137, b: 0.23921568627451}, 5277 {name: '210', r: 1, g: 0.627450980392157, b: 0.749019607843137}, 5278 {name: '211', r: 1, g: 0.466666666666667, b: 0.658823529411765}, 5279 {name: '212', r: 0.976470588235294, g: 0.309803921568627, b: 0.556862745098039}, 5280 {name: '213', r: 0.917647058823529, g: 0.0588235294117647, b: 0.419607843137255}, 5281 {name: '214', r: 0.8, g: 0.00784313725490196, b: 0.337254901960784}, 5282 {name: '215', r: 0.647058823529412, g: 0.0196078431372549, b: 0.266666666666667}, 5283 {name: '216', r: 0.486274509803922, g: 0.117647058823529, b: 0.247058823529412}, 5284 {name: '217', r: 0.956862745098039, g: 0.749019607843137, b: 0.819607843137255}, 5285 {name: '218', r: 0.929411764705882, g: 0.447058823529412, b: 0.666666666666667}, 5286 {name: '219', r: 0.886274509803922, g: 0.156862745098039, b: 0.509803921568627}, 5287 {name: '220', r: 0.666666666666667, g: 0, b: 0.309803921568627}, 5288 {name: '221', r: 0.576470588235294, g: 0, b: 0.258823529411765}, 5289 {name: '222', r: 0.43921568627451, g: 0.0980392156862745, b: 0.23921568627451}, 5290 {name: '223', r: 0.976470588235294, g: 0.576470588235294, b: 0.768627450980392}, 5291 {name: '224', r: 0.956862745098039, g: 0.419607843137255, b: 0.686274509803922},
5292 {name: '225', r: 0.929411764705882, g: 0.156862745098039, b: 0.576470588235294}, 5293 {name: '226', r: 0.83921568627451, g: 0.00784313725490196, b: 0.43921568627451}, 5294 {name: '227', r: 0.67843137254902, g: 0, b: 0.356862745098039}, 5295 {name: '228', r: 0.549019607843137, g: 0, b: 0.298039215686275}, 5296 {name: '229', r: 0.427450980392157, g: 0.129411764705882, b: 0.247058823529412}, 5297 {name: '230', r: 1, g: 0.627450980392157, b: 0.8}, 5298 {name: '231', r: 0.988235294117647, g: 0.43921568627451, b: 0.729411764705882}, 5299 {name: '232', r: 0.956862745098039, g: 0.247058823529412, b: 0.647058823529412}, 5300 {name: '233', r: 0.807843137254902, g: 0, b: 0.486274509803922}, 5301 {name: '234', r: 0.666666666666667, g: 0, b: 0.4}, 5302 {name: '235', r: 0.556862745098039, g: 0.0196078431372549, b: 0.329411764705882}, 5303 {name: '236', r: 0.976470588235294, g: 0.686274509803922, b: 0.827450980392157}, 5304 {name: '2365', r: 0.968627450980392, g: 0.768627450980392, b: 0.847058823529412}, 5305 {name: '237', r: 0.956862745098039, g: 0.517647058823529, b: 0.768627450980392}, 5306 {name: '2375', r: 0.917647058823529, g: 0.419607843137255, b: 0.749019607843137}, 5307 {name: '238', r: 0.929411764705882, g: 0.309803921568627, b: 0.686274509803922}, 5308 {name: '2385', r: 0.858823529411765, g: 0.156862745098039, b: 0.647058823529412}, 5309 {name: '239', r: 0.87843137254902, g: 0.129411764705882, b: 0.619607843137255}, 5310 {name: '2395', r: 0.768627450980392, g: 0, b: 0.549019607843137}, 5311 {name: '240', r: 0.768627450980392, g: 0.0588235294117647, b: 0.537254901960784}, 5312 {name: '2405', r: 0.658823529411765, g: 0, b: 0.47843137254902}, 5313 {name: '241', r: 0.67843137254902, g: 0, b: 0.458823529411765}, 5314 {name: '2415', r: 0.607843137254902, g: 0, b: 0.43921568627451}, 5315 {name: '242', r: 0.486274509803922, g: 0.109803921568627, b: 0.317647058823529}, 5316 {name: '2425', r: 0.529411764705882, g: 0, b: 0.356862745098039}, 5317 {name: '243', r: 0.949019607843137, g: 0.729411764705882, b: 0.847058823529412}, 5318 {name: '244', r: 0.929411764705882, g: 0.627450980392157, b: 0.827450980392157}, 5319 {name: '245', r: 0.909803921568627, g: 0.498039215686275, b: 0.788235294117647}, 5320 {name: '246', r: 0.8, g: 0, b: 0.627450980392157}, 5321 {name: '247', r: 0.717647058823529, g: 0, b: 0.556862745098039}, 5322 {name: '248', r: 0.63921568627451, g: 0.0196078431372549, b: 0.498039215686275}, 5323 {name: '249', r: 0.498039215686275, g: 0.156862745098039, b: 0.376470588235294}, 5324 {name: '250', r: 0.929411764705882, g: 0.768627450980392, b: 0.866666666666667}, 5325 {name: '251', r: 0.886274509803922, g: 0.619607843137255, b: 0.83921568627451}, 5326 {name: '252', r: 0.827450980392157, g: 0.419607843137255, b: 0.776470588235294}, 5327 {name: '253', r: 0.686274509803922, g: 0.137254901960784, b: 0.647058823529412}, 5328 {name: '254', r: 0.627450980392157, g: 0.176470588235294, b: 0.588235294117647}, 5329 {name: '255', r: 0.466666666666667, g: 0.176470588235294, b: 0.419607843137255}, 5330 {name: '256', r: 0.898039215686275, g: 0.768627450980392, b: 0.83921568627451}, 5331 {name: '2562', r: 0.847058823529412, g: 0.658823529411765, b: 0.847058823529412}, 5332 {name: '2563', r: 0.819607843137255, g: 0.627450980392157, b: 0.8}, 5333 {name: '2567', r: 0.749019607843137, g: 0.576470588235294, b: 0.8}, 5334 {name: '257', r: 0.827450980392157, g: 0.647058823529412, b: 0.788235294117647}, 5335 {name: '2572', r: 0.776470588235294, g: 0.529411764705882, b: 0.819607843137255}, 5336 {name: '2573', r: 0.729411764705882, g: 0.486274509803922, b: 0.737254901960784}, 5337 {name: '2577', r: 0.666666666666667, g: 0.447058823529412, b: 0.749019607843137}, 5338 {name: '258', r: 0.607843137254902, g: 0.309803921568627, b: 0.588235294117647}, 5339 {name: '2582', r: 0.666666666666667, g: 0.27843137254902, b: 0.729411764705882}, 5340 {name: '2583', r: 0.619607843137255, g: 0.309803921568627, b: 0.647058823529412}, 5341 {name: '2587', r: 0.556862745098039, g: 0.27843137254902, b: 0.67843137254902}, 5342 {name: '259', r: 0.447058823529412, g: 0.0862745098039216, b: 0.419607843137255}, 5343 {name: '2592', r: 0.576470588235294, g: 0.0588235294117647, b: 0.647058823529412},
5344 {name: '2593', r: 0.529411764705882, g: 0.168627450980392, b: 0.576470588235294}, 5345 {name: '2597', r: 0.4, g: 0, b: 0.549019607843137}, 5346 {name: '260', r: 0.407843137254902, g: 0.117647058823529, b: 0.356862745098039}, 5347 {name: '2602', r: 0.509803921568627, g: 0.0470588235294118, b: 0.556862745098039}, 5348 {name: '2603', r: 0.43921568627451, g: 0.0784313725490196, b: 0.47843137254902}, 5349 {name: '2607', r: 0.356862745098039, g: 0.00784313725490196, b: 0.47843137254902}, 5350 {name: '261', r: 0.368627450980392, g: 0.129411764705882, b: 0.329411764705882}, 5351 {name: '2612', r: 0.43921568627451, g: 0.117647058823529, b: 0.447058823529412}, 5352 {name: '2613', r: 0.4, g: 0.0666666666666667, b: 0.427450980392157}, 5353 {name: '2617', r: 0.337254901960784, g: 0.0470588235294118, b: 0.43921568627451}, 5354 {name: '262', r: 0.329411764705882, g: 0.137254901960784, b: 0.266666666666667}, 5355 {name: '2622', r: 0.376470588235294, g: 0.176470588235294, b: 0.349019607843137}, 5356 {name: '2623', r: 0.356862745098039, g: 0.0980392156862745, b: 0.368627450980392}, 5357 {name: '2627', r: 0.298039215686275, g: 0.0784313725490196, b: 0.368627450980392}, 5358 {name: '263', r: 0.87843137254902, g: 0.807843137254902, b: 0.87843137254902}, 5359 {name: '2635', r: 0.788235294117647, g: 0.67843137254902, b: 0.847058823529412}, 5360 {name: '264', r: 0.776470588235294, g: 0.666666666666667, b: 0.858823529411765}, 5361 {name: '2645', r: 0.709803921568627, g: 0.568627450980392, b: 0.819607843137255}, 5362 {name: '265', r: 0.588235294117647, g: 0.388235294117647, b: 0.768627450980392}, 5363 {name: '2655', r: 0.607843137254902, g: 0.427450980392157, b: 0.776470588235294}, 5364 {name: '266', r: 0.427450980392157, g: 0.156862745098039, b: 0.666666666666667}, 5365 {name: '2665', r: 0.537254901960784, g: 0.309803921568627, b: 0.749019607843137}, 5366 {name: '267', r: 0.349019607843137, g: 0.0666666666666667, b: 0.556862745098039}, 5367 {name: '268', r: 0.309803921568627, g: 0.129411764705882, b: 0.43921568627451}, 5368 {name: '2685', r: 0.337254901960784, g: 0, b: 0.549019607843137}, 5369 {name: '269', r: 0.266666666666667, g: 0.137254901960784, b: 0.349019607843137}, 5370 {name: '2695', r: 0.266666666666667, g: 0.137254901960784, b: 0.368627450980392}, 5371 {name: '270', r: 0.729411764705882, g: 0.686274509803922, b: 0.827450980392157}, 5372 {name: '2705', r: 0.67843137254902, g: 0.619607843137255, b: 0.827450980392157}, 5373 {name: '2706', r: 0.819607843137255, g: 0.807843137254902, b: 0.866666666666667}, 5374 {name: '2707', r: 0.749019607843137, g: 0.819607843137255, b: 0.898039215686275}, 5375 {name: '2708', r: 0.686274509803922, g: 0.737254901960784, b: 0.858823529411765}, 5376 {name: '271', r: 0.619607843137255, g: 0.568627450980392, b: 0.776470588235294}, 5377 {name: '2715', r: 0.576470588235294, g: 0.47843137254902, b: 0.8}, 5378 {name: '2716', r: 0.647058823529412, g: 0.627450980392157, b: 0.83921568627451}, 5379 {name: '2717', r: 0.647058823529412, g: 0.729411764705882, b: 0.87843137254902}, 5380 {name: '2718', r: 0.356862745098039, g: 0.466666666666667, b: 0.8}, 5381 {name: '272', r: 0.537254901960784, g: 0.466666666666667, b: 0.729411764705882}, 5382 {name: '2725', r: 0.447058823529412, g: 0.317647058823529, b: 0.737254901960784}, 5383 {name: '2726', r: 0.4, g: 0.337254901960784, b: 0.737254901960784}, 5384 {name: '2727', r: 0.368627450980392, g: 0.407843137254902, b: 0.768627450980392}, 5385 {name: '2728', r: 0.188235294117647, g: 0.266666666666667, b: 0.709803921568627}, 5386 {name: '273', r: 0.219607843137255, g: 0.0980392156862745, b: 0.47843137254902}, 5387 {name: '2735', r: 0.309803921568627, g: 0, b: 0.576470588235294}, 5388 {name: '2736', r: 0.286274509803922, g: 0.188235294117647, b: 0.67843137254902}, 5389 {name: '2738', r: 0.176470588235294, g: 0, b: 0.556862745098039}, 5390 {name: '274', r: 0.168627450980392, g: 0.0666666666666667, b: 0.4}, 5391 {name: '2745', r: 0.247058823529412, g: 0, b: 0.466666666666667}, 5392 {name: '2746', r: 0.247058823529412, g: 0.156862745098039, b: 0.576470588235294}, 5393 {name: '2747', r: 0.109803921568627, g: 0.0784313725490196, b: 0.419607843137255}, 5394 {name: '2748', r: 0.117647058823529, g: 0.109803921568627, b: 0.466666666666667}, 5395 {name: '275', r: 0.149019607843137, g: 0.0588235294117647, b: 0.32941176470
53955882}, 5396 {name: '2755', r: 0.207843137254902, g: 0, b: 0.427450980392157}, 5397 {name: '2756', r: 0.2, g: 0.156862745098039, b: 0.458823529411765}, 5398 {name: '2757', r: 0.0784313725490196, g: 0.0862745098039216, b: 0.329411764705882}, 5399 {name: '2758', r: 0.0980392156862745, g: 0.129411764705882, b: 0.407843137254902}, 5400 {name: '276', r: 0.168627450980392, g: 0.129411764705882, b: 0.27843137254902}, 5401 {name: '2765', r: 0.168627450980392, g: 0.0470588235294118, b: 0.337254901960784}, 5402 {name: '2766', r: 0.168627450980392, g: 0.149019607843137, b: 0.356862745098039}, 5403 {name: '2767', r: 0.0784313725490196, g: 0.129411764705882, b: 0.23921568627451}, 5404 {name: '2768', r: 0.0666666666666667, g: 0.129411764705882, b: 0.317647058823529}, 5405 {name: '277', r: 0.709803921568627, g: 0.819607843137255, b: 0.909803921568627}, 5406 {name: '278', r: 0.6, g: 0.729411764705882, b: 0.866666666666667}, 5407 {name: '279', r: 0.4, g: 0.537254901960784, b: 0.8}, 5408 {name: '280', r: 0, g: 0.168627450980392, b: 0.498039215686275}, 5409 {name: '281', r: 0, g: 0.156862745098039, b: 0.407843137254902}, 5410 {name: '282', r: 0, g: 0.149019607843137, b: 0.329411764705882}, 5411 {name: '283', r: 0.607843137254902, g: 0.768627450980392, b: 0.886274509803922}, 5412 {name: '284', r: 0.458823529411765, g: 0.666666666666667, b: 0.858823529411765}, 5413 {name: '285', r: 0.227450980392157, g: 0.458823529411765, b: 0.768627450980392}, 5414 {name: '286', r: 0, g: 0.219607843137255, b: 0.658823529411765}, 5415 {name: '287', r: 0, g: 0.219607843137255, b: 0.576470588235294}, 5416 {name: '288', r: 0, g: 0.2, b: 0.498039215686275}, 5417 {name: '289', r: 0, g: 0.149019607843137, b: 0.286274509803922}, 5418 {name: '290', r: 0.768627450980392, g: 0.847058823529412, b: 0.886274509803922}, 5419 {name: '2905', r: 0.576470588235294, g: 0.776470588235294, b: 0.87843137254902}, 5420 {name: '291', r: 0.658823529411765, g: 0.807843137254902, b: 0.886274509803922}, 5421 {name: '2915', r: 0.376470588235294, g: 0.686274509803922, b: 0.866666666666667}, 5422 {name: '292', r: 0.458823529411765, g: 0.698039215686274, b: 0.866666666666667}, 5423 {name: '2925', r: 0, g: 0.556862745098039, b: 0.83921568627451}, 5424 {name: '293', r: 0, g: 0.317647058823529, b: 0.729411764705882}, 5425 {name: '2935', r: 0, g: 0.356862745098039, b: 0.749019607843137}, 5426 {name: '294', r: 0, g: 0.247058823529412, b: 0.529411764705882}, 5427 {name: '2945', r: 0, g: 0.329411764705882, b: 0.627450980392157}, 5428 {name: '295', r: 0, g: 0.219607843137255, b: 0.419607843137255}, 5429 {name: '2955', r: 0, g: 0.23921568627451, b: 0.419607843137255}, 5430 {name: '296', r: 0, g: 0.176470588235294, b: 0.27843137254902}, 5431 {name: '2965', r: 0, g: 0.2, b: 0.298039215686275}, 5432 {name: '297', r: 0.509803921568627, g: 0.776470588235294, b: 0.886274509803922}, 5433 {name: '2975', r: 0.729411764705882, g: 0.87843137254902, b: 0.886274509803922}, 5434 {name: '298', r: 0.317647058823529, g: 0.709803921568627, b: 0.87843137254902}, 5435 {name: '2985', r: 0.317647058823529, g: 0.749019607843137, b: 0.886274509803922}, 5436 {name: '299', r: 0, g: 0.63921568627451, b: 0.866666666666667}, 5437 {name: '2995', r: 0, g: 0.647058823529412, b: 0.858823529411765}, 5438 {name: '300', r: 0, g: 0.447058823529412, b: 0.776470588235294}, 5439 {name: '3005', r: 0, g: 0.517647058823529, b: 0.788235294117647}, 5440 {name: '301', r: 0, g: 0.356862745098039, b: 0.6}, 5441 {name: '3015', r: 0, g: 0.43921568627451, b: 0.619607843137255}, 5442 {name: '302', r: 0, g: 0.309803921568627, b: 0.427450980392157}, 5443 {name: '3025', r: 0, g: 0.329411764705882, b: 0.419607843137255}, 5444 {name: '303', r: 0, g: 0.247058823529412, b: 0.329411764705882}, 5445 {name: '3035', r: 0, g: 0.266666666666667, b: 0.329411764705882}, 5446 {name: '304', r: 0.647058823529412, g: 0.866666666666667, b: 0.886274509803922}, 5447 {name: '305', r: 0.43921568627451, g: 0.807843137254902, b: 0.886274509803922}, 5448 {name: '306', r: 0, g: 0.737254901960784, b: 0.886274509803922}, 5449 {name: '306 2X', r: 0, g: 0.63921568627451, b: 0.819607843137255}, 5450 {name: '307', r: 0, g: 0.47843137254902, b: 0.647058823529412}, 5451 {name: '308', r: 0, g: 0.376470588235294, b: 0.486274509803922}, 5452 {name: '309', r: 0, g: 0.247058823529412, b: 0.286274509803922}, 5453 {name: '310', r: 0.447058823529412, g: 0.819607843137255, b: 0.866666666666667}, 5454 {name: '3105', r: 0.498039215686275, g: 0.83921568627451, b: 0.858823529411765}, 5455 {name: '311', r: 0.156862745098039, g: 0.768627450980392, b: 0.847058823529412}, 5456 {name: '3115', r: 0.176470588235294, g: 0.776470588235294, b: 0.83921568627451}, 5457 {name: '312', r: 0, g: 0.67843137254902, b: 0.776470588235294}, 5458 {name: '3125', r: 0, g: 0.717647058823529, b: 0.776470588235294}, 5459 {name: '313', r: 0, g: 0.6, b: 0.709803921568627}, 5460 {name: '3135', r: 0, g: 0.607843137254902, b: 0.666666666666667}, 5461 {name: '314', r: 0, g: 0.509803921568627, b: 0.607843137254902}, 5462 {name: '3145', r: 0, g: 0.517647058823529, b: 0.556862745098039}, 5463 {name: '315', r: 0, g: 0.419607843137255, b: 0.466666666666667}, 5464 {name: '3155', r: 0, g: 0.427450980392157, b: 0.458823529411765}, 5465 {name: '316', r: 0, g: 0.286274509803922, b: 0.309803921568627}, 5466 {name: '3165', r: 0, g: 0.337254901960784, b: 0.356862745098039}, 5467 {name: '317', r: 0.788235294117647, g: 0.909803921568627, b: 0.866666666666667},
5468 {name: '318', r: 0.576470588235294, g: 0.866666666666667, b: 0.858823529411765}, 5469 {name: '319', r: 0.298039215686275, g: 0.807843137254902, b: 0.819607843137255}, 5470 {name: '320', r: 0, g: 0.619607843137255, b: 0.627450980392157}, 5471 {name: '320 2X', r: 0, g: 0.498039215686275, b: 0.509803921568627}, 5472 {name: '321', r: 0, g: 0.529411764705882, b: 0.537254901960784}, 5473 {name: '322', r: 0, g: 0.447058823529412, b: 0.447058823529412}, 5474 {name: '323', r: 0, g: 0.4, b: 0.388235294117647}, 5475 {name: '324', r: 0.666666666666667, g: 0.866666666666667, b: 0.83921568627451}, 5476 {name: '3242', r: 0.529411764705882, g: 0.866666666666667, b: 0.819607843137255}, 5477 {name: '3245', r: 0.549019607843137, g: 0.87843137254902, b: 0.819607843137255}, 5478 {name: '3248', r: 0.47843137254902, g: 0.827450980392157, b: 0.756862745098039}, 5479 {name: '325', r: 0.337254901960784, g: 0.788235294117647, b: 0.756862745098039}, 5480 {name: '3252', r: 0.337254901960784, g: 0.83921568627451, b: 0.788235294117647}, 5481 {name: '3255', r: 0.27843137254902, g: 0.83921568627451, b: 0.756862745098039}, 5482 {name: '3258', r: 0.207843137254902, g: 0.768627450980392, b: 0.686274509803922}, 5483 {name: '326', r: 0, g: 0.698039215686274, b: 0.666666666666667}, 5484 {name: '3262', r: 0, g: 0.756862745098039, b: 0.709803921568627}, 5485 {name: '3265', r: 0, g: 0.776470588235294, b: 0.698039215686274}, 5486 {name: '3268', r: 0, g: 0.686274509803922, b: 0.6}, 5487 {name: '327', r: 0, g: 0.549019607843137, b: 0.509803921568627}, 5488 {name: '327 2X', r: 0, g: 0.537254901960784, b: 0.466666666666667}, 5489 {name: '3272', r: 0, g: 0.666666666666667, b: 0.619607843137255}, 5490 {name: '3275', r: 0, g: 0.698039215686274, b: 0.627450980392157}, 5491 {name: '3278', r: 0, g: 0.607843137254902, b: 0.517647058823529}, 5492 {name: '328', r: 0, g: 0.466666666666667, b: 0.43921568627451}, 5493 {name: '3282', r: 0, g: 0.549019607843137, b: 0.509803921568627}, 5494 {name: '3285', r: 0, g: 0.6, b: 0.529411764705882}, 5495 {name: '3288', r: 0, g: 0.509803921568627, b: 0.43921568627451}, 5496 {name: '329', r: 0, g: 0.427450980392157, b: 0.4}, 5497 {name: '3292', r: 0, g: 0.376470588235294, b: 0.337254901960784}, 5498 {name: '3295', r: 0, g: 0.509803921568627, b: 0.447058823529412}, 5499 {name: '3298', r: 0, g: 0.419607843137255, b: 0.356862745098039}, 5500 {name: '330', r: 0, g: 0.349019607843137, b: 0.317647058823529}, 5501 {name: '3302', r: 0, g: 0.286274509803922, b: 0.247058823529412}, 5502 {name: '3305', r: 0, g: 0.309803921568627, b: 0.258823529411765}, 5503 {name: '3308', r: 0, g: 0.266666666666667, b: 0.219607843137255}, 5504 {name: '331', r: 0.729411764705882, g: 0.917647058823529, b: 0.83921568627451}, 5505 {name: '332', r: 0.627450980392157, g: 0.898039215686275, b: 0.807843137254902}, 5506 {name: '333', r: 0.368627450980392, g: 0.866666666666667, b: 0.756862745098039}, 5507 {name: '334', r: 0, g: 0.6, b: 0.486274509803922}, 5508 {name: '335', r: 0, g: 0.486274509803922, b: 0.4}, 5509 {name: '336', r: 0, g: 0.407843137254902, b: 0.329411764705882}, 5510 {name: '337', r: 0.607843137254902, g: 0.858823529411765, b: 0.756862745098039}, 5511 {name: '3375', r: 0.556862745098039, g: 0.886274509803922, b: 0.737254901960784}, 5512 {name: '338', r: 0.47843137254902, g: 0.819607843137255, b: 0.709803921568627}, 5513 {name: '3385', r: 0.329411764705882, g: 0.847058823529412, b: 0.658823529411765}, 5514 {name: '339', r: 0, g: 0.698039215686274, b: 0.549019607843137}, 5515 {name: '3395', r: 0, g: 0.788235294117647, b: 0.576470588235294}, 5516 {name: '340', r: 0, g: 0.6, b: 0.466666666666667}, 5517 {name: '3405', r: 0, g: 0.698039215686274, b: 0.47843137254902}, 5518 {name: '341', r: 0, g: 0.47843137254902, b: 0.368627450980392}, 5519 {name: '3415', r: 0, g: 0.486274509803922, b: 0.349019607843137}, 5520 {name: '342', r: 0, g: 0.419607843137255, b: 0.329411764705882}, 5521 {name: '3425', r: 0, g: 0.407843137254902, b: 0.27843137254902}, 5522 {name: '343', r: 0, g: 0.337254901960784, b: 0.247058823529412}, 5523 {name: '3435', r: 0.00784313725490196, g: 0.286274509803922, b: 0.188235294117647}, 5524 {name: '344', r: 0.709803921568627, g: 0.886274509803922, b: 0.749019607843137}, 5525 {name: '345', r: 0.588235294117647, g: 0.847058823529412, b: 0.686274509803922}, 5526 {name: '346', r: 0.43921568627451, g: 0.807843137254902, b: 0.607843137254902}, 5527 {name: '347', r: 0, g: 0.619607843137255, b: 0.376470588235294},
5528 {name: '348', r: 0, g: 0.529411764705882, b: 0.317647058823529}, 5529 {name: '349', r: 0, g: 0.419607843137255, b: 0.247058823529412}, 5530 {name: '350', r: 0.137254901960784, g: 0.309803921568627, b: 0.2}, 5531 {name: '351', r: 0.709803921568627, g: 0.909803921568627, b: 0.749019607843137}, 5532 {name: '352', r: 0.6, g: 0.898039215686275, b: 0.698039215686274}, 5533 {name: '353', r: 0.517647058823529, g: 0.886274509803922, b: 0.658823529411765}, 5534 {name: '354', r: 0, g: 0.717647058823529, b: 0.376470588235294}, 5535 {name: '355', r: 0, g: 0.619607843137255, b: 0.286274509803922}, 5536 {name: '356', r: 0, g: 0.47843137254902, b: 0.23921568627451}, 5537 {name: '357', r: 0.129411764705882, g: 0.356862745098039, b: 0.2}, 5538 {name: '358', r: 0.666666666666667, g: 0.866666666666667, b: 0.588235294117647}, 5539 {name: '359', r: 0.627450980392157, g: 0.858823529411765, b: 0.556862745098039}, 5540 {name: '360', r: 0.376470588235294, g: 0.776470588235294, b: 0.349019607843137}, 5541 {name: '361', r: 0.117647058823529, g: 0.709803921568627, b: 0.227450980392157}, 5542 {name: '362', r: 0.2, g: 0.619607843137255, b: 0.207843137254902}, 5543 {name: '363', r: 0.23921568627451, g: 0.556862745098039, b: 0.2}, 5544 {name: '364', r: 0.227450980392157, g: 0.466666666666667, b: 0.156862745098039}, 5545 {name: '365', r: 0.827450980392157, g: 0.909803921568627, b: 0.63921568627451}, 5546 {name: '366', r: 0.768627450980392, g: 0.898039215686275, b: 0.556862745098039}, 5547 {name: '367', r: 0.666666666666667, g: 0.866666666666667, b: 0.427450980392157}, 5548 {name: '368', r: 0.356862745098039, g: 0.749019607843137, b: 0.129411764705882}, 5549 {name: '368 2X', r: 0, g: 0.619607843137255, b: 0.0588235294117647}, 5550 {name: '369', r: 0.337254901960784, g: 0.666666666666667, b: 0.109803921568627}, 5551 {name: '370', r: 0.337254901960784, g: 0.556862745098039, b: 0.0784313725490196}, 5552 {name: '371', r: 0.337254901960784, g: 0.419607843137255, b: 0.129411764705882}, 5553 {name: '372', r: 0.847058823529412, g: 0.929411764705882, b: 0.588235294117647}, 5554 {name: '373', r: 0.807843137254902, g: 0.917647058823529, b: 0.509803921568627}, 5555 {name: '374', r: 0.729411764705882, g: 0.909803921568627, b: 0.376470588235294}, 5556 {name: '375', r: 0.549019607843137, g: 0.83921568627451, b: 0}, 5557 {name: '375 2X', r: 0.329411764705882, g: 0.737254901960784, b: 0}, 5558 {name: '376', r: 0.498039215686275, g: 0.729411764705882, b: 0}, 5559 {name: '377', r: 0.43921568627451, g: 0.576470588235294, b: 0.00784313725490196}, 5560 {name: '378', r: 0.337254901960784, g: 0.388235294117647, b: 0.0784313725490196}, 5561 {name: '379', r: 0.87843137254902, g: 0.917647058823529, b: 0.407843137254902}, 5562 {name: '380', r: 0.83921568627451, g: 0.898039215686275, b: 0.258823529411765}, 5563 {name: '381', r: 0.8, g: 0.886274509803922, b: 0.149019607843137}, 5564 {name: '382', r: 0.729411764705882, g: 0.847058823529412, b: 0.0392156862745098}, 5565 {name: '382 2X', r: 0.619607843137255, g: 0.768627450980392, b: 0}, 5566 {name: '383', r: 0.63921568627451, g: 0.686274509803922, b: 0.0274509803921569}, 5567 {name: '384', r: 0.576470588235294, g: 0.6, b: 0.0196078431372549}, 5568 {name: '385', r: 0.43921568627451, g: 0.43921568627451, b: 0.0784313725490196}, 5569 {name: '386', r: 0.909803921568627, g: 0.929411764705882, b: 0.376470588235294}, 5570 {name: '387', r: 0.87843137254902, g: 0.929411764705882, b: 0.266666666666667}, 5571 {name: '388', r: 0.83921568627451, g: 0.909803921568627, b: 0.0588235294117647}, 5572 {name: '389', r: 0.807843137254902, g: 0.87843137254902, b: 0.0274509803921569}, 5573 {name: '390', r: 0.729411764705882, g: 0.768627450980392, b: 0.0196078431372549}, 5574 {name: '391', r: 0.619607843137255, g: 0.619607843137255, b: 0.0274509803921569}, 5575 {name: '392', r: 0.517647058823529, g: 0.509803921568627, b: 0.0196078431372549}, 5576 {name: '393', r: 0.949019607843137, g: 0.937254901960784, b: 0.529411764705882}, 5577 {name: '3935', r: 0.949019607843137, g: 0.929411764705882, b: 0.427450980392157}, 5578 {name: '394', r: 0.917647058823529, g: 0.929411764705882, b: 0.207843137254902}, 5579 {name: '3945', r: 0.937254901960784, g: 0.917647058823529, b: 0.0274509803921569}, 5580 {name: '395', r: 0.898039215686275, g: 0.909803921568627, b: 0.0666666666666667},
5581 {name: '3955', r: 0.929411764705882, g: 0.886274509803922, b: 0.0666666666666667}, 5582 {name: '396', r: 0.87843137254902, g: 0.886274509803922, b: 0.0470588235294118}, 5583 {name: '3965', r: 0.909803921568627, g: 0.866666666666667, b: 0.0666666666666667}, 5584 {name: '397', r: 0.756862745098039, g: 0.749019607843137, b: 0.0392156862745098}, 5585 {name: '3975', r: 0.709803921568627, g: 0.658823529411765, b: 0.0470588235294118}, 5586 {name: '398', r: 0.686274509803922, g: 0.658823529411765, b: 0.0392156862745098}, 5587 {name: '3985', r: 0.6, g: 0.549019607843137, b: 0.0392156862745098}, 5588 {name: '399', r: 0.6, g: 0.556862745098039, b: 0.0274509803921569}, 5589 {name: '3995', r: 0.427450980392157, g: 0.376470588235294, b: 0.00784313725490196}, 5590 {name: '400', r: 0.819607843137255, g: 0.776470588235294, b: 0.709803921568627}, 5591 {name: '401', r: 0.756862745098039, g: 0.709803921568627, b: 0.647058823529412}, 5592 {name: '402', r: 0.686274509803922, g: 0.647058823529412, b: 0.576470588235294}, 5593 {name: '403', r: 0.6, g: 0.549019607843137, b: 0.486274509803922}, 5594 {name: '404', r: 0.509803921568627, g: 0.458823529411765, b: 0.4}, 5595 {name: '405', r: 0.419607843137255, g: 0.368627450980392, b: 0.309803921568627}, 5596 {name: '406', r: 0.807843137254902, g: 0.756862745098039, b: 0.709803921568627}, 5597 {name: '408', r: 0.658823529411765, g: 0.6, b: 0.549019607843137}, 5598 {name: '409', r: 0.6, g: 0.537254901960784, b: 0.486274509803922}, 5599 {name: '410', r: 0.486274509803922, g: 0.427450980392157, b: 0.388235294117647}, 5600 {name: '411', r: 0.4, g: 0.349019607843137, b: 0.298039215686275}, 5601 {name: '412', r: 0.23921568627451, g: 0.188235294117647, b: 0.156862745098039}, 5602 {name: '413', r: 0.776470588235294, g: 0.756862745098039, b: 0.698039215686274}, 5603 {name: '414', r: 0.709803921568627, g: 0.686274509803922, b: 0.627450980392157}, 5604 {name: '415', r: 0.63921568627451, g: 0.619607843137255, b: 0.549019607843137}, 5605 {name: '416', r: 0.556862745098039, g: 0.549019607843137, b: 0.47843137254902}, 5606 {name: '417', r: 0.466666666666667, g: 0.447058823529412, b: 0.388235294117647}, 5607 {name: '418', r: 0.376470588235294, g: 0.368627450980392, b: 0.309803921568627}, 5608 {name: '419', r: 0.156862745098039, g: 0.156862745098039, b: 0.129411764705882}, 5609 {name: '420', r: 0.819607843137255, g: 0.8, b: 0.749019607843137}, 5610 {name: '421', r: 0.749019607843137, g: 0.729411764705882, b: 0.686274509803922}, 5611 {name: '422', r: 0.686274509803922, g: 0.666666666666667, b: 0.63921568627451}, 5612 {name: '423', r: 0.588235294117647, g: 0.576470588235294, b: 0.556862745098039}, 5613 {name: '424', r: 0.509803921568627, g: 0.498039215686275, b: 0.466666666666667}, 5614 {name: '425', r: 0.376470588235294, g: 0.376470588235294, b: 0.356862745098039}, 5615 {name: '426', r: 0.168627450980392, g: 0.168627450980392, b: 0.156862745098039}, 5616 {name: '427', r: 0.866666666666667, g: 0.858823529411765, b: 0.819607843137255}, 5617 {name: '428', r: 0.819607843137255, g: 0.807843137254902, b: 0.776470588235294}, 5618 {name: '429', r: 0.67843137254902, g: 0.686274509803922, b: 0.666666666666667}, 5619 {name: '430', r: 0.568627450980392, g: 0.588235294117647, b: 0.576470588235294}, 5620 {name: '431', r: 0.4, g: 0.427450980392157, b: 0.43921568627451}, 5621 {name: '432', r: 0.266666666666667, g: 0.309803921568627, b: 0.317647058823529}, 5622 {name: '433', r: 0.188235294117647, g: 0.219607843137255, b: 0.227450980392157}, 5623 {name: '433 2X', r: 0.0392156862745098, g: 0.0470588235294118, b: 0.0666666666666667}, 5624 {name: '434', r: 0.87843137254902, g: 0.819607843137255, b: 0.776470588235294}, 5625 {name: '435', r: 0.827450980392157, g: 0.749019607843137, b: 0.717647058823529}, 5626 {name: '436', r: 0.737254901960784, g: 0.647058823529412, b: 0.619607843137255}, 5627 {name: '437', r: 0.549019607843137, g: 0.43921568627451, b: 0.419607843137255}, 5628 {name: '438', r: 0.349019607843137, g: 0.247058823529412, b: 0.23921568627451}, 5629 {name: '439', r: 0.286274509803922, g: 0.207843137254902, b: 0.2}, 5630 {name: '440', r: 0.247058823529412, g: 0.188235294117647, b: 0.168627450980392}, 5631 {name: '441', r: 0.819607843137255, g: 0.819607843137255, b: 0.776470588235294},
5632 {name: '442', r: 0.729411764705882, g: 0.749019607843137, b: 0.717647058823529}, 5633 {name: '443', r: 0.63921568627451, g: 0.658823529411765, b: 0.63921568627451}, 5634 {name: '444', r: 0.537254901960784, g: 0.556862745098039, b: 0.549019607843137}, 5635 {name: '445', r: 0.337254901960784, g: 0.349019607843137, b: 0.349019607843137}, 5636 {name: '446', r: 0.286274509803922, g: 0.298039215686275, b: 0.286274509803922}, 5637 {name: '447', r: 0.247058823529412, g: 0.247058823529412, b: 0.219607843137255}, 5638 {name: '448', r: 0.329411764705882, g: 0.27843137254902, b: 0.176470588235294}, 5639 {name: '4485', r: 0.376470588235294, g: 0.298039215686275, b: 0.0666666666666667}, 5640 {name: '449', r: 0.329411764705882, g: 0.27843137254902, b: 0.149019607843137}, 5641 {name: '4495', r: 0.529411764705882, g: 0.458823529411765, b: 0.188235294117647}, 5642 {name: '450', r: 0.376470588235294, g: 0.329411764705882, b: 0.168627450980392}, 5643 {name: '4505', r: 0.627450980392157, g: 0.568627450980392, b: 0.317647058823529}, 5644 {name: '451', r: 0.67843137254902, g: 0.627450980392157, b: 0.47843137254902}, 5645 {name: '4515', r: 0.737254901960784, g: 0.67843137254902, b: 0.458823529411765}, 5646 {name: '452', r: 0.768627450980392, g: 0.717647058823529, b: 0.588235294117647}, 5647 {name: '4525', r: 0.8, g: 0.749019607843137, b: 0.556862745098039}, 5648 {name: '453', r: 0.83921568627451, g: 0.8, b: 0.686274509803922}, 5649 {name: '4535', r: 0.858823529411765, g: 0.807843137254902, b: 0.647058823529412}, 5650 {name: '454', r: 0.886274509803922, g: 0.847058823529412, b: 0.749019607843137}, 5651 {name: '4545', r: 0.898039215686275, g: 0.858823529411765, b: 0.729411764705882}, 5652 {name: '455', r: 0.4, g: 0.337254901960784, b: 0.0784313725490196}, 5653 {name: '456', r: 0.6, g: 0.529411764705882, b: 0.0784313725490196}, 5654 {name: '457', r: 0.709803921568627, g: 0.607843137254902, b: 0.0470588235294118}, 5655 {name: '458', r: 0.866666666666667, g: 0.8, b: 0.419607843137255}, 5656 {name: '459', r: 0.886274509803922, g: 0.83921568627451, b: 0.486274509803922}, 5657 {name: '460', r: 0.917647058823529, g: 0.866666666666667, b: 0.588235294117647}, 5658 {name: '461', r: 0.929411764705882, g: 0.898039215686275, b: 0.67843137254902}, 5659 {name: '462', r: 0.356862745098039, g: 0.27843137254902, b: 0.137254901960784}, 5660 {name: '4625', r: 0.27843137254902, g: 0.137254901960784, b: 0.0666666666666667}, 5661 {name: '463', r: 0.458823529411765, g: 0.329411764705882, b: 0.149019607843137}, 5662 {name: '4635', r: 0.549019607843137, g: 0.349019607843137, b: 0.2}, 5663 {name: '464', r: 0.529411764705882, g: 0.376470588235294, b: 0.156862745098039}, 5664 {name: '464 2X', r: 0.43921568627451, g: 0.258823529411765, b: 0.0784313725490196}, 5665 {name: '4645', r: 0.698039215686274, g: 0.509803921568627, b: 0.376470588235294}, 5666 {name: '465', r: 0.756862745098039, g: 0.658823529411765, b: 0.458823529411765}, 5667 {name: '4655', r: 0.768627450980392, g: 0.6, b: 0.466666666666667}, 5668 {name: '466', r: 0.819607843137255, g: 0.749019607843137, b: 0.568627450980392}, 5669 {name: '4665', r: 0.847058823529412, g: 0.709803921568627, b: 0.588235294117647}, 5670 {name: '467', r: 0.866666666666667, g: 0.8, b: 0.647058823529412}, 5671 {name: '4675', r: 0.898039215686275, g: 0.776470588235294, b: 0.666666666666667}, 5672 {name: '468', r: 0.886274509803922, g: 0.83921568627451, b: 0.709803921568627}, 5673 {name: '4685', r: 0.929411764705882, g: 0.827450980392157, b: 0.737254901960784}, 5674 {name: '469', r: 0.376470588235294, g: 0.2, b: 0.0666666666666667}, 5675 {name: '4695', r: 0.317647058823529, g: 0.149019607843137, b: 0.109803921568627}, 5676 {name: '470', r: 0.607843137254902, g: 0.309803921568627, b: 0.0980392156862745}, 5677 {name: '4705', r: 0.486274509803922, g: 0.317647058823529, b: 0.23921568627451}, 5678 {name: '471', r: 0.737254901960784, g: 0.368627450980392, b: 0.117647058823529}, 5679 {name: '471 2X', r: 0.63921568627451, g: 0.266666666666667, b: 0.00784313725490196}, 5680 {name: '4715', r: 0.6, g: 0.43921568627451, b: 0.356862745098039}, 5681 {name: '472', r: 0.917647058823529, g: 0.666666666666667, b: 0.47843137254902}, 5682 {name: '4725', r: 0.709803921568627, g: 0.568627450980392, b: 0.486274509803922}, 5683 {name: '473', r: 0.956862745098039, g: 0.768627450980392, b: 0.627450980392157}, 5684 {name: '4735', r: 0.8, g: 0.686274509803922, b: 0.607843137254902}, 5685 {name: '474', r: 0.956862745098039, g: 0.8, b: 0.666666666666667},
5686 {name: '4745', r: 0.847058823529412, g: 0.749019607843137, b: 0.666666666666667}, 5687 {name: '475', r: 0.968627450980392, g: 0.827450980392157, b: 0.709803921568627}, 5688 {name: '4755', r: 0.886274509803922, g: 0.8, b: 0.729411764705882}, 5689 {name: '476', r: 0.349019607843137, g: 0.23921568627451, b: 0.168627450980392}, 5690 {name: '477', r: 0.388235294117647, g: 0.219607843137255, b: 0.149019607843137}, 5691 {name: '478', r: 0.47843137254902, g: 0.247058823529412, b: 0.156862745098039}, 5692 {name: '479', r: 0.686274509803922, g: 0.537254901960784, b: 0.43921568627451}, 5693 {name: '480', r: 0.827450980392157, g: 0.717647058823529, b: 0.63921568627451}, 5694 {name: '481', r: 0.87843137254902, g: 0.8, b: 0.729411764705882}, 5695 {name: '482', r: 0.898039215686275, g: 0.827450980392157, b: 0.756862745098039}, 5696 {name: '483', r: 0.419607843137255, g: 0.188235294117647, b: 0.129411764705882}, 5697 {name: '484', r: 0.607843137254902, g: 0.188235294117647, b: 0.109803921568627}, 5698 {name: '485', r: 0.847058823529412, g: 0.117647058823529, b: 0.0196078431372549}, 5699 {name: '485 2X', r: 0.8, g: 0.0470588235294118, b: 0}, 5700 {name: '486', r: 0.929411764705882, g: 0.619607843137255, b: 0.517647058823529}, 5701 {name: '487', r: 0.937254901960784, g: 0.709803921568627, b: 0.627450980392157}, 5702 {name: '488', r: 0.949019607843137, g: 0.768627450980392, b: 0.686274509803922}, 5703 {name: '489', r: 0.949019607843137, g: 0.819607843137255, b: 0.749019607843137}, 5704 {name: '490', r: 0.356862745098039, g: 0.149019607843137, b: 0.149019607843137}, 5705 {name: '491', r: 0.458823529411765, g: 0.156862745098039, b: 0.156862745098039}, 5706 {name: '492', r: 0.568627450980392, g: 0.2, b: 0.219607843137255}, 5707 {name: '494', r: 0.949019607843137, g: 0.67843137254902, b: 0.698039215686274}, 5708 {name: '495', r: 0.956862745098039, g: 0.737254901960784, b: 0.749019607843137}, 5709 {name: '496', r: 0.968627450980392, g: 0.788235294117647, b: 0.776470588235294}, 5710 {name: '497', r: 0.317647058823529, g: 0.156862745098039, b: 0.149019607843137}, 5711 {name: '4975', r: 0.266666666666667, g: 0.117647058823529, b: 0.109803921568627}, 5712 {name: '498', r: 0.427450980392157, g: 0.2, b: 0.168627450980392}, 5713 {name: '4985', r: 0.517647058823529, g: 0.286274509803922, b: 0.286274509803922}, 5714 {name: '499', r: 0.47843137254902, g: 0.219607843137255, b: 0.176470588235294}, 5715 {name: '4995', r: 0.647058823529412, g: 0.419607843137255, b: 0.427450980392157}, 5716 {name: '500', r: 0.807843137254902, g: 0.537254901960784, b: 0.549019607843137}, 5717 {name: '5005', r: 0.737254901960784, g: 0.529411764705882, b: 0.529411764705882}, 5718 {name: '501', r: 0.917647058823529, g: 0.698039215686274, b: 0.698039215686274}, 5719 {name: '5015', r: 0.847058823529412, g: 0.67843137254902, b: 0.658823529411765}, 5720 {name: '502', r: 0.949019607843137, g: 0.776470588235294, b: 0.768627450980392}, 5721 {name: '5025', r: 0.886274509803922, g: 0.737254901960784, b: 0.717647058823529}, 5722 {name: '503', r: 0.956862745098039, g: 0.819607843137255, b: 0.8}, 5723 {name: '5035', r: 0.929411764705882, g: 0.807843137254902, b: 0.776470588235294}, 5724 {name: '504', r: 0.317647058823529, g: 0.117647058823529, b: 0.149019607843137}, 5725 {name: '505', r: 0.4, g: 0.117647058823529, b: 0.168627450980392}, 5726 {name: '506', r: 0.47843137254902, g: 0.149019607843137, b: 0.219607843137255}, 5727 {name: '507', r: 0.847058823529412, g: 0.537254901960784, b: 0.607843137254902}, 5728 {name: '508', r: 0.909803921568627, g: 0.647058823529412, b: 0.686274509803922}, 5729 {name: '509', r: 0.949019607843137, g: 0.729411764705882, b: 0.749019607843137}, 5730 {name: '510', r: 0.956862745098039, g: 0.776470588235294, b: 0.788235294117647}, 5731 {name: '511', r: 0.376470588235294, g: 0.129411764705882, b: 0.266666666666667}, 5732 {name: '5115', r: 0.309803921568627, g: 0.129411764705882, b: 0.227450980392157}, 5733 {name: '512', r: 0.517647058823529, g: 0.129411764705882, b: 0.419607843137255}, 5734 {name: '5125', r: 0.458823529411765, g: 0.27843137254902, b: 0.376470588235294}, 5735 {name: '513', r: 0.619607843137255, g: 0.137254901960784, b: 0.529411764705882},
5736 {name: '5135', r: 0.576470588235294, g: 0.419607843137255, b: 0.498039215686275}, 5737 {name: '514', r: 0.847058823529412, g: 0.517647058823529, b: 0.737254901960784}, 5738 {name: '5145', r: 0.67843137254902, g: 0.529411764705882, b: 0.6}, 5739 {name: '515', r: 0.909803921568627, g: 0.63921568627451, b: 0.788235294117647}, 5740 {name: '5155', r: 0.8, g: 0.686274509803922, b: 0.717647058823529}, 5741 {name: '516', r: 0.949019607843137, g: 0.729411764705882, b: 0.827450980392157}, 5742 {name: '5165', r: 0.87843137254902, g: 0.788235294117647, b: 0.8}, 5743 {name: '517', r: 0.956862745098039, g: 0.8, b: 0.847058823529412}, 5744 {name: '5175', r: 0.909803921568627, g: 0.83921568627451, b: 0.819607843137255}, 5745 {name: '518', r: 0.317647058823529, g: 0.176470588235294, b: 0.266666666666667}, 5746 {name: '5185', r: 0.27843137254902, g: 0.156862745098039, b: 0.207843137254902}, 5747 {name: '519', r: 0.388235294117647, g: 0.188235294117647, b: 0.368627450980392}, 5748 {name: '5195', r: 0.349019607843137, g: 0.2, b: 0.266666666666667}, 5749 {name: '520', r: 0.43921568627451, g: 0.207843137254902, b: 0.447058823529412}, 5750 {name: '5205', r: 0.556862745098039, g: 0.407843137254902, b: 0.466666666666667}, 5751 {name: '521', r: 0.709803921568627, g: 0.549019607843137, b: 0.698039215686274}, 5752 {name: '5215', r: 0.709803921568627, g: 0.576470588235294, b: 0.607843137254902}, 5753 {name: '522', r: 0.776470588235294, g: 0.63921568627451, b: 0.756862745098039}, 5754 {name: '5225', r: 0.8, g: 0.67843137254902, b: 0.686274509803922}, 5755 {name: '523', r: 0.827450980392157, g: 0.717647058823529, b: 0.8}, 5756 {name: '5235', r: 0.866666666666667, g: 0.776470588235294, b: 0.768627450980392}, 5757 {name: '524', r: 0.886274509803922, g: 0.8, b: 0.827450980392157}, 5758 {name: '5245', r: 0.898039215686275, g: 0.827450980392157, b: 0.8}, 5759 {name: '525', r: 0.317647058823529, g: 0.149019607843137, b: 0.329411764705882}, 5760 {name: '5255', r: 0.207843137254902, g: 0.149019607843137, b: 0.309803921568627}, 5761 {name: '526', r: 0.407843137254902, g: 0.129411764705882, b: 0.47843137254902}, 5762 {name: '5265', r: 0.286274509803922, g: 0.23921568627451, b: 0.388235294117647}, 5763 {name: '527', r: 0.47843137254902, g: 0.117647058823529, b: 0.6}, 5764 {name: '5275', r: 0.376470588235294, g: 0.337254901960784, b: 0.466666666666667}, 5765 {name: '528', r: 0.686274509803922, g: 0.447058823529412, b: 0.756862745098039}, 5766 {name: '5285', r: 0.549019607843137, g: 0.509803921568627, b: 0.6}, 5767 {name: '529', r: 0.807843137254902, g: 0.63921568627451, b: 0.827450980392157}, 5768 {name: '5295', r: 0.698039215686274, g: 0.658823529411765, b: 0.709803921568627}, 5769 {name: '530', r: 0.83921568627451, g: 0.686274509803922, b: 0.83921568627451}, 5770 {name: '5305', r: 0.8, g: 0.756862745098039, b: 0.776470588235294}, 5771 {name: '531', r: 0.898039215686275, g: 0.776470588235294, b: 0.858823529411765}, 5772 {name: '5315', r: 0.858823529411765, g: 0.827450980392157, b: 0.827450980392157}, 5773 {name: '532', r: 0.207843137254902, g: 0.219607843137255, b: 0.258823529411765}, 5774 {name: '533', r: 0.207843137254902, g: 0.247058823529412, b: 0.356862745098039}, 5775 {name: '534', r: 0.227450980392157, g: 0.286274509803922, b: 0.447058823529412}, 5776 {name: '535', r: 0.607843137254902, g: 0.63921568627451, b: 0.717647058823529}, 5777 {name: '536', r: 0.67843137254902, g: 0.698039215686274, b: 0.756862745098039}, 5778 {name: '537', r: 0.768627450980392, g: 0.776470588235294, b: 0.807843137254902}, 5779 {name: '538', r: 0.83921568627451, g: 0.827450980392157, b: 0.83921568627451}, 5780 {name: '539', r: 0, g: 0.188235294117647, b: 0.286274509803922}, 5781 {name: '5395', r: 0.00784313725490196, g: 0.156862745098039, b: 0.227450980392157}, 5782 {name: '540', r: 0, g: 0.2, b: 0.356862745098039}, 5783 {name: '5405', r: 0.247058823529412, g: 0.376470588235294, b: 0.458823529411765}, 5784 {name: '541', r: 0, g: 0.247058823529412, b: 0.466666666666667}, 5785 {name: '5415', r: 0.376470588235294, g: 0.486274509803922, b: 0.549019607843137}, 5786 {name: '542', r: 0.4, g: 0.576470588235294, b: 0.737254901960784}, 5787 {name: '5425', r: 0.517647058823529, g: 0.6, b: 0.647058823529412},
5788 {name: '543', r: 0.576470588235294, g: 0.717647058823529, b: 0.819607843137255}, 5789 {name: '5435', r: 0.686274509803922, g: 0.737254901960784, b: 0.749019607843137}, 5790 {name: '544', r: 0.717647058823529, g: 0.8, b: 0.858823529411765}, 5791 {name: '5445', r: 0.768627450980392, g: 0.8, b: 0.8}, 5792 {name: '545', r: 0.768627450980392, g: 0.827450980392157, b: 0.866666666666667}, 5793 {name: '5455', r: 0.83921568627451, g: 0.847058823529412, b: 0.827450980392157}, 5794 {name: '546', r: 0.0470588235294118, g: 0.219607843137255, b: 0.266666666666667}, 5795 {name: '5463', r: 0, g: 0.207843137254902, b: 0.227450980392157}, 5796 {name: '5467', r: 0.0980392156862745, g: 0.219607843137255, b: 0.2}, 5797 {name: '547', r: 0, g: 0.247058823529412, b: 0.329411764705882}, 5798 {name: '5473', r: 0.149019607843137, g: 0.407843137254902, b: 0.427450980392157}, 5799 {name: '5477', r: 0.227450980392157, g: 0.337254901960784, b: 0.309803921568627}, 5800 {name: '548', r: 0, g: 0.266666666666667, b: 0.349019607843137}, 5801 {name: '5483', r: 0.376470588235294, g: 0.568627450980392, b: 0.568627450980392}, 5802 {name: '5487', r: 0.4, g: 0.486274509803922, b: 0.447058823529412}, 5803 {name: '549', r: 0.368627450980392, g: 0.6, b: 0.666666666666667}, 5804 {name: '5493', r: 0.549019607843137, g: 0.686274509803922, b: 0.67843137254902}, 5805 {name: '5497', r: 0.568627450980392, g: 0.63921568627451, b: 0.6}, 5806 {name: '550', r: 0.529411764705882, g: 0.686274509803922, b: 0.749019607843137}, 5807 {name: '5503', r: 0.666666666666667, g: 0.768627450980392, b: 0.749019607843137}, 5808 {name: '5507', r: 0.686274509803922, g: 0.729411764705882, b: 0.698039215686274}, 5809 {name: '551', r: 0.63921568627451, g: 0.756862745098039, b: 0.788235294117647}, 5810 {name: '5513', r: 0.807843137254902, g: 0.847058823529412, b: 0.819607843137255}, 5811 {name: '5517', r: 0.788235294117647, g: 0.807843137254902, b: 0.768627450980392}, 5812 {name: '552', r: 0.768627450980392, g: 0.83921568627451, b: 0.83921568627451}, 5813 {name: '5523', r: 0.83921568627451, g: 0.866666666666667, b: 0.83921568627451}, 5814 {name: '5527', r: 0.807843137254902, g: 0.819607843137255, b: 0.776470588235294}, 5815 {name: '553', r: 0.137254901960784, g: 0.266666666666667, b: 0.207843137254902}, 5816 {name: '5535', r: 0.129411764705882, g: 0.23921568627451, b: 0.188235294117647}, 5817 {name: '554', r: 0.0980392156862745, g: 0.368627450980392, b: 0.27843137254902}, 5818 {name: '5545', r: 0.309803921568627, g: 0.427450980392157, b: 0.368627450980392}, 5819 {name: '555', r: 0.0274509803921569, g: 0.427450980392157, b: 0.329411764705882}, 5820 {name: '5555', r: 0.466666666666667, g: 0.568627450980392, b: 0.509803921568627}, 5821 {name: '556', r: 0.47843137254902, g: 0.658823529411765, b: 0.568627450980392}, 5822 {name: '5565', r: 0.588235294117647, g: 0.666666666666667, b: 0.6}, 5823 {name: '557', r: 0.63921568627451, g: 0.756862745098039, b: 0.67843137254902}, 5824 {name: '5575', r: 0.686274509803922, g: 0.749019607843137, b: 0.67843137254902}, 5825 {name: '558', r: 0.717647058823529, g: 0.807843137254902, b: 0.737254901960784}, 5826 {name: '5585', r: 0.768627450980392, g: 0.807843137254902, b: 0.749019607843137}, 5827 {name: '559', r: 0.776470588235294, g: 0.83921568627451, b: 0.768627450980392}, 5828 {name: '5595', r: 0.847058823529412, g: 0.858823529411765, b: 0.8}, 5829 {name: '560', r: 0.168627450980392, g: 0.298039215686275, b: 0.247058823529412}, 5830 {name: '5605', r: 0.137254901960784, g: 0.227450980392157, b: 0.176470588235294}, 5831 {name: '561', r: 0.149019607843137, g: 0.4, b: 0.349019607843137}, 5832 {name: '5615', r: 0.329411764705882, g: 0.407843137254902, b: 0.337254901960784}, 5833 {name: '562', r: 0.117647058823529, g: 0.47843137254902, b: 0.427450980392157}, 5834 {name: '5625', r: 0.447058823529412, g: 0.517647058823529, b: 0.43921568627451}, 5835 {name: '563', r: 0.498039215686275, g: 0.737254901960784, b: 0.666666666666667}, 5836 {name: '5635', r: 0.619607843137255, g: 0.666666666666667, b: 0.6}, 5837 {name: '564', r: 0.0196078431372549, g: 0.43921568627451, b: 0.368627450980392}, 5838 {name: '5645', r: 0.737254901960784, g: 0.756862745098039, b: 0.698039215686274}, 5839 {name: '565', r: 0.737254901960784, g: 0.858823529411765, b: 0.8},
5840 {name: '5655', r: 0.776470588235294, g: 0.8, b: 0.729411764705882}, 5841 {name: '566', r: 0.819607843137255, g: 0.886274509803922, b: 0.827450980392157}, 5842 {name: '5665', r: 0.83921568627451, g: 0.83921568627451, b: 0.776470588235294}, 5843 {name: '567', r: 0.149019607843137, g: 0.317647058823529, b: 0.258823529411765}, 5844 {name: '568', r: 0, g: 0.447058823529412, b: 0.388235294117647}, 5845 {name: '569', r: 0, g: 0.529411764705882, b: 0.447058823529412}, 5846 {name: '570', r: 0.498039215686275, g: 0.776470588235294, b: 0.698039215686274}, 5847 {name: '571', r: 0.666666666666667, g: 0.858823529411765, b: 0.776470588235294}, 5848 {name: '572', r: 0.737254901960784, g: 0.886274509803922, b: 0.807843137254902}, 5849 {name: '573', r: 0.8, g: 0.898039215686275, b: 0.83921568627451}, 5850 {name: '574', r: 0.286274509803922, g: 0.349019607843137, b: 0.156862745098039}, 5851 {name: '5743', r: 0.247058823529412, g: 0.286274509803922, b: 0.149019607843137}, 5852 {name: '5747', r: 0.258823529411765, g: 0.27843137254902, b: 0.0862745098039216}, 5853 {name: '575', r: 0.329411764705882, g: 0.466666666666667, b: 0.188235294117647}, 5854 {name: '5753', r: 0.368627450980392, g: 0.4, b: 0.227450980392157}, 5855 {name: '5757', r: 0.419607843137255, g: 0.43921568627451, b: 0.168627450980392}, 5856 {name: '576', r: 0.376470588235294, g: 0.556862745098039, b: 0.227450980392157}, 5857 {name: '5763', r: 0.466666666666667, g: 0.486274509803922, b: 0.309803921568627}, 5858 {name: '5767', r: 0.549019607843137, g: 0.568627450980392, b: 0.309803921568627}, 5859 {name: '577', r: 0.709803921568627, g: 0.8, b: 0.556862745098039}, 5860 {name: '5773', r: 0.607843137254902, g: 0.619607843137255, b: 0.447058823529412}, 5861 {name: '5777', r: 0.666666666666667, g: 0.67843137254902, b: 0.458823529411765}, 5862 {name: '578', r: 0.776470588235294, g: 0.83921568627451, b: 0.627450980392157}, 5863 {name: '5783', r: 0.709803921568627, g: 0.709803921568627, b: 0.556862745098039}, 5864 {name: '5787', r: 0.776470588235294, g: 0.776470588235294, b: 0.6}, 5865 {name: '579', r: 0.788235294117647, g: 0.83921568627451, b: 0.63921568627451}, 5866 {name: '5793', r: 0.776470588235294, g: 0.776470588235294, b: 0.647058823529412}, 5867 {name: '5797', r: 0.827450980392157, g: 0.819607843137255, b: 0.666666666666667}, 5868 {name: '580', r: 0.847058823529412, g: 0.866666666666667, b: 0.709803921568627}, 5869 {name: '5803', r: 0.847058823529412, g: 0.83921568627451, b: 0.717647058823529}, 5870 {name: '5807', r: 0.87843137254902, g: 0.866666666666667, b: 0.737254901960784}, 5871 {name: '581', r: 0.376470588235294, g: 0.368627450980392, b: 0.0666666666666667}, 5872 {name: '5815', r: 0.286274509803922, g: 0.266666666666667, b: 0.0666666666666667}, 5873 {name: '582', r: 0.529411764705882, g: 0.537254901960784, b: 0.0196078431372549}, 5874 {name: '5825', r: 0.458823529411765, g: 0.43921568627451, b: 0.168627450980392}, 5875 {name: '583', r: 0.666666666666667, g: 0.729411764705882, b: 0.0392156862745098}, 5876 {name: '5835', r: 0.619607843137255, g: 0.6, b: 0.349019607843137}, 5877 {name: '584', r: 0.807843137254902, g: 0.83921568627451, b: 0.286274509803922}, 5878 {name: '5845', r: 0.698039215686274, g: 0.666666666666667, b: 0.43921568627451}, 5879 {name: '585', r: 0.858823529411765, g: 0.87843137254902, b: 0.419607843137255}, 5880 {name: '5855', r: 0.8, g: 0.776470588235294, b: 0.576470588235294}, 5881 {name: '586', r: 0.886274509803922, g: 0.898039215686275, b: 0.517647058823529}, 5882 {name: '5865', r: 0.83921568627451, g: 0.807843137254902, b: 0.63921568627451}, 5883 {name: '587', r: 0.909803921568627, g: 0.909803921568627, b: 0.607843137254902}, 5884 {name: '5875', r: 0.87843137254902, g: 0.858823529411765, b: 0.709803921568627}, 5885 {name: '600', r: 0.956862745098039, g: 0.929411764705882, b: 0.686274509803922}, 5886 {name: '601', r: 0.949019607843137, g: 0.929411764705882, b: 0.619607843137255}, 5887 {name: '602', r: 0.949019607843137, g: 0.917647058823529, b: 0.529411764705882}, 5888 {name: '603', r: 0.929411764705882, g: 0.909803921568627, b: 0.356862745098039}, 5889 {name: '604', r: 0.909803921568627, g: 0.866666666666667, b: 0.129411764705882}, 5890 {name: '605', r: 0.866666666666667, g: 0.807843137254902, b: 0.0666666666666667},
5891 {name: '606', r: 0.827450980392157, g: 0.749019607843137, b: 0.0666666666666667}, 5892 {name: '607', r: 0.949019607843137, g: 0.917647058823529, b: 0.737254901960784}, 5893 {name: '608', r: 0.937254901960784, g: 0.909803921568627, b: 0.67843137254902}, 5894 {name: '609', r: 0.917647058823529, g: 0.898039215686275, b: 0.588235294117647}, 5895 {name: '610', r: 0.886274509803922, g: 0.858823529411765, b: 0.447058823529412}, 5896 {name: '611', r: 0.83921568627451, g: 0.807843137254902, b: 0.286274509803922}, 5897 {name: '612', r: 0.768627450980392, g: 0.729411764705882, b: 0}, 5898 {name: '613', r: 0.686274509803922, g: 0.627450980392157, b: 0.0470588235294118}, 5899 {name: '614', r: 0.917647058823529, g: 0.886274509803922, b: 0.717647058823529}, 5900 {name: '615', r: 0.886274509803922, g: 0.858823529411765, b: 0.666666666666667}, 5901 {name: '616', r: 0.866666666666667, g: 0.83921568627451, b: 0.607843137254902}, 5902 {name: '617', r: 0.8, g: 0.768627450980392, b: 0.486274509803922}, 5903 {name: '618', r: 0.709803921568627, g: 0.666666666666667, b: 0.349019607843137}, 5904 {name: '619', r: 0.588235294117647, g: 0.549019607843137, b: 0.156862745098039}, 5905 {name: '620', r: 0.517647058823529, g: 0.466666666666667, b: 0.0666666666666667}, 5906 {name: '621', r: 0.847058823529412, g: 0.866666666666667, b: 0.807843137254902}, 5907 {name: '622', r: 0.756862745098039, g: 0.819607843137255, b: 0.749019607843137}, 5908 {name: '623', r: 0.647058823529412, g: 0.749019607843137, b: 0.666666666666667}, 5909 {name: '624', r: 0.498039215686275, g: 0.627450980392157, b: 0.549019607843137}, 5910 {name: '625', r: 0.356862745098039, g: 0.529411764705882, b: 0.447058823529412}, 5911 {name: '626', r: 0.129411764705882, g: 0.329411764705882, b: 0.247058823529412}, 5912 {name: '627', r: 0.0470588235294118, g: 0.188235294117647, b: 0.149019607843137}, 5913 {name: '628', r: 0.8, g: 0.886274509803922, b: 0.866666666666667}, 5914 {name: '629', r: 0.698039215686274, g: 0.847058823529412, b: 0.847058823529412}, 5915 {name: '630', r: 0.549019607843137, g: 0.8, b: 0.827450980392157}, 5916 {name: '631', r: 0.329411764705882, g: 0.717647058823529, b: 0.776470588235294}, 5917 {name: '632', r: 0, g: 0.627450980392157, b: 0.729411764705882}, 5918 {name: '633', r: 0, g: 0.498039215686275, b: 0.6}, 5919 {name: '634', r: 0, g: 0.4, b: 0.498039215686275}, 5920 {name: '635', r: 0.729411764705882, g: 0.87843137254902, b: 0.87843137254902}, 5921 {name: '636', r: 0.6, g: 0.83921568627451, b: 0.866666666666667}, 5922 {name: '637', r: 0.419607843137255, g: 0.788235294117647, b: 0.858823529411765}, 5923 {name: '638', r: 0, g: 0.709803921568627, b: 0.83921568627451}, 5924 {name: '639', r: 0, g: 0.627450980392157, b: 0.768627450980392}, 5925 {name: '640', r: 0, g: 0.549019607843137, b: 0.698039215686274}, 5926 {name: '641', r: 0, g: 0.47843137254902, b: 0.647058823529412}, 5927 {name: '642', r: 0.819607843137255, g: 0.847058823529412, b: 0.847058823529412}, 5928 {name: '643', r: 0.776470588235294, g: 0.819607843137255, b: 0.83921568627451}, 5929 {name: '644', r: 0.607843137254902, g: 0.686274509803922, b: 0.768627450980392}, 5930 {name: '645', r: 0.466666666666667, g: 0.588235294117647, b: 0.698039215686274}, 5931 {name: '646', r: 0.368627450980392, g: 0.509803921568627, b: 0.63921568627451}, 5932 {name: '647', r: 0.149019607843137, g: 0.329411764705882, b: 0.486274509803922}, 5933 {name: '648', r: 0, g: 0.188235294117647, b: 0.368627450980392}, 5934 {name: '649', r: 0.83921568627451, g: 0.83921568627451, b: 0.847058823529412}, 5935 {name: '650', r: 0.749019607843137, g: 0.776470588235294, b: 0.819607843137255}, 5936 {name: '651', r: 0.607843137254902, g: 0.666666666666667, b: 0.749019607843137}, 5937 {name: '652', r: 0.427450980392157, g: 0.529411764705882, b: 0.658823529411765}, 5938 {name: '653', r: 0.2, g: 0.337254901960784, b: 0.529411764705882}, 5939 {name: '654', r: 0.0588235294117647, g: 0.168627450980392, b: 0.356862745098039}, 5940 {name: '655', r: 0.0470588235294118, g: 0.109803921568627, b: 0.27843137254902}, 5941 {name: '656', r: 0.83921568627451, g: 0.858823529411765, b: 0.87843137254902}, 5942 {name: '657', r: 0.756862745098039, g: 0.788235294117647, b: 0.866666666666667}, 5943 {name: '658', r: 0.647058823529412, g: 0.686274509803922, b: 0.83921568627451}, 5944 {name: '659', r: 0.498039215686275, g: 0.549019607843137, b: 0.749
5944019607843137}, 5945 {name: '660', r: 0.349019607843137, g: 0.376470588235294, b: 0.658823529411765}, 5946 {name: '661', r: 0.176470588235294, g: 0.2, b: 0.556862745098039}, 5947 {name: '662', r: 0.0470588235294118, g: 0.0980392156862745, b: 0.458823529411765}, 5948 {name: '663', r: 0.886274509803922, g: 0.827450980392157, b: 0.83921568627451}, 5949 {name: '664', r: 0.847058823529412, g: 0.8, b: 0.819607843137255}, 5950 {name: '665', r: 0.776470588235294, g: 0.709803921568627, b: 0.768627450980392}, 5951 {name: '666', r: 0.658823529411765, g: 0.576470588235294, b: 0.67843137254902}, 5952 {name: '667', r: 0.498039215686275, g: 0.4, b: 0.537254901960784}, 5953 {name: '668', r: 0.4, g: 0.286274509803922, b: 0.458823529411765}, 5954 {name: '669', r: 0.27843137254902, g: 0.168627450980392, b: 0.349019607843137}, 5955 {name: '670', r: 0.949019607843137, g: 0.83921568627451, b: 0.847058823529412}, 5956 {name: '671', r: 0.937254901960784, g: 0.776470588235294, b: 0.827450980392157}, 5957 {name: '672', r: 0.917647058823529, g: 0.666666666666667, b: 0.768627450980392}, 5958 {name: '673', r: 0.87843137254902, g: 0.549019607843137, b: 0.698039215686274}, 5959 {name: '674', r: 0.827450980392157, g: 0.419607843137255, b: 0.619607843137255}, 5960 {name: '675', r: 0.737254901960784, g: 0.219607843137255, b: 0.466666666666667}, 5961 {name: '676', r: 0.627450980392157, g: 0, b: 0.329411764705882}, 5962 {name: '677', r: 0.929411764705882, g: 0.83921568627451, b: 0.83921568627451}, 5963 {name: '678', r: 0.917647058823529, g: 0.8, b: 0.807843137254902}, 5964 {name: '679', r: 0.898039215686275, g: 0.749019607843137, b: 0.776470588235294}, 5965 {name: '680', r: 0.827450980392157, g: 0.619607843137255, b: 0.686274509803922}, 5966 {name: '681', r: 0.717647058823529, g: 0.447058823529412, b: 0.556862745098039}, 5967 {name: '682', r: 0.627450980392157, g: 0.317647058823529, b: 0.458823529411765}, 5968 {name: '683', r: 0.498039215686275, g: 0.156862745098039, b: 0.309803921568627}, 5969 {name: '684', r: 0.937254901960784, g: 0.8, b: 0.807843137254902}, 5970 {name: '685', r: 0.917647058823529, g: 0.749019607843137, b: 0.768627450980392}, 5971 {name: '686', r: 0.87843137254902, g: 0.666666666666667, b: 0.729411764705882}, 5972 {name: '687', r: 0.788235294117647, g: 0.537254901960784, b: 0.619607843137255}, 5973 {name: '688', r: 0.698039215686274, g: 0.4, b: 0.517647058823529}, 5974 {name: '689', r: 0.576470588235294, g: 0.258823529411765, b: 0.4}, 5975 {name: '690', r: 0.43921568627451, g: 0.137254901960784, b: 0.258823529411765}, 5976 {name: '691', r: 0.937254901960784, g: 0.819607843137255, b: 0.788235294117647}, 5977 {name: '692', r: 0.909803921568627, g: 0.749019607843137, b: 0.729411764705882}, 5978 {name: '693', r: 0.858823529411765, g: 0.658823529411765, b: 0.647058823529412}, 5979 {name: '694', r: 0.788235294117647, g: 0.549019607843137, b: 0.549019607843137}, 5980 {name: '695', r: 0.698039215686274, g: 0.419607843137255, b: 0.43921568627451}, 5981 {name: '696', r: 0.556862745098039, g: 0.27843137254902, b: 0.286274509803922}, 5982 {name: '697', r: 0.498039215686275, g: 0.219607843137255, b: 0.227450980392157}, 5983 {name: '698', r: 0.968627450980392, g: 0.819607843137255, b: 0.8}, 5984 {name: '699', r: 0.968627450980392, g: 0.749019607843137, b: 0.749019607843137}, 5985 {name: '700', r: 0.949019607843137, g: 0.647058823529412, b: 0.666666666666667}, 5986 {name: '701', r: 0.909803921568627, g: 0.529411764705882, b: 0.556862745098039}, 5987 {name: '702', r: 0.83921568627451, g: 0.376470588235294, b: 0.427450980392157}, 5988 {name: '703', r: 0.717647058823529, g: 0.219607843137255, b: 0.266666666666667}, 5989 {name: '704', r: 0.619607843137255, g: 0.156862745098039, b: 0.156862745098039}, 5990 {name: '705', r: 0.976470588235294, g: 0.866666666666667, b: 0.83921568627451}, 5991 {name: '706', r: 0.988235294117647, g: 0.788235294117647, b: 0.776470588235294}, 5992 {name: '707', r: 0.988235294117647, g: 0.67843137254902, b: 0.686274509803922}, 5993 {name: '708', r: 0.976470588235294, g: 0.556862745098039, b: 0.6}, 5994 {name: '709', r: 0.949019607843137, g: 0.407843137254902, b: 0.466666666666667}, 5995 {name: '710', r: 0.87843137254902, g: 0.258823529411765, b: 0.317647058823529}, 5996 {name: '711', r: 0.819607843137255, g: 0.176470588235294, b: 0.2}, 5997 {name: '712', r: 1, g: 0.827450980392157, b: 0.666666666666667}, 5998 {name: '713', r: 0.976470588235294, g: 0.788235294117647, b: 0.63921568627451},
5999 {name: '714', r: 0.976470588235294, g: 0.729411764705882, b: 0.509803921568627}, 6000 {name: '715', r: 0.988235294117647, g: 0.619607843137255, b: 0.286274509803922}, 6001 {name: '716', r: 0.949019607843137, g: 0.517647058823529, b: 0.0666666666666667}, 6002 {name: '717', r: 0.827450980392157, g: 0.427450980392157, b: 0}, 6003 {name: '718', r: 0.749019607843137, g: 0.356862745098039, b: 0}, 6004 {name: '719', r: 0.956862745098039, g: 0.819607843137255, b: 0.686274509803922}, 6005 {name: '720', r: 0.937254901960784, g: 0.768627450980392, b: 0.619607843137255}, 6006 {name: '721', r: 0.909803921568627, g: 0.698039215686274, b: 0.509803921568627}, 6007 {name: '722', r: 0.819607843137255, g: 0.556862745098039, b: 0.329411764705882}, 6008 {name: '723', r: 0.729411764705882, g: 0.458823529411765, b: 0.188235294117647}, 6009 {name: '724', r: 0.556862745098039, g: 0.286274509803922, b: 0.0196078431372549}, 6010 {name: '725', r: 0.458823529411765, g: 0.219607843137255, b: 0.00784313725490196}, 6011 {name: '726', r: 0.929411764705882, g: 0.827450980392157, b: 0.709803921568627}, 6012 {name: '727', r: 0.886274509803922, g: 0.749019607843137, b: 0.607843137254902}, 6013 {name: '728', r: 0.827450980392157, g: 0.658823529411765, b: 0.486274509803922}, 6014 {name: '729', r: 0.756862745098039, g: 0.556862745098039, b: 0.376470588235294}, 6015 {name: '730', r: 0.666666666666667, g: 0.458823529411765, b: 0.247058823529412}, 6016 {name: '731', r: 0.447058823529412, g: 0.247058823529412, b: 0.0392156862745098}, 6017 {name: '732', r: 0.376470588235294, g: 0.2, b: 0.0392156862745098}, 6018 {name: '801', r: 0, g: 0.666666666666667, b: 0.8}, 6019 {name: '801 2X', r: 0, g: 0.537254901960784, b: 0.686274509803922}, 6020 {name: '802', r: 0.376470588235294, g: 0.866666666666667, b: 0.286274509803922}, 6021 {name: '802 2X', r: 0.109803921568627, g: 0.807843137254902, b: 0.156862745098039}, 6022 {name: '803', r: 1, g: 0.929411764705882, b: 0.219607843137255}, 6023 {name: '803 2X', r: 1, g: 0.847058823529412, b: 0.0862745098039216}, 6024 {name: '804', r: 1, g: 0.576470588235294, b: 0.219607843137255}, 6025 {name: '804 2X', r: 1, g: 0.498039215686275, b: 0.117647058823529}, 6026 {name: '805', r: 0.976470588235294, g: 0.349019607843137, b: 0.317647058823529}, 6027 {name: '805 2X', r: 0.976470588235294, g: 0.227450980392157, b: 0.168627450980392}, 6028 {name: '806', r: 1, g: 0, b: 0.576470588235294}, 6029 {name: '806 2X', r: 0.968627450980392, g: 0.00784313725490196, b: 0.486274509803922}, 6030 {name: '807', r: 0.83921568627451, g: 0, b: 0.619607843137255}, 6031 {name: '807 2X', r: 0.749019607843137, g: 0, b: 0.549019607843137}, 6032 {name: '808', r: 0, g: 0.709803921568627, b: 0.607843137254902}, 6033 {name: '808 2X', r: 0, g: 0.627450980392157, b: 0.529411764705882}, 6034 {name: '809', r: 0.866666666666667, g: 0.87843137254902, b: 0.0588235294117647}, 6035 {name: '809 2X', r: 0.83921568627451, g: 0.83921568627451, b: 0.0470588235294118}, 6036 {name: '810', r: 1, g: 0.8, b: 0.117647058823529}, 6037 {name: '810 2X', r: 1, g: 0.737254901960784, b: 0.129411764705882}, 6038 {name: '811', r: 1, g: 0.447058823529412, b: 0.27843137254902}, 6039 {name: '811 2X', r: 1, g: 0.329411764705882, b: 0.0862745098039216}, 6040 {name: '812', r: 0.988235294117647, g: 0.137254901960784, b: 0.4}, 6041 {name: '812 2X', r: 0.988235294117647, g: 0.0274509803921569, b: 0.309803921568627}, 6042 {name: '813', r: 0.898039215686275, g: 0, b: 0.6}, 6043 {name: '813 2X', r: 0.819607843137255, g: 0, b: 0.517647058823529}, 6044 {name: '814', r: 0.549019607843137, g: 0.376470588235294, b: 0.756862745098039}, 6045 {name: '814 2X', r: 0.43921568627451, g: 0.247058823529412, b: 0.686274509803922 }, 6046 { name: 'Black', r: 0, g: 0, b: 0 }, 6047 { name: 'White', r: 1, g: 1, b: 1 } 6048 ]; 6049});; 6050/** Class representing the Product Grid. */ 6051var ProductGrid = (function () { 6052 //Current indexes within quantity ranges 6053 var indexes = {}; 6054 //The product price grids 6055 var priceGrids = {}; 6056 //The product quantity ranges 6057 var quantityRanges = {}; 6058 //The selected quantity range 6059 var selectedQuantityRange = {}; 6060 6061 /** 6062 * Initialize the product grids and quantities in order to better extract grid data in a predicable format 6063 * @param {object} grids - The product pricing grids 6064 * @param {object} quantities - The product quantity ranges 6065 */ 6066 function initGrids(grids, quantities) { 6067 if (typeof (grids) !== 'undefined' && typeof (quantities) !== 'undefined') { 6068 priceGrids = grids; 6069 quantityRanges = quantities; 6070 6071 for (grid in priceGrids) { 6072 indexes[grid] = null; 6073 } 6074 } 6075 } 6076 6077 /** 6078 * Update the grid with a highlighted cell corresponding to the correct quantity range 6079 * @param {object} table - The target table to highlight cell 6080 * @param {number} decorationMethodId - The decoration method ID 6081 * @param {number} totalQuantityCount - The total quantity count 6082 */ 6083 function updateGrid(table, decorationMethodId, totalQuantityCount) { 6084 if (totalQuantityCount > 0) { 6085 //Filter passed in quantity ranges in an attempt to match the range with passed in quantity count 6086 selectedQuantityRange = quantityRanges[decorationMethodId].filter(function (value) { 6087 if ((totalQuantityCount >= value.QuantityFrom) && ((totalQuantityCount <= value.QuantityTo) || (!value.QuantityTo))) 6088 return value; 6089 })[0]; 6090 6091 if (typeof (selectedQuantityRange) !== 'undefined') { 6092 $(table).find('td').removeClass('bolded'); 6093 6094 if (table.hasClass('table-horizontal')) { 6095 $(table).find('td:nth-of-type(' + selectedQuantityRange.Index + ')').addClass('bolded'); 6096 } else if (table.hasClass('table-vertical')) { 6097 $(table).find('tr:nth-of-type(' + (selectedQuantityRange.Index + 1) + ') td').addClass('bolded'); 6098 } 6099 6100 if (indexes[decorationMethodId] != selectedQuantityRange.Index) { 6101 //Set the global index to the new index 6102 indexes[decorationMethodId] = selectedQuantityRange.Index; 6103 6104 if (table.hasClass('table-horizontal')) { 6105 //Highlight the cell once when the range changes 6106 $(table).find('td:nth-of-type(' + selectedQuantityRange.Index + ')').effect("highlight", { c
6106olor: '#333' }, 500); 6107 } else if (table.hasClass('table-vertical')) { 6108 //Highlight the cell once when the range changes 6109 $(table).find('tr:nth-of-type(' + (selectedQuantityRange.Index + 1) + ') td').effect("highlight", { color: '#333' }, 500); 6110 } 6111 } 6112 } else { 6113 indexes[decorationMethodId] = null; 6114 $(table).find('td').removeClass('bolded'); 6115 } 6116 } 6117 } 6118 6119 /** 6120 * Get the current price of the selected quantity range 6121 * @param {number} decorationMethodId - The decoration method ID 6122 * @param {array} gridIdArray - The grid ID array 6123 * @param {object} colourElement - The colour object 6124 * @return {number} The current price 6125 */ 6126 function getPrice(decorationMethodId, gridIdArray, colourElement) { 6127 var price = null; 6128 6129 if (typeof (selectedQuantityRange) !== 'undefined') { 6130 if (typeof (priceGrids[decorationMethodId]) !== 'undefined') { 6131 //Get possible grids for a chosen colour 6132 var colourGridIdArray = colourElement.length ? colourElement.data('grid-id').toString().split(',') : []; 6133 //Find intersecting grids between the colour and quantity, if any. There should only be one. 6134 var intersectingGrids = gridIdArray.filter(function (n) { 6135 return colourGridIdArray.indexOf(n) > -1; 6136 }); 6137 var gridId = intersectingGrids.length ? intersectingGrids[0] : 0; 6138 6139 if (typeof (priceGrids[decorationMethodId][gridId]) !== 'undefined') { 6140 //If the grid id key is defined, set the price to match the ListPrice of the selected quantity range index in a given decoration method 6141 price = priceGrids[decorationMethodId][gridId][0].Prices.filter(function (value) { 6142 if (selectedQuantityRange.Index == value.Index) 6143 return value; 6144 })[0].ListPrice; 6145 } else { 6146 //If not, simply look in the first price grid available in a given decoration method 6147 price = priceGrids[decorationMethodId][gridIdArray[0]][0].Prices.filter(function (value) { 6148 if (selectedQuantityRange.Index == value.Index) 6149 return value; 6150 })[0].ListPrice; 6151 } 6152 } 6153 } 6154 6155 return price; 6156 } 6157 6158 /** 6159 * Get the current setup charge of the selected quantity range 6160 * @param {number} decorationMethodId - The decoration method ID 6161 * @return {number} The current price 6162 */ 6163 function getSetupCharge(decorationMethodId) { 6164 var price = null; 6165 6166 if (typeof (selectedQuantityRange) !== 'undefined') { 6167 if (typeof (priceGrids[decorationMethodId]) !== 'undefined') { 6168 //Get the setup charge of the first grid available in a given decoration method 6169 price = priceGrids[decorationMethodId][Object.keys(priceGrids[decorationMethodId])[0]][0].SetupCharge; 6170 } 6171 } 6172 6173 return price; 6174 } 6175 6176 /** 6177 * Get maximum number of decoration colours for a given decoration method 6178 * @param {number} decorationMethodId - The decoration method ID 6179 * @return {number} The current price 6180 */ 6181 function getDecorationColourMax(decorationMethodId) { 6182 var max = 1; 6183 6184 if (typeof (selectedQuantityRange) !== 'undefined') { 6185 if (typeof (priceGrids[decorationMethodId][Object.keys(priceGrids[decorationMethodId])[0]]) !== 'undefined') { 6186 //Look in the first price grid available in a given decoration method to match the AdditionalCost of the selected quantity range index 6187 var additionalCost = (priceGrids[decorationMethodId][Object.keys(priceGrids[decorationMethodId])[0]][0].Prices.filter(function (value) { 6188 if (selectedQuantityRange.Index == value.Index) 6189 return value; 6190 })[0].AdditionalCost); 6191 6192 //Get the maximum CostIndex and set it as the max 6193 if (additionalCost.length) 6194 max = Math.max.apply(Math, additionalCost.map(function (value) { return value.CostIndex; })) 6195 } 6196 } 6197 6198 return max; 6199 } 6200 6201 /** 6202 * Get the decoration colour cost of a given colour in a given decoration method 6203 * @param {number} decorationMethodId - The decoration method ID 6204 * @param {number} index - The cost index 6205 * @return {number} The decoration colour cost 6206 */ 6207 function getDecorationColourCost(decorationMethodId, index) { 6208 var cost = null; 6209 6210 if (typeof (selectedQuantityRange) !== 'undefined') { 6211 if (typeof (priceGrids[decorationMethodId][Object.keys(priceGrids[decorationMethodId])[0]]) !== 'undefined') { 6212 //Look in the first price grid available in a given decoration method to match the Prices of the selected quantity range index 6213 var priceGrid = priceGrids[decorationMethodId][Object.keys(priceGrids[decorationMethodId])[0]][0].Prices.filter(function (value) { 6214 if (selectedQuantityRange.Index == value.Index) 6215 return value; 6216 }); 6217 6218 if (priceGrid.length) { 6219 //Find the cost index in the AdditionalCost array matching the index received
6220 var colourArr = priceGrid[0].AdditionalCost.filter(function (colour) { 6221 if (colour.CostIndex == index) 6222 return colour; 6223 }); 6224 6225 if (colourArr.length) 6226 cost = colourArr[0].Sell; 6227 } 6228 } 6229 } 6230 6231 return cost; 6232 } 6233 6234 /** 6235 * Get the decoration colour setup charge in a given decoration method 6236 * @param {number} decorationMethodId - The decoration method ID 6237 * @param {number} index - The cost index 6238 * @return {number} The decoration colour setup charge 6239 */ 6240 function getDecorationColourSetupCharge(decorationMethodId, index) { 6241 var setupCharge = null; 6242 6243 if (typeof (selectedQuantityRange) !== 'undefined') { 6244 if (typeof (priceGrids[decorationMethodId][Object.keys(priceGrids[decorationMethodId])[0]]) !== 'undefined') { 6245 //Look in the first price grid available in a given decoration method to match the Prices of the selected quantity range index 6246 var priceGrid = priceGrids[decorationMethodId][Object.keys(priceGrids[decorationMethodId])[0]][0].Prices.filter(function (value) { 6247 if (selectedQuantityRange.Index == value.Index) 6248 return value; 6249 }); 6250 6251 if (priceGrid.length) { 6252 //Find the cost index in the AdditionalCost array matching the index received 6253 var colourArr = priceGrid[0].AdditionalCost.filter(function (colour) { 6254 if (colour.CostIndex == index) 6255 return colour; 6256 }); 6257 6258 //If there is a match, set setupCharge to the SetupCharge property 6259 if (colourArr.length) 6260 setupCharge = colourArr[0].SetupCharge; 6261 } 6262 } 6263 } 6264 6265 return setupCharge; 6266 } 6267 6268 /** 6269 * Get the grid ID of a given colour in a given decoration method 6270 * @param {number} decorationMethodId - The decoration method ID 6271 * @param {number} colourId - The colour id 6272 * @return {number} The grid id of the colour 6273 */ 6274 function getColourGridId(decorationMethodId, colourId) { 6275 var id = null; 6276 6277 if (typeof (selectedQuantityRange) !== 'undefined') { 6278 if (typeof (priceGrids[decorationMethodId]) !== 'undefined') { 6279 if (typeof (colourId) !== 'undefined') { 6280 for (grid in priceGrids[decorationMethodId]) { 6281 //Look through all grids in a given decoration method 6282 priceGrids[decorationMethodId][grid].forEach(function (gridValue) { 6283 //If the colour is found in the grid that matches the passed in colour id 6284 var match = gridValue.Colors.filter(function (color) { 6285 if (color.Id == colourId) 6286 return color.Id; 6287 })[0]; 6288 6289 //Set the matched grid id 6290 if (match) { 6291 id = match['GridId']; 6292 } 6293 }); 6294 } 6295 } else { 6296 //If not, simply get the first grid ID available in a given decoration method 6297 id = priceGrids[decorationMethodId][Object.keys(priceGrids[decorationMethodId])[0]][0].GridId; 6298 } 6299 } 6300 } 6301 6302 return id; 6303 } 6304 6305 /** 6306 * Get the supported colours of a given decoration method 6307 * @param {number} decorationMethodId - The decoration method ID 6308 * @return {array} The array of colours 6309 */ 6310 function getDecorationMethodColours(decorationMethodId) { 6311 var colours = []; 6312 6313 if (typeof (selectedQuantityRange) !== 'undefined') { 6314 if (typeof (priceGrids[decorationMethodId]) !== 'undefined') { 6315 for (grid in priceGrids[decorationMethodId]) { 6316 //Look through all grids in a given decoration method and return all enabled colours 6317 var enabledColors = priceGrids[decorationMethodId][grid][0].Colors.filter(function (value) { 6318 if (value.Enabled) 6319 return value; 6320 }); 6321
6322 enabledColors.forEach(function (value) { 6323 var colour = []; 6324 6325 //If the colour is already in the colours array, get a reference to it 6326 colour = colours.filter(function (color) { 6327 return color.Id == value.Id; 6328 }); 6329 6330 //If we are editing a colour, make sure to append all possible grid IDs 6331 if (colour.length) { 6332 var gridIds = colour[0]['GridId'].toString().split(); 6333 gridIds.push(grid); 6334 colour[0]['GridId'] = gridIds.join(','); 6335 } else { 6336 //Set the grid id for each enabled colour to the current grid 6337 value['GridId'] = parseInt(grid); 6338 colours.push(value); 6339 } 6340 }); 6341 } 6342 } 6343 } 6344 6345 return colours; 6346 } 6347 6348 /** 6349 * Get the price grid HTML of a given decoration method 6350 * @param {number} decorationMethodId - The decoration method ID 6351 * @return {string} The price grid HTML 6352 */ 6353 function getGridHtml(decorationMethodId) { 6354 var source = $('#productPricingGrid').html(); 6355 var template = Handlebars.compile(source); 6356 var html = ''; 6357 6358 if (typeof (decorationMethodId) !== 'undefined') { 6359 //Pass in the selected grid and selected quantity range to the template 6360 var selectedMethodGrids = priceGrids[decorationMethodId]; 6361 var selectedQuantityRanges = quantityRanges[decorationMethodId]; 6362 6363 //Get the first grid available in the decoration method grids 6364 var firstGrid = Object.keys(selectedMethodGrids)[0]; 6365 var price = 0; 6366 //Get first list price in prices array 6367 if (selectedMethodGrids[firstGrid][0].hasOwnProperty('Prices') && selectedMethodGrids[firstGrid][0].Prices.length > 0) 6368 price = numeral().unformat(selectedMethodGrids[firstGrid][0].Prices[0].ListPrice); 6369 6370 html = template({ 6371 quantities: selectedQuantityRanges, 6372 comment: selectedMethodGrids[firstGrid][0].Comment, 6373 grids: selectedMethodGrids, 6374 hidePrice: (price > 0) ? false : true 6375 }); 6376 } 6377 6378 return html; 6379 } 6380 6381 /** 6382 * Get the vertical price grid HTML of a given decoration method 6383 * @param {number} decorationMethodId - The decoration method ID 6384 * @return {string} The price grid HTML 6385 */ 6386 function getVerticalGridHtml(decorationMethodId) { 6387 var source = $('#productPricingVerticalGrid').html(); 6388 var template = Handlebars.compile(source); 6389 var html = ''; 6390 6391 if (typeof (decorationMethodId) !== 'undefined') { 6392 //Pass in the selected grid and selected quantity range to the template 6393 var selectedMethodGrids = priceGrids[decorationMethodId]; 6394 var selectedQuantityRanges = quantityRanges[decorationMethodId]; 6395 6396 //Get the first grid available in the decoration method grids 6397 var firstGrid = Object.keys(selectedMethodGrids)[0]; 6398 var price = 0; 6399 //Get first list price in prices array 6400 if (selectedMethodGrids[firstGrid][0].hasOwnProperty('Prices') && selectedMethodGrids[firstGrid][0].Prices.length > 0) 6401 price = numeral().unformat(selectedMethodGrids[firstGrid][0].Prices[0].ListPrice); 6402 6403 //Return a custom data format for selected quantity ranges and leave price as an empty array 6404 var quantitiesPrices = selectedQuantityRanges.map(function (value) { 6405 return { 6406 QuantityFrom: value.QuantityFrom, 6407 QuantityTo: value.QuantityTo, 6408 Prices: [] 6409 } 6410 }); 6411 6412 //Loop through selected method grids and push the grid prices 6413 for (grid in selectedMethodGrids) { 6414 for (var i = 0; i < selectedMethodGrids[grid][0].Prices.length; i++) { 6415 if (typeof (quantitiesPrices[i]) !== 'undefined') { 6416 quantitiesPrices[i].Prices.push(selectedMethodGrids[grid][0].Prices[i]); 6417 } 6418 } 6419 } 6420 6421 html = template({ 6422 quantities: quantitiesPrices, 6423 comment: selectedMethodGrids[firstGrid][0].Comment, 6424 grids: selectedMethodGrids,
6425 hidePrice: (price > 0) ? false : true 6426 }); 6427 } 6428 6429 return html; 6430 } 6431 6432 /** 6433 * Get quantity range of a given selected decoration method 6434 * @param {number} decorationMethodId - The decoration method ID 6435 * @return {array} The quantity range array 6436 */ 6437 function getQuantityRange(decorationMethodId) { 6438 if (typeof (decorationMethodId) !== 'undefined') { 6439 return quantityRanges[decorationMethodId]; 6440 } 6441 6442 return []; 6443 } 6444 6445 /** 6446 * Get valid grid ids for selected colour 6447 * @param {number} decorationMethodId - The decoration method ID 6448 * @param {number} colourId - The colour ID 6449 * @return {object} The grid ids object 6450 */ 6451 function getColorEnabledGrids(decorationMethodId, colourId) { 6452 var gridIds = {}; 6453 6454 if (decorationMethodId && colourId) { 6455 for (grid in priceGrids[decorationMethodId]) { 6456 priceGrids[decorationMethodId][grid].forEach(function (gridValue) { 6457 //Loop through all grids in a given decoration method and attempt to match passed in colour in the Colors array 6458 var match = gridValue.Colors.filter(function (color) { 6459 if (color.Id == colourId) 6460 return color.Id; 6461 })[0]; 6462 6463 //If there is a match, create a new grid ID key with array as value and push the color 6464 if (match) { 6465 if (typeof (gridIds[grid]) === 'undefined') { 6466 gridIds[grid] = []; 6467 } 6468 6469 gridIds[grid].push(match['Id']) 6470 } 6471 }); 6472 } 6473 } 6474 return gridIds; 6475 } 6476 6477 return { 6478 InitGrids: function (grids, quantities) { 6479 initGrids(grids, quantities); 6480 }, 6481 GetQuantityRange: function (decorationMethodId) { 6482 return getQuantityRange(decorationMethodId); 6483 }, 6484 UpdateGrid: function (table, decorationMethodId, totalQuantityCount) { 6485 updateGrid(table, decorationMethodId, totalQuantityCount) 6486 }, 6487 GetPrice: function (decorationMethodId, gridIdArray, colourElement) { 6488 return getPrice(decorationMethodId, gridIdArray, colourElement); 6489 }, 6490 GetSetupCharge: function (decorationMethodId) { 6491 return getSetupCharge(decorationMethodId); 6492 }, 6493 GetGridHtml: function (decorationMethodId) { 6494 return getGridHtml(decorationMethodId); 6495 }, 6496 GetVerticalGridHtml: function (decorationMethodId) { 6497 return getVerticalGridHtml(decorationMethodId); 6498 }, 6499 GetDecorationColourMax: function (decorationMethodId) { 6500 return getDecorationColourMax(decorationMethodId); 6501 }, 6502 GetDecorationColourCost: function (decorationMethodId, index) { 6503 return getDecorationColourCost(decorationMethodId, index); 6504 }, 6505 GetDecorationColourSetupCharge: function (decorationMethodId, index) { 6506 return getDecorationColourSetupCharge(decorationMethodId, index); 6507 }, 6508 GetColourGridId: function (decorationMethodId, colourGridId) { 6509 return getColourGridId(decorationMethodId, colourGridId); 6510 }, 6511 GetDecorationMethodColours: function (decorationMethodId) { 6512 return getDecorationMethodColours(decorationMethodId); 6513 }, 6514 GetColorEnabledGrids: function (decorationMethodId, colourId) { 6515 return getColorEnabledGrids(decorationMethodId, colourId); 6516 } 6517 } 6518}());; 6519/** Class representing the Product Configure pages. */ 6520var ProductConfigure = (function () { 6521 //Reference to the product configure quantity grids 6522 var quantityGrids = []; 6523 //Reference to the product configure quantity count 6524 var currentQuantityCount = 0; 6525 //Reference to the selected colour label 6526 var selectedColourLabel = null; 6527 //Table representing the product configure total data 6528 var table = $("#product-config-total table"); 6529 //Reference to the current product config page 6530 var currentPage = 1; 6531 //Used to hold product parameters
6532 var productParams = {}; 6533 //Used to hold Product configure parameters 6534 var productConfigureParams = {}; 6535 //Used to load cart line items when editing an order item 6536 var productDisplayParams = {}; 6537 //Used to hold product price grids 6538 var priceGrids = {}; 6539 //Used to hold all validation rules for product config areas 6540 var validateRules = {}; 6541 //Used to hold references to all valid forms on product config pages 6542 var validForms = {}; 6543 //Used to hold product colours 6544 var coloursArr = []; 6545 //Default list of PMS colours 6546 var filteredDecorationColours = [{ "HexCode": "#000000", "Pms": "Black" }, { "HexCode": "#0038a8", "Pms": "286" }, { "HexCode": "#876028", "Pms": "464" }, { "HexCode": "#8c2633", "Pms": "202" }, { "HexCode": "#00bce2", "Pms": "306" }, { "HexCode": "#603311", "Pms": "469" }, { "HexCode": "#a09151", "Pms": "4505" }, { "HexCode": "#006847", "Pms": "3425" }, { "HexCode": "#ddcc6b", "Pms": "458" }, { "HexCode": "#009e49", "Pms": "355" }, { "HexCode": "#60dd49", "Pms": "802" }, { "HexCode": "#666d70", "Pms": "431" }, { "HexCode": "#75aadb", "Pms": "284" }, { "HexCode": "#afaaa3", "Pms": "422" }, { "HexCode": "#00386b", "Pms": "295" }, { "HexCode": "#f47c00", "Pms": "1505" }, { "HexCode": "#F3B6D2", "Pms": "165 2X" }, { "HexCode": "#ff0093", "Pms": "806" }, { "HexCode": "#fc8c99", "Pms": "183" }, { "HexCode": "#72166b", "Pms": "259" }, { "HexCode": "#8c60c1", "Pms": "814" }, { "HexCode": "#e8112d", "Pms": "185" }, { "HexCode": "#d81e05", "Pms": "485" }, { "HexCode": "#005bbf", "Pms": "2935" }, { "HexCode": "#e0dbb5", "Pms": "5875" }, { "HexCode": "#008789", "Pms": "321" }, { "HexCode": "#FFFFFF", "Pms": "White" }, { "HexCode": "#f9e814", "Pms": "102" }]; 6547 6548 /** 6549 * Initialize the product configure page 6550 * @param {object} params - The parameters passed in to properly initialize Product Configure 6551 */ 6552 function init(params) { 6553 if (typeof (params) !== 'undefined') { 6554 productParams = params; 6555 productConfigureParams.CurrentQuantity = []; 6556 6557 priceGrids = Main.GetFormattedPriceGrid(productParams.PriceGrids, productParams.Sizes); 6558 6559 if (productParams.hasOwnProperty('ProductId') && !isNaN(productParams.ProductId)) 6560 productConfigureParams.CurrentProductId = productParams.ProductId; 6561 //If product has sizes, populate current quantity array with correct size ids 6562 if ((productParams.hasOwnProperty('SizeId')) && (productParams.SizeId > 0) && (productParams.hasOwnProperty('Quantity')) && (productParams.Quantity > 0)) { 6563 productConfigureParams.CurrentQuantity.push( 6564 { 6565 Id: productParams.SizeId, 6566 Quantity: productParams.Quantity, 6567 GridId: productParams.GridId 6568 } 6569 ); 6570 //If no sizes available, size ID will be null 6571 } else if (productParams.hasOwnProperty('Quantity') && (productParams.Quantity > 0)) { 6572 productConfigureParams.CurrentQuantity.push( 6573 { 6574 Id: null, 6575 Quantity: productParams.Quantity, 6576 GridId: productParams.GridId 6577 } 6578 ); 6579 } 6580 if (productParams.hasOwnProperty('DecorationMethodId') && (productParams.DecorationMethodId > 0)) 6581 productConfigureParams.CurrentMethod = productParams.DecorationMethodId; 6582 if (productParams.hasOwnProperty('ColourId') && (productParams.ColourId > 0)) 6583 productConfigureParams.CurrentColour = productParams.ColourId; 6584 //If editing and cart items already found, display them 6585 if (productParams.hasOwnProperty('CartItems') && productParams.CartItems !== null) { 6586 initCartItems(productParams.CartItems); 6587 displayCartItems(productParams.CartItems); 6588 } 6589 if (productParams.hasOwnProperty('Colors') && productParam
6589s.Colors.length) 6590 coloursArr = productParams.Colors; 6591 } 6592 6593 //Output the HTML for the current page 6594 displayPageTemplate(currentPage); 6595 //Update the breadcrumb to save search parameters 6596 updateBreadcrumb(); 6597 6598 //If JS media queries are supported 6599 if (matchMedia) { 6600 //Match all viewports below 992px in width 6601 var smallMediaMatch = window.matchMedia("(max-width: 991px)"); 6602 //Subscribe smallWidthChange to match media 6603 smallMediaMatch.addListener(smallWidthChange); 6604 //Immediately call small width change with active settings 6605 smallWidthChange(smallMediaMatch); 6606 } 6607 } 6608 6609 /** 6610 * If user hasn't already selected the same product with same colour, get selected value of the custom control for product colour (which is not in a form) and set the original control with this value to ensure that it can be serialized in a form 6611 * @param {object} listItem - The link in the list item of the unordered list that was created for the custom control 6612 */ 6613 function selectProductSwatch(listItem) { 6614 if (typeof ($(listItem).data('id')) !== 'undefined' && Number.isInteger($(listItem).data('id'))) { 6615 var options = { 6616 callback: { 6617 done: function (response) { 6618 //If another product was found with the same colour 6619 if ((response.ItemId > 0) && (response.ItemId != productParams.ItemId)) { 6620 swal({ 6621 title: 'Duplicate Product', 6622 text: "There is a duplicate product in cart with the same colour. Would you like to load this product and edit it instead?", 6623 type: 'warning', 6624 showCancelButton: true, 6625 confirmButtonClass: 'swal2-confirm swal2-styled', 6626 cancelButtonClass: 'swal2-cancel swal2-styled' 6627 }).then(function () { 6628 //If the user clicks OK, edit the product that was found with the same colour 6629 location.href = '/product/configure/?productid=' + productConfigureParams.CurrentProductId + '&itemid=' + response.ItemId + '&edit=true'; 6630 }, function (dismiss) { 6631 }); 6632 } else { 6633 $(listItem).closest('ul').find('li > a').removeClass('active'); 6634 //Get the original form-friendly element that this custom control corresponds to 6635 var select = $(listItem).closest('ul').data('original-element'); 6636 //Set its value to the value that was clicked on the custom control 6637 $(select).val($(listItem).data('id')).change(); 6638 6639 //If the current product we are configuring only has a single quantity 6640 if ($('#product-config-quantity-form #single-quantity').length) { 6641 //Set the grid id to the passed in value 6642 $('#product-config-quantity-form #single-quantity').data('grid-id', $(listItem).data('grid-id')); 6643 6644 //Update quantity and totals 6645 ProductConfigure.SetQuantity($('#product-config-quantity-form input')); 6646 ProductConfigure.UpdateTotalColumn(ProductConfigureSteps.GetPageObj(1)); 6647 } 6648 6649 //Add colour to global product colour 6650 setColour($(listItem)); 6651 } 6652 }, 6653 fail: function () { 6654 // Throw an exception if the request failed. 6655 AsyncException({ 6656 ErrorType: 2, 6657 Message: 'An error occurred while attempting to check if product exists in selected swatch.' 6658 }); 6659 } 6660 }, 6661 params: { 6662 colourId: $(listItem).data('id'),
6663 productId: productConfigureParams.CurrentProductId 6664 }, 6665 method: 'GET' 6666 } 6667 6668 DataManager.process('Product', 'CheckColour', options); 6669 } 6670 } 6671 6672 /** 6673 * Sets the quantity values of the given product based on the quantity input group 6674 * @param {object} quantitiesObj - The input(s) corresponding to the entered quantities 6675 */ 6676 function setQuantity(quantitiesObj) { 6677 quantityGrids = []; 6678 currentQuantityCount = 0; 6679 6680 if ($(quantitiesObj).length) { 6681 $(quantitiesObj).each(function () { 6682 if (!isNaN($(this).val()) && $(this).val() > 0) { 6683 //Get the current grid id of given input 6684 var gridId = $(this).data('grid-id'); 6685 quantityGrids.push({ 6686 Id: parseInt($(this).attr('id')), 6687 Quantity: parseInt($(this).val()), 6688 GridId: parseInt(gridId) 6689 }); 6690 6691 //Add the value to current quantity count 6692 currentQuantityCount += parseInt($(this).val()); 6693 } 6694 }); 6695 } 6696 6697 var quantityRanges = ProductGrid.GetQuantityRange(getSelectedDecorationMethodId()); 6698 productConfigureParams.CurrentQuantity = quantityGrids; 6699 6700 if (quantityRanges.length > 0) { 6701 //Get the difference between the lowest quantity and the current quantity 6702 var difference = quantityRanges[0].QuantityFrom - currentQuantityCount; 6703 //If the user has exceeded the minimum quantity count, display the current quantity 6704 if (difference <= 0) 6705 $('#product-selected-quantity').html(currentQuantityCount + " item(s)"); 6706 } 6707 6708 //Redraw the product config pricing table 6709 $('#product-config-pricing-table').empty() 6710 .append(ProductGrid.GetGridHtml(getSelectedDecorationMethodId())) 6711 .append(ProductGrid.GetVerticalGridHtml(getSelectedDecorationMethodId())); 6712 //If there are any discount prices available, cross out the regular prices 6713 if (Main.GetDiscount() > 0) 6714 $('#product-config-pricing-table td span.regular-price').css('text-decoration', 'line-through'); 6715 6716 //Update the product grid with the current quantity 6717 ProductGrid.UpdateGrid($('#product-config-pricing-table table:visible'), getSelectedDecorationMethodId(), currentQuantityCount); 6718 } 6719 6720 /** 6721 * Sets the colour of the given product 6722 * @param {object} colourObj - Reference to the colour element 6723 */ 6724 function setColour(colourObj) { 6725 if (colourObj && colourObj.length) { 6726 selectedColourLabel = $(colourObj).data('label'); 6727 $('#product-config-colour-form select').val($(colourObj).data('id')); 6728 $(colourObj).addClass('active'); 6729 6730 productConfigureParams.CurrentColour = parseInt($(colourObj).data('id')); 6731 6732 var colors = $(colourObj).data('bg-color').split(","); 6733 var swatch; 6734 6735 //If more than 2 colours in list, display a dual tone swatch. If not, simply display a solid color 6736 if (colors.length > 1) { 6737 swatch = $('<span />', { 'class': 'swatch' }).css('background', 'linear-gradient(to bottom right, ' + colors[0] + ' 49%, ' + colors[1] + ' 51%)'); 6738 } else { 6739 swatch = $('<span />', { 'class': 'swatch' }).css('background-color', colors[0]); 6740 } 6741 6742 //Set the display text to the current colour 6743 $('#product-selected-colour').html( 6744 $('<div />', { 'class': 'product-colours' }).append( 6745 swatch, 6746 $('<span />', { 'class': 'swatch-title', 'text': selectedColourLabel }) 6747 ) 6748 ); 6749 6750 //Set the display text to the current colour in the total column 6751 $('.item-colour').each(function () { 6752 $(this).text(' ('+selectedColourLabel+')'); 6753 }); 6754 } else { 6755 //Reset all colour settings 6756 selectedColourLabel = null; 6757 $('#product-config-colour-form select').val('');
6758 productConfigureParams.CurrentColour = null; 6759 6760 $('#product-selected-colour').empty(); 6761 $('.item-colour').empty(); 6762 } 6763 6764 //Sets the quantity values of the given product based on the quantity input group 6765 setQuantity($('#product-config-quantity-form input')); 6766 //Validate form passed in based on custom predefined validation rules on a given page 6767 validateForms(['product-config-quantity-form']); 6768 //Update total column on product configure with current page config object 6769 updateTotalColumn(ProductConfigureSteps.GetPageObj(1)); 6770 } 6771 6772 /** 6773 * Update decoration colour based on serialized decoration colour form 6774 */ 6775 function updateDecorationColour() { 6776 productConfigureParams.CurrentDecorationColours = []; 6777 6778 //Get reference to checked values in product configure decoration colour form 6779 var decorationColoursArr = $('#product-config-decoration-colour-form input'); 6780 $(decorationColoursArr).each(function () { 6781 if ($(this).val()) { 6782 var selectedColour = ($(this).val() == 'White' || $(this).val() == 'Black') ? $(this).val() : 'PMS ' + $(this).val(); 6783 var selectedColourValue = $(this).val(); 6784 var selectedBgColour = $(this).data('bg-color'); 6785 6786 productConfigureParams.CurrentDecorationColours.push( 6787 { 6788 Pms: selectedColourValue, 6789 Color: selectedColour, 6790 BgColor: selectedBgColour 6791 } 6792 ); 6793 } 6794 }); 6795 6796 //If no product colours are present, re-append product colours container. If not, simply empty it 6797 if (!$('#product-decoration-selected-colour .product-colours').length) { 6798 $('#product-decoration-selected-colour').empty(); 6799 $('<div />', { 'class': 'product-colours' }).appendTo($('#product-decoration-selected-colour')); 6800 } else { 6801 $('#product-decoration-selected-colour .product-colours').empty(); 6802 } 6803 6804 //Append swatches to current decoration colour list 6805 productConfigureParams.CurrentDecorationColours.forEach(function (value) { 6806 $('<span />', { 'class': 'swatch' }).css('background-color',value.BgColor).appendTo($('#product-decoration-selected-colour .product-colours')); 6807 $('<span />', { 'class': 'swatch-title', 'text': value.Color }).appendTo('#product-decoration-selected-colour .product-colours'); 6808 }); 6809 } 6810 6811 /** 6812 * Add a decoration method for a given product 6813 * @param {object} methodObj - Reference to the method element 6814 */ 6815 function setMethod(methodObj) { 6816 if (typeof (methodObj) !== 'undefined') { 6817 var currentMethod = methodObj.data('label'); 6818 //Manually trigger the check event on the method element 6819 $(methodObj).iCheck('check'); 6820 productConfigureParams.CurrentMethod = parseInt(methodObj.val()); 6821 6822 //Hide the old decoration method image 6823 $('#product-config-decoration-method .decoration-method').hide(); 6824 //Show the new decoration method image 6825 $('#product-config-decoration-method .decoration-method[data-decoration-id="' + methodObj.val() + '"]').show(); 6826 6827 if (typeof (currentMethod) !== 'undefined') 6828 $('#product-selected-method').text(currentMethod); 6829 else 6830 $('#product-selected-method').empty(); 6831 } 6832 } 6833 6834 /** 6835 * Add a decoration location for a given product 6836 * @param {object} locationObj - Reference to the location element 6837 */ 6838 function setLocation(locationObj) { 6839 if (typeof (locationObj) !== 'undefined') { 6840 var selectedLocation = locationObj.data('label'); 6841 //Manually trigger the check event on the location element 6842 $(locationObj).iCheck('check'); 6843 productConfigureParams.CurrentLocation = parseInt(locationObj.val()); 6844 6845 if (typeof (selectedLocation) !== 'undefined') 6846 $('#product-selected-location').text(selectedLocation); 6847 else 6848 $('#product-selected-location').empty(); 6849 } 6850 } 6851 6852 /** 6853 * Add decoration artwork for a given product 6854 * @param {object} artworkObj - Reference to the artwork element 6855 */ 6856 function setArtwork(artworkObj) { 6857 if (typeof (artworkObj) !== 'undefined') { 6858 var currentArtwork = artworkObj.data('label'); 6859 //Manually trigger the check event on the artwork element 6860 $(artworkObj).iCheck('check');
6861 productConfigureParams.CurrentArtwork = parseInt(artworkObj.val()); 6862 6863 if (typeof (currentArtwork) !== 'undefined') 6864 $('#product-selected-artwork').text(currentArtwork); 6865 else 6866 $('#product-selected-artwork').empty(); 6867 } 6868 } 6869 6870 /** 6871 * Set artwork file based on passed in file options object 6872 * @param {object} fileObj - A object with file options 6873 */ 6874 function setArtworkFile(fileObj) { 6875 if (typeof (fileObj) !== 'undefined') { 6876 productConfigureParams.CurrentArtworkFile = fileObj; 6877 } 6878 } 6879 6880 /** 6881 * Add comments for artwork options 6882 * @param {string} comments - A comment string 6883 */ 6884 function setComments(comments) { 6885 if (comments.length) { 6886 $('#product-config-comments-form #comments').val(comments); 6887 6888 productConfigureParams.CurrentComments = comments; 6889 } 6890 } 6891 6892 /** 6893 * Update and display a given product configuration page 6894 * @param {number} page - Page number 6895 */ 6896 function changePage(page) { 6897 currentPage = page; 6898 //Set all pages beyond next page to disabled 6899 updateDisabledPages(); 6900 6901 //Remove done class on each list item in progress bar 6902 $('.product-config-progress > li').each(function () { 6903 $(this).removeClass('done'); 6904 }); 6905 //If we are on any page besides the first... 6906 if (currentPage > 1) { 6907 //Add done class to all steps prior to the previous page on the progress bar 6908 for (var i = currentPage; i > 0; i--) 6909 $('.product-config-progress > li').eq(i - 1).attr('class', 'done'); 6910 } 6911 6912 $('.product-config-progress > li').each(function () { 6913 //Remove active class from all steps in progress bar 6914 if ($(this).hasClass('active')) 6915 $(this).removeClass('active'); 6916 }); 6917 //Set the active class on the current step in progress bar 6918 $('.product-config-progress > li').eq((currentPage - 1)).attr('class', 'active'); 6919 //Set the product config content to the HTML response 6920 displayPageTemplate(currentPage); 6921 6922 //Call the JavaScript for this specific page 6923 ProductConfigureSteps.UpdateJS(page); 6924 } 6925 6926 /** 6927 * Update the product config progress bar and add disabled class to all pages beyond the next page 6928 */ 6929 function updateDisabledPages() { 6930 $('.product-config-progress li a').each(function () { 6931 if ($(this).data('page') >= (currentPage + 2)) { 6932 $(this).parent().addClass('disabled'); 6933 } else { 6934 $(this).parent().removeClass('disabled'); 6935 } 6936 }); 6937 } 6938 6939 /** 6940 * Update product configure total column 6941 * @param {object} obj - Object that includes form groups with page number and titles 6942 */ 6943 function updateTotalColumn(obj) { 6944 if (typeof (obj) !== 'undefined') { 6945 if (obj.forms.length) { 6946 var elements = []; 6947 var rowHtml = ""; 6948 var validForms = getValidForms(obj); 6949 6950 if (validForms.length) { 6951 for (var i = 0; i < obj.forms.length; i++) { 6952 //Loop through all the forms and set elements variable to serialized key/values pairs that are not empty 6953 elements = $('#' + obj.forms[i].name).serializeArray().filter(function (input) { 6954 if (input.value != '') 6955 return input; 6956 }); 6957 6958 //Return validated status of a particular form name 6959 if (getFormStatus(obj.forms[i].name)) { 6960 if (elements.length) { 6961 //Create a title and total row for a given form 6962 createTitleRow(obj); 6963 //Concatenate all total row HTML strings for the given form 6964 rowHtml += getTotalRows(obj.forms[i].name, elements, obj.page); 6965 } 6966 } 6967 } 6968 } else { 6969 //If current quantity is below minimum...remove both title row and data 6970 var nextTitle = $('#' + obj.rowTitle).nextAll('tr[id]').first(); 6971 6972 //Remove all titles and rows for the given form 6973 if ($('#' + obj.rowTitle).nextUntil(nextTitle, 'tr').andSelf().length) 6974 $('#' + obj.rowTitle).nextUntil(nextTitle, 'tr').andSelf().remove(); 6975 } 6976 6977 $(rowHtml).insertAfter('#' + obj.rowTitle); 6978 6979 //Update the total price of the order 6980 updateTotalPrice(); 6981 //Localize all relevant elements 6982 Main.LocalizePage(); 6983 } 6984 } 6985 } 6986 6987 /** 6988 * Update product configure total column 6989 */ 6990 function loadTotalColumn() { 6991 var rowHtml = ""; 6992 6993 for (var page in productDisplayParams) { 6994 //Get the given page object and create a title row 6995 var pageObj = ProductConfigureSteps.GetPageObj(page); 6996 //Create a title row for a given form 6997 createTitleRow(pageObj); 6998 6999 //Loop through all forms of the given page 7000 productDisplayParams[page].forEach(function (value) { 7001 //Concatenate all HTML for total rows for the given elements in a given form 7002 rowHtml += getTotalRows(value.form, value.elements, page); 7003 }); 7004 7005 //Insert total rows after the row title 7006 $(rowHtml).insertAfter('#' + pageObj.rowTitle); 7007 rowHtml = ""; 7008 } 7009 7010 //Display updated total price 7011 updateTotalPrice(); 7012 } 7013 7014 /** 7015 * Update total price 7016 */ 7017 function updateTotalPrice() { 7018 var currentTotal = 0; 7019 //Get all price values in the total column and unformat them into floating numbers 7020 var totalPrice = $(table).find('.product-price').map(function (key, value) { 7021 if (parseInt(numeral().unformat($(this).html()))) 7022 return numeral().unformat($(this).html()); 7023 }); 7024 if (totalPrice.length) 7025 //Add all those numbers together 7026 var currentTotal = $.makeArray(totalPrice).reduce(function (previousValue, currentValue) { 7027 return previousValue + currentValue; 7028 }); 7029 7030 //If the total is greater than 0, display it 7031 if (currentTotal > 0) 7032 $('#product-total').text(numeral(currentTotal).format('$0,0.00')); 7033 else 7034 $('#product-total').html("—"); 7035 } 7036 7037 /** 7038 * Get the size input HTML of a given decoration method 7039 * @param {number} decorationMethodId - The decoration method ID 7040 * @return {string} The HTML for the size input controls 7041 */ 7042 function getSizesHtml(decorationMethodId) { 7043 var source = $('#productSizes').html(); 7044 var template = Handlebars.compile(source); 7045 var html = ''; 7046 var singleGridId = ''; 7047 7048 if (typeof (decorationMethodId) !== 'undefined') { 7049 var sizeArr = []; 7050 7051 for (var grid in priceGrids[decorationMethodId]) { 7052 priceGrids[decorationMethodId][grid][0].Sizes.forEac
7052h(function (value) { 7053 //For each size, if not already present in the size array, push it 7054 if (!sizeArr.some(function(size) { 7055 return size.Id == value.Id 7056 })) { 7057 sizeArr.push(value); 7058 } else { 7059 //If the current size was found in the size array 7060 var record = sizeArr.find(function (size) { 7061 return size.Id == value.Id 7062 }); 7063 if (record) { 7064 //Get the grid IDs of the current size 7065 var currentGrids = record.GridId.toString(); 7066 //Get a grid ID array if more than one ID was found 7067 var gridIdArr = currentGrids.split(','); 7068 7069 //If the grid ID wasn't found in the grid ID array, push it 7070 if (gridIdArr.indexOf(value.GridId.toString()) == -1) 7071 gridIdArr.push(value.GridId); 7072 7073 //Set the grid ID in record to joined elements in gridIdArr 7074 record.GridId = gridIdArr.join(','); 7075 } 7076 } 7077 }); 7078 } 7079 7080 //If a current colour is present, set the single grid ID to that particular colour grid ID 7081 if (typeof (productConfigureParams.CurrentColour) !== 'undefined') 7082 singleGridId = ProductGrid.GetColourGridId(decorationMethodId, productConfigureParams.CurrentColour); 7083 else 7084 singleGridId = ProductGrid.GetColourGridId(decorationMethodId); 7085 7086 var html = template({ 7087 sizes: sizeArr, 7088 gridId: singleGridId 7089 }); 7090 } 7091 7092 return html; 7093 } 7094 7095 /** 7096 * Get the selected decoration method ID 7097 * @return {number} The selected decoration method ID 7098 */ 7099 function getSelectedDecorationMethodId() { 7100 var selectedDecorationMethod; 7101 7102 if (productParams.PriceGrids.length > 0) { 7103 //Search the available price grids and return the decoration method ID if default grid is set to true 7104 var defaultDecorationMethodId = productParams.PriceGrids.filter(function (value) { 7105 if (value.DefaultGrid) 7106 return value; 7107 })[0].DecorationMethodId; 7108 } 7109 7110 //If a current method is specified, set it. If not, get the default decoration method ID. 7111 selectedDecorationMethod = ((productConfigureParams.hasOwnProperty('CurrentMethod') && productConfigureParams.CurrentMethod > 0) ? productConfigureParams.CurrentMethod : defaultDecorationMethodId); 7112 7113 return selectedDecorationMethod; 7114 } 7115 7116 /** 7117 * Display the given product configure page template 7118 * @param {number} page - The page number 7119 */ 7120 function displayPageTemplate(page) { 7121 if (productParams.Decorations.Methods.length > 0) { 7122 //Get product config page template 7123 var source = (page != 1) ? $('#productConfigPage' + page).html() : $('#productConfigPage').html(); 7124 var template = Handlebars.compile(source); 7125 7126 var htmlObj = { 7127 colors: productParams.Colors, 7128 decorations: productParams.Decorations.Methods, 7129 edit: productParams.Edit 7130 }; 7131 7132 var selectedDecorationMethod = []; 7133 if (!isNaN(productConfigureParams.CurrentMethod)) { 7134 //Search passed in decoration methods and return the current method value 7135 selectedDecorationMethod = productParams.Decorations.Methods.filter(function (value) { 7136 if (value.Id == productConfigureParams.CurrentMethod) 7137 return value; 7138 }); 7139
7140 //Set the decoration colours to a sorted array of colours 7141 selectedDecorationMethod[0].decorationColours = sortColorsByHue(getFormattedColors(filteredDecorationColours)); 7142 //Set method to the returned decoration method 7143 htmlObj['method'] = selectedDecorationMethod 7144 } 7145 7146 var html = template(htmlObj); 7147 7148 $('#product-config-container').empty().append(html).hide().fadeIn(600); 7149 //Localize all relevant elements 7150 Main.LocalizePage(); 7151 //Remove all down states for total columns 7152 resetLineItemDownstates(); 7153 } 7154 } 7155 7156 /** 7157 * Populate the input values after the template has been output 7158 * @param {number} page - The page number 7159 */ 7160 function updatePageValues(page) { 7161 switch (page) { 7162 //Page 1 7163 case 1: 7164 //If current quantity exists, populate all quantity inputs 7165 if (productConfigureParams.hasOwnProperty('CurrentQuantity') && productConfigureParams.CurrentQuantity.length) { 7166 populateQuantityInputs(); 7167 } 7168 //If current colour exists, trigger a click event on that given colour 7169 if (productConfigureParams.hasOwnProperty('CurrentColour') && typeof(productConfigureParams.CurrentColour) !== 'undefined') { 7170 $('#product-colours ul li a[data-id=' + productConfigureParams.CurrentColour + ']').trigger('click'); 7171 } 7172 //If current method exists, set the method radio button to the current method 7173 if (productConfigureParams.hasOwnProperty('CurrentMethod') && typeof (productConfigureParams.CurrentMethod) !== 'undefined') { 7174 setMethod($('#product-config-method-form input[value=' + productConfigureParams.CurrentMethod + ']')); 7175 } 7176 break; 7177 //Page 2 7178 case 2: 7179 //If location exists, set the location radio button to the current location 7180 if (productConfigureParams.hasOwnProperty('CurrentLocation') && typeof (productConfigureParams.CurrentLocation) !== 'undefined') { 7181 setLocation($('#product-config-location-form input[value=' + productConfigureParams.CurrentLocation + ']')); 7182 } 7183 //If decoration colours exist, loop through them and set colours in the colour picker 7184 if (productConfigureParams.hasOwnProperty('CurrentDecorationColours') && productConfigureParams.CurrentDecorationColours.length) { 7185 var currentDecorationColours = productConfigureParams.CurrentDecorationColours; 7186 7187 for (var i = 0; i < currentDecorationColours.length; i++) { 7188 $('#product-config-decoration-colour-form input#color-picker-' + (i + 1)).colorpicker('setColor', currentDecorationColours[i].Pms); 7189 } 7190 } 7191 break; 7192 //Page 3 7193 case 3: 7194 //If artwork option exists, set the artwork radio button to the current artwork option 7195 if (productConfigureParams.hasOwnProperty('CurrentArtwork') && typeof (productConfigureParams.CurrentArtwork) !== 'undefined') { 7196 setArtwork($('#product-config-artwork-form input[value=' + productConfigureParams.CurrentArtwork + ']')); 7197 } else { 7198 setArtwork($('#product-config-artwork-form input:checked')); 7199 } 7200 if (productConfigureParams.hasOwnProperty('CurrentArtworkFile') && typeof (productConfigureParams.CurrentArtworkFile) !== 'undefined') { 7201 setArtworkFile(productConfigureParams.CurrentArtworkFile); 7202 7203 //Initialize existing file object 7204 var file = { 7205 name: productConfigureParams.CurrentArtworkFile.Filename, 7206 size: productConfigureParams.CurrentArtworkFile.Size,
7207 path: productParams.ArtworkPath 7208 }; 7209 7210 if ($("#upload-artwork").length) { 7211 //Create a dropzone for upload artwork element 7212 var thisDropzone = Dropzone.forElement("#upload-artwork"); 7213 7214 //Call the default addedfile event handler 7215 thisDropzone.emit("addedfile", file); 7216 //And optionally show the thumbnail of the file: 7217 thisDropzone.emit("thumbnail", file, file.path + file.name); 7218 thisDropzone.createThumbnailFromUrl(file, file.path + file.name, function () { }, true); 7219 //Call the complete event 7220 thisDropzone.emit("complete", file); 7221 } 7222 } 7223 //If the comment exists, set it 7224 if (productConfigureParams.hasOwnProperty('CurrentComments') && productConfigureParams.CurrentComments.length > 0) { 7225 setComments(productConfigureParams.CurrentComments); 7226 } 7227 break; 7228 } 7229 } 7230 7231 /** 7232 * When editing a product in your cart, ensure that product configure parameters are initialized with values from the cart item 7233 * @param {cartItems} cartItems - The items in your cart 7234 */ 7235 function initCartItems(cartItems) { 7236 var currentItem = cartItems[0]; 7237 7238 if (currentItem.hasOwnProperty('Id')) 7239 productConfigureParams.CurrentItemId = currentItem.Id; 7240 if (currentItem.hasOwnProperty('Quantities')) { 7241 productConfigureParams.CurrentQuantity = []; 7242 //Loop through all cart item quantities and push quantity objects 7243 for (var i = 0; i < currentItem.Quantities.length; i++) { 7244 productConfigureParams.CurrentQuantity.push( 7245 { 7246 Id: currentItem.Quantities[i].SizeId, 7247 Quantity: currentItem.Quantities[i].Quantity, 7248 GridId: currentItem.Quantities[i].GridId 7249 } 7250 ); 7251 } 7252 } 7253 if(currentItem.hasOwnProperty('ColourId')) 7254 productConfigureParams.CurrentColour = currentItem.ColourId; 7255 if (currentItem.hasOwnProperty('DecorationMethodId')) 7256 productConfigureParams.CurrentMethod = currentItem.DecorationMethodId; 7257 if (currentItem.hasOwnProperty('DecorationLocation')) 7258 productConfigureParams.CurrentLocation = currentItem.DecorationLocation.Id; 7259 if (currentItem.hasOwnProperty('DecorationColours')) { 7260 if (!productConfigureParams.hasOwnProperty('CurrentDecorationColours')) 7261 productConfigureParams.CurrentDecorationColours = []; 7262 7263 //Loop through all decoration colours and push decoration colour objects 7264 currentItem.DecorationColours.forEach(function (value) { 7265 productConfigureParams.CurrentDecorationColours.push( 7266 { 7267 Pms: value.Color.Pms, 7268 Color: 'PMS ' + value.Color.Label 7269 } 7270 ); 7271 }); 7272 } 7273 if (currentItem.hasOwnProperty('Comment')) 7274 productConfigureParams.CurrentComments = currentItem.Comment; 7275 //If the current item has an artwork file, set it and ensure that current artwork option is set to 1 (upload art) or 2 (contact me) 7276 if (currentItem.hasOwnProperty('ArtworkFile') && currentItem.ArtworkFile.Filename) { 7277 productConfigureParams.CurrentArtworkFile = currentItem.ArtworkFile; 7278 productConfigureParams.CurrentArtwork = 1; 7279 } else { 7280 productConfigureParams.CurrentArtwork = 2; 7281 } 7282 } 7283 7284 /** 7285 * Display total rows based on passed in values from cart item. Each display configuration object will follow a consistent pattern so that total rows can properly handle the values. 7286 * @param {cartItems} cartItems - The items in your cart 7287 */ 7288 function displayCartItems(cartItems) { 7289 var currentItem = cartItems[0]; 7290 //Get the number of pages available 7291 var pageCount = ProductConfigureSteps.GetPageCount(); 7292 7293 for (var i = 0; i < pageCount; i++) 7294 productDisplayParams[i + 1] = []; 7295 7296 if (currentItem.hasOwnProperty('Quantities')) { 7297 var elements = []; 7298 for (var i = 0; i < currentItem.Quantities.length; i++) { 7299 //Push a quantity object with name and value into elements 7300 elements.push({ 7301 "name": currentItem.Quantities[i].Size.Title.length ? currentItem.Quantities[i].Size.Title : "Quantity", 7302 "value": currentItem.Quantities[i].Quantity 7303 }); 7304 } 7305 7306 //For quantities, push an object with populated form class and form elements to display title and total rows 7307 productDisplayParams[1].push( 7308 { 7309 'form': 'product-config-quantity-form',
7310 'elements': elements 7311 }); 7312 } 7313 7314 if (currentItem.hasOwnProperty('DecorationMethodId')) { 7315 //For decoration method, push an object with populated form class and form elements to display title and total rows 7316 productDisplayParams[1].push({ 7317 'form': 'product-config-method-form', 7318 'elements': [ 7319 { 7320 "name": "Decoration Method", 7321 "value": currentItem.DecorationMethod.Title 7322 } 7323 ] 7324 }); 7325 } 7326 7327 if (currentItem.hasOwnProperty('DecorationLocation')) { 7328 //For decoration location, push an object with populated form class and form elements to display title and total rows 7329 productDisplayParams[2].push({ 7330 'form': 'product-config-location-form', 7331 'elements': [ 7332 { 7333 'name': "Location", 7334 'value': currentItem.DecorationLocation.Title 7335 } 7336 ] 7337 }); 7338 } 7339 7340 if (currentItem.hasOwnProperty('DecorationColours')) { 7341 var elements = []; 7342 //For each decoration colour, push an object with name and value 7343 for (var i = 0; i < currentItem.DecorationColours.length; i++) { 7344 elements.push({ 7345 "name": "decorationColours[]", 7346 "value": currentItem.DecorationColours[i].Colour.Title 7347 }); 7348 } 7349 7350 //For decoration colours, push an object with populated form class and form elements to display title and total rows 7351 productDisplayParams[2].push({ 7352 'form': 'product-config-decoration-colour-form', 7353 'elements': elements 7354 }); 7355 } 7356 7357 if (currentItem.hasOwnProperty('ArtworkFile')) { 7358 //For artwork file, push an object with populated form class and form elements to display title and total rows 7359 productDisplayParams[3].push({ 7360 'form': 'product-config-artwork-form', 7361 'elements': [ 7362 { 7363 'name': "Product Artwork", 7364 'value': (currentItem.ArtworkFile.Filename.length > 0) ? "Upload Art" : "Contact Me" 7365 } 7366 ] 7367 }); 7368 } 7369 } 7370 7371 /** 7372 * Populate product quantity inputs with existing values 7373 */ 7374 function populateQuantityInputs() { 7375 if (productConfigureParams.hasOwnProperty('CurrentQuantity') && typeof(productConfigureParams.CurrentQuantity) !== 'undefined') { 7376 if ($('#product-config-quantity-form input').length > 1) { 7377 if (productConfigureParams.CurrentQuantity.length) { 7378 //Loop through all quantities and set the value of each populated quantity 7379 for (var quantity in productConfigureParams.CurrentQuantity) { 7380 $('#product-config-quantity-form input[id="' + productConfigureParams.CurrentQuantity[quantity].Id + '"]').val(productConfigureParams.CurrentQuantity[quantity].Quantity); 7381 } 7382 } 7383 } else if ($('#product-config-quantity-form input').length == 1) { 7384 if (productConfigureParams.CurrentQuantity.length) { 7385 //Simply set the single input to the populated quantity 7386 $('#product-config-quantity-form input').val(productConfigureParams.CurrentQuantity[0].Quantity); 7387 //Used to revert value to a legal number (higher than the minimum quantity) 7388 $('#product-config-quantity-form input').data('current-value', productConfigureParams.CurrentQuantity[0].Quantity); 7389 } else { 7390 //If there are no populated quantities, get the minimum quantity from the price grid and set it 7391 if (typeof (Main.GetQuantityRanges(priceGrids)[getSelectedDecorationMethodId()] !== 'undefined')) { 7392 //Get the quantity range for the selected decoration method id 7393 var quantityRanges = Main.GetQuantityRanges(priceGrids)[getSelectedDecorationMethodId()]; 7394 7395 if(quantityRanges.length) { 7396 $('#product-config-quantity-form input').val(quantityRanges[0].QuantityFrom); 7397 //Used to revert value to a legal number (higher than the minimum quantity) 7398 $('#product-config-quantity-form input').data('current-value', quantityRanges[0].QuantityFrom); 7399 } 7400 } 7401 } 7402 } 7403 } 7404 } 7405 7406 /** 7407 * Validate all the forms passed in based on custom predefined validation rules on a given page 7408 * @param {array} formArr - The array of form elements 7409 * @param {number} page - The page number 7410 */ 7411 function validateForms(formArr, page) { 7412 //If validForms doesn't have a key for current page, create one 7413 if (typeof (validForms[currentPage]) === 'undefined') 7414 validForms[currentPage] = {}; 7415 7416 //Set local forms variable to passed in form array, or keys of validate rules object 7417 var forms = (typeof (page) === 'undefined') ? formArr : Object.keys(vali
7417dateRules[page]); 7418 7419 for (var i = 0; i < forms.length; i++) { 7420 //If a validation rules exist for this form 7421 if (typeof (validateRules[currentPage][forms[i]]) !== 'undefined') { 7422 //If there is no valid form key in valid forms, create one and initialize it to an empty array 7423 if (typeof (validForms[currentPage][forms[i]]) === 'undefined') 7424 validForms[currentPage][forms[i]] = []; 7425 7426 if ($('#' + forms[i]).length) { 7427 //Get a reference to the form to get at the validation rules 7428 var form = validateRules[currentPage][forms[i]]; 7429 for (var rule in form) { 7430 //If the given validation function returns false 7431 if (!form[rule].validateFunc()) { 7432 //Display the custom error for that rule 7433 form[rule].displayValidateError(); 7434 //Set the valid status to false 7435 validForms[currentPage][forms[i]] = false; 7436 break; 7437 } else { 7438 //Set the valid status to true 7439 validForms[currentPage][forms[i]] = true; 7440 //Run the success function 7441 form[rule].displayValidateSuccess(); 7442 } 7443 } 7444 } 7445 } 7446 } 7447 } 7448 7449 /** 7450 * Get the status for a given form 7451 * @param {string} form - The name of a given form 7452 * @return {bool} The form status 7453 */ 7454 function getFormStatus(form) { 7455 if (form.length > 0) { 7456 if (typeof (validForms[currentPage]) === 'undefined') 7457 //Set a new key for the current page if it doesn't exist 7458 validForms[currentPage] = {}; 7459 if (typeof (validForms[currentPage][form]) !== 'undefined') { 7460 //Return the status for passed in form name 7461 return validForms[currentPage][form]; 7462 } 7463 } 7464 } 7465 7466 /** 7467 * Get the name of the failing form in a given page 7468 * @param {number} page - The page number 7469 * @return {string} The form name 7470 */ 7471 function getFailedForm(page) { 7472 if (typeof (validForms[page]) === 'undefined') 7473 //Set a new key for the passed in page if it doesn't exist 7474 validForms[page] = {}; 7475 7476 if (Object.keys(validForms[page]).length) { 7477 //Loop through all forms in valid forms 7478 for (var form in validForms[page]) { 7479 //If not valid, return form name 7480 if (!validForms[page][form]) { 7481 return form; 7482 } 7483 } 7484 } 7485 7486 return ''; 7487 } 7488 7489 /** 7490 * Add validation rules for all forms on a given page 7491 * @param {object} obj - The object containing all pages and forms 7492 */ 7493 function addValidationRules(obj) { 7494 if (typeof (validateRules[obj.page]) === 'undefined') 7495 //Create a key for given page 7496 validateRules[obj.page] = {}; 7497 7498 if (obj.hasOwnProperty('forms')) { 7499 if (typeof (validateRules[obj.page]) !== 'undefined') { 7500 7501 obj.forms.forEach(function (value) { 7502 if (typeof (validateRules[obj.page][value.name]) === 'undefined') 7503 //Create a key for given form 7504 validateRules[obj.page][value.name] = {}; 7505 7506 //Loop through all validation rules 7507 for (var rule in value.validateRulesList) { 7508 if (typeof (validateRules[obj.page][value.name][rule]) === 'undefined') 7509 //Create a key for given rule 7510 validateRules[obj.page][value.name][rule] = {}; 7511 7512 //For each rule, populate a rule object with the validation methods 7513 validateRules[obj.page][value.name][rule] = { 7514 validateFunc: value.validateRulesList[rule], 7515 displayValidateError: value.displayValidateErrorList[rule], 7516 displayValidateSuccess: value.displayValidateSuccessList[rule] 7517 }; 7518 } 7519 }); 7520 } 7521 } 7522 } 7523 7524 /** 7525 * Remove current artwork file key from product configure parameters 7526 */ 7527 function removeArtworkFile() {
7528 if(productConfigureParams.hasOwnProperty('CurrentArtworkFile')) 7529 delete productConfigureParams['CurrentArtworkFile']; 7530 } 7531 7532 /** 7533 * Update breadcrumb to previously saved product search parameters 7534 */ 7535 function updateBreadcrumb() { 7536 //If cookies are enabled 7537 if (navigator.cookieEnabled) { 7538 //If storage API supported 7539 if (typeof (Storage) !== "undefined") { 7540 //If session storage key exists 7541 if (sessionStorage.hasOwnProperty('breadcrumbSearchParams')) { 7542 //Parse JSON for breadcrumb search params 7543 var breadcrumbString = JSON.parse(sessionStorage.breadcrumbSearchParams); 7544 //If breadcrumbString has current product id as key 7545 if (breadcrumbString.hasOwnProperty(productConfigureParams.CurrentProductId)) { 7546 //If product key is defined 7547 if (breadcrumbString[productConfigureParams.CurrentProductId]) 7548 //Set breadcrumb link to saved search parameters 7549 $('.breadcrumb li a[data-type="search"]').attr('href', '/search/' + breadcrumbString[productConfigureParams.CurrentProductId]); 7550 } 7551 } 7552 } 7553 } 7554 } 7555 7556 /** 7557 * Reset all states for total rows and remove down class 7558 */ 7559 function resetLineItemDownstates() { 7560 $('#product-config-total table td').each(function () { 7561 if ($(this).hasClass('down')) 7562 $(this).removeClass('down'); 7563 }); 7564 } 7565 7566 /** 7567 * Get total rows HTML based on passed in form, elements, and page 7568 * @param {string} form - The name of the form 7569 * @param {array} elements - The key/value pairs of that form 7570 * @param {number} page - The page number 7571 * @return {string} The total rows HTML 7572 */ 7573 function getTotalRows(form, elements, page) { 7574 var rowHtml = ""; 7575 7576 //Get the page object for passed in page 7577 var pageObj = ProductConfigureSteps.GetPageObj(page); 7578 //Get a reference to the form configuration of the form name that was passed in 7579 var selectedForm = pageObj.forms.filter(function (value) { 7580 if (value.name == form) 7581 return value; 7582 })[0]; 7583 7584 if (selectedForm !== 'undefined' && elements.length) { 7585 for (var k = 0; k < elements.length; k++) { 7586 if (typeof (selectedForm.writeLineTotal) !== 'undefined') { 7587 //Build the row HTML based on the custom function passed in 7588 rowHtml += selectedForm.writeLineTotal(elements[k].name, elements[k].value, pageObj.page, selectedColourLabel, (k + 1)); 7589 } 7590 } 7591 } 7592 7593 return rowHtml; 7594 } 7595 7596 /** 7597 * Get total rows HTML based on passed in form, elements, and page 7598 * @param {object} obj - The object containing row titles and pages 7599 */ 7600 function createTitleRow(obj) { 7601 //Create HTML for a new title row in product config total 7602 var titleRow = $('<tr id="' + obj.rowTitle + '" data-page="' + obj.page + '"><th>' + obj.title + '</th><th> </th></tr>'); 7603 //Get a reference to the next title row, if any 7604 var nextTitle = $('#' + obj.rowTitle).nextAll('tr[id]').first(); 7605 //If we have a title row that comes after the current title row, remove all data (not title) rows between them. This will allow the key/value forms to constantly "refresh", but keep the title row as reference 7606 if ($('#' + obj.rowTitle).nextUntil(nextTitle, 'tr').length) 7607 $('#' + obj.rowTitle).nextUntil(nextTitle, 'tr').remove(); 7608 7609 //If the current title row doesn't exist... 7610 if (!$('#' + obj.rowTitle).length) { 7611 //...and there is a title row that should come after it on the next page (eg. you are editing a page by going back a step) 7612 if (($("tr[data-page=" + (obj.page + 1) + "]").length)) 7613 //Insert the title row before that row
7614 $(titleRow).insertBefore($("tr[data-page=" + (obj.page + 1) + "]")); 7615 else 7616 //If not, insert it before the total row (after that row) 7617 $(titleRow).insertBefore($("tr#total-row")); 7618 } 7619 } 7620 7621 /** 7622 * Get a list of all valid forms 7623 * @param {object} obj - The object containing all pages and forms 7624 * @return {array} An array of all valid form names 7625 */ 7626 function getValidForms(obj) { 7627 //Get all form names where the inner key/value pairs of those forms are not empty 7628 var validForms = obj.forms.map(function (value) { 7629 var elements = ($('#' + value.name).serializeArray().filter(function (input) { 7630 if (input.value != '') 7631 return input; 7632 })); 7633 if (elements.length) 7634 return value.name; 7635 else 7636 return ''; 7637 }).filter(function (value) { 7638 if (value != '') 7639 return value; 7640 }); 7641 7642 return validForms; 7643 } 7644 7645 /** 7646 * Toggle visibility of elements based value of media queries 7647 * @param {object} match - A media query list that matches a pre-determined breakpoint 7648 */ 7649 function smallWidthChange(match) {
7650 //Match all viewports below 992px in width 7651 if (match.matches) { 7652 $('#rep-window').hide(); 7653 } else { 7654 $('#rep-window').show(); 7655 } 7656 7657 //Update the grid as required 7658 ProductGrid.UpdateGrid($('#product-config-pricing-table table:visible'), getSelectedDecorationMethodId(), currentQuantityCount); 7659 } 7660 7661 return { 7662 Init: function (params) { 7663 init(params); 7664 }, 7665 ChangePage: function (page) { 7666 changePage(page); 7667 }, 7668 UpdateTotalColumn: function (obj) { 7669 updateTotalColumn(obj); 7670 }, 7671 SetColour: function (colour) { 7672 setColour(colour); 7673 }, 7674 GetColour: function() { 7675 return productConfigureParams.CurrentColour; 7676 }, 7677 GetProductColours: function() { 7678 return coloursArr; 7679 }, 7680 SetQuantity: function (quantitiesObj) { 7681 setQuantity(quantitiesObj); 7682 }, 7683 GetQuantity: function () { 7684 return currentQuantity; 7685 }, 7686 GetQuantityCount: function () { 7687 return currentQuantityCount; 7688 }, 7689 SetMethod: function (methodObj) { 7690 setMethod(methodObj); 7691 }, 7692 SetLocation: function (locationObj) { 7693 setLocation(locationObj); 7694 }, 7695 SetArtwork: function (artworkObj) { 7696 setArtwork(artworkObj); 7697 }, 7698 SetComments: function (comments) { 7699 setComments(comments); 7700 }, 7701 UpdatePageValues: function (page) { 7702 updatePageValues(page); 7703 }, 7704 GetPriceGrids: function() { 7705 return priceGrids; 7706 }, 7707 GetProductConfigureParams: function () { 7708 return productConfigureParams; 7709 }, 7710 GetSizesHtml: function (decorationMethodId) { 7711 return getSizesHtml(decorationMethodId); 7712 }, 7713 GetSelectedDecorationMethodId: function() { 7714 return getSelectedDecorationMethodId(); 7715 }, 7716 GetCurrentPage: function() { 7717 return currentPage; 7718 }, 7719 PopulateQuantityInputs: function () { 7720 populateQuantityInputs(); 7721 }, 7722 SetArtworkFile: function (fileObj) { 7723 setArtworkFile(fileObj); 7724 }, 7725 GetArtworkFile: function () { 7726 return productConfigureParams.CurrentArtworkFile; 7727 }, 7728 RemoveArtworkFile: function () { 7729 removeArtworkFile(); 7730 }, 7731 ValidateForms: function (formArr, page) { 7732 validateForms(formArr, page); 7733 }, 7734 AddValidationRules: function(forms) { 7735 addValidationRules(forms); 7736 }, 7737 GetProductId: function() { 7738 return productConfigureParams.CurrentProductId; 7739 }, 7740 GetFormStatus: function(form) { 7741 return getFormStatus(form); 7742 }, 7743 GetFailedForm: function (page) { 7744 return getFailedForm(page); 7745 }, 7746 UpdateDisabledPages: function () { 7747 updateDisabledPages(); 7748 }, 7749 ResetLineItemDownstates: function () { 7750 resetLineItemDownstates(); 7751 }, 7752 SelectProductSwatch: function (listItem) { 7753 selectProductSwatch(listItem); 7754 }, 7755 LoadTotalColumn: function() { 7756 loadTotalColumn(); 7757 }, 7758 UpdateDecorationColour: function () { 7759 updateDecorationColour(); 7760 } 7761 } 7762 7763}());; 7764/** Class representing the Product Configure steps. This class holds all of the unique configuration data for all 3 product config pages */ 7765var ProductConfigureSteps = (function () { 7766 //Used to hold all configuration objects for product configure pages 7767 var productConfigPages = {}; 7768 //Used to hold dropzone instance 7769 var myDropzone = {}; 7770 7771 /** 7772 * Initialize the product configure steps with the appropriate page data 7773 */ 7774 function init() { 7775 //Set options for page 1 7776 productConfigPages[1] = { 7777 //Page numbre 7778 page: 1, 7779 //Row title ID 7780 rowTitle: 'product-quantity-title', 7781 //List of forms to group under title 7782 forms: [ 7783 { 7784 //Set the form name 7785 name: 'product-config-quantity-form',
7786 //Custom function that handles how an HTML string is constructed for key/value pairs in this particular form 7787 writeLineTotal: function (name, value, page, colour) { 7788 //Get the quantity ranges from the product grid 7789 var quantityRanges = ProductGrid.GetQuantityRange(ProductConfigure.GetSelectedDecorationMethodId()); 7790 //Get the product configure quantity count 7791 var updatedQuantity = ProductConfigure.GetQuantityCount(); 7792 7793 //If an integer is successfully parsed and quantity is greater than minimum allowed quantity 7794 if ((parseInt(value)) && (updatedQuantity >= quantityRanges[0].QuantityFrom)) { 7795 //Get grid array from form 7796 var gridArray = $('form input[name="' + name + '"]').length ? $('form input[name="' + name + '"]').data('grid-id').toString().split(',') : []; 7797 7798 //Get the current price of the selected quantity range 7799 var price = ProductGrid.GetPrice(ProductConfigure.GetSelectedDecorationMethodId(), gridArray, $('#product-colours ul li a.active')); 7800 7801 //If there are any discount prices available, cross out the regular prices 7802 if (Main.GetDiscount() > 0) 7803 var priceUnformatted = numeral().unformat(price) * (1 - Main.GetDiscount()); 7804 else 7805 var priceUnformatted = numeral().unformat(price); 7806 7807 //Calculate price based on price and value passed in 7808 var calculatedPrice = priceUnformatted * value; 7809 //Format price into dollar value 7810 var parsedPrice = numeral(calculatedPrice).format('$0,0.00'); 7811 //If a colour is defined, create a span with the colour label 7812 var colour = (colour != null) ? " <span class='item-colour'>(" + colour + ")</span>" : "<span class='item-colour'></span>"; 7813 7814 //Return row HTML for display in product config total 7815 return "<tr class='line-item' data-type='quantity' data-name='" + name + "' data-next-page=" + page + "><td>" + value + " " + name + colour + "</td><td style='text-align:right;'><span class='product-price'>" + parsedPrice + "</span></td></tr>"; 7816 } else { 7817 return ""; 7818 } 7819 }, 7820 //Object that holds all the validation rules for this form 7821 validateRulesList: { 7822 //Sizes rule - if there are no sizes inputted, validation check will fail 7823 'sizes': function () { 7824 var sizes = $('#product-config-quantity-form input').filter(function () { 7825 return $(this).val() != ""; 7826 }); 7827 7828 if (!sizes.length) 7829 return false; 7830 else 7831 return true; 7832 }, 7833 //Invalid chars rule - if the inputted entries are not integers, validation check will fail 7834 'invalidchars': function () { 7835 var invalidEntries = $('#product-config-quantity-form input').filter(function () { 7836 if (!Number.isInteger(parseInt($(this).val()))) 7837 return $(this).val(); 7838 }); 7839 7840 if (invalidEntries.length) 7841 return false; 7842 else 7843 return true; 7844 }, 7845 //Minimum quantity rule - if the total quantity falls below the minimum, validation check will fail 7846 'minimumquantity': function () { 7847 var quantityRanges = ProductGrid.GetQuantityRange(ProductConfigure.GetSelectedDecorationMethodId()); 7848 if ((ProductConfigure.GetQuantityCount() < quantityRanges[0].QuantityFrom)) 7849 return false; 7850 else 7851 return true; 7852 } 7853 }, 7854 displayValidateErrorList: { 7855 //For sizes rule fail, output the following 7856 'sizes': function () { 7857 $('#product-selected-quantity').html('<span class="validation-error"><i class="fa fa-exclamation-circle"></i> Enter a quantity below your required sizes.</span>'); 7858 $('#product-config-quantity-form input').css('border', '1px solid #a94442'); 7859 }, 7860 //For invalidchars rule fail, output the following 7861 'invalidchars': function () { 7862 $('#product-selected-quantity').html('<span class="validation-error"><i class="fa fa-exclamation-circle"></i> Please ensure that only numbers are entered.</span>'); 7863 $('#product-config-quantity-form input').css('border', '1px solid #a94442'); 7864 }, 7865 //For minimumquantity rule fail, output the following 7866 'minimumquantity': function () { 7867 var quantityRanges = ProductGrid.GetQuantityRange(ProductConfigure.GetSelectedDecorationMethodId()); 7868 //If this is a positive number, that means that we haven't reached the minimum yet 7869 var difference = quantityRanges[0].QuantityFrom - ProductConfigure.GetQuantityCount(); 7870 7871 if (difference > 0) 7872 $('#product-selected-quantity').html("<span class='validation-error'><i class='fa fa-exclamation-circle'></i> " + ProductConfigure.GetQuantityCount() + " item(s), add " + difference + " more to meet minimum.</span>"); 7873 7874 $('#product-config-quantity-form input').css('border', '1px solid #a94442'); 7875 } 7876 }, 7877 displayValidateSuccessList: { 7878 //For sizes rule success, output the following 7879 'sizes': function () { 7880 $('#product-config-quantity-form input').css('border', '1px solid #e7e7e7'); 7881 }, 7882 //For invalidchars rule success, output the following 7883 'invalidchars': function () { 7884 $('#product-config-quantity-form input').css('border', '1px solid #e7e7e7'); 7885 }, 7886 //For minimumquantity rule success, output the following 7887 'minimumquantity': function () { 7888 $('#product-config-quantity-form input').css('border', '1px solid #e7e7e7'); 7889 } 7890 } 7891 }, 7892 { 7893 name: 'product-config-colour-form', 7894 //Object that holds all the validation rules for this form 7895 validateRulesList: { 7896 //Required rule - if there are no colours checked, validation check will fail 7897 'required': function () { 7898 var checkedColours = $('#product-colours ul li a.active'); 7899 7900 if (!checkedColours.length) 7901 return false; 7902 else 7903 return true; 7904 } 7905 }, 7906 displayValidateErrorList: { 7907 //For required rule fail, output the following 7908 'required': function () { 7909 $('#product-selected-colour').html('<span class="validation-error"><i class="fa fa-exclamation-circle"></i>
7909 Please select a ' + Localize.GetLocaleString('color') + '.</span>'); 7910 } 7911 }, 7912 displayValidateSuccessList: { 7913 'required': function () { } 7914 }, 7915 writeLineTotal: function () { 7916 return ""; 7917 } 7918 }, 7919 { 7920 //Set the form name 7921 name: 'product-config-method-form', 7922 //Custom function that handles how an HTML string is constructed for key/value pairs in this particular form 7923 writeLineTotal: function (name, value, page, colour) { 7924 //Get name value to display in total grid column 7925 var totalName = $('form input[name="' + name + '"]:checked').length ? $('form input[name="' + name + '"]:checked').data('name') : name; 7926 //Get the setup charge of passed in decoration method ID 7927 var price = ProductGrid.GetSetupCharge(ProductConfigure.GetSelectedDecorationMethodId()); 7928 //Get custom label in checkbox data attribute 7929 var label = $('form input[name="' + name + '"]:checked').length ? $('form input[name="' + name + '"]:checked').data('label') : value; 7930 //Format price into dollar value 7931 var parsedPrice = numeral(price).format('$0,0.00'); 7932 //Return row HTML for display in product config total 7933 return "<tr class='line-item' data-type='method' data-name='DecorationMethod' data-next-page=" + page + "><td>" + totalName + " - " + label + "</td><td style='text-align:right;'><span class='product-price'>" + parsedPrice + "</span></td></tr>"; 7934 }, 7935 //Object that holds all the validation rules for this form 7936 validateRulesList: { 7937 //Required rule - if there are no methods checked, validation check will fail 7938 'required': function () { 7939 var checkedMethods = $('#product-config-method-form input[name="DecorationMethod"]:checked'); 7940 7941 if (!checkedMethods.length) 7942 return false; 7943 else 7944 return true; 7945 } 7946 }, 7947 displayValidateErrorList: { 7948 //For required rule fail, output the following 7949 'required': function () { 7950 $('#product-selected-method').html('<span class="validation-error"><i class="fa fa-exclamation-circle"></i> Please select a decoration method.</span>'); 7951 } 7952 }, 7953 displayValidateSuccessList: { 7954 'required': function () { 7955 } 7956 } 7957 } 7958 ], 7959 //Row title label 7960 title: 'Product Quantity' 7961 }; 7962 //Set options for page 2 7963 productConfigPages[2] = { 7964 //Page number 7965 page: 2, 7966 //Row title ID 7967 rowTitle: 'product-decoration-title', 7968 //List of forms to group under title 7969 forms: [ 7970 { 7971 //Set the form name 7972 name: 'product-config-location-form',
7973 //Custom function that handles how an HTML string is constructed for key/value pairs in this particular form 7974 writeLineTotal: function (name, value, page) { 7975 var label = $('form input[name="' + name + '"]').length ? $('form input[name="' + name + '"]:checked').data('label') : value; 7976 return "<tr class='line-item' data-type='location' data-name='" + name + "' data-next-page=" + page + "><td colspan='2'>" + name + " - " + label + "</td></tr>"; 7977 }, 7978 //Object that holds all the validation rules for this form 7979 validateRulesList: { 7980 //Required rule - if there are no locations checked, validation check will fail 7981 'required': function () { 7982 var checkedMethods = $('#product-config-location-form input[name="location"]:checked'); 7983 7984 if (!checkedMethods.length) 7985 return false; 7986 else 7987 return true; 7988 } 7989 }, 7990 displayValidateErrorList: { 7991 //For required rule fail, output the following 7992 'required': function () { 7993 $('#product-selected-location').html('<span class="validation-error"><i class="fa fa-exclamation-circle"></i> Please select a location.</span>'); 7994 } 7995 }, 7996 displayValidateSuccessList: { 7997 'required': function () { 7998 } 7999 } 8000 }, 8001 { 8002 //Set the form name 8003 name: 'product-config-decoration-colour-form', 8004 //Custom function that handles how an HTML string is constructed for key/value pairs in this particular form 8005 writeLineTotal: function (name, value, page, colour, count) { 8006 var parsedPrice = ""; 8007 var parsedSetupCharge = ""; 8008 8009 //All other colours should automatically calculate cost 8010 if (count != 1) { 8011 //Get decoration colour cost based on passed in decoration method ID and count 8012 var price = ProductGrid.GetDecorationColourCost(ProductConfigure.GetSelectedDecorationMethodId(), count); 8013 //Get decoration colour setup charge based on passed in decoration method ID and count 8014 var setupCharge = ProductGrid.GetDecorationColourSetupCharge(ProductConfigure.GetSelectedDecorationMethodId(), count); 8015 //Multiply price by quantity count 8016 var calculatedPrice = price * ProductConfigure.GetQuantityCount(); 8017 //Format the price into currency 8018 parsedPrice = numeral(calculatedPrice).format('$0,0.00'); 8019 8020 var calculatedPrice = setupCharge; 8021 //Format the setup charge into currency 8022 parsedSetupCharge = numeral(calculatedPrice).format('$0,0.00'); 8023 } else { 8024 //The first colour is free 8025 parsedPrice = "INCLUDED"; 8026 parsedSetupCharge = "INCLUDED"; 8027 } 8028 8029 //Get unique colour label from data attribute of colour radio button 8030 var label = $('form input[name="' + name + '"][value="' + value + '"]:checked').length ? $('form input[name="' + name + '"][value="' + value + '"]:checked').data('label') : value; 8031 //If label is black or white, don't prepend PMS 8032 var updatedLabel = ((label == 'Black') || (label == 'White')) ? label : 'PMS ' + label; 8033 8034 //Return row HTML for display in product config total 8035 return "<tr class='line-item' data-type='decoration-colour' data-name='" + name + "' data-next-page=" + page + "><td>" + getOrdinal(count) + " <span class='localized'>Color</span> - <strong> " + updatedLabel + "</strong></td><td style='text-align:right;'><span class='product-price'>" + parsedPrice + "</span></td></tr>" + 8036 "<tr class='line-item' data-type='decoration-colour' data-name='" + name + "' data-next-page=" + page + "><td>Setup Charge</td><td style='text-align:right;'><span class='product-price'>" + parsedSetupCharge + "</span></td></tr>"; 8037 }, 8038 //Object that holds all the validation rules for this form 8039 validateRulesList: { 8040 'required': function () { 8041 //Required rule - if there are no product decoration colours checked, validation check will fail 8042 var checkedColours = $('#product-config-input input.colorpicker-popup').map(function (value) { 8043 if ($(this).val()) { 8044 return $(this).val(); 8045 } 8046 }); 8047 8048 if (!checkedColours.length) 8049 return false; 8050 else 8051 return true; 8052 } 8053 }, 8054 displayValidateErrorList: { 8055 //For required rule fail, output the following 8056 'required': function () { 8057 $('#product-decoration-selected-colour').html('<span class="validation-error"><i class="fa fa-exclamation-circle"></i>
8057 Please select a ' + Localize.GetLocaleString('color') + '.</span>'); 8058 } 8059 }, 8060 displayValidateSuccessList: { 8061 'required': function () { } 8062 } 8063 } 8064 ], 8065 //Row title label 8066 title: 'Decorating Options' 8067 }; 8068 //Set options for page 3 8069 productConfigPages[3] = { 8070 //Page number 8071 page: 3, 8072 //Row title ID 8073 rowTitle: 'product-artwork-location-title', 8074 //List of forms to group under title 8075 forms: [ 8076 { 8077 //Set the form name 8078 name: 'product-config-artwork-form', 8079 //Custom function that handles how an HTML string is constructed for key/value pairs in this particular form 8080 writeLineTotal: function (name, value, page) { 8081 //Get name value to display in total grid column 8082 var newName = $('form input[name="' + name + '"]:checked').length ? $('form input[name="' + name + '"]:checked').data('name') : name; 8083 //Get custom label in radio input 8084 var label = $('form input[name="' + name + '"]:checked').length ? $('form input[name="' + name + '"]:checked').data('label') : value; 8085 8086 return "<tr class='line-item' data-type='artwork' data-name='" + name + "' data-next-page=" + page + "><td>" + newName + " - " + label + "</td><td style='text-align:right;'>N/A</td></tr>"; 8087 }, 8088 //Object that holds all the validation rules for this form 8089 validateRulesList: { 8090 //Required rule - if there are no artwork options checked, validation check will fail 8091 'required': function () { 8092 var checkedArtwork = $('#product-config-artwork-form input[name="artwork"]:checked'); 8093 8094 if (!checkedArtwork.length) 8095 return false; 8096 else 8097 return true; 8098 } 8099 }, 8100 displayValidateErrorList: { 8101 //For required rule fail, output the following 8102 'required': function () { 8103 $('#product-selected-artwork').html('<span class="validation-error"><i class="fa fa-exclamation-circle"></i> Please select a method.</span>'); 8104 } 8105 }, 8106 displayValidateSuccessList: { 8107 'required': function () { 8108 } 8109 } 8110 } 8111 ], 8112 //Row title label 8113 title: 'Product Artwork' 8114 }; 8115 } 8116 8117 /** 8118 * Retrieve the configuration options for a specific product configure page 8119 * @param {number} page - The page number 8120 * @return {object} The product configure page object 8121 */ 8122 function getPageObj(page) { 8123 if (typeof (productConfigPages[page]) !== 'undefined') { 8124 return productConfigPages[page]; 8125 } 8126 } 8127 8128 /** 8129 * Get the product configure page count 8130 * @return {number} The number of product configure pages 8131 */ 8132 function getPageCount() { 8133 return Object.keys(productConfigPages).length; 8134 } 8135 8136 /** 8137 * Enable or disable dropzone based on current value of decoration method 8138 * @param {number} artworkType - The artwork radio value 8139 */ 8140 function checkMethodStatus(artworkType) { 8141 if (artworkType == 1) { 8142 myDropzone.enable(); 8143 $('#upload-artwork').fadeTo("fast", 1); 8144 } else { 8145 myDropzone.disable(); 8146 $('#upload-artwork').fadeTo("fast", 0.3); 8147 } 8148 }; 8149 8150 /** 8151 * Update the JavaScript based on the page that is loaded in product configure 8152 * @param {number} page - Page number 8153 */ 8154 function updateJS(page) { 8155 //Get the page number 8156 switch (page) { 8157 case 1: 8158 //Initialize product grid with product config pricing table 8159 ProductGrid.InitGrids(ProductConfigure.GetPriceGrids(), Main.GetQuantityRanges(ProductConfigure.GetPriceGrids())); 8160 //Append the sizes HTML to the quantity container for the selected decoration method 8161 $('#product-config-quantity-container').empty().append(ProductConfigure.GetSizesHtml(ProductConfigure.GetSelectedDecorationMethodId())); 8162 //Redraw the product config pricing table 8163 $('#product-config-pricing-table').empty() 8164 .append(ProductGrid.GetGridHtml(ProductConfigure.GetSelectedDecorationMethodId())) 8165 .append(ProductGrid.GetVerticalGridHtml(ProductConfigure.GetSelectedDecorationMethodId())); 8166 //Add validation rules found in page configuration object 8167 ProductConfigure.AddValidationRules(getPageObj(page)); 8168 8169 //If a decoration method is already defined, set it in form 8170 if (typeof (ProductConfigure.GetSelectedDecorationMethodId()) !== 'undefined') { 8171 $('#product-config-method-form input[value=' + ProductConfigure.GetSelectedDecorationMethodId() + ']').iCheck('check'); 8172 } 8173 8174 //Update inputs with selected data, if any 8175 ProductConfigure.UpdatePageValues(page); 8176 8177 //Set quantity in product grid 8178 ProductConfigure.SetQuantity($('#product-config-quantity-form input')); 8179 //If there are any discount prices available, cross out the regular prices 8180 if(Main.GetDiscount() > 0) 8181 $('#product-config-pricing-table td span.regular-price').css('text-decoration', 'line-through'); 8182 8183 //When in edit mode, if any of the parameters below are present, validate forms on first page 8184 if ((typeof (getUrlParameter('Edit')) !== 'undefined' && getUrlParameter('Edit')) || 8185 ( 8186 (typeof (getUrlParameter('Quantity')) !== 'undefined') && 8187 (typeof (getUrlParameter('SizeId')) !== 'undefined') 8188 ) || 8189 (typeof (getUrlParameter('ColourId')) !== 'undefined') || 8190 (typeof (getUrlParameter('DecorationMethodId')) !== 'undefined') 8191 ) 8192 //Validate the forms for page 1 and save the results of those tests 8193 ProductConfigure.ValidateForms([], 1); 8194 8195 //Update total column on product configure with custom object 8196 if($('#product-config-quantity-form input#single-quantity').length) 8197 ProductConfigure.ValidateForms(['product-config-quantity-form']); 8198 //Update total column on product configure with current page config object 8199 ProductConfigure.UpdateTotalColumn(getPageObj(page)); 8200 8201 // Set the NumericInput plugin on quantity inputs to prevent decimal inputs. 8202 $('.quantity-input').numericInput({ min: 0, allowNegative: false, allowFloat: false }); 8203 8204 break; 8205 case 2: 8206 //Add validation rules found in page configuration object 8207 ProductConfigure.AddValidationRules(getPageObj(page)); 8208 8209 //If there is only one location, simply check it 8210 if ($('#product-config-location-form input').length == 1) { 8211 $('#product-config-location-form input').iCheck('check'); 8212 } 8213 8214 //Get reference to product decoration colour checkboxes 8215 var $checkboxesObj = $('#product-config-colours'); 8216 //Hide original product decoration colour checkboxes 8217 $checkboxesObj.find('div.checkbox').hide(); 8218 //Parse the checkboxes and return an object representing its values 8219 var listObject = Main.ParseElement($checkboxesObj); 8220 //Create an unordered list with custom colour swatches and add a custom validation function
8221 var swatchSelector = Main.CreateSwatches(listObject); 8222 8223 //Prepend the HTML for the custom colour swatches in the correct location 8224 $('#product-decoration-colours').prepend(swatchSelector); 8225 8226 //Get the maximum amount of decoration colours 8227 var maxInputs = ProductGrid.GetDecorationColourMax(ProductConfigure.GetSelectedDecorationMethodId()); 8228 8229 //Output the number of max input controls for decoration colours 8230 for (i = 0; i < maxInputs; i++) { 8231 $('#product-config-input').append( 8232 $('<div />', { 'class': 'color-line' }).append( 8233 $('<label />', { 'for': 'color-picker-' + (i + 1), 'html': getOrdinal(i + 1) + ' <span class="localized">color</span>' }), 8234 $('<input />', { 'type': 'text', 'class': 'form-control colorpicker-popup', 'id': 'color-picker-' + (i + 1), 'name': 'color-picker-' + (i + 1) }), 8235 $('<button />', { 'type': 'button', 'class': 'color-picker-remove', 'data-id': (i + 1) }).append( 8236 $('<i />', { 'class': 'fa fa-close' }) 8237 ) 8238 ) 8239 ); 8240 } 8241 8242 //Localize all relevant elements 8243 Main.LocalizePage(); 8244 8245 8246 //Intialize colour picker for decoration colours 8247 $('.colorpicker-popup').colorpicker({ 8248 showOn: 'both', 8249 buttonColorize: true, 8250 parts: ['map', 'swatches', 'footer'], 8251 swatches: 'pantone', 8252 colorFormat: 'NAME', 8253 swatchesWidth: 170, 8254 limit: 'name', 8255 select: function (e, color) { 8256 $(e.target).data('bg-color', color.colorPicker.options.color); 8257 8258 //Update decoration colour based on serialized decoration colour form 8259 ProductConfigure.UpdateDecorationColour(); 8260 //Validate the form and save the results of those tests 8261 ProductConfigure.ValidateForms(['product-config-decoration-colour-form']); 8262 //Update total column on product configure with current page config object 8263 ProductConfigure.UpdateTotalColumn(getPageObj(page)); 8264 } 8265 }); 8266 8267 //Update inputs with selected data, if any 8268 ProductConfigure.UpdatePageValues(page); 8269 //If editing a product 8270 if (typeof (getUrlParameter('Edit')) !== 'undefined' && getUrlParameter('Edit')) 8271 //Validate the forms for page 2 and save the results of those tests 8272 ProductConfigure.ValidateForms([], 2); 8273 //Update total column on product configure with custom object 8274 ProductConfigure.UpdateTotalColumn(getPageObj(page)); 8275 break; 8276 case 3: 8277 //Add validation rules found in page configuration object 8278 ProductConfigure.AddValidationRules(getPageObj(page)); 8279 8280 //Get HTML for "Dropzone" template 8281 var template = $('#dropzoneTemplate').html(); 8282 //Compile template using handlebars 8283 var handlebarsTemplate = Handlebars.compile(template); 8284 var html = handlebarsTemplate(); 8285 //Empty and append dropzone html 8286 $('#artwork-tab').empty().append(html); 8287 8288 //Disabling autoDiscover, otherwise Dropzone will try to attach twice. 8289 Dropzone.autoDiscover = false; 8290 //Initialize Dropzone for drag-and-drop file uploading 8291 myDropzone = new Dropzone("#upload-artwork", 8292 { 8293 //Target URL 8294 url: "/Cart/AsyncAddArtwork", 8295 //Only accept the file types below for decoration artwork 8296 acceptedFiles: ".jpg,.jpeg,.png,.gif,.tif,.eps,.dst,.ai,.pdf,.svg", 8297 addRemoveLinks: true, 8298 maxFiles: 1, 8299 paramName: "file", 8300 init: function () { 8301 this.on("addedfile", function (file) { 8302 //Check if svg image is clean 8303 sanitizeSVG(file).then(cleanResult => { 8304 if (!cleanResult) { 8305 this.cancelUpload(file); 8306 swal('Upload Error', "Invalid file upload", 'error'); 8307 } 8308 }) 8309 8310 //If there are 2 files, remove the first one in array 8311 if (this.files[1] != null) { 8312 this.removeFile(this.files[0]); 8313 } 8314 }); 8315 this.on("success", function (file) { 8316 //If upload was successful, set the artwork file 8317 if (typeof (file) !== 'undefined') { 8318 var newDataObj = { 8319 'Filename': file.name, 8320 'Size': file.size 8321 }; 8322 8323 ProductConfigure.SetArtworkFile(newDataObj); 8324 } 8325 }); 8326 this.on("error", function (file, errorMessage) { 8327 //If upload not successful, remove file and show alert 8328 this.removeFile(file); 8329 8330 swal('Error', errorMessage, 'error'); 8331 }); 8332 this.on("removedfile", function (file) { 8333 //When a file is removed, get artwork file 8334 var currentFileObj = ProductConfigure.GetArtworkFile(); 8335 8336 if (typeof (currentFileObj) !== 'undefined') { 8337 //Is the saved file equal to the file attempting to be removed? 8338 if (file.name == currentFileObj.Filename) { 8339 if (!myDropzone.files.length) { 8340 var options = { 8341 callback: { 8342 done: function (response) { 8343 swal({ 8344 title: 'File deleted.', 8345 text: "Your file " + file.name + " was deleted.", 8346 type: 'success', 8347 showCancelButton: fal
8347se, 8348 confirmButtonClass: 'swal2-confirm swal2-styled', 8349 cancelButtonClass: 'swal2-cancel swal2-styled' 8350 }).then(function () { 8351 //Remove file and check the appropriate artwork option 8352 ProductConfigure.RemoveArtworkFile(); 8353 8354 $('#product-config-artwork-form input[value=2]').iCheck('check'); 8355 }); 8356 }, 8357 fail: function () { 8358 // Throw an exception if the request failed. 8359 AsyncException({ 8360 ErrorType: 2, 8361 Message: 'An error occurred while attempting to remove file.' 8362 }); 8363 } 8364 }, 8365 params: { 8366 fileName: file.name 8367 } 8368 } 8369 8370 DataManager.process('Cart', 'RemoveArtwork', options); 8371 } 8372 } 8373 } 8374 }); 8375 } 8376 }); 8377 8378 //Check the appropriate artwork option 8379 $('#product-config-artwork-form input[value=2]').iCheck('check'); 8380 8381 //Update inputs with selected data, if any 8382 ProductConfigure.UpdatePageValues(page); 8383 //If editing a product 8384 if (typeof (getUrlParameter('Edit')) !== 'undefined' && getUrlParameter('Edit')) 8385 //Validate the forms for page 1 and save the results of those tests 8386 ProductConfigure.ValidateForms([], 3); 8387 //Update total column on product configure with current page config object 8388 ProductConfigure.UpdateTotalColumn(getPageObj(page)); 8389 8390 //Enable or disable dropzone based on current value of decoration method 8391 checkMethodStatus(parseInt($('#product-config-artwork-form input[name="artwork"]:checked').val())); 8392 break; 8393 } 8394 8395 //Convert all radios to iCheck display 8396 $('#product-config-content input[type=radio]').iCheck({ 8397 radioClass: 'iradio_minimal' 8398 }); 8399 } 8400 8401 return { 8402 Init: function() { 8403 init(); 8404 }, 8405 UpdateJS: function (page) { 8406 updateJS(page); 8407 }, 8408 GetPageObj: function (page) { 8409 return getPageObj(page); 8410 }, 8411 GetPageCount: function () { 8412 return getPageCount(); 8413 }, 8414 CheckMethodStatus: function (artworkType) { 8415 checkMethodStatus(artworkType); 8416 } 8417 } 8418}());; 8419//When an AJAX call is made, block the product config content 8420$(document).ajaxStart(function () { 8421 $('section#product-config-content').block({ 8422 message: null, 8423 overlayCSS: { 8424 backgroundColor: '#ffffff' 8425 } 8426 }); 8427}); 8428 8429//When an AJAX call is done, unblock it 8430$(document).ajaxStop(function () { 8431 $('section#product-config-content').unblock(); 8432}); 8433 8434//When the next button is clicked, change the page 8435$('body').on('click', '#product-config-next', function () { 8436 //Validate the forms for the current page and save the results of those tests 8437 ProductConfigure.ValidateForms([], ProductConfigure.GetCurrentPage()); 8438 8439 //If there is no failing form 8440 if (!ProductConfigure.GetFailedForm(ProductConfigure.GetCurrentPage()).length) { 8441 //Get the next page number and update the page display 8442 if (parseInt($(this).data('next-page'))) { 8443 ProductConfigure.ChangePage($(this).data('next-page')); 8444 } 8445 } else { 8446 //If there is a failing form, automatically scroll to it 8447 if ($("#" + ProductConfigure.GetFailedForm(ProductConfigure.GetCurrentPage())).parents('section').first().length) 8448 $('html,body').animate({ scrollTop: $("#" + ProductConfigure.GetFailedForm(ProductConfigure.GetCurrentPage())).parents('section').first().offset().top - $('#top-wrapper').height() }, 'slow'); 8449 } 8450}); 8451 8452//When the previous button is clicked, change the page 8453$('body').on('click', '#product-config-previous', function () { 8454 if (parseInt($(this).data('previous-page'))) { 8455 ProductConfigure.ChangePage($(this).data('previous-page')); 8456 } 8457}); 8458 8459//Update the product config progress bar and add disabled class to all pages beyond the next page 8460ProductConfigure.UpdateDisabledPages(); 8461 8462//When any numbers on the progress bar are clicked, move to that page 8463$('body').on('click', '.product-config-progress li a', function () { 8464 //If the page number can be parsed successfully 8465 if (parseInt($(this).data('page'))) { 8466 //Do not proceed if the button is disabled 8467 if ($(this).parent().hasClass('disabled')) { 8468 return; 8469 } 8470 8471 //Validate the forms for the current page and save the results of those tests 8472 ProductConfigure.ValidateForms([],ProductConfigure.GetCurrentPage()); 8473 8474 //If there is no failing form, the page clicked is equal to this page plus 1 OR the page clicked is the current page or a page preceeding it 8475 if (!(ProductConfigure.GetFailedForm(ProductConfigure.GetCurrentPage()).length && ($(this).data('page') == (ProductConfigure.GetCurrentPage() + 1))) || (parseInt($(this).data('page')) <= ProductConfigure.GetCurrentPage())) { 8476 ProductConfigure.ChangePage($(this).data('page')); 8477 } else { 8478 //If there is a failing form, automatically scroll to it 8479 if($("#" + ProductConfigure.GetFailedForm(ProductConfigure.GetCurrentPage())).parents('section').first().length) 8480 $('html,body').animate({ scrollTop: $("#" + ProductConfigure.GetFailedForm(ProductConfigure.GetCurrentPage())).parents('section').first().offset().top - $('#top-wrapper').height() }, 'slow'); 8481 } 8482 } 8483}); 8484 8485//Whenever a total row is moused over, add active class 8486$(document).on('mouseover', '#product-config-total tr.line-item', function () { 8487 $(this).find('td').addClass('active') 8488}); 8489 8490//Whenever a total row is moused out, remove active class 8491$('body').on('mouseleave', '#product-config-total tr.line-item', function () { 8492 $(this).find('td').removeClass('active') 8493}); 8494 8495//When a total row is clicked 8496$('body').on('click', '#product-config-total tr.line-item', function () { 8497 //Remove all down states for total columns 8498 ProductConfigure.ResetLineItemDownstates(); 8499 //Add down state to line item 8500 $(this).find('td').addClass('down') 8501 8502 if (typeof ($(this).data('next-page')) !== 'undefined') { 8503 //If next page number is defined and it's not equal to the current page, go to that page 8504 if (ProductConfigure.GetCurrentPage() != parseInt($(this).data('next-page'))) { 8505 ProductConfigure.ChangePage($(this).data('next-page')); 8506 } 8507 } 8508 8509 if (typeof ($(this).data('type')) !== 'undefined') { 8510 //Depending on the total row clicked, go to corresponding form 8511 switch ($(this).data('type')) { 8512 //If quantity row clicked, scroll to quantity form 8513 case 'quantity': 8514 if (typeof ($(this).data('name')) !== 'undefined') { 8515 $('html,body').animate({ scrollTop: $("#product-config-container").offset().top }, 'slow'); 8516 $('#product-config-quantity-form input[name="' + $(this).data('name') + '"]').focus() 8517 } 8518 break; 8519 //If method row clicked, scroll to method form 8520 case 'method': 8521 if (typeof ($(this).data('name')) !== 'undefined') { 8522 $('html,body').animate({ scrollTop: $("#product-config-decoration-method").offset().top }, 'slow'); 8523 $('#product-config-method-form input[name="' + $(this).data('name') + '"]').focus() 8524 } 8525 break; 8526 //If location row clicked, scroll to location form 8527 case 'location': 8528 if (typeof ($(this).data('name')) !== 'undefined') { 8529 $('html,body').animate({ scrollTop: $("#product-config-decoration-location").offset().top }, 'slow'); 8530 $('#product-config-location-form input[name="' + $(this).data('name') + '"]').focus() 8531 } 8532 break; 8533 //If decoration colour row clicked, scroll to decoration colour form 8534 case 'decoration-colour': 8535 if (typeof ($(this).data('name')) !== 'undefined') { 8536 $('html,body').animate({ scrollTop: $("#product-config-colour").offset().top }, 'slow'); 8537 } 8538 break; 8539 //If artwork row clicked, scroll to artwork form 8540 case 'artwork': 8541 if (typeof ($(this).data('name')) !== 'undefined') { 8542 $('html,body').animate({ scrollTop: $("#product-config-artwork-options").offset().top }, 'slow'); 8543 $('#product-config-artwork-form input[name="' + $(this).data('name') + '"]').focus() 8544 } 8545 break; 8546 } 8547 } 8548}); 8549 8550//When back to cart button is clicked, get product configure parameters and submit via form POST 8551$('#back-to-cart').on('click', function () { 8552 let params = TpcUtility.stripHtmlTags(ProductConfigure.GetProductConfigureParam
8552s()); 8553 $.form('/cart/additem/', params, 'POST').submit(); 8554}); 8555 8556//When product config quantity form is submitted, cancel event 8557$('body').on('submit', '#product-config-quantity-form', function (e) { 8558 e.preventDefault(); 8559}); 8560 8561//Add click handler to handle changing of quantity manually 8562$('body').on('change', '#product-config-quantity-form input', function () { 8563 var page = 1; 8564 8565 //Get quantity range from product grid 8566 var quantityRange = ProductGrid.GetQuantityRange(ProductConfigure.GetSelectedDecorationMethodId()); 8567 8568 if (quantityRange.length) { 8569 //If quantity is greater or equal to the lowest possible value... 8570 if (parseInt($('.product-quantity').val()) >= quantityRange[0].QuantityFrom) 8571 //Update newly decremented value in input 8572 $('.product-quantity-container .product-quantity').val($(this).val()); 8573 8574 //Set quantity in product configure class 8575 ProductConfigure.SetQuantity($('#product-config-quantity-form input')); 8576 //If there are any discount prices available, cross out the regular prices 8577 if (Main.GetDiscount() > 0) 8578 $('#product-config-pricing-table td span.regular-price').css('text-decoration', 'line-through'); 8579 //Validate the form and save the results of those tests 8580 ProductConfigure.ValidateForms(['product-config-quantity-form']); 8581 //Update total column on product configure with current page config object 8582 ProductConfigure.UpdateTotalColumn(ProductConfigureSteps.GetPageObj(page)); 8583 } 8584}); 8585 8586//Add click handler to add quantity button 8587$('body').on('click', '.product-quantity-container .add-quantity', function () { 8588 var page = 1; 8589 8590 //Parse integer from quantity input values 8591 var newValue = parseInt($('.product-quantity-container input').val()) + 1; 8592 //Update newly incremented value in input 8593 $('.product-quantity-container input').val(newValue); 8594 //Used to revert value to a legal number (higher than the minimum quantity) 8595 $('.product-quantity-container input').data('current-value', $('.product-quantity-container input').val()); 8596 //Set quantity in product configure class 8597 ProductConfigure.SetQuantity($('#product-config-quantity-form input')); 8598 //If there are any discount prices available, cross out the regular prices 8599 if (Main.GetDiscount() > 0) 8600 $('#product-config-pricing-table td span.regular-price').css('text-decoration', 'line-through'); 8601 //Validate the forms for the current page and save the results of those tests 8602 ProductConfigure.ValidateForms(['product-config-quantity-form']); 8603 //Update total column on product configure with current page config object 8604 ProductConfigure.UpdateTotalColumn(ProductConfigureSteps.GetPageObj(page)); 8605}); 8606 8607//Add click handler to the remove quantity button 8608$('body').on('click', '.product-quantity-container .remove-quantity', function () { 8609 var page = 1; 8610 8611 //Parse integer from quantity input values 8612 var newValue = parseInt($('.product-quantity-container input').val()) - 1; 8613 //Get quantity range from product grid 8614 var quantityRange = ProductGrid.GetQuantityRange(ProductConfigure.GetSelectedDecorationMethodId()); 8615 8616 if (quantityRange.length) { 8617 //If quantity is greater than the lowest possible value... 8618 if (parseInt($('.product-quantity-container input').val()) > quantityRange[0].QuantityFrom) { 8619 //Update newly decremented value in input 8620 $('.product-quantity-container input').val(newValue); 8621 $('.product-quantity-container input').data('current-value', $('.product-quantity-container input').val()); 8622 } 8623 //Set quantity in product configure class 8624 ProductConfigure.SetQuantity($('#product-config-quantity-form input')); 8625 //If there are any discount prices available, cross out the regular prices 8626 if (Main.GetDiscount() > 0) 8627 $('#product-config-pricing-table td span.regular-price').css('text-decoration', 'line-through'); 8628 //Validate the forms for the current page and save the results of those tests 8629 ProductConfigure.ValidateForms(['product-config-quantity-form']); 8630 //Update total column on product configure with current page config object 8631 ProductConfigure.UpdateTotalColumn(ProductConfigureSteps.GetPageObj(page)); 8632 } 8633}); 8634 8635$('body').on('ifChecked', '#product-config-method-form input', function () { 8636 var page = 1; 8637 8638 //Set decoration method to the selected radio button 8639 ProductConfigure.SetMethod($(this)); 8640 8641 //Append the sizes HTML to the quantity container for the selected decoration method 8642 $('#product-config-quantity-container').empty().append(ProductConfigure.GetSizesHtml(ProductConfigure.GetSelectedDecorationMethodId())); 8643 //Redraw the product config pricing table 8644 $('#product-config-pricing-table').empty() 8645 .append(ProductGrid.GetGridHtml(ProductConfigure.GetSelectedDecorationMethodId())) 8646 .append(ProductGrid.GetVerticalGridHtml(ProductConfigure.GetSelectedDecorationMethodId())); 8647 8648 //Get the quantity range for selected decoration method 8649 var quantityRange = ProductGrid.GetQuantityRange(ProductConfigure.GetSelectedDecorationMethodId()); 8650 if (quantityRange.length) { 8651 //If the current quantity is out of bounds... 8652 if ((ProductConfigure.GetQuantityCount() > 0) && (ProductConfigure.GetQuantityCount() < quantityRange[0].QuantityFrom)) { 8653 //Set the product quantity to the lowest possible value 8654 $('.product-quantity-container .product-quantity').val(quantityRange[0].QuantityFrom); 8655 $('.product-quantity-container .product-quantity').data('current-value', quantityRange[0].QuantityFrom); 8656 8657 //Display a notification when user selects a different decoration method 8658 swal('Price updated!', 'You have selected a different decoration method. <strong>Minimum quantity</strong> and <strong>pricing</strong> have been updated.', 'info'); 8659 8660 //Scroll back up to the product grid after user selects a different method 8661 $('html,body').animate({ scrollTop: $("#product-config-steps").offset().top }, 'slow'); 8662 } 8663 } 8664 8665 if ($('#colour-selector').length) { 8666 //Empty the colour selector and get colours based on passed in decoration method 8667 $('#colour-selector').empty(); 8668 var colours = (ProductGrid.GetDecorationMethodColours(ProductConfigure.GetSelectedDecorationMethodId()).length) ? ProductGrid.GetDecorationMethodColours(ProductConfigure.GetSelectedDecorationMethodId()) : ProductConfigure.GetProductColours(); 8669 //Get all colour IDs from the colours array 8670 var colourIds = colours.map(function (value) { 8671 return value.Id; 8672 }); 8673 8674 //Append a default option 8675 $('#colour-selector').append($('<option />').val("").text(''));
8676 colours.forEach(function (value) { 8677 //For each returned colour, build options and append relevant attributes 8678 var listItem = $('<option />').val(value.Id); 8679 listItem.text(value.Label); 8680 listItem.data('bg-color', value.HexCodes.map(function (value) { 8681 return value.HexCode; 8682 })); 8683 listItem.data('grid-id', value.GridId); 8684 8685 $('#colour-selector').append(listItem); 8686 }); 8687 8688 //Get reference to product colour select 8689 var $selectObj = $('#colour-selector').hide(); 8690 //Parse the select and return an object representing its values 8691 var listObject = Main.ParseElement($selectObj); 8692 //Create an unordered list with custom colour swatches 8693 var swatchSelector = Main.CreateSwatches(listObject); 8694 //Prepend the HTML for the custom colour swatches in the correct location 8695 $('#product-colours > ul').remove(); 8696 $('#product-colours').prepend(swatchSelector); 8697 8698 //If only one colour returned, trigger a click event 8699 if ($('#product-config-colour #product-colours ul li').length == 1) { 8700 $('#product-config-colour #product-colours ul li a').trigger('click'); 8701 } else { 8702 //Otherwise, set colour to null 8703 if($.inArray(ProductConfigure.GetColour(),colourIds) == -1) 8704 ProductConfigure.SetColour(null); 8705 } 8706 } 8707 8708 //Populate product quantity inputs with existing values 8709 ProductConfigure.PopulateQuantityInputs(); 8710 //Sets the quantity values of the given product based on the quantity input group 8711 ProductConfigure.SetQuantity($('#product-config-quantity-form input')); 8712 //Validate form passed in based on custom predefined validation rules on a given page 8713 ProductConfigure.ValidateForms(['product-config-method-form']); 8714 //Update total column on product configure with current page config object 8715 ProductConfigure.UpdateTotalColumn(ProductConfigureSteps.GetPageObj(page)); 8716}); 8717 8718$('body').on('click touchstart', '#product-config-colour #product-colours ul li a', function (e) { 8719 e.stopPropagation(); 8720 e.preventDefault(); 8721 8722 var page = 1; 8723 8724 // Get valid grids for selected colour and enable only relevant sizes 8725 var gridIds = Object.keys(ProductGrid.GetColorEnabledGrids(ProductConfigure.GetSelectedDecorationMethodId(), $(e.target).data('id'))); 8726 8727 if (gridIds.length && $('#product-config-quantity-form input').length > 1) { 8728 // Disable all sizes by default 8729 $('#product-config-quantity-form input').prop('disabled', true); 8730 8731 //Loop through colour enabled grid ids 8732 gridIds.forEach(function (value) { 8733 $('#product-config-quantity-form input').each(function () { 8734 //For each quantity input, get the grid ID and split it on the comma 8735 var ids = $(this).data('grid-id').toString().split(','); 8736 8737 //If the current grid ID isn't found in the ids array 8738 if ($.inArray(value, ids) != -1) { 8739 //Disable the current colour 8740 $(this).prop('disabled', false); 8741 } 8742 }); 8743 }); 8744 8745 // If there are still disabled inputs, clear the values 8746 $('#product-config-quantity-form input:disabled').each(function () { 8747 $(this).val(''); 8748 }); 8749 } 8750 8751 ProductConfigure.SelectProductSwatch(e.target); 8752}); 8753 8754//Add click handler when location is checked 8755$('body').on('ifChecked', '#product-config-location-form input', function () { 8756 var page = 2; 8757 8758 //Set quantity in product configure class 8759 if ($(this).data('src').length) 8760 $('#decoration-location-img').empty().append($('<img />', { 'src': "/Images/" + $(this).data('src'), 'class': 'img-responsive', 'alt': '' })); 8761 else 8762 $('#decoration-location-img').empty(); 8763 8764 //Set a decoration location for a given product 8765 ProductConfigure.SetLocation($(this)); 8766 //Validate form passed in based on custom predefined validation rules on a given page 8767 ProductConfigure.ValidateForms(['product-config-location-form']); 8768 //Update total column on product configure with current page config object 8769 ProductConfigure.UpdateTotalColumn(ProductConfigureSteps.GetPageObj(page)); 8770}); 8771 8772//When product config decoration colour form is submitted, cancel event 8773$('body').on('submit', '#product-config-decoration-colour-form', function (e) { 8774 e.preventDefault(); 8775}); 8776 8777//When add to cart button is clicked 8778$('body').on('click', '#add-to-cart', function (e) { 8779 var page = 3; 8780 8781 e.preventDefault(); 8782 8783 //Validate form passed in based on custom predefined validation rules on selected page 8784 ProductConfigure.ValidateForms([], page); 8785 //If there are no failed forms on given page, get product configure parameters and submit via form POST 8786 if (!ProductConfigure.GetFailedForm(page).length) { 8787 let params = TpcUtility.stripHtmlTags(ProductConfigure.GetProductConfigureParam
8787s()); 8788 $.form('/cart/additem/', params, 'POST').submit(); 8789 } else { 8790 //If there is a failing form, automatically scroll to it 8791 $('html,body').animate({ scrollTop: $("#" + ProductConfigure.GetFailedForm(ProductConfigure.GetCurrentPage())).parents('section').first().offset().top - $('#top-wrapper').height() }, 'slow'); 8792 } 8793}); 8794 8795//When artwork radio button is checked 8796$('body').on('ifChecked', '#product-config-artwork-form input', function () { 8797 var page = 3; 8798 8799 //Set artwork to value of input that was clicked in product configure class 8800 ProductConfigure.SetArtwork($(this)); 8801 //Validate the passed in form and save the results of those tests 8802 ProductConfigure.ValidateForms(['product-config-artwork-form']); 8803 //Update total column on product configure with current page config object 8804 ProductConfigure.UpdateTotalColumn(ProductConfigureSteps.GetPageObj(page)); 8805 //Fade upload artwork control in or out depending on passed in value 8806 ProductConfigureSteps.CheckMethodStatus(parseInt($(this).val())) 8807}); 8808 8809//Set value of comments on every key press 8810$('body').on('keyup', '#product-config-comments-form #comments', function () { 8811 ProductConfigure.SetComments($(this).val()); 8812}); 8813 8814//When a decoration colour swatch is clicked 8815$('body').on('click touchstart', '#product-decoration-colours ul li a', function (e) { 8816 e.stopPropagation(); 8817 e.preventDefault(); 8818 8819 //Get PMS value 8820 if ($(e.target).data('pms')) { 8821 $('.colorpicker-popup').each(function () { 8822 if (!$(this).colorpicker('getColor')) { 8823 //Set the colour in colour picker with passed in PMS value 8824 $(this).colorpicker('setColor', $(e.target).data('pms')); 8825 return false; 8826 } 8827 }); 8828 } 8829}); 8830 8831//When remove button next to decoration colour is clicked 8832$('body').on('click', 'button.color-picker-remove', function (e) { 8833 if ($('#color-picker-' + $(e.currentTarget).data('id')).length) { 8834 //Set colour to null 8835 $('#color-picker-' + $(e.currentTarget).data('id')).colorpicker('setColor', null); 8836 } 8837}); 8838 8839//Initialize the main slick carousel with predetermined options 8840$('.product-slider').slick({ 8841 slidesToShow: 1, 8842 slidesToScroll: 1, 8843 prevArrow: "<i class='fa fa-chevron-left slick-prev'></i>", 8844 nextArrow: "<i class='fa fa-chevron-right slick-next'></i>", 8845 fade: true 8846});;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.